Monday, December 5, 2011

Ikariam Empire Board


// coding: utf-8
// ==UserScript==
// @name  Ikariam Empire Board
// @namespace empire-board.ikariam
// @version 205
// @author  oliezekat
// @description Display population, resources, trading, transports, incomes, buildings, and army or fleet units overviews for each cities. Support any countries/languages.
// @icon http://s3.amazonaws.com/uso_ss/icon/41051/large.jpg
// @require http://userscripts.org/scripts/source/60774.user.js
// @include http://s*.ikariam.*/*
// @include http://s*.*.ikariam.*/*
// @exclude http://support.ikariam.*/*
// @exclude http://board.*.ikariam.*/*
// ==/UserScript==

/**************************************************************************************************
LAST CHANGES:

Version 2.0.5:
- Fix to detect troop/fleet deployment under v.0.4.4.1
- Detect government type
- Detect number of cultural treaties into any museum
- Apply research bonus per cultural treaties under Demokratie government
- Fix to detect current Ikariam version
- Support new fleet units (under v.0.4.x rev 28493 on s666 server)
- Fix to detect premium features remaining time
- Add premium icon to report if require to fetch features remaining times
- Fix if tavern has been demolished without disable wine usage
- Fix if barracks/shipyard has been demolished while units were under construction
- Report foreign transports which will arrive for trading or exchange (from "Troop movements" view)

PREVIOUS CHANGES:
http://feeds.feedburner.com/ikariam-v3-empire-board

Based on "Ikariam Alarm And Overview Table" script (for Ikariam v0.2.8)
http://userscripts.org/scripts/show/35995
**************************************************************************************************/

// Old global vars
var config;
var langtype;
var texts;
var buildings;
var tavernWineUsage = [0, 4, 8, 13, 18, 24, 30, 37, 44, 51, 60, 68, 78, 88, 99, 110, 122, 136,150,165,180,197,216,235,255,277,300,325,351,378,408,439,472,507,544,584,626,670,717,766,818,874,933,995,1060,1129,1202,1278];
var townHallSpaces = [0, 60, 96, 142, 200, 262, 332, 410, 492, 580, 672, 768, 870, 976, 1086, 1200, 1320, 1440, 1566, 1696, 1828, 1964, 2102, 2246, 2390, 2540, 2690, 2845, 3003, 3163, 3326, 3492, 3710, 3880, 4054, 4230, 4410, 4590, 4774, 4960, 5148, 5340, 5532, 5728, 5926, 6126, 6328, 6534, 6760];

// Old objects
function Resource()
 {
 this.wood  = 0;
 this.wine  = 0;
 this.marble  = 0;
 this.glass  = 0; // For crystal
 this.sulfur  = 0;
 }

// New unique object
if (!EmpireBoard) var EmpireBoard = {};

EmpireBoard =
 {
 /* Requires modules */
 Log:    {},
 DOM:    {},
 Str:    {},
 Ikariam:   {},
 DB:     {},
 Renders:   {},
 Tooltip:   {},
 Handlers:   {},
 Updater:   {},
 
 StartTime:   0,
 EndTime:   0,
 LogEnabled:   false,
 MainID:    'EmpireBoard',
 
 /* Script metas */
 ScriptName:   'Ikariam Empire Board',
 Version:   205,
 HomePage:   '',
 ScriptURL:   '',
 UserScriptsID:  41051
 };

EmpireBoard.Init = function()
 {
 this.StartTime = new Date().getTime();
 this.HomePage   = 'http://userscripts.org/scripts/show/'+this.UserScriptsID;
 this.ScriptURL   = 'http://userscripts.org/scripts/source/'+this.UserScriptsID+'.user.js';
 
 /* Init Log */
 this.Log.Init(this);
 this.Log._Enabled = this.LogEnabled;
 this.Log.Add('Start...');
 
 this.DOM.Init(this);
 this.Str.Init(this);
 this.Ikariam.Init(this);
 this.DB.Init(this);
 this.DB.Load_Options();
 this.Intl.Init(this, this.MainID);
 this.Renders.Init(this);
 this.Tooltip.Init(this, this.MainID+'Tooltip', this.MainID);
 this.Handlers.Init(this);
 this.Updater.Init(this);
 
 // Always create main div for add-ons which need to check version
 var body = this.DOM.Get_First_Node("//body");
 if (body != null)
  {
  var div = document.createElement('div');
  div.id = this.MainID;
  div.setAttribute("version", this.Version);
  body.appendChild(div);
  }
 
 this.DB.Load();
 
 this.Intl.SetLanguage(this.DB.Options.Prefs.LANGUAGE);
 this.Intl.Load_LocalizedTexts();
 
 // Str module presets
 this.Str._decimalPoint     = this.Ikariam.LocalizationStrings('decimalPoint');
 this.Str._thousandSeparator    = this.Ikariam.LocalizationStrings('thousandSeperator');
 if (this.Str._decimalPoint == undefined)
  this.Str._decimalPoint = '.';
 if (this.Str._thousandSeparator == undefined)
  this.Str._thousandSeparator = ',';
 this.Str._timeunits_short_day   = this.Ikariam.LocalizationStrings('day','timeunits','short');
 this.Str._timeunits_short_hour   = this.Ikariam.LocalizationStrings('hour','timeunits','short');
 this.Str._timeunits_short_minute  = this.Ikariam.LocalizationStrings('minute','timeunits','short');
 this.Str._timeunits_short_second  = this.Ikariam.LocalizationStrings('second','timeunits','short');
 if (this.Str._timeunits_short_day == undefined)
  this.Str._timeunits_short_day = 'D';
 if (this.Str._timeunits_short_hour == undefined)
  this.Str._timeunits_short_hour = 'h';
 if (this.Str._timeunits_short_minute == undefined)
  this.Str._timeunits_short_minute = 'm';
 if (this.Str._timeunits_short_second == undefined)
  this.Str._timeunits_short_second = 's';
 
 this.CheckScriptUpdate();
 
 this.FetchData();
 };
 
EmpireBoard.FetchData = function()
 {
 // 1. Global data
 
 // 1.1 current cities
 this.Ikariam.Fetch_CitiesSelect(this.DB.CurrentCities, true);
 // 1.2 gold
 var GoldTitle = this.DOM.Get_First_Node_Title("//div[@id='globalResources']//li[@class='gold']",'?');
 if (GoldTitle != '?')
  {
  config.gold = this.Str.To_Integer(GoldTitle, 0);
  }
 else
  {
  // not connected ?
  }
 this.Log.Add('Gold = '+config.gold);
 
 // 2. Current city data
 
 // 2.1 Current city Id
 
 // 2.2 Current city ressources
 
 // 3. Main view data
 
 };
 
EmpireBoard.CheckScriptUpdate = function()
 {
 if ((this.DB.Options['LastCheckUpdate'] == undefined) || (this.DB.Options['LastCheckUpdate'] < this.StartTime - (1000 * 60 * 60 * 24)))
  {
  var self = this;
  var ScriptURL = 'http://userscripts.org/scripts/source/'+this.UserScriptsID+'.meta.js?since='+this.StartTime;
  this.Updater.Check(ScriptURL, function(availableVersion) { self._CompareScriptUpdate(availableVersion); });
  }
 else
  {
  this.Log.Add('Not need check update today');
  }
 };
 
EmpireBoard._CompareScriptUpdate = function(availableVersion)
 {
 this.Log.Add('Available version: '+availableVersion);
 if (availableVersion != 0)
  {
  availableVersion = parseInt(availableVersion);

  if ((availableVersion > this.Version) && ((this.DB.Options['AvailableVersion'] == undefined) || (availableVersion > this.DB.Options['AvailableVersion'])))
   {
   if (confirm("Do you want to install \""+this.ScriptName+"\" v. "+availableVersion+" ?"))
    {
    GM_openInTab(this.ScriptURL+'?version='+availableVersion+'.user.js');
    }
   }
  
  this.DB.Options['AvailableVersion'] = availableVersion;
  this.DB.Options['LastCheckUpdate'] = this.StartTime;
  this.DB.Save_Options();
  }
 };
 
EmpireBoard.ViewIsFinances = function()
 {
 if (this.Ikariam.Is_Version('0.3.4') == true)
  {
  var Cities = this.DB.CurrentCities;
  
  // 1. Sum of population
  var overallPop = 0;
  for (CityId in Cities)
   {
   if (Cities[CityId].own != true) continue;
   var city = getCity(CityId);
   var population = getArrValue(city.buildings['townHall'], 'population', '?');
   
   if (population == '?')
    {
    overallPop = '?';
    break;
    }
   else
    {
    overallPop += parseInt(population);
    }
   }
  
  if (overallPop != '?')
   {
   this.Log.Add('overallPop = '+overallPop);
   
   // 2. Fetch overall Upkeep
   var overallUpkeep = '?';
   var cells = this.DOM.Get_Nodes("//table[@id='upkeepReductionTable'][3]//td[contains(@class,'hidden')]");
   if (cells.snapshotLength >= 3)
    {
    overallUpkeep = Math.abs(this.Str.To_Integer(cells.snapshotItem(1).textContent,0));
    
    config["upkeeps"]['overall'] = overallUpkeep;
    
    this.Log.Add('overallUpkeep = '+overallUpkeep);
    }
    
   if (overallUpkeep != '?')
    {
    // 3. Fetch and update citizens (gold) production
    // 3.1. Array of cities per name
    var citiesIDs = {};
    var lName = '';
    for (CityId in Cities)
     {
     if (Cities[CityId].own != true) continue;
     var cName = Cities[CityId].name+'';
     citiesIDs[cName] = parseInt(CityId);
     if (lName == cName) this.Ikariam.Insert_Warning("You may choose different names for each cities.",this.ScriptName);
     lName = cName+'';
     }
    // 3.2. Fetch cities table
    var nodes = this.DOM.Get_Nodes("//table[@id='balance']//td[@class='city']");
    for (var i = 0; i < nodes.snapshotLength; i++)
     {
     var node = nodes.snapshotItem(i);
     var cName = this.Str.Trim(node.innerHTML);
     var cID = citiesIDs[cName];
     
     var tr = node.parentNode;
     var tds = tr.getElementsByTagName("td");
     //var tds = tr.childNodes;
     var citizensProd = this.Str.To_Integer(tds[3].innerHTML);
     
     var city = getCity(cID); 
     
     if (city.buildings["townHall"] == undefined) city.buildings["townHall"] = {};
     
     city.buildings["townHall"].citizensProd  = citizensProd;
     this.Log.Add('['+cName+'] (from Finances): citizensProd='+citizensProd);
     }
    
    // 4. Calc shared upkeep for each cities
    for (CityId in Cities)
     {
     if (Cities[CityId].own != true) continue;
     var city = getCity(CityId);
     var population = getArrValue(city.buildings['townHall'], 'population', '?');
     
     if (population != '?')
      {
      var upkeep = Math.ceil(((overallUpkeep*parseInt(population)) / overallPop)-0.6);
      city.buildings["townHall"].upkeep = upkeep;
      this.Log.Add('['+Cities[CityId].name+'] (from Finances): upkeep='+upkeep);
      
      // 5. Calc new income
      var citizensProd = getArrValue(city.buildings['townHall'], 'citizensProd', '?');
      if (citizensProd != '?')
       {
       var incomegold = citizensProd - upkeep;
       city.buildings["townHall"].incomegold = incomegold;
       this.Log.Add('['+Cities[CityId].name+'] (from Finances): incomegold='+incomegold);
       }
      }
     }
    }
   }
  }
 else if (this.Ikariam.Is_Version('0.3.3') == true)
  {
  // Too late to support it, sorry
  }
 else
  {
  var citiesIDs = {};
  var res = this.DOM.Get_Nodes("//select[@id='citySelect']/option");
  for(var i = 0; i < res.snapshotLength; i++)
    {
    var n = res.snapshotItem(i);
    var cName = this.Ikariam.Trim_Coords(n.innerHTML);
    citiesIDs[cName] = parseInt(n.value);
    }
    
  var nodes = this.DOM.Get_Nodes("//table[@id='balance']//td[@class='city']");
  for (var i = 0; i < nodes.snapshotLength; i++)
   {
   var node = nodes.snapshotItem(i);
   var cName = this.Str.Trim(node.innerHTML);
   var cID = citiesIDs[cName];
   
   var tr = node.parentNode;
   var tds = tr.getElementsByTagName("td");
   //var tds = tr.childNodes;
   var incomegold = this.Str.To_Integer(tds[3].innerHTML);
   
   var city = getCity(cID); 
   if (city.buildings["townHall"] == undefined) city.buildings["townHall"] = {};
   city.buildings["townHall"].incomegold  = incomegold;
   }
  }
  
 config.financestime = this.StartTime;
 };
 
EmpireBoard.ViewIsCity = function()
 {
 
 };
 
EmpireBoard.ViewIsBuildingTemple = function()
 {
 var _self = this;
 
 function reportTemple()
  {
  setViewRqTime('finances');
  _self.DB.Save();
  }
 
 var n = document.getElementById("inputWorkersSubmit");
 n.addEventListener("click", reportTemple, false);
 
 var city = getCity(city_idmainView);
 
 var n = document.getElementById("valuePriests");
 city.buildings["temple"].priests = this.Str.To_Integer(n.textContent);
 this.Log.Add('valuePriests = '+city.buildings["temple"].priests);
 };
 
EmpireBoard.ViewIsBuildingMuseum = function()
 {
 var totalCulturalGoods = 0;
 
 var players = this.DOM.Get_Nodes("//div[@id='mainview']//table[@class='content_table']//td[@class='player']");
 if (players.snapshotLength > 0)
  {
  totalCulturalGoods = players.snapshotLength;
  }
  
 
 config.totalCulturalGoods = totalCulturalGoods;
 this.Log.Add('totalCulturalGoods = '+config.totalCulturalGoods);
 };
 
EmpireBoard.ViewIsBuildingPalace = function()
 {
 var newGov = 'ikakratie';
 // values: ikakratie, aristokratie, demokratie
 
 if (this.Ikariam.Is_Version('0.4.4'))
  {
  var government_pic_img = this.DOM.Get_First_Node("//*[@class='government_pic']/img");
  var govRegExp = /\/([a-z]+)_280/.exec(government_pic_img.src);
  if (govRegExp != null)
   {
   newGov = '' + RegExp.$1;
   }
  }
  
 config.government = newGov;
 this.Log.Add('Government = '+config.government);
 };
 
EmpireBoard.ViewIsBuildingAcademy = function()
 {
 var _self = this;
 
 function reportAcademy()
  {
  setViewRqTime('finances');
  _self.DB.Save();
  }
 
 var n = document.getElementById("inputWorkersSubmit");
 n.addEventListener("click", reportAcademy, false);
 
 var city = getCity(city_idmainView);
 
 var n = document.getElementById("valueResearch");
 city.buildings["academy"].Research = this.Str.To_Integer(n.textContent);
 this.Log.Add('valueResearch = '+city.buildings["academy"].Research);
 
 var n = document.getElementById("valueWorkers");
 city.buildings["academy"].scientists = this.Str.To_Integer(n.textContent);
 this.Log.Add('valueWorkers(scientists) = '+city.buildings["academy"].scientists);
 };
 
EmpireBoard.ViewIsBuildingBranchOffice = function()
 {
 var city = getCity(city_idmainView);
 
 var reservedGold =  document.getElementById("reservedGold");
 if (reservedGold != null)
  {
  city.buildings["branchOffice"].reservedGold = this.Str.To_Integer(reservedGold.innerHTML, 0);
  }
 else
  {
  city.buildings["branchOffice"].reservedGold = 0;
  }
  
 // Fetch wood offer
 city.tradewood = 0;
 var selectElt = document.getElementById('resourceTradeType');
 if ((selectElt != null) && (selectElt.value == '444'))
  {
  var inputElt = document.getElementById('resource');
  if ((inputElt != null) && (inputElt.value != '') && (inputElt.value != '0'))
   {
   city.tradewood = this.Str.To_Integer(inputElt.value, 0);
   }
  }
  
 // Fetch wine offer
 city.tradewine = 0;
 var selectElt = document.getElementById('tradegood1TradeType');
 if ((selectElt != null) && (selectElt.value == '444'))
  {
  var inputElt = document.getElementById('tradegood1');
  if ((inputElt != null) && (inputElt.value != '') && (inputElt.value != '0'))
   {
   city.tradewine = this.Str.To_Integer(inputElt.value, 0);
   }
  }
  
 // Fetch marble offer
 city.trademarble = 0;
 var selectElt = document.getElementById('tradegood2TradeType');
 if ((selectElt != null) && (selectElt.value == '444'))
  {
  var inputElt = document.getElementById('tradegood2');
  if ((inputElt != null) && (inputElt.value != '') && (inputElt.value != '0'))
   {
   city.trademarble = this.Str.To_Integer(inputElt.value, 0);
   }
  }
  
 // Fetch crystal offer
 city.tradeglass = 0;
 var selectElt = document.getElementById('tradegood3TradeType');
 if ((selectElt != null) && (selectElt.value == '444'))
  {
  var inputElt = document.getElementById('tradegood3');
  if ((inputElt != null) && (inputElt.value != '') && (inputElt.value != '0'))
   {
   city.tradeglass = this.Str.To_Integer(inputElt.value, 0);
   }
  }
  
 // Fetch sulfur offer
 city.tradesulfur = 0;
 var selectElt = document.getElementById('tradegood4TradeType');
 if ((selectElt != null) && (selectElt.value == '444'))
  {
  var inputElt = document.getElementById('tradegood4');
  if ((inputElt != null) && (inputElt.value != '') && (inputElt.value != '0'))
   {
   city.tradesulfur = this.Str.To_Integer(inputElt.value, 0);
   }
  }
 };
 
EmpireBoard.ViewIsIslandResource = function()
 {
 var cityID = 0;
  
 cityID = this.DOM.Get_First_Node_Value("//form[@id='setWorkers']//input[@name='cityId']",0);
 if (cityID > 0)
  {
  var city = getCity(cityID);
  
  if (city.buildings["townHall"] == undefined) city.buildings["townHall"] = {};
  
  // Fetch wood workers
  var woodworkers = 0;
  var valueWorkers = document.getElementById("valueWorkers");
  if (valueWorkers != null) 
   {
   woodworkers = Number(valueWorkers.textContent);
   }
  
  city.buildings["townHall"].woodworkers = woodworkers;
  this.Log.Add('woodworkers (from Resource)='+woodworkers);
  }
 
 var _self = this;
 
 function reportResource()
  {
  setViewRqTime('finances');
  _self.DB.Save();
  }
 
 var n = document.getElementById("inputWorkersSubmit");
 if (n != null) 
  {
  n.addEventListener("click", reportResource, false);
  }
 };

EmpireBoard.ViewIsIslandTradeGood = function()
 {
 var cityID = 0;
  
 cityID = this.DOM.Get_First_Node_Value("//form[@id='setWorkers']//input[@name='cityId']",0);
 if (cityID > 0)
  {
  var city = getCity(cityID);
  
  if (city.buildings["townHall"] == undefined) city.buildings["townHall"] = {};
  
  // Fetch wood workers
  var specialworkers = 0;
  var valueWorkers = document.getElementById("valueWorkers");
  if (valueWorkers != null) 
   {
   specialworkers = Number(valueWorkers.textContent);
   }
  
  city.buildings["townHall"].specialworkers = specialworkers;
  this.Log.Add('specialworkers (from Resource)='+specialworkers);
  }
 
 var _self = this;
 
 function reportTradegood()
  {
  setViewRqTime('finances');
  _self.DB.Save();
  }
 
 var n = document.getElementById("inputWorkersSubmit");
 if (n != null)
  {
  n.addEventListener("click", reportTradegood, false);
  }
 };
  
EmpireBoard.ViewIsBuildingTavern = function()
 {
 var city = getCity(city_idmainView);
 
 // New method Thank  to TorfDrottel 
 var iniValue = 0;
 var scripts = document.getElementsByTagName("script");
 for (var j = 0; j < scripts.length; j++)
  {
  var nScript = scripts[j];
  var sCode = nScript.innerHTML;
  if (sCode.indexOf('create_slider') > 0)
   {
   iniValue = parseInt(/iniValue : (\d+)/.exec(sCode)[1])
   }
  }
 city.wineUsageId = iniValue;
 
 var savedWine = 0;
 if (unsafeWindow && unsafeWindow.savedWine)
  {
  savedWine = unsafeWindow.savedWine[iniValue];
  }
 if ((savedWine == '&nbsp;') || (savedWine == ''))
  {
  savedWine = 0;
  }
 savedWine = Math.round(parseFloat(savedWine));
 var wineUsage = tavernWineUsage[iniValue] - savedWine;
 city.wineUsage = wineUsage;
 
 this.Log.Add('Tavern: iniValue= '+iniValue+', savedWine='+savedWine+', wineUsage='+wineUsage);
 
 var _self = this;

 function storeWineUsage()
  {
  try
   {
   var city_id = _self.DOM.Get_First_Node_Value("//form[@id='wineAssignForm']/input[@type='hidden' and @name='id']");
   var city = getCity(city_id);
   var n = document.getElementById("wineAmount");
   
   var iniValue = n.selectedIndex;
   if (city.wineUsageId != iniValue)
    {
    setViewRqTime('townHall', city_id);
    }
   city.wineUsageId = iniValue;
   
   var savedWine = getSavedWine();
   var wineUsage = tavernWineUsage[iniValue] - savedWine;
   city.wineUsage = wineUsage;
   
   _self.Log.Add('Tavern: iniValue= '+iniValue+', savedWine='+savedWine+', wineUsage='+wineUsage);
   
   _self.DB.Save();
   }
  catch (e)
   {
   }
  }
  
 // Fix for v3
 function getSavedWine() 
  {
  try 
   {
   var n = document.getElementById("savedWine");
   if ((n.innerHTML != '&nbsp;') && (_self.Str.Trim(n.innerHTML) != ''))
    {
    return Math.round(parseFloat(n.innerHTML));
    }
   else return 0;
   }
  catch (e) 
   {
   return 0;
   }
  }
 
 // Soon deprecated
 var n = this.DOM.Get_First_Node("//form[@id='wineAssignForm']//*[@type='submit']");
 n.addEventListener("click", storeWineUsage, false);
 };

EmpireBoard.ViewIsBuildingTownHall = function()
 {
 var city = getCity(city_idmainView);
 
 if (city.buildings["townHall"] == undefined) city.buildings["townHall"] = {};

 var population = 0;
 population = Number(this.DOM.Get_First_Node_TextContent("//li[contains(@class, 'space')]/span[contains(@class, 'occupied')]", "0"));
 city.buildings["townHall"].population = population;
 //city.population = population; // Soon deprecated
 
 // May use happiness than growth...
 city.buildings["townHall"].growth = this.Str.To_Float(this.DOM.Get_First_Node_TextContent("//li[contains(@class, 'growth')]/span[@class='value']", "0"),'?',this.Ikariam.LocalizationStrings('decimalPoint'));
 this.Log.Add('Growth (from TownHall)='+city.buildings["townHall"].growth);
 
 city.buildings["townHall"].happiness  = Number(this.DOM.Get_First_Node_TextContent("//div[contains(@class, 'happiness')]/div[@class='value']", "0")) + city.buildings["townHall"].population;

 city.buildings["townHall"].bonusspace = Number(this.DOM.Get_First_Node_TextContent("//li[contains(@class, 'space')]/span[contains(@class, 'total')]", "0")) - townHallSpaces[getBuildingLevel(city_idmainView, 'townHall', 1, 0)];
 
 // Fetch citizens
 var citizens = 0;
 citizens = Number(this.DOM.Get_First_Node_TextContent("//div[contains(@class, 'citizens')]//span[@class='count']", "0"));
 city.buildings["townHall"].citizens = citizens;
 this.Log.Add('citizens (from TownHall)='+citizens);
 
 // Fetch wood workers
 var woodworkers = 0;
 woodworkers = Number(this.DOM.Get_First_Node_TextContent("//div[contains(@class, 'woodworkers')]//span[@class='count']", "0"));
 city.buildings["townHall"].woodworkers = woodworkers;
 this.Log.Add('woodworkers (from TownHall)='+woodworkers);
 
 // Fetch good workers
 var specialworkers = 0;
 specialworkers = Number(this.DOM.Get_First_Node_TextContent("//div[contains(@class, 'specialworkers')]//span[@class='count']", "0"));
 city.buildings["townHall"].specialworkers = specialworkers;
 this.Log.Add('specialworkers (from TownHall)='+specialworkers);
 
 // Fetch scientist
 var scientists = 0;
 scientists = Number(this.DOM.Get_First_Node_TextContent("//div[contains(@class, 'scientists')]//span[@class='count']", "0"));
 if ((scientists > 0) || (city.buildings["academy"] != undefined))
  {
  if (city.buildings["academy"] == undefined) city.buildings["academy"] = {};
  city.buildings["academy"].scientists = scientists;
  }
 this.Log.Add('scientists (from TownHall)='+scientists);
 
 // Fetch priests
 if (this.Ikariam.Is_Version('0.3.2') == true)
  {
  var priests = 0;
  priests = Number(this.DOM.Get_First_Node_TextContent("//div[contains(@class, 'priests')]//span[@class='count']", "0"));
  if ((priests > 0) || (city.buildings["temple"] != undefined))
   {
   if (city.buildings["temple"] == undefined) city.buildings["temple"] = {};
   city.buildings["temple"].priests = priests;
   }
  this.Log.Add('priests (from TownHall)='+priests);
  }

 var citizensProd = 0;
 citizensProd = this.Str.To_Integer(this.DOM.Get_First_Node_TextContent("//div[@class='citizens']/span[@class='production']", "0"),0);
 city.buildings["townHall"].citizensProd = citizensProd;
 this.Log.Add('citizensProd (from TownHall)='+citizensProd);
 
 if (this.Ikariam.Is_Version('0.3.5') == true)
  {
  
  }
 else
  {
  var incomegold = 0;
  incomegold = Number(this.DOM.Get_First_Node_TextContent("//li[contains(@class, 'incomegold')]/span[@class='value']", "0"));
  city.buildings["townHall"].incomegold = incomegold;
  this.Log.Add('IncomeGold (from TownHall)='+incomegold);

  var upkeep = citizensProd - incomegold;
  city.buildings["townHall"].upkeep = upkeep;
  this.Log.Add('Upkeep (from TownHall)='+upkeep);
  }
 };
 
EmpireBoard.ViewIsDiplomacyAdvisorTreaty = function()
 {
 
 };
 
EmpireBoard.ViewIsResearchAdvisor = function()
 {
 var _self = this;
 
 function reportResearch()
  {
  setViewRqTime('researchOverview');
  _self.DB.Save();
  }
 
 var rButtons = this.DOM.Get_Nodes("//ul[@class='researchTypes']//div[@class='researchButton']//a[contains(@class, 'build')]");
 this.Log.Add("Research buttons: "+rButtons.snapshotLength);
 if (rButtons.snapshotLength > 0)
  {
  for (var i=0; i < rButtons.snapshotLength; i++)
   {
   var rButton = rButtons.snapshotItem(i);
   //rButton.href='';
   rButton.addEventListener("click", reportResearch, false);
   }
  }
 };

// Thank to matteo466
EmpireBoard.ViewIsResearchOverview = function()
 {
 this.Log.Add('Fetch discovered research...');
 
 config["research"] = {};
 
 var LIs = this.DOM.Get_Nodes("//div[@id='mainview']//div[contains(@class, 'content')]//li[@class='explored']");
 this.Log.Add("Research explored: "+LIs.snapshotLength);
 if (LIs.snapshotLength > 0)
  {
  for (var i=0; i < LIs.snapshotLength; i++)
   {
   var researchLI = LIs.snapshotItem(i);
   var researchA = researchLI.getElementsByTagName("a")[0];
   var resReg = /[\?&]{1}researchId=([0-9]+)&?/i.exec(researchA.href);
   if (resReg != null)
    {
    var researchID = parseInt(resReg[1]);
    var researchLevel = this.Str.To_Integer(researchA.textContent.replace(/\-/g, ""),1);
    
    this.Log.Add("Found research: "+researchID+', level '+researchLevel);
    
    config["research"][researchID] = {};
    config["research"][researchID].Explored = true;
    config["research"][researchID].Level = researchLevel;
    }
   }
  }
 
 function isExplored(researchID)
  {
  if ((config["research"][researchID] != undefined) && (config["research"][researchID].Explored == true))
   return true;
  else
   return false;
  }
 
 var FleetUpkeepBonus = 0;
 if (isExplored(1020)) FleetUpkeepBonus += 2;
 if (isExplored(1050)) FleetUpkeepBonus += 4;
 if (isExplored(1090)) FleetUpkeepBonus += 8;
 if (isExplored(1999))
  {
  FleetUpkeepBonus += 2*config["research"][1999].Level;
  }
 this.Log.Add("FleetUpkeepBonus: "+FleetUpkeepBonus);
 config["research"].FleetUpkeepBonus = FleetUpkeepBonus;
 
 var ArmyUpkeepBonus = 0;
 if (isExplored(4020)) ArmyUpkeepBonus += 2;
 if (isExplored(4050)) ArmyUpkeepBonus += 4;
 if (isExplored(4090)) ArmyUpkeepBonus += 8;
 if (isExplored(4999))
  {
  ArmyUpkeepBonus += 2*config["research"][4999].Level;
  }
 this.Log.Add("ArmyUpkeepBonus: "+ArmyUpkeepBonus);
 config["research"].ArmyUpkeepBonus = ArmyUpkeepBonus;
 
 var ResearchCost = 6;
 if (isExplored(3110)) ResearchCost -= 3;
 this.Log.Add("ResearchCost: "+ResearchCost);
 config["research"].ResearchCost = ResearchCost;
 
 var ResearchBonus = 0;
 if (isExplored(3020)) ResearchBonus += 2;
 if (isExplored(3050)) ResearchBonus += 4;
 if (isExplored(3090)) ResearchBonus += 8;
 if (isExplored(3999))
  {
  ResearchBonus += 2*config["research"][3999].Level;
  }
 this.Log.Add("ResearchBonus: "+ResearchBonus);
 config["research"].ResearchBonus = ResearchBonus;
 
 config["research"].uptime = this.StartTime;
 };
 
EmpireBoard.ViewIsPremium = function()
 {
 if (config["premium"] == undefined) config["premium"] = {};
 
 var TRs = this.DOM.Get_Nodes("//div[@id='premiumOffers']//table[contains(@class, 'TableHoriMax')]//tr");
 this.Log.Add("premiumOffers rows: "+TRs.snapshotLength);
 
 // array of TR index per features
 var premiumOffers = {};
 if (this.Ikariam.Is_Version('0.4.4'))
  {
  premiumOffers['account']     = 2;
  premiumOffers['woodbonus']     = 7;
  premiumOffers['marblebonus']    = 10;
  premiumOffers['sulfurbonus']    = 13;
  premiumOffers['crystalbonus']    = 16;
  premiumOffers['winebonus']     = 19;
  premiumOffers['savecapacityBonus']   = 22;
  premiumOffers['storagecapacityBonus']  = 25;
  }
 else if (this.Ikariam.Is_Version('0.4.2'))
  {
  premiumOffers['account']     = 2;
  premiumOffers['savecapacityBonus']   = 20;
  premiumOffers['storagecapacityBonus']  = 23;
  }
 
 var featureId;
 for (featureId in premiumOffers)
  {
  var TrNo = premiumOffers[featureId];
  var TDstatus = TRs.snapshotItem(TrNo).getElementsByTagName("td")[0];
  if (this.DOM.Has_ClassName(TDstatus,'active') == true)
   {
   var remainingTime = 60*60*1000; // set minimal remaining time if fail to fetch time counter
   var remainingText = TDstatus.textContent;
   var regExp = new RegExp("([0-9])\\s+([a-z])", "ig");
   var RegExpRes = regExp.exec(remainingText);
   if (RegExpRes != null)
    {
    var timeValue = parseInt(RegExpRes[1]);
    var timeUnit = RegExpRes[2];
    
    if (timeUnit == this.Ikariam.LocalizationStrings('day','timeunits','short'))
     {
     remainingTime = timeValue*24*60*60*1000;
     }
    else if (timeUnit == this.Ikariam.LocalizationStrings('hour','timeunits','short'))
     {
     remainingTime = timeValue*60*60*1000;
     }
    else if (timeUnit == this.Ikariam.LocalizationStrings('minute','timeunits','short'))
     {
     remainingTime = timeValue*60*1000;
     }
    else if (timeUnit == this.Ikariam.LocalizationStrings('second','timeunits','short'))
     {
     remainingTime = timeValue*1000;
     }
    else
     {
     remainingTime = 24*60*60*1000;
     }
    }
   else
    {
    remainingTime = 24*60*60*1000;
    }
   config["premium"][featureId] = this.StartTime + remainingTime;
   setViewRqTime('premium',0,this.StartTime + remainingTime);
   this.Log.Add("premium["+featureId+"]: remainingTime="+remainingTime+", timeValue="+timeValue+", timeUnit="+timeUnit);
   }
  }
 
 config["premium"].uptime = this.StartTime;
 };
 
EmpireBoard.ViewIsActionTransport = function()
 {
 // Todo
 };
 
EmpireBoard.ViewIsActionDeployment = function()
 {
 var self = this;
 
 var dSubmit = this.DOM.Get_First_Node("//form[@id='deploymentForm']//input[@type='submit']");
 dSubmit.addEventListener("click", function(e) { self.Handlers.Deployment_Submit_Event(e); }, false);
 };
 
EmpireBoard.ViewIsActionPlunder = function()
 {
 // Todo
 };
 
EmpireBoard.ViewIsActionBlockade = function()
 {
 // Todo
 };
 
EmpireBoard.ViewIsActionOccupy = function()
 {
 // Todo
 };
 
EmpireBoard.ViewIsActionDefendCity = function()
 {
 // Todo
 };
 
EmpireBoard.ViewIsActionDefendPort = function()
 {
 // Todo
 };
 
EmpireBoard.ViewIsMerchantNavy = function()
 {
 var _self = this;
 var MerchantTimes = {};
 this.Ikariam.Fetch_MerchantNavy_Boxes(this.DB.MerchantBoxes, true);
 this.Ikariam.Fetch_TimeCounters(MerchantTimes,'getCountdown');
 
 config["transports"] = {};
 
 function addTransport(cityID, transportID, endTime)
  {
  if (config["transports"][cityID] == undefined) config["transports"][cityID] = {};
  if (config["transports"][cityID][transportID] == undefined) config["transports"][cityID][transportID] = {};
  config["transports"][cityID][transportID].endTime = endTime;
  
  _self.Log.Add('Transport['+transportID+'] from oCityId='+cityID+' while '+_self.Str.FormatRemainingTime(endTime-_self.StartTime));
  }
 
 var boxId;
 for (boxId in this.DB.MerchantBoxes)
  {
  if (this.DB.MerchantBoxes[boxId].missions != undefined)
   {
   var missionId;
   for (missionId in this.DB.MerchantBoxes[boxId].missions)
    {
    var oCityId = this.DB.MerchantBoxes[boxId].missions[missionId].oCityId;
    if (oCityId > 0)
     {
     var endTime = 0;
     
     var ETA = this.DB.MerchantBoxes[boxId].missions[missionId].ETA;
     var ETAtime = 0;
     if ((ETA != '') && (MerchantTimes[ETA] != undefined))
      {
      ETAtime = this.StartTime + (MerchantTimes[ETA].enddate - MerchantTimes[ETA].currentdate);
      }
     if (ETAtime > 0) endTime = ETAtime;
      
     var RETtime = 0;
     var RET = this.DB.MerchantBoxes[boxId].missions[missionId].RET;
     if ((RET != '') && (MerchantTimes[RET] != undefined))
      {
      RETtime = this.StartTime + (MerchantTimes[RET].enddate - MerchantTimes[RET].currentdate);
      }
     if ((RETtime > 0) && (RETtime > endTime)) endTime = RETtime;
     
     if (endTime <= 0)
      endTime = this.StartTime + (1 * 20 * 60 * 1000);
     
     addTransport(oCityId, missionId, endTime);
     }
    }
   }
  }
 };
 
EmpireBoard.ViewIsMilitaryMovements = function()
 {
 config["movements"] = {};
 function addMovement(cityID, movementID, FleetMovement)
  {
  if (config["movements"][cityID] == undefined) config["movements"][cityID] = {};
  if (config["movements"][cityID][movementID] == undefined) config["movements"][cityID][movementID] = {};

  config["movements"][cityID][movementID] = FleetMovement;
  config["movements"][cityID][movementID].endTime = FleetMovement.time;
  }
  
 config["attacks"] = {};
 function addAttacks(cityID, movementID, FleetMovement)
  {
  if (config["attacks"][cityID] == undefined) config["attacks"][cityID] = {};
  if (config["attacks"][cityID][movementID] == undefined) config["attacks"][cityID][movementID] = {};

  config["attacks"][cityID][movementID] = FleetMovement;
  config["attacks"][cityID][movementID].endTime = FleetMovement.time;
  }
 
 config["foreignTransports"] = {};
 function addForeignTransport(cityID, movementID, FleetMovement)
  {
  if (config["foreignTransports"][cityID] == undefined)
   config["foreignTransports"][cityID] = {};
  if (config["foreignTransports"][cityID][movementID] == undefined)
   config["foreignTransports"][cityID][movementID] = {};

  config["foreignTransports"][cityID][movementID] = FleetMovement;
  config["foreignTransports"][cityID][movementID].endTime = FleetMovement.time;
  }
 
 this.Ikariam.Fetch_FleetMovements(this.DB.FleetMovements);
 
 var resMi = this.DOM.Get_Nodes("//div[@id='fleetMovements']//table[contains(@class, 'locationEvents')]/tbody/tr/td/img[contains(@src, 'mission_')]");
 if (resMi.snapshotLength > 0)
  {
  for (var i=0; i < resMi.snapshotLength; i++)
   {
   var tr = resMi.snapshotItem(i).parentNode.parentNode;
   var tds = tr.getElementsByTagName("td");
   //var tds = tr.childNodes;
    
   var fleetId = tds[1].id;
   
   if ((fleetId != '') && (this.DB.FleetMovements[fleetId] != undefined))
    {
    var FleetMovement = this.DB.FleetMovements[fleetId];
    var toOwn = false;
    if ((this.DB.CurrentCities[FleetMovement.tCityId] != undefined) && (FleetMovement.tCityId != FleetMovement.oCityId) && (this.DB.CurrentCities[FleetMovement.tCityId].own == true))
     {
     toOwn = true;
     }
    
    // Values: deployarmy, deployfleet, plunder, blockade, defend, defend_port, trade, transport, occupy
    if (FleetMovement.hostile == true)
     {
     addAttacks(FleetMovement.tCityId, fleetId, FleetMovement);
     }
    else if (FleetMovement.own == true)
     {
     if (FleetMovement.mission == 'trade')
      {
      // Not military movement
      }
     else if (FleetMovement.mission == 'transport')
      {
      // Not military movement
      if ((FleetMovement.hasAction == true) && (FleetMovement.hasGoods == true) && (FleetMovement.toLeft == false) && (FleetMovement.toRight == false) && (toOwn == true))
       {
       setViewRqTime('merchantNavy',0,FleetMovement.time);
       }
      }
     else if (FleetMovement.mission == 'deployarmy')
      {
      addMovement(FleetMovement.oCityId, fleetId, FleetMovement);
      
      if ((FleetMovement.toRight == true) && (toOwn == true))
       {
       this.Log.Add("Army "+fleetId+" will arrive to city["+FleetMovement.tCityId+"]");
       setViewRqTime('cityMilitary-army', FleetMovement.tCityId, FleetMovement.time);
       }
      else if (FleetMovement.toLeft == true)
       {
       this.Log.Add("Army "+fleetId+" come back to city["+FleetMovement.oCityId+"]");
       setViewRqTime('cityMilitary-army', FleetMovement.oCityId, FleetMovement.time);
       }
      }
     else if (FleetMovement.mission == 'deployfleet')
      {
      addMovement(FleetMovement.oCityId, fleetId, FleetMovement);
      
      if ((FleetMovement.toRight == true) && (toOwn == true))
       {
       this.Log.Add("Fleet "+fleetId+" will arrive to city["+FleetMovement.tCityId+"]");
       setViewRqTime('cityMilitary-fleet', FleetMovement.tCityId, FleetMovement.time);
       }
      else if (FleetMovement.toLeft == true)
       {
       this.Log.Add("Fleet "+fleetId+" come back to city["+FleetMovement.oCityId+"]");
       setViewRqTime('cityMilitary-fleet', FleetMovement.oCityId, FleetMovement.time);
       }
      }
     else if (FleetMovement.mission == 'plunder')
      {
      addMovement(FleetMovement.oCityId, fleetId, FleetMovement);
      
      if ((FleetMovement.hasGoods == true) && (FleetMovement.toLeft == false) && (FleetMovement.toRight == false))
       {
       setViewRqTime('merchantNavy',0,FleetMovement.time);
       }
      }
     else if (FleetMovement.mission == 'blockade')
      {
      addMovement(FleetMovement.oCityId, fleetId, FleetMovement);
      }
     else
      {
      addMovement(FleetMovement.oCityId, fleetId, FleetMovement);
      }
     }
    else
     {
     if (FleetMovement.mission == 'trade')
      {
      if ((toOwn == true) && (FleetMovement.toRight == true))
       {
       this.Log.Add("Foreign trade "+fleetId+" arrive to city["+FleetMovement.tCityId+"] "+this.Str.FormatRemainingTime(FleetMovement.time - EmpireBoard.StartTime));
       setViewRqTime('branchOffice', FleetMovement.tCityId, FleetMovement.time);
       addForeignTransport(FleetMovement.tCityId, fleetId, FleetMovement);
       }
      }
     else if (FleetMovement.mission == 'transport')
      {
      if ((toOwn == true) && (FleetMovement.toRight == true))
       {
       this.Log.Add("Foreign transport "+fleetId+" arrive to city["+FleetMovement.tCityId+"] "+this.Str.FormatRemainingTime(FleetMovement.time - EmpireBoard.StartTime));
       setViewRqTime('', FleetMovement.tCityId, FleetMovement.time);
       addForeignTransport(FleetMovement.tCityId, fleetId, FleetMovement);
       }
      }
     }
    }
   }
  }
  
 config.mAMMtime = this.StartTime;
 };
 
EmpireBoard.ViewIsBuildingWorkshop = function()
 {
 var scripts = document.getElementsByTagName("script");
 var found = false;
 var sCode = '';
 for (var j = 0; j < scripts.length; j++)
  {
  // search upgradeCountDown
  var nScript = scripts[j];
  sCode = nScript.innerHTML;
  if (sCode.indexOf('upgradeCountdown') >= 0)
   {
   found = true;
   break;
   }
  }
 if (found == true)
  {
  // buildings under upgrading
  var enddate = 0;
  var currentdate = 0;
  if (/enddate[^0-9]*([0-9]+)/.exec(sCode) != null)
   {
   enddate = parseFloat(RegExp.$1) * 1000; 
   }
  if (/currentdate[^0-9]*([0-9]+)/.exec(sCode) != null)
   {
   currentdate = parseFloat(RegExp.$1) * 1000; 
   }
  if (enddate != 0 && currentdate != 0)
   {
   setViewRqTime('workshop', city_idmainView, this.StartTime + (enddate - currentdate), true);
   this.Log.Add('Workshop upgrade remaining time: '+enddate+' - '+currentdate+' = '+(enddate-currentdate)/1000+'s');
   }
  }
 };
 
EmpireBoard.DB =
 {
 _Parent:    null,
 Prefix:     '',
 CurrentCities:   {},
 FleetMovements:   {},
 MerchantBoxes:   {},
 Options:    {}
 };

EmpireBoard.DB.Init = function(parent, host)
 {
 this._Parent = parent;
 if (host == undefined) host = this._Parent.Ikariam.Host();
 
 var prefix = host;
 prefix = prefix.replace('.ikariam.', '-');
 prefix = prefix.replace('.', '-');
 this.Prefix = prefix;
 };
  
EmpireBoard.DB.Serialize = function(data)
 {
 return uneval(data);
 };

EmpireBoard.DB.UnSerialize = function(data)
 {
 return eval(data);
 };
 
function getVar(varname, vardefault) {
  var res = GM_getValue(EmpireBoard.Ikariam.Host()+varname);
  if (res == undefined) {
    return vardefault;
  }
  return res;
}

function setVar(varname, varvalue) {
  GM_setValue(EmpireBoard.Ikariam.Host()+varname, varvalue);
}

EmpireBoard.DB.Load = function()
 {
 config = this.UnSerialize(getVar("config", ""));
 if (config == null || config == undefined || config == "" || ("".config == "NaN"))
  {
  config = new Object();
  }
 
 // Set dbversion for migrate agent
 if (config["dbversion"] == undefined)   config["dbversion"]  = this._Parent.Version-1;
 
 // Check if main arrays exists
 if (config["unitnames"] == undefined)    config["unitnames"]    = {};
 if (config["upkeeps"] == undefined)     config["upkeeps"]     = {};
 if (config["arrivinggoods"] == undefined)   config["arrivinggoods"]   = {};
 if (config["movements"] == undefined)    config["movements"]    = {};
 if (config["attacks"] == undefined)     config["attacks"]     = {};
 if (config["transports"] == undefined)    config["transports"]    = {};
 if (config["foreignTransports"] == undefined)  config["foreignTransports"]  = {};
 if (config["research"] == undefined)    config["research"]     = {};
 if (config["premium"] == undefined)     config["premium"]     = {};
 
 if (config["dbversion"] < this._Parent.Version)
  {
  this.MigrateAgent();
  }
 };
 
EmpireBoard.DB.MigrateAgent = function()
 {
 this._Parent.Log.Add('Apply Migrate Agent to DB v. '+config["dbversion"]);
 
 config["dbversion"] = this._Parent.Version;
 };
 
EmpireBoard.DB.GarbageCollector = function()
 {
 var ConfigIds = '';
 var ConfigId;
 for (ConfigId in config)
  {
  var toDelete = false;
  switch(ConfigId)
   {
   case 'unitnames':
   case 'upkeeps':
   case 'movements':
   case 'attacks':
   case 'transports':
   case 'foreignTransports':
   case 'research':
   case 'premium':
   case 'gold':
   case 'merchantNavyrqtime':
   case 'merchantNavytime':
   case 'financestime':
   case 'financesrqtime':
   case 'mAMMtime':
   case 'mAMMrqtime':
   case 'government':
   case 'totalCulturalGoods':
   case 'dbversion':
    toDelete = false;
    break;
   
   case 'arrivinggoods':
    var oCityId;
    for (oCityId in config['arrivinggoods'])
     {
     if (this.CurrentCities[oCityId] == undefined)
      {
      if (delete config['arrivinggoods'][oCityId])
       this._Parent.Log.Add('Garbage collector has removed arrivinggoods of unkown city['+oCityId+']');
      }
     }
    toDelete = false;
    break;
 
   case 'cfg':
    toDelete = true;
    break;
   
   default:
    // Check if old city
    var CityId = this._Parent.Str.To_Integer(ConfigId,'NaN');
    if (CityId != 'NaN')
     {
     if (this.CurrentCities[CityId] == undefined)
      {
      toDelete = true;
      }
     else
      {
      toDelete = false;
      
      // deprecated attributes
      var ConfigSubIds = '';
      var ConfigSubId;
      var unkownConfigSubIds = '';
      for (ConfigSubId in config[ConfigId])
       {
       var subToDelete = false;
       switch(ConfigSubId)
        {
        case 'city_name':
        case 'city_coord':
        case 'island_id':
        case 'actions':
        case 'citytime':
        case 'rqtime':
        case 'wood':
        case 'wine':
        case 'marble':
        case 'glass':
        case 'sulfur':
        case 'prodwood':
        case 'prodwine':
        case 'prodmarble':
        case 'prodglass':
        case 'prodsulfur':
        case 'prodgood':
        case 'prodtime':
        case 'tradewood':
        case 'tradewine':
        case 'trademarble':
        case 'tradeglass':
        case 'tradesulfur':
        case 'wineUsageId':
        case 'wineUsage':
        case 'buildings':
        case 'underConstructionName':
        case 'underConstructionPosition':
        case 'underConstructionTime':
        case 'units':
        case 'cityMilitaryarmytime':
        case 'cityMilitaryarmyrqtime':
        case 'cityMilitaryfleettime':
        case 'cityMilitaryfleetrqtime':
         subToDelete = false;
         break;
         
        case 'crystal':
        case 'underConstruction':
        case 'population':
        case 'citizens':
         subToDelete = true;
         break;
        
        default:
         unkownConfigSubIds += ' '+ConfigSubId;
         break;
        }
       if (subToDelete == true)
        {
        if (delete config[ConfigId][ConfigSubId])
         ConfigSubIds += ' '+ConfigSubId;
        }
       }
      if (ConfigSubIds != '') this._Parent.Log.Add('Garbage collector has removed city['+ConfigId+'] properties:'+ConfigSubIds);
      if (unkownConfigSubIds != '') this._Parent.Log.Add('Garbage collector has detected unknown city['+ConfigId+'] objects:'+unkownConfigSubIds);
      }
     }
    else
     {
     this._Parent.Log.Add('Garbage collector has detected unknown object: '+ConfigId);
     }
    break;
   }
  
  if (toDelete == true)
   {
   if (delete config[ConfigId])
    ConfigIds += ' '+ConfigId;
   }
  }
 
 if (ConfigIds != '') this._Parent.Log.Add('Garbage collector has removed array:'+ConfigIds);
 };

EmpireBoard.DB.Save = function()
 {
 setVar("config", this.Serialize(config));
 };

EmpireBoard.DB.Load_Options = function()
 {
 this.Options = this.UnSerialize(GM_getValue(this.Prefix+'.Opt', false)) || {};
 
 if (this.Options.Prefs == undefined)      this.Options.Prefs = {};
 if (this.Options.Prefs.TABLE_RESOURCES == undefined)  this.Options.Prefs.TABLE_RESOURCES = true;
 if (this.Options.Prefs.TABLE_BUILDINGS == undefined)  this.Options.Prefs.TABLE_BUILDINGS = true;
 if (this.Options.Prefs.TABLE_ARMYFLEET == undefined)  this.Options.Prefs.TABLE_ARMYFLEET = true;
 if (this.Options.Prefs.PROGRESS_BAR_MODE == undefined)  this.Options.Prefs.PROGRESS_BAR_MODE = 'time';
 if (this.Options.Prefs.LANGUAGE == undefined)    this.Options.Prefs.LANGUAGE = '';
 };

EmpireBoard.DB.Save_Options = function()
 {
 GM_setValue(this.Prefix+'.Opt', this.Serialize(this.Options));
 };
 
EmpireBoard.Renders =
 {
 _Parent:    null
 };

EmpireBoard.Renders.Init = function(parent)
 {
 this._Parent = parent;
 };
 
function createLink(text, href, attrs)
 {
 return "<a href=\""+href+"\" "+attrs+">"+text+"</a>";
 }

EmpireBoard.Renders.Buildings_Table_Content = function()
 {
 var s = '';
 var Cities = this._Parent.DB.CurrentCities;
 
 // Array use to group buildings
 var orderedBuildings = this._Parent.Ikariam.BuildingsList();
 
 function getBuildingCount(city_id, name, defaultValue)
  {
  if (defaultValue == undefined) defaultValue = 0;
  var count = 0;
  var city = getCity(city_id);
  
  if ((city.buildings == undefined) || (city.buildings[name] == undefined))
   {
   if (name == 'townHall') count = 1;
   }
  else if (city.buildings[name].levels != undefined)
   {
   var p;
   for (p in city.buildings[name].levels)
    {
    count++;
    }
   }
  else if (city.underConstructionName == name)
   {
   count = 1;
   }
  
  if (count == 0) count = defaultValue;
  return count;
  }
 
 // Search buildings used
 var CityId;
 var buildingsCount = [];
 for (CityId in Cities)
  {
  if (Cities[CityId].own != true) continue;
  for (key in orderedBuildings)
   {
   var count = getBuildingCount(CityId, key, 0);
   if (buildingsCount[key] == undefined || buildingsCount[key] < count)
    {
    buildingsCount[key] = count;
    }
   }
  }
 
 s += "<table class='Overview Buildings'>";
 
 // Table header
 s += "<thead><tr><th class='nolf city_name' nowrap>"+this._Parent.Intl.TT("cityName")+"</th>";
 s += "<th class='actions' nowrap>"+this.Buildings_HeaderIcons(current_city_id)+"</th>";
 var firstStyle = '';
 var buildsNum = 0;
 var lastTopic = '';
 for (key in orderedBuildings) 
  {
  if (buildingsCount[key] > 0)
   {
   var colspan = (buildingsCount[key] > 1) ? ' colspan='+buildingsCount[key] : '';
   if (lastTopic != orderedBuildings[key]) { firstStyle = "lf"; } else { firstStyle = ""; }
   s += "<th"+colspan+" building='"+key+"' class='"+firstStyle+" build_name build_name"+buildingsCount[key]+" "+key+"' nowrap>"+
    this._Parent.Intl.TT(key,'buildings_short')+
    "</th>";
   lastTopic = orderedBuildings[key];
   buildsNum++;
   }
  }
 if (buildsNum <= 1) s += "<th class='lf'></th><th></th><th></th><th></th><th></th><th></th>";
 s += "</tr></thead>";
 
 s += "<tbody>";
 
 function createLinkToCityView(city_id)
  {
  var rHTML = '';
  rHTML += '<a href="?view=city&cityId='+city_id+'" class="changeCity" cityid="'+city_id+'" title="View city"><img align="absmiddle" src="skin/layout/icon-city2.gif" /></a>';
  if (reportViewToSurvey('city', city_id) == '!')
   {
   rHTML += '<sup class=Red title="Require attention">!</sup>';
   }
  else
   {
   rHTML += '&nbsp;';
   }
  return rHTML;
  }

 function getBuildingLink(city_id, name, defaultValue, position)
  {
  if (defaultValue == undefined) defaultValue = '';
  if (position == undefined)
   {
   position = -1;
   if (name == 'townHall') position = 0;
   }
  var link = '';
  
  if (position == -1)
   {
   // will deprecated
   var city = getCity(city_id);
   link = getArrValue(city.buildings[name], "link", defaultValue);
   }
  else
   {
   link = '?view='+name+'&id='+city_id+'&position='+position;
   }
  
  if (link == '') link = defaultValue;
  return link;
  }

 var CityId;
 var i = 0;
 var odd = '';
 for (CityId in Cities)
  {
  if (Cities[CityId].own != true) continue;
  var city = getCity(CityId);
  
  var trclass = (parseInt(current_city_id) == parseInt(CityId)) ? "current" : "";
  s += "<tr class='"+odd+" "+trclass+"' cityid='"+CityId+"' islandid='"+city.island_id+"' coord='"+city.city_coord+"'>";
  
  var usedspaces = getCityBuildingsCount(CityId, 0);
  s += "<td class='nolf city_name' nowrap>"+createLinkToChangeCity(Cities[CityId].name, CityId, i, (usedspaces > 0) ? 15-usedspaces : '', 'Green', 'Available free spaces')+"</td>";
  s += "<td class='actions' nowrap>"+createLinkToCityView(CityId)+"</td>";
  
  var firstStyle = '';
  var lastTopic = '';
  for (key in orderedBuildings)
   {
   if (buildingsCount[key] > 0)
    {
    if (lastTopic != orderedBuildings[key]) { firstStyle = "lf"; } else { firstStyle = ""; }
    
    var buildingCount = 0;
    if (city.buildings[key] != undefined)
     {
     if (city.buildings[key].levels == undefined)
      {
      // soon deprecated
      city.buildings[key].levels = {};
      var position = getBuildingPosition(parseInt(CityId), key, -1);
      var level = getBuildingLevel(parseInt(CityId), key, 0, position);
      city.buildings[key].levels[position] = level;
      }
     
     var position;
     for (position in city.buildings[key].levels)
      {
      var currentBuildingStyle = "";
      if ((key == this._Parent.Ikariam.View()) && (parseInt(CityId) == city_idmainView) && (position == city_positionmainView))
       {
       currentBuildingStyle = " Bold current";
       }

      var level = getBuildingLevel(parseInt(CityId), key, '-', position);
      if (level == undefined || level == "" || level == 0)
       {
       level = "-";
       }

      var link = getBuildingLink(parseInt(CityId), key, '-', position);

      if ((city.underConstructionName == key) && (city.underConstructionPosition == position))
       {
       if (level == "-") { level = 0; }
       var underConstructionTime = city.underConstructionTime;
       // deprecated
       //if (underConstructionTime == undefined) underConstructionTime = city.underConstruction.split(",")[1];
       var sdate = smartDateFormat(underConstructionTime);
       if (underConstructionTime <= this._Parent.StartTime)
        {
        var levellink = level;
        if (link != "-")
         levellink = "<a href='" + link + "' class=\"changeCity Green Bold\" cityid="+CityId+">"+level+"</a>";
        levellink += '<sup class=Red title="Require attention">!</sup>';
        levelUpgrading = createTooltip(levellink, '<nobr>'+sdate+'</nobr>', this._Parent.Intl.TT("finishedBuilding")+':' );
        }
       else
        {
        var counter = "<font id='mytimecounter' counter='"+Math.round(underConstructionTime)+"' class='time_counter'>___:___:___</font>";
        var levellink =level+"&raquo;"+(level+1);
        if (link != "-")
         levellink = "<a href='" + link + "' class=\"changeCity Green Bold\" cityid="+CityId+">"+level+"&raquo;"+(level+1)+"</a>";
        if ((level > 0) && (reportViewToSurvey(key, CityId) == '!'))
         {
         levellink += '<sup class=Red title="Require attention">!</sup>';
         }
        else
         {
         levellink += '&nbsp;';
         }
        levelUpgrading = createTooltip(levellink, '<nobr>'+sdate +' ('+ counter+')</nobr>', this._Parent.Intl.TT("currentlyBuilding")+':');
        }
       s += "<td level='"+level+"' view='"+key+"' position='"+position+"' class='"+firstStyle+" "+key+" "+currentBuildingStyle+"'>"+levelUpgrading+"</td>";
       }
      else
       {
       var levellink =level;
       if (level != "-")
        {
        levellink = "<a href='" + link + "' class=changeCity cityid="+CityId+">"+level+"</a>";
        
        if (reportViewToSurvey(key, CityId) == '!')
         {
         levellink += '<sup class=Red title="Require attention">!</sup>';
         }
        else
         {
         levellink += '&nbsp;';
         }
        }
       else
        {
        levellink += '&nbsp;';
        }
       s += "<td level='"+level+"' view='"+key+"' position='"+position+"' class='"+firstStyle+" "+key+" "+currentBuildingStyle+"'>"+levellink+"</td>";
       }
      buildingCount++;
      firstStyle = 'lfdash';
      }
     }
    else
     {
     s += "<td level='0' view='"+key+"' class='"+firstStyle+" "+key+"'>-&nbsp;</td>";
     buildingCount++;
     firstStyle = '';
     }

    if (buildingCount < buildingsCount[key])
     {
     for (var j = buildingCount; j < buildingsCount[key]; j++)
      {
      s += "<td level='0' view='"+key+"' class='"+firstStyle+" "+key+"'>-&nbsp;</td>";
      firstStyle = 'lfdash';
      }
     }

    lastTopic = orderedBuildings[key];
    }
   }
  
  if (buildsNum <= 1) s += "<td class='lf'></td><td></td><td></td><td></td><td></td><td></td>";
  
  s += "</tr>";
  
  if (odd == '') { odd = 'odd'; } else { odd = ''; }
  i++;
  }
 
 s += "</tbody>";
 
 s += "<tfoot></tfoot>";
 
 s += "</table>";
 
 return s;
 };
 
EmpireBoard.Renders.BuildingName_Tooltip_Content = function(building_id)
 {
 return '<nobr>'+this._Parent.Intl.TT(building_id,'buildings')+'</nobr>';
 };
 
EmpireBoard.Renders.Resources_Table_Content = function()
 {
 var _self = this;
 
 var s = "";
 var Cities = this._Parent.DB.CurrentCities;
 
 s += "<table class='Overview Resources'>";
 
 s += "<thead><tr>";
 s += "<th class='nolf city_name' nowrap>"+this._Parent.Intl.TT("cityName")+"</th>"+
   "<th class='actions' nowrap>"+this.Resources_HeaderIcons(current_city_id)+"</th>"+
   "<th colspan=3 class='lf population' nowrap>"+this._Parent.Intl.TT("Population")+"</th>"+
   "<th colspan=1 class='growth' nowrap>"+this._Parent.Intl.TT("Growth")+"</th>"+
   "<th colspan=1 class='lf research' nowrap>"+this._Parent.Intl.TT("Research")+"</th>"+
   "<th colspan=1 class='lf incomes' nowrap>"+this._Parent.Intl.TT("Incomes")+"</th>"+
   "<th colspan=2 class='lf wood'>"+this._Parent.Intl.TT("Wood")+"</th>"+
   "<th colspan=3 class='lf wine'>"+this._Parent.Intl.TT("Wine")+"</th>"+
   "<th colspan=2 class='lf marble'>"+this._Parent.Intl.TT("Marble")+"</th>"+
   "<th colspan=2 class='lf crystal'>"+this._Parent.Intl.TT("Crystal")+"</th>"+
   "<th colspan=2 class='lf sulfur'>"+this._Parent.Intl.TT("Sulfur")+"</th>";
 s += "</tr></thead>";
 
 var sumres = new Resource("");
 sumres.population  = 0;
 sumres.citizens   = 0;
 sumres.spacetotal  = 0;
 sumres.growth   = 0;
 sumres.Income   = 0;
 sumres.reservedGold  = '';
 sumres.Research   = 0;
 sumres.ResearchBonus = '';
 
 var sumProd = new Resource("");
 sumProd.wineUsage = 0;
 
 var sumArTr = new Resource("");

 function createIncome(prodPerHour, extraTooltip, classname)
  {
  if (classname == undefined) classname = '';
  if (""+prodPerHour == "NaN" || ""+prodPerHour == "" || ""+prodPerHour == "?" || prodPerHour == undefined || ""+prodPerHour == "???")
   {
   return "?";
   }
  else if (""+prodPerHour == "0")
   {
   return "0";
   }
  else
   {
   var tooltip = _self._Parent.Str.FormatBigNumber(Math.round(24 * prodPerHour), true)+" / "+_self._Parent.Ikariam.LocalizationStrings('day','timeunits','short');
   if ((extraTooltip != undefined) && (extraTooltip != ''))
    {
    tooltip += "<br>&nbsp;"+extraTooltip;
    }
   return createTooltip('<span class="'+classname+'">'+_self._Parent.Str.FormatBigNumber(Math.round(prodPerHour), true)+'</span>', tooltip);
   }
  }

 function createLinkToAgora(city_id)
  {
  var rHTML = '';
  
  if (_self._Parent.Ikariam.Is_Version('0.3.2') == true)
   {
   var res = getCity(city_id);
   
   if (res.island_id != undefined)
    {
    rHTML += '<a href="?view=islandBoard&id='+res.island_id+'" title="View island agora"><img hspace="3" height="12" src="skin/board/schriftrolle_offen2.gif" align="absmiddle" /></a>';
    }
   }
   
  return rHTML;
  }

 function createLinkToMap(city_id)
  {
  var res = getCity(city_id);
  var rHTML = '';
  
  if (res.city_coord != undefined)
   {
   cCoord =  res.city_coord.split(":");
   rHTML += '<a href="?view=worldmap_iso&islandX='+_self._Parent.Str.To_Integer(cCoord[0],'')+'&islandY='+_self._Parent.Str.To_Integer(cCoord[1],'')+'" title="' + res.city_coord + ' View world map"><img align="absmiddle" src="skin/layout/icon-world.gif" /></a>'; 
   }
   
  if ((res.island_id != undefined) && (res.city_coord != undefined))
   {
   rHTML += '<a href="?view=island&id=' + res.island_id + '&selectCity='+city_id+'" title="' + res.city_coord + ' View island"><img align="absmiddle" src="skin/layout/icon-island.gif" /></a>'; 
   }
  else if (res.island_id != undefined)
   {
   rHTML += '<a href="?view=island&id=' + res.island_id + '&selectCity='+city_id+'" title="View island"><img align="absmiddle" src="skin/layout/icon-island.gif" /></a>'; 
   }
   
  return rHTML;
  }

 function createLinkToResourceCond(condition, text, island_id, city_id, city_index)
  {
  if (condition == true && island_id != undefined && island_id != "")
   {
   return createLink(text, "?view=resource&type=resource&id="+island_id, "class=changeCity cityid="+city_id);
   }
  return text;
  }

 function createLinkToTradegoodCond(condition, text, island_id, city_id, city_index)
  {
  if (condition == true && island_id != undefined && island_id != "")
   {
   return createLink(text, "?view=tradegood&type=tradegood&id="+island_id, "class=changeCity cityid="+city_id);
   }
  return text;
  }

 function createLinkToResources(city_id)
  {
  var res = getCity(city_id);
  var rHTML = '';
  if (res.island_id != undefined)
   {
   rHTML += '<a class="changeCity" cityid="'+city_id+'" href="?view=resource&type=resource&id=' + res.island_id + '" title="View island saw mill"><img height="12" align="absmiddle" src="skin/resources/icon_wood.gif" /></a>';
   rHTML += '&nbsp;';
   
   if (res.prodgood == 'wine')
    {
    rHTML += '<a class="changeCity" cityid="'+city_id+'" href="?view=tradegood&type=tradegood&id=' + res.island_id + '" title="View island vineyard"><img height="12" align="absmiddle" src="skin/resources/icon_wine.gif" /></a>';
    }
   else if (res.prodgood == 'marble')
    {
    rHTML += '<a class="changeCity" cityid="'+city_id+'" href="?view=tradegood&type=tradegood&id=' + res.island_id + '" title="View island quarry"><img height="12" align="absmiddle" src="skin/resources/icon_marble.gif" /></a>';
    }
   else if (res.prodgood == 'glass')
    {
    rHTML += '<a class="changeCity" cityid="'+city_id+'" href="?view=tradegood&type=tradegood&id=' + res.island_id + '" title="View island crystal mine"><img height="12" align="absmiddle" src="skin/resources/icon_glass.gif" /></a>';
    }
   else if (res.prodgood == 'sulfur')
    {
    rHTML += '<a class="changeCity" cityid="'+city_id+'" href="?view=tradegood&type=tradegood&id=' + res.island_id + '" title="View island sulphur pit"><img height="12" align="absmiddle" src="skin/resources/icon_sulfur.gif" /></a>';
    }
    
   rHTML += '&nbsp;';
   }
  return rHTML;
  }

 function createLinkToTransportGoods(city_id)
  {
  var rHTML = '';
  if (current_city_id == city_id)
   {
   rHTML += '<img class="Action" src="skin/actions/transport_disabled.gif" align="absmiddle" />';
   }
  else
   {
   rHTML += '<a view=transport href="?view=transport&destinationCityId='+city_id+'" title="Transports goods"><img class="Action" src="skin/actions/transport.gif" align="absmiddle" /></a>';
   }
  return rHTML;
  }

 function createProd(prodPerHour, extraTooltip)
  {
  if (prodPerHour == "-" || prodPerHour == "?")
   {
   return prodPerHour;
   }
  else if (""+prodPerHour == "NaN" || ""+prodPerHour == "" || ""+prodPerHour == "0" || prodPerHour == undefined || ""+prodPerHour == "???")
   {
   return "";
   }
  else
   {
   var tooltip = _self._Parent.Str.FormatBigNumber(Math.round(24 * prodPerHour), true)+" / "+_self._Parent.Ikariam.LocalizationStrings('day','timeunits','short');
   if (extraTooltip != undefined)
    {
    tooltip += ", "+extraTooltip;
    }
   return createTooltip(_self._Parent.Str.FormatBigNumber(Math.round(prodPerHour), true), tooltip);
   }
  }

 function createResCounter(startTime, startAmount, factPerHour, showTooltip, maxAmount, tradeAmount, secureAmount, arrAmount)
  {
  if (tradeAmount == undefined) tradeAmount = 0;
  if (arrAmount == undefined) arrAmount = 0;
  if ((maxAmount == undefined) || (maxAmount == '-'))
   {
   maxAmount = '-';
   }
  else
   {
   maxAmount = maxAmount - tradeAmount;
   }
  var currAmount = startAmount;
  var tooltip = "";
  var res;
  
  if ((startAmount == undefined) || (startAmount+"" == "NaN"))
   {
   res = '?';
   }
  else if ((factPerHour != undefined) && (factPerHour+"" != "NaN") && (factPerHour != 0))
   {
   var counterClass = '';
   var intfactPerHour = Math.round(factPerHour);
   var dailyFact = Math.round(24 * factPerHour);
   if (startTime != undefined)
    {
    currAmount = getCurrentResourceAmount(_self._Parent.StartTime, startTime, startAmount, intfactPerHour);
    if (intfactPerHour > 0)
     {
     counterClass = 'Bold';
     }
    else if (intfactPerHour < 0)
     {
     if (currAmount+(6*intfactPerHour) <= 0)
      {
      counterClass = 'Red';
      }
     else if (currAmount+(24*intfactPerHour) <= 0)
      {
      counterClass = 'DarkRed';
      }
     }
    res = "<font id='myresourcecounter' counter='"+startTime+","+startAmount+","+intfactPerHour+","+maxAmount+"' class='"+counterClass+"'>"+_self._Parent.Str.FormatBigNumber(currAmount)+"</font>";
    }
   
   if (showTooltip == true) 
    {
       tooltip = _self._Parent.Str.FormatBigNumber(intfactPerHour, true)+" / "+_self._Parent.Ikariam.LocalizationStrings('hour','timeunits','short')+"<br> "+_self._Parent.Str.FormatBigNumber(dailyFact, true)+" / "+_self._Parent.Ikariam.LocalizationStrings('day','timeunits','short');
    if (intfactPerHour < 0)
     tooltip += "<br>&nbsp;" + _self._Parent.Str.FormatRemainingTime(-1 * (currAmount+arrAmount) / intfactPerHour * 60 * 60 * 1000) + " to empty";
    }
   }
  else
   {
   res = _self._Parent.Str.FormatBigNumber(currAmount);
   }
   
  // Safety goods ?
  if ((secureAmount > 0) && (secureAmount >= (currAmount+tradeAmount)))
   {
   res = '<img src="skin/layout/icon-wall.gif" class="Safe" title="Safety resources"/> '+res;
   }
   
  if (tooltip != '') res = createTooltip(res, tooltip);
  return res + "&nbsp;";
  }
 
 function createResearch(prodPerHour, extraTooltip)
  {
  if (prodPerHour == "-" || prodPerHour == "?")
   {
   return prodPerHour;
   }
  else if (""+prodPerHour == "0")
   {
   return '+0';
   }
  else if (""+prodPerHour == "NaN" || ""+prodPerHour == "" || prodPerHour == undefined || ""+prodPerHour == "???")
   {
   return "";
   }
  else
   {
   var tooltip = _self._Parent.Str.FormatBigNumber(Math.round(24 * prodPerHour), true)+" / "+_self._Parent.Ikariam.LocalizationStrings('day','timeunits','short');
   if (extraTooltip != undefined)
    {
    tooltip += ", "+extraTooltip;
    }
   return createTooltip(_self._Parent.Str.FormatBigNumber(Math.round(prodPerHour), true), tooltip);
   }
  }

 function getArrivingGoodsSum(city_id, resName)
  {
  var sum = 0;
  var city = getCity(city_id);
  var rows = getArrValue(config.arrivinggoods, city_id, []);
  var key;
  for (key in rows)
   {
   var row = rows[key];
   var res = row["res"];
   var a = getArrValue(res, resName, 0);
   var arrivetime = parseInt(getArrValue(row, "arrivetime", ""));
   if ((a > 0) && (arrivetime > city.prodtime)) sum += a;
   }
  return sum;
  }
 
 function getArrivingGoods(city_id, resName, tradinggoods, resAmount, ArrivingGoodsSum)
  {
  var sum = 0;
  var found = false;
  if (ArrivingGoodsSum == undefined)
   ArrivingGoodsSum = getArrivingGoodsSum(city_id, resName);
  if (ArrivingGoodsSum > 0)
   {
   sum += ArrivingGoodsSum;
   found = true;
   }

  if ((tradinggoods != undefined) && (parseInt(tradinggoods) > 0))
   {
   sum += parseInt(tradinggoods);
   }

  var s = "<font class='More'>-&nbsp;</font>";
  if (found == true)
   {
   s = "<font class='More MoreGoods Green'>"+_self._Parent.Str.FormatBigNumber(sum, true);
   if (getDeliveredGoodsTransports(city_id, resName) > 0)
    {
    s += "<sup>*</sup>";
    }
   else s += "&nbsp;";
   s += "</font>";
   }
  else if (sum > 0)
   {
   s = "<font class='More MoreGoods'>"+_self._Parent.Str.FormatBigNumber(sum, true)+"&nbsp;</font>";
   }
  return s;
  }

 function createReservedGold(sum)
  {
  var output = '';
  if (sum == '?')
   {
   output = '<font class="More">?</font>';
   }
  else if (sum === 0)
   {
   output = '<font class="More">-</font>';
   }
  else if ((sum != undefined) && (sum != ''))
   {
   output = '<font class="More" title="Reserved gold">'+_self._Parent.Str.FormatBigNumber(sum)+'</font>';
   }
  return output;
  }
  
 function createSimpleProd(prodPerHour)
  {
  if (""+prodPerHour == "NaN" || ""+prodPerHour == "" || ""+prodPerHour == "0" || prodPerHour == undefined || ""+prodPerHour == "???")
   {
   return "";
   }
  return _self._Parent.Str.FormatBigNumber(Math.round(prodPerHour), true);
  }

 function createTransports(cityID)
  {
  var res = "<font class='More'></font>";
  var numTransports = 0;
  if (config["transports"] == undefined)
   {
   
   }
  else if (config["transports"][cityID] != undefined)
   {
   for (key in config["transports"][cityID])
    {
    if (config["transports"][cityID][key].endTime >= _self._Parent.StartTime) numTransports++;
    }
    
   if (numTransports > 0) res = "<font class='More Transports'>"+numTransports+" transport(s) on way</font>";
   }
   
  return res;
  }

 function createForeignTransports(cityID)
  {
  var res = "<font class='More'></font>";
  var numMovements = 0;
  if (config["foreignTransports"] == undefined)
   {
   
   }
  else if (config["foreignTransports"][cityID] != undefined)
   {
   for (key in config["foreignTransports"][cityID])
    {
    if (config["foreignTransports"][cityID][key].endTime >= _self._Parent.StartTime)
     numMovements++;
    }
    
   if (numMovements > 0)
    res = "<font class='More ForeignTransports'>"+numMovements+" foreign transport(s)</font>";
   }
   
  return res;
  }
  
 function createResProgressBar(startTime, startAmount, factPerHour, maxCapacity, secureCapacity)
  {
  var res = '';
  if ((_self._Parent.DB.Options.Prefs.PROGRESS_BAR_MODE != "off") && (maxCapacity > 0) && (startTime != undefined))
   {
   var curres = getCurrentResourceAmount(new Date().getTime(), startTime, startAmount, factPerHour);
   var perc = Math.min(100, Math.round(curres / maxCapacity * 100.0));
   var remaining = "";
   var remhour = 100000000;
   if (curres >= maxCapacity)
    {
    // no more
    remhour = 0;
    }
   else if (factPerHour > 0)
    {
    remhour = (maxCapacity - curres) / factPerHour;
    remaining = "<br>"+_self._Parent.Str.FormatRemainingTime(remhour*60*60*1000)+" to full";
    }
   else if (factPerHour < 0)
    {
    remaining = "<br>"+_self._Parent.Str.FormatRemainingTime((curres / -factPerHour)*60*60*1000) + " to empty";
    }
   var cl = "Normal";
   var vperc = perc;
   if ((curres > 0) && (vperc < 4)) vperc = 4;
   if ((_self._Parent.DB.Options.Prefs.PROGRESS_BAR_MODE == "time") && (factPerHour != 0))
    {
    if (remhour <= 1) 
     {
     cl = "Full";
     } 
    else if (remhour < 24)
     {
     cl = "AlmostFull";
     }
    else if (remhour < 72)
     {
     cl = "Warning";
     }
    }
   else
    {
    if (perc >= 99)
     {
     cl = "Full";
     }
    else if (perc >= 90)
     {
     cl = "AlmostFull";
     }
    else if (perc >= 80)
     {
     cl = "Warning";
     }
    } 
   res +=  "<table class='myPercent' "+createTooltipAttribute(_self._Parent.Str.FormatBigNumber(maxCapacity) + " total capacity<br>"+_self._Parent.Str.FormatBigNumber(secureCapacity)+" safety capacity<br>" + perc+"% full" + remaining)+">"+
   "<tr>"+
   "<td width='"+vperc+"%' class='"+cl+"'></td>"+
   "<td width='"+(100-vperc)+"%'></td>"+
   "</tr>"+
   "</table>";
   }
  else if (_self._Parent.DB.Options.Prefs.PROGRESS_BAR_MODE != "off")
   {
   res +=  "<table class='myPercent'>"+
   "<tr>"+
   "<td></td>"+
   "</tr>"+
   "</table>";
   }
  return res;
  }

 s += "<tbody>";

 var CityId;
 var i = 0;
 var odd = '';
 for (CityId in Cities)
  {
  if (Cities[CityId].own != true) continue;
  var city = getCity(CityId);
  
  if (getBuildingLevel(CityId, "branchOffice", "-") != '-')
   {
   if (city.tradewood == undefined) city.tradewood = 0;
   if (city.tradewine == undefined) city.tradewine = 0;
   if (city.trademarble == undefined) city.trademarble = 0;
   if (city.tradeglass == undefined) city.tradeglass = 0;
   if (city.tradesulfur == undefined) city.tradesulfur = 0;
   }
  else
   {
   city.tradewood = 0;
   city.tradewine = 0;
   city.trademarble = 0;
   city.tradeglass = 0;
   city.tradesulfur = 0;
   }
  
  var wineUsage = 0;
  var cellarLevel = getBuildingLevel(CityId, "vineyard", "-");
  var tavernLevel = getBuildingLevel(CityId, "tavern", "-");
  if (tavernLevel == '-')
   {
   // Fix if tavern has been demolished without disable wine usage
   }
  else if (city.wineUsageId != undefined)
   {
   wineUsage = tavernWineUsage[city.wineUsageId];
   if (cellarLevel != '-') 
    {
    wineSave = wineUsage * cellarLevel;
    wineSave = Math.round(wineSave / 100);
    wineUsage = wineUsage - wineSave;
    }
   }
  else if (city.wineUsage != undefined)
   {
   wineUsage = city.wineUsage;
   } 
  // Wine usage tooltip
  var wineUsageHtml = '-';
  if (wineUsage > 0)
   {
   wineUsageHtml = createSimpleProd(-1 * wineUsage);
   }
  
  // Estimate current amount of each resources
  var curres = new Resource("");
  curres.wood   = getCurrentResourceAmount(this._Parent.StartTime, city.prodtime, city.wood, city.prodwood);
  curres.wine   = getCurrentResourceAmount(this._Parent.StartTime, city.prodtime, city.wine, city.prodwine - wineUsage);
  curres.marble  = getCurrentResourceAmount(this._Parent.StartTime, city.prodtime, city.marble, city.prodmarble);
  curres.glass  = getCurrentResourceAmount(this._Parent.StartTime, city.prodtime, city.glass, city.prodglass);
  curres.sulfur  = getCurrentResourceAmount(this._Parent.StartTime, city.prodtime, city.sulfur, city.prodsulfur);

  sumres.wood   += curres.wood;
  sumres.wine   += curres.wine;
  sumres.marble  += curres.marble;
  sumres.glass  += curres.glass;
  sumres.sulfur  += curres.sulfur;

  sumProd.wood   += city.prodwood;
  sumProd.wine   += city.prodwine;
  sumProd.wineUsage  += wineUsage;
  sumProd.marble   += city.prodmarble;
  sumProd.glass   += city.prodglass;
  sumProd.sulfur   += city.prodsulfur;
  
  // Resources which will arrive
  var arrres = new Resource('');
  arrres.wood   = getArrivingGoodsSum(CityId, 'wood');
  arrres.wine   = getArrivingGoodsSum(CityId, 'wine');
  arrres.marble  = getArrivingGoodsSum(CityId, 'marble');
  arrres.glass  = getArrivingGoodsSum(CityId, 'glass');
  arrres.sulfur  = getArrivingGoodsSum(CityId, 'sulfur');

  sumArTr.wood  += city.tradewood + arrres.wood;
  sumArTr.wine  += city.tradewine + arrres.wine;
  sumArTr.marble  += city.trademarble + arrres.marble;
  sumArTr.glass  += city.tradeglass + arrres.glass;
  sumArTr.sulfur  += city.tradesulfur + arrres.sulfur;
  
  // City income
  var Income = getArrValue(city.buildings["townHall"],"incomegold","?");
  if (Income != "?")
   {
   sumres.Income += Income;
   }
  
  // Gold in trading post
  var reservedGold = '';
  if (city.buildings["branchOffice"] != undefined)
   {
   if (city.buildings["branchOffice"].reservedGold == undefined)
    {
    reservedGold = '?';
    }
   else
    {
    reservedGold = city.buildings["branchOffice"].reservedGold;
    if (reservedGold > 0)
     {
     if (sumres.reservedGold == '')
      {
      sumres.reservedGold = reservedGold;
      }
     else
      {
      sumres.reservedGold += reservedGold;
      }
     }
    }
   }
   
  // Research point
  var Research = '-';
  if (getBuildingLevel(CityId, "academy", 0) > 0)
   {
   Research = getArrValue(city.buildings["academy"],"Research","?");
   
   if (Research != '?')
    {
    sumres.Research += Research;
    }
   }
  
  var spacetotal   = '?';
  var townHallLevel  = getBuildingLevel(CityId, "townHall", "?", 0);
  if (townHallLevel != '?')
   spacetotal = townHallSpaces[townHallLevel];
  var bonusspace   = getArrValue(city.buildings["townHall"], "bonusspace", "?");

  var workers    = '?';
  var population   = getArrValue(city.buildings["townHall"], "population", 0);
  var citizens   = getArrValue(city.buildings["townHall"], "citizens", '?');
  if (citizens != '?')
   workers = population - citizens;
  
  // Estimate current population and growth
  var growth    = 0;
  var happiness   = getArrValue(city.buildings["townHall"], "happiness", "?");
  if ((happiness != '?') && (spacetotal != '?') && (bonusspace != '?'))
   {
   population = getEstimatedPopulation(population, city.prodtime, this._Parent.StartTime, happiness - population);
   if (parseInt(population) > parseInt(spacetotal) + parseInt(bonusspace))
    {
    population = parseInt(spacetotal) + parseInt(bonusspace);
    }
   happiness -= population;
   
   if (happiness != 0)
    growth = (0.02 * happiness) + 0.01;
   }
  else
   {
   growth = getArrValue(city.buildings["townHall"], "growth", "?");
   }
  sumres.population += population;
  
  // Current citizens
  if (workers != '?')
   {
   citizens = population - workers;
   if (sumres.citizens != '?')
    {
    sumres.citizens += citizens;
    }
   }
  else
   {
   citizens = '?';
   sumres.citizens = '?';
   }
  
  // Estimate growth remaining time
  var growthRemainingHours = '';
  if (happiness != "?" && happiness > 0 && bonusspace != "?" && growth >= 0.20)
   {
   growthRemainingHours = getGrowthRemainingHours(population, parseInt(spacetotal) + parseInt(bonusspace), this._Parent.StartTime, happiness);
   }
  
  // Global growth
  if ((growth != '?') && (sumres.growth != '?'))
   {
   if (parseInt(population) < parseInt(spacetotal) + parseInt(bonusspace))
    sumres.growth += growth;
   }
  else
   {
   sumres.growth = '?';
   }
  
  // Is current city ?
  var trclass = "";
  if (parseInt(current_city_id) == parseInt(CityId))
   {
   trclass = "current";
   }

  var townHallStyle = "";
  var growthStyle = "";
  if (parseInt(population) >= parseInt(spacetotal) + parseInt(bonusspace))
   {
   // Townhall is full
   growthRemainingHours = '';
   if (growth >= 1.20) 
    {
    townHallStyle = " DarkRed";
    }
   else if (growth >= 0.20) 
    {
    townHallStyle = " Brown";
    }
   else
    {
    townHallStyle = " Bold";
    }
   }
  else if (growth >= 0.20)
   {
   growthStyle = " Green";
   }
  else if (growth >= 0)
   {
   growthStyle = "";
   }
  else if (growth <= -1)
   {
   growthStyle = " Red";
   }
  else if (growth <= -0.20)
   {
   growthStyle = " DarkRed";
   }
  
  // Global townhall capacity
  if (bonusspace != "?")
   {
   if (sumres.spacetotal != '?')
    sumres.spacetotal += parseInt(spacetotal) + parseInt(bonusspace);
   spacetotal = this._Parent.Str.FormatBigNumber(parseInt(spacetotal) + parseInt(bonusspace));
   }
  else
   {
   sumres.spacetotal = '?';
   spacetotal = this._Parent.Str.FormatBigNumber(spacetotal) + " + ?";
   }
  
  // Warehouse safe capacity bonus by premium option
  var savecapacityBonus = 0;
  if (config["premium"] != undefined)
   {
   if ((config["premium"].savecapacityBonus != undefined) && (config["premium"].savecapacityBonus > this._Parent.StartTime))
    {
    savecapacityBonus = 100;
    }
   }
  
  // Warehouse storage capacity bonus by premium option
  var storagecapacityBonus = 0;
  if (config["premium"] != undefined)
   {
   if ((config["premium"].storagecapacityBonus != undefined) && (config["premium"].storagecapacityBonus > this._Parent.StartTime))
    {
    storagecapacityBonus = 100;
    }
   }
  
  // Warehouse max capacity
  var maxcwood   = 0;
  var maxcother   = 0;
  var maxsafewood   = 0;
  var maxsafeother  = 0;
  if (this._Parent.Ikariam.Is_Version('0.3.4') == true)
   {
   var WarehousesLevels = [];
   var WarehousesLevel = 0;
   if ((city.buildings['warehouse'] != undefined) && (city.buildings['warehouse'].levels != undefined))
    {
    var p;
    for (p in city.buildings['warehouse'].levels)
     {
     var WarehouseLevel = getBuildingLevel(CityId, 'warehouse', city.buildings['warehouse'].levels[p], p);
     WarehousesLevel += WarehouseLevel;
     WarehousesLevels.push(WarehouseLevel);
     }
    }
   else
    {
    // While build first warehouse
    WarehousesLevel  = getBuildingLevel(CityId,'warehouse', 0, -1);
    WarehousesLevels.push(WarehousesLevel);
    }
    
   var DumpLevel = getBuildingLevel(CityId,'dump', 0, -1);
   
   maxcwood   = this._Parent.Ikariam.Resource_Capacity('wood',WarehousesLevel,DumpLevel,storagecapacityBonus);
   maxcother   = maxcwood;
   maxsafewood   = this._Parent.Ikariam.Resource_SafeCapacity('wood',WarehousesLevels,savecapacityBonus);
   maxsafeother  = maxsafewood;
   }
  else
   {
   // Soon deprecated
   var WarehousesLevel  = getBuildingLevel(CityId,'warehouse', 0, -1);
   
   maxcwood   = this._Parent.Ikariam.Resource_Capacity('wood',WarehousesLevel,0,storagecapacityBonus);
   maxcother   = this._Parent.Ikariam.Resource_Capacity('wine',WarehousesLevel,0,storagecapacityBonus);
   maxsafewood   = this._Parent.Ikariam.Resource_SafeCapacity('wood',WarehousesLevel,savecapacityBonus);
   maxsafeother  = this._Parent.Ikariam.Resource_SafeCapacity('wine',WarehousesLevel,savecapacityBonus);
   }

  var cityLink = '';
  if (reportViewToSurvey('',CityId) == '!')
   {
   cityLink = createLinkToChangeCity(Cities[CityId].name, CityId, i, reportViewToSurvey('',CityId),'Red', 'Require attention');
   }
  else
   {
   cityLink = createLinkToChangeCity(Cities[CityId].name, CityId, i , city.actions, 'Green', 'Available action points');
   }
  
  s += "<tr class='"+odd+" "+trclass+"' cityid='"+CityId+"' islandid='"+city.island_id+"' coord='"+city.city_coord+"' tradegood='"+city.prodgood+"'>";
  
  s += "<td class='nolf city_name' nowrap>"+cityLink+createTransports(CityId)+createForeignTransports(CityId)+"</td>"+
    "<td class='actions' nowrap>"+createLinkToMap(CityId)+createLinkToAgora(CityId)+"<br />"+createLinkToResources(CityId)+createLinkToTransportGoods(CityId)+"</td>"+
    "<td class='lf'>"+
     "<span title='Citizens'>"+(population > 0 ? this._Parent.Str.FormatBigNumber(citizens) : '?')+"</span>"+
     "&nbsp;("+
    "</td>"+
    "<td class='nolf'>"+
     "<span title='Overall inhabitants' class='inhabitant"+townHallStyle+"'>"+(population > 0 ? this._Parent.Str.FormatBigNumber(population) : '?')+"</span>)"+
     "&nbsp;/</td>"+
    "<td class='nolf' title='Housing space'>"+spacetotal+"</td>"+
    "<td class='"+growthStyle+"'>"+(growth != '?' ? '<img src="'+this._Parent.Ikariam.Get_Happiness_ImgSrc(growth)+'" align=left height=18 hspace=2 vspace=0 title="Total satisfaction: '+happiness+'">' : '')+createTooltip(this._Parent.Str.FormatFloatNumber(growth,2,true), growthRemainingHours)+"</td>"+
    "<td class='lf'>"+createResearch(Research)+"</td>"+
    "<td class='lf'>"+
     createIncome(Income)+
     createReservedGold(reservedGold)+
    "</td>"+
    "<td class='lf' resource='wood'>"+
     createLinkToResourceCond(true, createResCounter(city.prodtime, city.wood, city.prodwood, false, maxcwood, city.tradewood, maxsafewood), city.island_id, CityId, i)+
     getArrivingGoods(CityId, "wood", city.tradewood, curres.wood, arrres.wood)+
     createResProgressBar(city.prodtime, city.wood + arrres.wood, city.prodwood, maxcwood - city.tradewood, maxsafewood)+
    "</td>"+
    "<td class='lfdash'>"+createProd(city.prodwood)+"</td>"+
    "<td class='lf' resource='wine'>"+
     createLinkToTradegoodCond((city.prodwine > 0) || (city.prodgood == 'wine'), createResCounter(city.prodtime, city.wine, city.prodwine - wineUsage, true, maxcother, city.tradewine, maxsafeother, arrres.wine), city.island_id, CityId, i)+
     getArrivingGoods(CityId, "wine", city.tradewine, curres.wine, arrres.wine)+
     createResProgressBar(city.prodtime, city.wine + arrres.wine, city.prodwine - wineUsage, maxcother - city.tradewine, maxsafeother)+
    "</td>"+
    "<td class='lfdash'>"+createSimpleProd(city.prodwine)+"</td>"+
    "<td class='lfdash'>"+wineUsageHtml+"</td>"+
    "<td class='lf' resource='marble'>"+
     createLinkToTradegoodCond((city.prodmarble > 0) || (city.prodgood == 'marble'), createResCounter(city.prodtime, city.marble, city.prodmarble, false, maxcother, city.trademarble, maxsafeother), city.island_id, CityId, i)+
     getArrivingGoods(CityId, "marble", city.trademarble, curres.marble, arrres.marble)+
     createResProgressBar(city.prodtime, city.marble + arrres.marble, city.prodmarble, maxcother - city.trademarble, maxsafeother)+
    "</td>"+
    "<td class='lfdash'>"+createProd(city.prodmarble)+"</td>"+
    "<td class='lf' resource='glass'>"+
     createLinkToTradegoodCond((city.prodglass > 0) || (city.prodgood == 'glass'), createResCounter(city.prodtime, city.glass, city.prodglass, false, maxcother, city.tradeglass, maxsafeother), city.island_id, CityId, i)+
     getArrivingGoods(CityId, "glass", city.tradeglass, curres.glass, arrres.glass)+
     createResProgressBar(city.prodtime, city.glass + arrres.glass, city.prodglass, maxcother - city.tradeglass, maxsafeother)+
    "</td>"+
    "<td class='lfdash'>"+createProd(city.prodglass)+"</td>"+
    "<td class='lf' resource='sulfur'>"+
     createLinkToTradegoodCond((city.prodsulfur > 0) || (city.prodgood == 'sulfur'), createResCounter(city.prodtime, city.sulfur, city.prodsulfur, false, maxcother, city.tradesulfur, maxsafeother), city.island_id, CityId, i)+
     getArrivingGoods(CityId, "sulfur", city.tradesulfur, curres.sulfur, arrres.sulfur)+
     createResProgressBar(city.prodtime, city.sulfur + arrres.sulfur, city.prodsulfur, maxcother - city.tradesulfur, maxsafeother)+
    "</td>"+
    "<td class='lfdash'>"+createProd(city.prodsulfur)+"</td>";
  s += "</tr>";
  
  i++;
  if (odd == '') { odd = 'odd'; } else { odd = ''; }
  }
 
 s += "</tbody>";
 
 // Gold usage remaining time
 var goldRemainingHours = '';
 var goldStyle = '';
 if (sumres.Income < 0) 
  {
  var RemainingHours = -1 * config.gold / sumres.Income;
  if (RemainingHours <= 6)
   {
   goldStyle = 'Red';
   }
  else if (RemainingHours <= 72)
   {
   goldStyle = 'DarkRed';
   }
  goldRemainingHours = this._Parent.Str.FormatRemainingTime(RemainingHours*60*60*1000)+" to expense";
  }
  
 // Research bonus from government
 if (this._Parent.Ikariam.Is_Version('0.4.4'))
  {
  if ((config.government == undefined) || (config.government == ''))
   {
   
   }
  else if (config.government == 'demokratie')
   {
   if ((config.totalCulturalGoods != undefined) && (config.totalCulturalGoods != ''))
    {
    sumres.ResearchBonus = config.totalCulturalGoods;
    }
   }
  }
 
 function createMoreResearch(sum)
  {
  var output = '';
  if (sum > 0) 
   {
   output = '<font class="More">'+_self._Parent.Str.FormatBigNumber(sum, true)+'</font>';
   }
   return output;
  }
  
 function createMoreGoods(sum)
  {
  var output = '';
  if (sum > 0) 
   {
   output = '<font class="More">'+_self._Parent.Str.FormatBigNumber(sum, true)+'&nbsp;</font>';
   }
   return output;
  }
  
 s += "<tfoot class='Summary'><tr>";
 s += "<td class='nolf sigma' nowrap colspan=2><img vspace=2 hspace=5 src='skin/layout/sigma.gif'></td>"+
   "<td class='lf'>"+
   "<span title='Citizens'>"+this._Parent.Str.FormatBigNumber(sumres.citizens)+'</span>'+
   "&nbsp;("+
   "</td>"+
   "<td class='nolf'>"+
   "<span title='Overall inhabitants'>"+this._Parent.Str.FormatBigNumber(sumres.population)+"</span>)"+
   "&nbsp;/</td>"+
   "<td class='nolf' title='Housing space'>"+this._Parent.Str.FormatBigNumber(sumres.spacetotal)+"</td>"+
   "<td>"+this._Parent.Str.FormatFloatNumber(sumres.growth,2,true)+"</td>"+
   "<td class='lf'>"+
   createResearch(sumres.Research)+
   createMoreResearch(sumres.ResearchBonus)+
   "</td>"+
   "<td class='lf'>"+
   createIncome(sumres.Income, goldRemainingHours, goldStyle)+
   createReservedGold(sumres.reservedGold)+
   "</td>"+
   "<td class='lf'>"+
       createResCounter(this._Parent.StartTime, sumres.wood, sumProd.wood)+
       createMoreGoods(sumArTr.wood)+
       "</td>"+
   "<td class='lfdash'>"+createProd(sumProd.wood)+"</td>"+
   "<td class='lf'>"+
       createResCounter(this._Parent.StartTime, sumres.wine, sumProd.wine - sumProd.wineUsage, true)+
       createMoreGoods(sumArTr.wine)+
       "</td>"+
   "<td class='lfdash'>"+createSimpleProd(sumProd.wine)+"</td>"+
   "<td class='lfdash'>"+createSimpleProd(-1 * sumProd.wineUsage)+"</td>"+
   "<td class='lf'>"+
       createResCounter(this._Parent.StartTime, sumres.marble, sumProd.marble)+
       createMoreGoods(sumArTr.marble)+
       "</td>"+
   "<td class='lfdash'>"+createProd(sumProd.marble)+"</td>"+
   "<td class='lf'>"+
       createResCounter(this._Parent.StartTime, sumres.glass, sumProd.glass)+
       createMoreGoods(sumArTr.glass)+
       "</td>"+
   "<td class='lfdash'>"+createProd(sumProd.glass)+"</td>"+
   "<td class='lf'>"+
       createResCounter(this._Parent.StartTime, sumres.sulfur, sumProd.sulfur)+
       createMoreGoods(sumArTr.sulfur)+
       "</td>"+
   "<td class='lfdash'>"+createProd(sumProd.sulfur)+"</td>";
 s += "</tr></tfoot>";
 
 s += "</table>";
 
 return s;
 };
 
EmpireBoard.Renders.ArmyFleet_Table_Content = function()
 {
 var _self = this;
 
 var s = "";
 var Cities = this._Parent.DB.CurrentCities;
 
 var FleetUpkeepBonus = 0;
 if (config["research"].FleetUpkeepBonus != undefined)
  FleetUpkeepBonus = config["research"].FleetUpkeepBonus;
 
 var ArmyUpkeepBonus = 0;
 if (config["research"].ArmyUpkeepBonus != undefined) 
  ArmyUpkeepBonus = config["research"].ArmyUpkeepBonus;
 
 function applyUpkeepBonus(value, bonus)
  {
  if ((value == '-') || (value == '?') || (value == 0) || (bonus == 0))
   {
   return value;
   }
  else
   {
   return (value - (value/100*bonus));
   }
  }
 
 var orderedUnits = this._Parent.Ikariam.UnitsList();
 
 var usedIndexes = {};
 var usedIndexesCount = 0;
 if (config["unitnames"] != undefined)
  {
  var CityId;
  for (CityId in Cities)
   {
   if (Cities[CityId].own != true) continue;
   var city = getCity(CityId);
   var key;
   for (key in orderedUnits)
    {
    var ukey = 'unit '+key;
    if (parseInt(getArrValue(getArrValue(city.units, ukey), "count", 0)) > 0)
     {
     usedIndexes[key] = 1;
     usedIndexesCount++;
     }
    else if (parseInt(getArrValue(getArrValue(city.units, ukey), "construction", 0)) > 0)
     {
     usedIndexes[key] = 1;
     usedIndexesCount++;
     }
    }
   }
  }
 
 s += "<thead><tr><th class='nolf city_name' nowrap>"+this._Parent.Intl.TT("cityName")+"</th>";
 s += "<th class='actions' nowrap>"+this._Parent.Renders.ArmyFleet_HeaderIcons(current_city_id)+"</th>";
 if (usedIndexesCount > 0)
  {
  var firstStyle = "";
  var lastTopic = '';
  var key;
  for (key in orderedUnits)
   {
   var ukey = 'unit '+key;
   var name = this._Parent.Intl.TT(ukey,'army_units');
   if (usedIndexes[key] == 1) 
    {
    if (lastTopic != orderedUnits[key]) { firstStyle = "lf"; } else { firstStyle = ""; }
    
    s += "<th unit='"+key+"' class='"+firstStyle+" unit_name "+key+"' nowrap>"+name+"</th>";
    firstStyle = "";
    
    lastTopic = orderedUnits[key];
    }
   }
  }
 else s += "<th class='lf'></th><th></th><th></th><th></th><th></th><th></th><th></th>";
 s += "<th class='upkeep lf' nowrap title='"+this._Parent.Intl.TT("Upkeep")+"'>"+this._Parent.Intl.TT("Upkeep")+"</th>";
 s += "</tr></thead>";
 
 function createAttacks(cityID)
  {
  var res = "<font class='More Red'></font>";
  var numMovements = 0;
  if (config["attacks"] == undefined)
   {
   
   }
  else if (config["attacks"][cityID] != undefined)
   {
   for (key in config["attacks"][cityID])
    {
    if (config["attacks"][cityID][key].endTime >= _self._Parent.StartTime)
     numMovements++;
    }
    
   if (numMovements > 0)
    res = "<font class='More Attacks Red'>under "+numMovements+" attack(s)</font>";
   }
   
  return res;
  }

 function createLinkToArmyView(city_id)
  {
  var rHTML = '';
  rHTML += '<a href="?view=cityMilitary-army&id='+city_id+'" class="changeCity" cityid="'+city_id+'" title="View army overview"><img align="absmiddle" src="skin/img/city/building_barracks.gif" /></a>';
  if (reportViewToSurvey('cityMilitary-army', city_id) == '!')
   {
   rHTML += '<sup class=Red title="Require attention">!</sup>';
   }
  else
   {
   rHTML += '&nbsp;';
   }
  return rHTML;
  }
 
 function createLinkToFleetView(city_id)
  {
  var rHTML = '';
  rHTML += '<a href="?view=cityMilitary-fleet&id='+city_id+'" class="changeCity" cityid="'+city_id+'" title="View fleet overview"><img align="absmiddle" src="skin/img/city/building_shipyard.gif" /></a>';
  if (reportViewToSurvey('cityMilitary-fleet', city_id) == '!')
   {
   rHTML += '<sup class=Red title="Require attention">!</sup>';
   }
  else
   {
   rHTML += '&nbsp;';
   }
  return rHTML;
  }
  
 function createLinkToDeployArmy(city_id)
  {
  var rHTML = '';
  if (current_city_id == city_id)
   {
   rHTML += '<img class="Action" src="skin/actions/move_army_disabled.gif" align="absmiddle" />';
   }
  else
   {
   rHTML += '<a view=deployment deploymenttype=army href="?view=deployment&deploymentType=army&destinationCityId='+city_id+'" title="Deploy troops"><img class="Action" src="skin/actions/move_army.gif" align="absmiddle" /></a>';
   }
  return rHTML;
  }

 function createLinkToDeployFleet(city_id)
  {
  var rHTML = '';
  if (current_city_id == city_id)
   {
   rHTML += '<img class="Action" src="skin/actions/move_fleet_disabled.gif" align="absmiddle" />';
   }
  else
   {
   rHTML += '<a view=deployment deploymenttype=fleet href="?view=deployment&deploymentType=fleet&destinationCityId='+city_id+'" title="Station fleets"><img class="Action" src="skin/actions/move_fleet.gif" align="absmiddle" /></a>';
   }
  return rHTML;
  }

 function createMovements(cityID)
  {
  var res = "<font class='More'></font>";
  var numMovements = 0;
  if (config["movements"] == undefined)
   {
   
   }
  else if (config["movements"][cityID] != undefined)
   {
   var key;
   for (key in config["movements"][cityID])
    {
    if (config["movements"][cityID][key].endTime >= _self._Parent.StartTime) numMovements++;
    }
    
   if (numMovements > 0) res = "<font class='More Movements'>"+numMovements+" movement(s) on way</font>";
   }
  return res;
  }

 var sum = [];
 var sumConstruction = [];
 var sumUpkeep = 0;
 var sumConstructionUpkeep = 0;
 s += "<tbody class='ownCities'>";
 var i = 0;
 var odd = '';
 var CityId;
 for (CityId in Cities)
  {
  if (Cities[CityId].own != true) continue;
  var city = getCity(CityId);
  var trclass = (parseInt(current_city_id) == parseInt(CityId)) ? "current" : "";
  
  s += "<tr class='"+odd+" "+trclass+"' cityid='"+CityId+"' islandid='"+city.island_id+"' coord='"+city.city_coord+"'>";
  
  s += "<td class='nolf city_name' nowrap>"+
          createLinkToChangeCity(Cities[CityId].name, CityId, i, city.actions, 'Green', 'Available action points')+
          createMovements(CityId)+
          createAttacks(CityId)+
          "</td>";
  s += "<td class='actions' nowrap>"+createLinkToArmyView(CityId)+createLinkToDeployArmy(CityId)+"<br />"+createLinkToFleetView(CityId)+createLinkToDeployFleet(CityId)+"</td>";
  
  var barracksLevel = getBuildingLevel(CityId, "barracks", "-");
  var shipyardLevel = getBuildingLevel(CityId, "shipyard", "-");
  var cityUpkeep = 0;
  var cityConstructionUpkeep = 0;
  if (usedIndexesCount > 0)
   {
   var firstStyle = "";
   var lastTopic = '';
   for (key in orderedUnits)
    {
    var ukey = 'unit '+key;
    var ugender = this._Parent.Ikariam.Get_UnitGender(key);
    if (usedIndexes[key] == 1) 
     {
     if (lastTopic != orderedUnits[key]) { firstStyle = "lf"; } else { firstStyle = ""; }
    
     var unitCount = this._Parent.Str.To_Integer(getArrValue(getArrValue(city.units, ukey), "count", 0), 0);
      
     if (config["upkeeps"][key] == undefined)
      {
      cityUpkeep = '?';
      }
     else if (cityUpkeep != '?')
      {
      if (ugender == 'army')
       {
       cityUpkeep += applyUpkeepBonus(config["upkeeps"][key]*unitCount,ArmyUpkeepBonus);
       }
      else if (ugender == 'fleet')
       {
       cityUpkeep += applyUpkeepBonus(config["upkeeps"][key]*unitCount,FleetUpkeepBonus);
       }
      }
      
     if (unitCount == 0)
      {
      unitCount = "-";
      }
     else
      {
      sum[key] = (sum[key] == undefined) ? unitCount : sum[key] + unitCount;
      }
      
     var unitConstructionHTML = '<font class="More">-</font>';
     var unitConstruction = 0;
     if ((ugender == 'army') && (barracksLevel == '-'))
      {
      // Fix if barracks has been demolished while units were under construction
      }
     else if ((ugender == 'fleet') && (shipyardLevel == '-'))
      {
      // Fix if barracks has been demolished while units were under construction
      }
     else
      {
      unitConstruction = this._Parent.Str.To_Integer(getArrValue(getArrValue(city.units, ukey, undefined), "construction", 0), 0);
      }
     
     if (config["upkeeps"][key] == undefined)
      {
      cityConstructionUpkeep = '?';
      }
     else if (cityConstructionUpkeep != '?')
      {
      if (ugender == 'army')
       {
       cityConstructionUpkeep += applyUpkeepBonus(config["upkeeps"][key]*unitConstruction,ArmyUpkeepBonus);
       }
      else if (ugender == 'fleet')
       {
       cityConstructionUpkeep += applyUpkeepBonus(config["upkeeps"][key]*unitConstruction,FleetUpkeepBonus);
       }
      }
      
     if (unitConstruction > 0)
      {
      unitConstructionHTML = '<font class="More" title="'+this._Parent.Intl.TT("currentlyBuilding")+'">'+this._Parent.Str.FormatBigNumber(unitConstruction, true)+'</font>';
      sumConstruction[key] = (sumConstruction[key] == undefined) ? unitConstruction : sumConstruction[key] + unitConstruction;
      }
     
     s += "<td unit='"+key+"' class='"+firstStyle+" "+key+"'>"+
          this._Parent.Str.FormatBigNumber(unitCount)+
          unitConstructionHTML+
          "</td>";
    
     lastTopic = orderedUnits[key];
     }
    }
   }
  else s += "<td class='lf'></td><td></td><td></td><td></td><td></td><td></td><td></td>";
  
  if (sumUpkeep != '?')
   {
   if (cityUpkeep != '?')
    {
    sumUpkeep += cityUpkeep;
    }
   else sumUpkeep = '?';
   }
  if (cityUpkeep == 0) cityUpkeep = '-';
  
  if (sumConstructionUpkeep != '?')
   {
   if (cityConstructionUpkeep != '?')
    {
    sumConstructionUpkeep += cityConstructionUpkeep;
    }
   else sumConstructionUpkeep = '?';
   }
  if (cityConstructionUpkeep == 0) cityConstructionUpkeep = '-';
  
  s += "<td class='upkeep lf'>"+(cityUpkeep != '-' ? this._Parent.Str.FormatBigNumber(-1*Math.round(cityUpkeep), true) : cityUpkeep)+"<font class='More'>"+(cityConstructionUpkeep != '-' ? this._Parent.Str.FormatBigNumber(-1*Math.round(cityConstructionUpkeep), true) : cityConstructionUpkeep)+"</font></td>";
  
  s += "</tr>";
  i++;
  if (odd == '') { odd = 'odd'; } else { odd = ''; }
  }
  
 s += "</tbody>";
 
 //s += "<tbody class='foreignCities'>";
 //s += "</tbody>";
 
 s += "<tfoot class='Summary'>";
 
 s += "<tr class='Units'>";
 
 s += "<td class='nolf sigma' colspan=2><img vspace=2 hspace=5 src='skin/layout/sigma.gif'></td>";
 if (usedIndexesCount > 0)
  {
  var firstStyle = "";
  var lastTopic = '';
  for(key in orderedUnits)
   {
   if (usedIndexes[key] == 1)
    {
    if (lastTopic != orderedUnits[key]) { firstStyle = "lf"; } else { firstStyle = ""; }

    var unitConstructionHTML = '<font class="More">-</font>';
    if (sumConstruction[key] > 0)
     {
     unitConstructionHTML = '<font class="More">'+this._Parent.Str.FormatBigNumber(sumConstruction[key], true)+'</font>';
     }
    s += "<td unit='"+key+"' class='"+firstStyle+" "+key+"'>"+
        (sum[key] == undefined ? '-' : this._Parent.Str.FormatBigNumber(sum[key]))+
        unitConstructionHTML+
        "</td>";

    lastTopic = orderedUnits[key];
    }
   }
  }
 else s += "<td class='lf'></td><td></td><td></td><td></td><td></td><td></td><td></td>";
 
 if (sumUpkeep == 0) sumUpkeep = '-';
 if (sumConstructionUpkeep == 0) sumConstructionUpkeep = '-';
 s += "<td class='upkeep lf'>"+(sumUpkeep != '-' ? this._Parent.Str.FormatBigNumber(-1*Math.round(sumUpkeep), true) : sumUpkeep)+"<font class='More'>"+(sumConstructionUpkeep != '-' ? this._Parent.Str.FormatBigNumber(-1*Math.round(sumConstructionUpkeep), true) : sumConstructionUpkeep)+"</font></td>";
 
 s += "</tr>";
 
 s += "</tfoot>";
 
 s += "</table>";
 
 return s;
 };
 
EmpireBoard.Renders.UnitName_Tooltip_Content = function(unit_id)
 {
 return '<nobr>'+this._Parent.Intl.TT('unit '+unit_id,'army_units')+'</nobr>';
 };
 
EmpireBoard.Renders.Set_Common_Styles = function()
 {
 var default_style = <><![CDATA[
 #EmpireBoard {
  width: 990px;
  margin: -15px auto 20px;
  }
 
 #EmpireBoard.LtoR,
 #EmpireBoard.LtoR * {
  direction: ltr;
  }
 
 #EmpireBoard.RtoL,
 #EmpireBoard.RtoL * {
  direction: rtl;
  }
 
 #EmpireBoard div.Table {
  margin-bottom: 2px;
  }
 
 #EmpireBoard table.Overview {
  width: 100% !important;
  margin-bottom: 3px;
  background-color: #F6EBBA; /* #FDF7DD */
  text-align: center;
  border-collapse: collapse;
  border: 2px solid #fff;
  box-shadow: 3px 3px 0 #AB9166;
  }
  
 #EmpireBoard table.Overview thead {
  background: #F8E7B3 url(skin/input/button.gif) repeat-x scroll 0 bottom;
  }
 
 #EmpireBoard table.Overview tfoot { 
  background: #E7C680 url(skin/input/button.gif) repeat-x scroll 0 0;
  border-top: 2px solid #CB9B6A;
  }

 #EmpireBoard table.Overview tbody tr {
  border-top: 1px solid #ECCF8E;
  }
 
 #EmpireBoard table.Overview tfoot tr { 
  border-top: 1px solid #CB9B6A;
  }
 
 #EmpireBoard table.Overview tr.odd {
  background-color: #FDF1D4;
  }
 
 #EmpireBoard table.Overview tr.current {
  background-color: #FAE3B8;
  }
  
 #EmpireBoard table.Overview th,
 #EmpireBoard table.Overview td {
  border-left: 1px solid #ECCF8E;
  }
  
 #EmpireBoard.RtoL table.Overview th,
 #EmpireBoard.RtoL table.Overview td {
  border-left: inherit;
  border-right: 1px solid #ECCF8E;
  }
  
 #EmpireBoard table.Overview th {
  height: 22px;
  width: auto;
  padding: 1px;
  padding-bottom: 2px;
  padding-left: 3px;
  text-align: center !important;
  color: #542C0F; 
  font-weight: bold;
  text-shadow:0 1px #FFFFFF;
  }
  
 #EmpireBoard table.Overview td {
  height: auto;
  line-height: 11px;
  font-size: 11px;
  min-width: 10px;
  padding: 1px;
  vertical-align: top;
  text-align: right;
  color: #542C0F;
  text-shadow:0 1px #FFFFFF;
  }
  
 #EmpireBoard table.Overview th.lf,
 #EmpireBoard table.Overview td.lf {
  border-left: 2px solid #CB9B6A;
  }
 #EmpireBoard.RtoL table.Overview th.lf,
 #EmpireBoard.RtoL table.Overview td.lf {
  border-left: inherit;
  border-right: 2px solid #CB9B6A;
  }
  
 #EmpireBoard table.Overview th.nolf,
 #EmpireBoard table.Overview td.nolf {
  border-left: none;
  }
 #EmpireBoard.RtoL table.Overview th.nolf,
 #EmpireBoard.RtoL table.Overview td.nolf {
  border-left: inherit;
  border-right: none;
  }
  
 #EmpireBoard table.Overview th.city_name,
 #EmpireBoard table.Overview td.city_name {
  overflow: hidden;
  }

 #EmpireBoard table.Overview th.actions,
 #EmpireBoard table.Overview td.actions,
 #EmpireBoard table.Overview th.lfdash,
 #EmpireBoard table.Overview td.lfdash {
  border-left: 1px dashed #ECCF8E;
  }
 #EmpireBoard.RtoL table.Overview th.actions,
 #EmpireBoard.RtoL table.Overview td.actions,
 #EmpireBoard.RtoL table.Overview th.lfdash,
 #EmpireBoard.RtoL table.Overview td.lfdash {
  border-left: inherit;
  border-right: 1px dashed #ECCF8E;
  }
  
 #EmpireBoard table.Overview th.city_name {
  width: 95px !important;
  max-width: 95px;
  }
 #EmpireBoard.RtoL table.Overview th.city_name {}
 
 #EmpireBoard table.Overview th.actions {
  width: 62px;
  max-width: 62px;
  padding-left: 2px;
  padding-bottom: 3px;
  text-align: right !important;
  vertical-align: bottom;
  }

 #EmpireBoard table.Buildings th.build_name0,
 #EmpireBoard table.Buildings th.build_name1,
 #EmpireBoard table.Buildings th.build_name2,
 #EmpireBoard table.Buildings th.build_name3,
 #EmpireBoard table.Buildings th.build_name4,
 #EmpireBoard table.Buildings th.build_name5,
 #EmpireBoard table.Buildings th.build_name6,
 #EmpireBoard table.Buildings th.build_name7,
 #EmpireBoard table.Buildings th.build_name8,
 #EmpireBoard table.Buildings th.build_name9,
 #EmpireBoard table.Buildings th.build_name10,
 #EmpireBoard table.Buildings th.build_name11,
 #EmpireBoard table.Buildings th.build_name12 { max-width: 25px; overflow: hidden; cursor: default;}
 #EmpireBoard table.Buildings th.build_name2 { max-width: 45px;}
 #EmpireBoard table.Buildings th.build_name3 { max-width: 65px;}
 #EmpireBoard table.Buildings th.build_name4 { max-width: 80px;}
 #EmpireBoard table.Buildings th.build_name5 { max-width: 95px;}
 #EmpireBoard table.Buildings th.build_name6 { max-width: 105px;}
 #EmpireBoard table.Buildings th.build_name7 { max-width: 115px;}
 #EmpireBoard table.Buildings th.build_name8 { max-width: 125px;}
 #EmpireBoard table.Buildings th.build_name9 { max-width: 135px;}
 #EmpireBoard table.Buildings th.build_name10 { max-width: 140px;}
 #EmpireBoard table.Buildings th.build_name11 { max-width: 145px;}
 #EmpireBoard table.Buildings th.build_name12 { max-width: 150px;}
 
 #EmpireBoard table.Army th.unit_name { min-width: 25px; max-width: 35px; overflow: hidden; cursor: default;}
 
 #EmpireBoard table.Army th.upkeep { min-width: 20px; overflow: hidden; cursor: default; }

 #EmpireBoard table.Overview tfoot td { 
  font-weight: bold;
  }
 
 #EmpireBoard table.Buildings td {vertical-align: middle;}
 
 #EmpireBoard table.Overview td.city_name {
  width: 110px;
  max-width: 110px;
  padding-left: 3px;
  text-align: left;
  }
  
 #EmpireBoard.RtoL table.Overview td.city_name { text-align: right; }
 
 #EmpireBoard table.Overview td.actions {  text-align: right; line-height:12px; padding-right:3px;}
 #EmpireBoard.RtoL table.Overview td.actions { }

 #EmpireBoard table.Overview th.actions img,
 #EmpireBoard table.Overview td.actions img { margin-left: 1px; border: none; max-height: 15px;}
 #EmpireBoard table.Overview td.actions img.Action { height: 12px; margin-top: 1px; }

 #EmpireBoard.RtoL table.Overview td.sigma {
  text-align: left;
  }
  
 #EmpireBoard table.Overview .More {
  font-size: 10px;
  line-height: 10px !important;
  height: 10px !important;
  margin-top:-1px;
  clear: both;
  display: block;
  cursor: default;
  text-shadow: none;
  }
 #EmpireBoard table.Resources .MoreGoods { margin-top:0; }
 #EmpireBoard table.Overview tbody .More { color: #CB9B6A;}

 #EmpireBoard table.Buildings td.current {
  }
 #EmpireBoard table.Buildings td.current a {
  color: #542C0F;
  }

 /****************** progress bar styles *******************/
 #EmpireBoard table.Overview table.myPercent {
  height: auto !important;
  width: 92%;
  margin-top: 2px;
  margin-left: 2px;
  margin-right: 2px;
  background-color: !transparent !important;
  box-shadow: 0 0 1px rgba(0, 0, 0, 0.6);
  }
 #EmpireBoard table.Overview table.myPercent td {
  height: 4px !important;
  min-width: 0px !important;
  padding: 0px !important;
  background-color: #CB9B6A;
  border: 1px solid #FDF7DD;
  }
 #EmpireBoard table.Overview table.myPercent td.Normal { background-color: #73443E;}
 #EmpireBoard table.Overview table.myPercent td.Warning { background-color: #8F1D1A;}
 #EmpireBoard table.Overview table.myPercent td.AlmostFull { background-color: #B42521;}
 #EmpireBoard table.Overview table.myPercent td.Full { background-color: #ff0000;}
 /****************** alerts *******************/
 #EmpireBoard sup {
  vertical-align: top !important;
  font-size: 9px;
  line-height: 9px;
  margin-left: 1px;
  }
 #EmpireBoard .Bold,
 #EmpireBoard .Brown,
 #EmpireBoard .DarkRed,
 #EmpireBoard .Red {font-weight: bold;}
 #EmpireBoard .Green {  color: green !important;}
 #EmpireBoard .Brown {  color: #8F1D1A !important;}
 #EmpireBoard .DarkRed {  color: #CC3300 !important;}
 #EmpireBoard .Red {  color: red !important;}
 #EmpireBoard img.Safe { height: 11px; }
 #EmpireBoard table.Overview td img.Safe {float: left; margin-left: 1px; margin-right: 1px;}

 /****************** footer *******************/

 #EmpireBoard p {text-align: left; display: block;  }
 #EmpireBoard.RtoL p {text-align: right;}
 #EmpireBoard p.Caption { font-size: 9px; margin: 0 2px;}

 #EmpireBoardSettings {}
 #EmpireBoardSettings td {border: none !important;}
 #EmpireBoardSettings input.button {margin-right: 5px;}
 
 #EmpireBoard #EmpireBoardAddons { float: left; text-align: left;}
 #EmpireBoard.RtoL #EmpireBoardAddons { text-align: right;}
 #EmpireBoardAddons u { font-weight: bold; }
 #EmpireBoardAddons li { list-style-type: disc; list-style-position: inside; padding-left: 15px; }

 #EmpireBoard p.Footer {text-align: right; clear: both;}
 #EmpireBoard.RtoL p.Footer {text-align: left;}
 #EmpireBoard p.Footer .button {}

 /****************** tooltip *******************/
 #EmpireBoardTooltip {
  position:absolute;
  z-index: 2000;
  }
 #WzTtDiV,
 #EmpireBoardTooltip {
  box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2); 
  }

 .TTContent {
  padding: 3px;
  color: #542C0F;
  background-color: #FDF7DD;
  border: 1px solid #BE8D53;
  border-top-width: 4px;
  }
 .TTTitle { font-weight: bold; background-color: #FAE0AE;padding: 3px; margin: -3px; margin-bottom:4px;}
 .RtoL .TTTitle { text-align: right; }
 
 .TTContent table tbody {background-color: #FAEAC6; border-bottom-width: 3px; border-bottom-color: #FDF7DD;border-bottom-style: solid;}
 .TTContent table tfoot {background-color: #FAE0AE;}
 .TTContent table td {padding: 2px; height: auto !important;}
 .TTContent table .Small td {
  padding-top: 0px;
  font-size: 10px !important;
  line-height: 10px !important;
  }
 .TTContent table td.Mission img { max-height: 15px;}
 ]]></>.toXMLString();
 
 GM_addStyle(default_style);
 };

EmpireBoard.Renders.ArmyFleet_HeaderIcons = function(currentCityId)
 {
 var rHTML = '';
  
 rHTML += this.IconTo_safehouseReports(currentCityId);
 if (reportViewToSurvey('safehouse-reports') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 rHTML += '<a view="militaryAdvisorCombatReports" href="?view=militaryAdvisorCombatReports" title="View combat reports"><img align="absmiddle" src="skin/layout/medallie32x32_gold.gif"/></a>';
 // skin/layout/icon-helmet.gif
 if (reportViewToSurvey('militaryAdvisorCombatReports') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 rHTML += '<a view="militaryAdvisorMilitaryMovements" href="?view=militaryAdvisorMilitaryMovements" title="View military advisor"><img align="absmiddle" src="skin/relatedCities/general.gif"/></a>';
 // skin/layout/icon-helmet.gif
 if (reportViewToSurvey('militaryAdvisorMilitaryMovements') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 return rHTML;
 };

EmpireBoard.Renders.IconTo_safehouseReports = function(currentCityId,Title)
 {
 if (currentCityId == undefined) currentCityId = 0;
 if (Title == undefined) Title = "View espionage reports";
 var rHTML = '';
 var sCityId = 0;
 var sCityPos = -1;
 
 if (currentCityId > 0) 
  {
  sCityPos = getBuildingPosition(currentCityId, 'safehouse', -1);
  if (sCityPos > 0)
   {
   sCityId = currentCityId;
   }
  }
  
 if (sCityId == 0)
  {
  var Cities = this._Parent.DB.CurrentCities;
  for (CityId in Cities)
   {
   if (Cities[CityId].own != true) continue;
   sCityPos = getBuildingPosition(CityId, 'safehouse', -1);
   if (sCityPos > 0)
    {
    sCityId = CityId;
    break;
    }
   }
  }
  
 if ((sCityId == 0) || (sCityPos <= 0))
  {
  return '';
  }
 else
  {
  rHTML += '<a view="safehouse" tab="reports" cityid="'+sCityId+'" position="'+sCityPos+'" href="?view=safehouse&id='+sCityId+'&position='+sCityPos+'&tab=reports" title="'+Title+'"><img align="absmiddle" src="skin/buildings/x40_y40/safehouse.gif"/></a>';
  // skin/img/city/building_safehouse.gif
  return rHTML;
  }
 };
  
EmpireBoard.Renders.Resources_HeaderIcons = function(currentCityId)
 {
 var rHTML = '';
  
 rHTML += '<a href="?view=merchantNavy" view="merchantNavy" title="View merchant navy"><img align="absmiddle" src="skin/img/city/building_port.gif" /></a>';
 if (reportViewToSurvey('merchantNavy') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 rHTML += '<a href="?view=finances" view="finances" title="View finances"><img align="absmiddle" src="skin/img/city/building_townhall.gif" /></a>';
 if (reportViewToSurvey('finances') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 rHTML += '<a href="?view=premium" view="premium" title="View premium features"><img align="absmiddle" src="skin/premium/ambrosia_icon.gif" /></a>';
 if (reportViewToSurvey('premium') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 return rHTML;
 };
  
EmpireBoard.Renders.Buildings_HeaderIcons = function(currentCityId)
 {
 var rHTML = '';
 
 rHTML += this.IconTo_researchOverview(currentCityId);
 if (reportViewToSurvey('researchOverview') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 rHTML += this.IconTo_researchAdvisor();
 if (reportViewToSurvey('researchAdvisor') == '!')
  {
  rHTML += '<sup class=Red title="Require attention">!</sup>';
  }
 else
  {
  rHTML += '&nbsp;';
  }
 
 return rHTML;
 };
 
EmpireBoard.Renders.IconTo_researchAdvisor = function(Title)
 {
 if (Title == undefined) Title = "View research advisor";
 var rHTML = '';
  
 rHTML += '<a view="researchAdvisor" href="?view=researchAdvisor" title="'+Title+'"><img align="absmiddle" src="skin/resources/icon_scientist.gif"/></a>';
 
 return rHTML;
 };
  
EmpireBoard.Renders.IconTo_researchOverview = function(currentCityId,Title)
 {
 if (currentCityId == undefined) currentCityId = 0;
 if (Title == undefined) Title = "View research library";
 var rHTML = '';
  
 rHTML += '<a view="researchOverview" cityid="'+currentCityId+'" href="?view=researchOverview&id='+currentCityId+'" title="'+Title+'"><img align="absmiddle" src="skin/buildings/x40_y40/academy.gif"/></a>';
 // skin/icons/researchbonus_30x30.gif
 // skin/img/city/building_academy.gif
 return rHTML;
 };
  
EmpireBoard.Renders.Movements_Tooltip_Content = function(cityID)
 {
 var tooltip = "<table>";
 var orderedUnits = this._Parent.Ikariam.UnitsList();
 
 if (config["movements"] == undefined)
  {
  return '';
  }
 else if (config["movements"][cityID] != undefined)
  {
  for (key in config["movements"][cityID])
   {
   var arrivetime = config["movements"][cityID][key].endTime;
   if (arrivetime >= this._Parent.StartTime)
    {
    var tCityId = config["movements"][cityID][key].tCityId;
    var tCity ='';
    if ((this._Parent.DB.CurrentCities[tCityId] != undefined) && (this._Parent.DB.CurrentCities[tCityId].own == true))
     {
     tCity = config["movements"][cityID][key].tCityName;
     }
    else
     {
     tCity = config["movements"][cityID][key].tCityName+" ("+config["movements"][cityID][key].tPlayerName+")";
     }
    
    var tLocation = "";
    if (config["movements"][cityID][key].toLeft == true)
     {
     tLocation += "&laquo;";
     }
    else if (config["movements"][cityID][key].toRight == true)
     {
     tLocation += "&raquo;";
     }
    else
     {
     tLocation += "&laquo;&raquo;";
     }
    tLocation += "&nbsp;";
    tLocation += "<i>"+tCity+"</i>";
    
    var payload = '';
    if (config["movements"][cityID][key].payload != undefined)
     {
     for (utype in orderedUnits)
      {
      if (config["movements"][cityID][key].payload[utype] != undefined)
       {
       var ugender = this._Parent.Ikariam.Get_UnitGender(utype);
       if (ugender == 'army')
        {
        payload += config["movements"][cityID][key].payload[utype]+' <img align="absmiddle" height="18" src="/skin/characters/military/x40_y40/y40_'+utype+'_faceright.gif">&nbsp;';
        }
       else if (ugender == 'fleet')
        {
        payload += config["movements"][cityID][key].payload[utype]+' <img align="absmiddle" height="18" src="/skin/characters/fleet/40x40/'+utype+'_r_40x40.gif">&nbsp;';
        }
       }
      }
     }
    
    var counter = "(<font id='mytimecounter' counter='"+Math.round(arrivetime)+"' class='time_counter'>__:__:__</font>)";
    var smartDate = smartDateFormat(arrivetime);
     
    tooltip += "<tbody><tr>"+
       "<td valign=top align=left class='Mission'><img src='"+this._Parent.Ikariam.Get_FleetMission_ImgSrc(config["movements"][cityID][key].mission)+"' /></td>"+
       "<td valign=top align=right><nobr><b>"+config["movements"][cityID][key].summary+"</b></nobr>&nbsp;</td>"+
       "<td valign=top align=left>"+tLocation+"</td>"+
       "</tr><tr class=Small>"+
       "<td class=Payload align=left valign=middle colspan=2><nobr>"+payload+"</nobr></td>"+
       "<td align=right colspan=3>&nbsp;<nobr>"+smartDate+"&nbsp;"+counter+"</nobr></td>"+
       "</tr></tbody>";
    }
   }
  }
 else
  {
  return '';
  }
 
 tooltip += "</table>";
 return tooltip;
 };
 
EmpireBoard.Renders.Attacks_Tooltip_Content = function(cityID)
 {
 var tooltip = "<table>";
 
 if (config["attacks"] == undefined)
  {
  return '';
  }
 else if (config["attacks"][cityID] != undefined)
  {
  for (key in config["attacks"][cityID])
   {
   var arrivetime = config["attacks"][cityID][key].endTime;
   if (arrivetime >= this._Parent.StartTime)
    {
    var tCityId = config["attacks"][cityID][key].oCityId;
    var tCity ='';
     
    tCity = config["attacks"][cityID][key].oCityName+" ("+config["attacks"][cityID][key].oPlayerName+")";
    
    var tLocation = "";
    tLocation += "<i>"+tCity+"</i>";
    tLocation += "&nbsp;";
    if (config["attacks"][cityID][key].toLeft == true)
     {
     tLocation += "&laquo;";
     }
    else if (config["attacks"][cityID][key].toRight == true)
     {
     tLocation += "&raquo;";
     }
    else
     {
     tLocation += "&laquo;&raquo;";
     }
    
    var counter = "(<font id='mytimecounter' counter='"+Math.round(arrivetime)+"' class='time_counter'>__:__:__</font>)";
    var smartDate = smartDateFormat(arrivetime);
     
    tooltip += "<tbody><tr>"+
       "<td valign=top align=left class=Red>"+tLocation+"</td>"+
       "<td valign=top align=left class='Mission'><img src='"+this._Parent.Ikariam.Get_FleetMission_ImgSrc(config["attacks"][cityID][key].mission)+"' /></td>"+
       "<td valign=top align=right class=Red><b>"+config["attacks"][cityID][key].summary+"</b>&nbsp;</td>"+
       "</tr><tr class=Small>"+
       "<td align=right colspan=3>&nbsp;&nbsp;"+smartDate+"&nbsp;"+counter+"</td>"+
       "</tr></tbody>";
    }
   }
  }
 else
  {
  return '';
  }
 
 tooltip += "</table>";
 return tooltip;
 };
 
EmpireBoard.Renders.ArrivingGoods_Tooltip_Content = function(city_id, resName)
 {
 var _nowTime = new Date().getTime();
 
 var tooltip = "<table>";
 
 var sum = 0;
 
 var city = getCity(city_id);
 var rows = getArrValue(config.arrivinggoods, city_id, []);
 var key;
 var higherTime = 0;
 for (key in rows)
  {
  var row = rows[key];
  var res = row["res"];
  var a = parseInt(getArrValue(res, resName, 0));
  var arrivetime = parseInt(getArrValue(row, "arrivetime", ""));
  if ((a > 0) && (arrivetime > city.prodtime))
   {
   sum += a;
   var startcity = getArrValue(row, "startcity", "");
   var quest = getArrValue(row, "quest", "");
   if (_nowTime >= arrivetime)
    {
    var counter = "(delivered)";
    var smartDate = '';
    }
   else if (quest == 'loading')
    {
    var counter = "(loading)";
    var smartDate = '';
    }
   else
    {
    if (arrivetime > higherTime) higherTime = arrivetime;
    var counter = "(<font id='mytimecounter' counter='"+Math.round(arrivetime)+"' class='time_counter'>__:__:__</font>)";
    var smartDate = smartDateFormat(arrivetime);
    }
   var fromLocation = "&laquo;&nbsp;<i>" + startcity + "</i>";
    
   tooltip += "<tbody><tr>"+
      "<td valign=top>+</td>"+
      "<td valign=top align=right><b>"+this._Parent.Str.FormatBigNumber(a) + "</b>&nbsp;</td>"+
      "<td valign=top align=left>"+fromLocation+"</td>"+
      "</tr><tr class=Small>"+
      "<td align=right colspan=3>&nbsp;&nbsp;" + smartDate + "&nbsp;"+counter+"</td>"+
      "</tr></tbody>";
   }
  }
 
 var tradinggoods = 0;
 var hourlyprod = 0;
 var resAmount = parseInt(getArrValue(city, resName, 0));
 if (resName == 'wood')
  {
  tradinggoods = city.tradewood;
  hourlyprod = city.prodwood;
  resAmount = getCurrentResourceAmount(_nowTime, city.prodtime, city.wood, city.prodwood);
  }
 else if (resName == 'wine')
  {
  tradinggoods = city.tradewine;
  var wineUsage = 0;
  var cellarLevel = getBuildingLevel(city_id, "vineyard", "-");
  var tavernLevel = getBuildingLevel(city_id, "tavern", "-");
  if (tavernLevel == '-')
   {
   // Fix if tavern has been demolished without disable wine usage
   }
  else if (city.wineUsageId != undefined)
   {
   wineUsage = tavernWineUsage[city.wineUsageId];
   if (cellarLevel != '-')
    {
    wineSave = wineUsage * cellarLevel;
    wineSave = Math.round(wineSave / 100);
    wineUsage = wineUsage - wineSave;
    }
   }
  hourlyprod = city.prodwine - wineUsage;
  resAmount = getCurrentResourceAmount(_nowTime, city.prodtime, city.wine, city.prodwine - wineUsage);
  }
 else if (resName == 'marble')
  {
  tradinggoods = city.trademarble;
  hourlyprod = city.prodmarble;
  resAmount = getCurrentResourceAmount(_nowTime, city.prodtime, city.marble, city.prodmarble);
  }
 else if (resName == 'glass')
  {
  tradinggoods = city.tradeglass;
  hourlyprod = city.prodglass;
  resAmount = getCurrentResourceAmount(_nowTime, city.prodtime, city.glass, city.prodglass);
  }
 else if (resName == 'sulfur')
  {
  tradinggoods = city.tradesulfur;
  hourlyprod = city.prodsulfur;
  resAmount = getCurrentResourceAmount(_nowTime, city.prodtime, city.sulfur, city.prodsulfur);
  }
  
 if ((tradinggoods != undefined) && (parseInt(tradinggoods) > 0))
  {
  sum += parseInt(tradinggoods);
  tooltip += "<tbody><tr>"+
      "<td>+</td>"+
      "<td align=right><b>"+this._Parent.Str.FormatBigNumber(parseInt(tradinggoods)) + "</b>&nbsp;</td>"+
      "<td align=left>&laquo;&nbsp;<i>" + this._Parent.Intl.TT('branchOffice','buildings') + "</i></td>"+
     "</tr></tbody>";
  }
  
 if (resAmount > 0)
  {
  tooltip += "<tbody><tr>"+
     "<td>+</td>"+
     "<td align=right><b>"+this._Parent.Str.FormatBigNumber(resAmount) + "</b>&nbsp;</td>"+
     "<td align=left>&laquo;&nbsp;<i>" + this._Parent.Intl.TT('warehouse','buildings') + "</i></td>"+
     "</tr></tbody>";
  }
    
 if (sum > 0)
  {
  tooltip += "<tfoot><tr>"+
     "<td>=</td>"+
     "<td align=right><b>"+this._Parent.Str.FormatBigNumber(sum+resAmount) + "</b>&nbsp;</td>"+
     "<td></td>"+
     "</tr>";
  if ((hourlyprod != 0) && (higherTime > _nowTime + (1000 * 60 * 20)))
   {
   var restHours = (higherTime - _nowTime) / (1000 * 60 * 60);
   var prodSign = '+';
   if (hourlyprod < 0) prodSign = '-';
   tooltip += "<tr class=Small>"+
      "<td>"+prodSign+"</td>"+
      "<td align=right>"+this._Parent.Str.FormatBigNumber(Math.abs(hourlyprod)) + "&nbsp;</td>"+
      "<td align=left>x&nbsp;" + this._Parent.Str.FormatFloatNumber(restHours, 1) + this._Parent.Ikariam.LocalizationStrings('hour','timeunits','short')+"</td>"+
      "</tr>";
   tooltip += "<tr class=Small>"+
      "<td>=</td>"+
      "<td align=right>"+this._Parent.Str.FormatBigNumber(sum+resAmount+Math.floor(restHours*hourlyprod)) + "&nbsp;</td>"+
      "<td align=left>&raquo;&nbsp;" + smartDateFormat(higherTime)+"</td>"+
      "</tr>";
   }
  tooltip += "</tfoot>";
  }

 tooltip += "</table>";
 return tooltip;
 };

EmpireBoard.Ikariam =
 {
 _Parent:     null,
 _View:      null,
 _Tab:      null,
 _Host:      null,
 _Server:     null,
 _Language:     null,
 _Version:     null,
 _Revision:     null,
 _IsVersions:    {},
 _ActionRequest:    null,
 _currentCity:    null,
 _phpSet:     null,
 _LocalizationStrings:  null,
 _UnitsList:     null,
 _UnitsClassNames:   null,
 _BuildingsList:    null,
 _IsLogged:     null
 };
 
EmpireBoard.Ikariam.Init = function(parent)
 {
 this._Parent = parent;
 };

EmpireBoard.Ikariam.BuildingsList = function()
 {
 if (this._BuildingsList == null)
  {
  this._BuildingsList       = {};
  this._BuildingsList['townHall']    = 'growth';
  this._BuildingsList['palace']    = 'growth';
  this._BuildingsList['palaceColony']   = 'growth';
  this._BuildingsList['tavern']    = 'growth';
  this._BuildingsList['museum']    = 'growth';
  this._BuildingsList['academy']    = 'research';
  this._BuildingsList['workshop']    = 'research';
  this._BuildingsList['temple']    = 'research';
  this._BuildingsList['embassy']    = 'diplomacy';
  this._BuildingsList['warehouse']   = 'trading';
  this._BuildingsList['dump']     = 'trading';
  this._BuildingsList['port']     = 'trading';
  this._BuildingsList['branchOffice']   = 'trading';
  this._BuildingsList['wall']     = 'military';
  this._BuildingsList['safehouse']   = 'military';
  this._BuildingsList['barracks']    = 'military';
  this._BuildingsList['shipyard']    = 'military';
  this._BuildingsList['forester']    = 'wood';
  this._BuildingsList['carpentering']   = 'wood';
  this._BuildingsList['winegrower']   = 'wine';
  this._BuildingsList['vineyard']    = 'wine';
  this._BuildingsList['stonemason']   = 'marble';
  this._BuildingsList['architect']   = 'marble';
  this._BuildingsList['glassblowing']   = 'crystal';
  this._BuildingsList['optician']    = 'crystal';
  this._BuildingsList['alchemist']   = 'sulfur';
  this._BuildingsList['fireworker']   = 'sulfur';
  }
 return this._BuildingsList;
 };

EmpireBoard.Ikariam.Get_BuildingUsage = function(buildingName)
 {
 var buildingUsage = '';
 orderedBuildings = this.BuildingsList();
 if (orderedBuildings[buildingName] != undefined)
  {
  var arrayClassNames = orderedBuildings[buildingName].split(' ');
  buildingUsage = arrayClassNames[0];
  }
 return buildingUsage;
 };

EmpireBoard.Ikariam.UnitsClassNames = function()
 {
 if (this._UnitsClassNames == null)
  {
  this._UnitsClassNames = {};
  // Army
  this._UnitsClassNames[301] = 'slinger';
  this._UnitsClassNames[302] = 'swordsman';
  this._UnitsClassNames[303] = 'phalanx';
  this._UnitsClassNames[304] = 'marksman';
  this._UnitsClassNames[305] = 'mortar';
  this._UnitsClassNames[306] = 'catapult';
  this._UnitsClassNames[307] = 'ram';
  this._UnitsClassNames[308] = 'steamgiant';
  this._UnitsClassNames[309] = 'bombardier';
  this._UnitsClassNames[310] = 'cook';
  this._UnitsClassNames[311] = 'medic';
  this._UnitsClassNames[312] = 'gyrocopter';
  this._UnitsClassNames[313] = 'archer';
  this._UnitsClassNames[315] = 'spearman';
  // Fleet
  this._UnitsClassNames[210] = 'ship_ram';
  this._UnitsClassNames[211] = 'ship_flamethrower';
  this._UnitsClassNames[212] = 'ship_submarine';
  this._UnitsClassNames[213] = 'ship_ballista';
  this._UnitsClassNames[214] = 'ship_catapult';
  this._UnitsClassNames[215] = 'ship_mortar';
  this._UnitsClassNames[216] = 'ship_steamboat';
  // v.0.4.x new units
  this._UnitsClassNames[217] = 'ship_rocketship';
  this._UnitsClassNames[218] = 'ship_paddlespeedship';
  this._UnitsClassNames[219] = 'ship_ballooncarrier';
  this._UnitsClassNames[220] = 'ship_tender';
  }
 return this._UnitsClassNames;
 };

EmpireBoard.Ikariam.UnitsList = function()
 {
 if (this._UnitsList == null)
  {
  this._UnitsList        = {};
  this._UnitsList['phalanx']     = 'army line1';
  this._UnitsList['steamgiant']    = 'army line1';
  this._UnitsList['spearman']     = 'army flank';
  this._UnitsList['swordsman']    = 'army flank';
  this._UnitsList['slinger']     = 'army line2';
  this._UnitsList['archer']     = 'army line2';
  this._UnitsList['marksman']     = 'army line2';
  this._UnitsList['ram']      = 'army artillery';
  this._UnitsList['catapult']     = 'army artillery';
  this._UnitsList['mortar']     = 'army artillery';
  this._UnitsList['gyrocopter']    = 'army air';
  this._UnitsList['bombardier']    = 'army air';
  this._UnitsList['cook']      = 'army support';
  this._UnitsList['medic']     = 'army support';
  this._UnitsList['ship_ram']     = 'fleet line1';
  this._UnitsList['ship_flamethrower']  = 'fleet line1';
  this._UnitsList['ship_steamboat']   = 'fleet line1';
  this._UnitsList['ship_ballista']   = 'fleet line2';
  this._UnitsList['ship_catapult']   = 'fleet line2';
  this._UnitsList['ship_mortar']    = 'fleet line2';
  this._UnitsList['ship_rocketship']   = 'fleet firststrike';
  this._UnitsList['ship_submarine']   = 'fleet firststrike';
  this._UnitsList['ship_paddlespeedship']  = 'fleet carrier';
  this._UnitsList['ship_ballooncarrier']  = 'fleet carrier';
  this._UnitsList['ship_tender']    = 'fleet support';
  }
 return this._UnitsList;
 };
 
EmpireBoard.Ikariam.Get_UnitGender = function(unitType)
 {
 var unitGender = '';
 orderedUnits = this.UnitsList();
 if (orderedUnits[unitType] != undefined)
  {
  var arrayClassNames = orderedUnits[unitType].split(' ');
  unitGender = arrayClassNames[0];
  }
 return unitGender;
 };

EmpireBoard.Ikariam.Is_Logged = function()
 {
 if (this._IsLogged == null)
  {
  this._IsLogged = this._Parent.DOM.Has_Node("//div[@id='GF_toolbar']//li[contains(@class,'logout')]");
  this._Parent.Log.Add('User logged : '+(this._IsLogged == true ? 'yes' : 'no'));
  }
  
 return this._IsLogged;
 };

EmpireBoard.Ikariam.View = function()
 {
 if (this._View == null)
  {
  this._View = '';
  
  if (this.phpSet('currentView') != undefined)
   {
   this._View = this.phpSet('currentView');
   }
  else
   {
   // Fetch view name
   try
    {
    this._View = document.getElementsByTagName("body")[0].id;
    }
   catch (e)
    {
    var url_view = /[\?&]view=([a-zA-Z0-9\-_]+)/.exec(document.URL);
    if (url_view != null) this._View = RegExp.$1;
    }
   }
  
  this._Parent.Log.Add('View = '+this._View);
  }
  
 return this._View;
 };
 
EmpireBoard.Ikariam.Host = function()
 {
 if (this._Host == null)
  {
  this._Host = '';
  
  this._Host = document.location.host;
  }
  
 return this._Host;
 };
 
EmpireBoard.Ikariam.Server = function(host)
 {
 if (this._Server == null)
  {
  if (host == undefined) host = this.Host();
  this._Server = '';
  
  var parts = host.split(".");
  var idx = 0;
  if (parts[0] == 'www') idx++;
  this._Server = parts[idx];
  }
 
 return this._Server;
 };

EmpireBoard.Ikariam.Language = function()
 {
 if (this._Language == null)
  {
  if (this.LocalizationStrings('language') != undefined)
   {
   this._Language = this.LocalizationStrings('language');
   }
  else
   {
   this._Language = '';
   
   var sCode = '';
   var scripts = document.getElementsByTagName("script");
   for (var j = 0; j < scripts.length; j++)
    {
    var nScript = scripts[j];
    sCode = nScript.innerHTML;
    if (sCode.indexOf('LocalizationStrings') >= 0)
     {
     break;
     }
    }
   
   if (sCode != '')
    {
    var reg = /LocalizationStrings\['language'\]\s+=\s+'(.+)';/;
    var res = reg.exec(sCode);
    if (res != null) this._Language = res[1];
    }
   }
   
  //if (this._Language == '') this._Language = 'en';
  }
 return this._Language;
 };
 
EmpireBoard.Ikariam.Grab_JSCompleteScript_Version = function(defaultVersion)
 {
 // Requires: DOM
 var Version = '';
 if (defaultVersion != undefined) Version = defaultVersion;
 
 var JSCompleteScript = this._Parent.DOM.Get_First_Node("//script[contains(@src,'/js/complete')]");
 if (JSCompleteScript != null)
  {
  var JSCompleteSrc = JSCompleteScript.src;
  var JSCompleteRegExp_x3 = /complete-([0-9]+\.[0-9]+\.[0-9]+)/.exec(JSCompleteSrc);
  if (JSCompleteRegExp_x3 != null)
   {
   Version = RegExp.$1;
   }
  var JSCompleteRegExp_x4 = /complete-([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/.exec(JSCompleteSrc);
  if (JSCompleteRegExp_x4 != null)
   {
   Version = RegExp.$1;
   }
  }
  
 return Version;
 };
 
EmpireBoard.Ikariam.Version = function()
 {
 // Requires: DOM
 if (this._Version == null)
  {
  this._Version = '';
  
  this._Version = this._Parent.DOM.Get_First_Node_TextContent("//div[@id='GF_toolbar']//li[@class='version']//span[@class='textLabel']",'');
  
  // remove "v."
  this._Version = this._Version.replace(/v\./gi, "");
  // remove "v"
  this._Version = this._Version.replace(/v/gi, "");
  // build number use space separator
  this._Version = this._Version.replace(/ /gi, ".");
  
  if ((this._Version == '0.4.X') || (this._Version == '0.4.x'))
   {
   this._Version = this.Grab_JSCompleteScript_Version('0.4.4.2');
   }
  else if (this._Version == '0.4.4')
   {
   this._Version = this.Grab_JSCompleteScript_Version('0.4.4');
   }
  else if (this._Version == '0.4.2')
   {
   this._Version = this.Grab_JSCompleteScript_Version('0.4.2');
   }
  
  this._Parent.Log.Add("Ikariam server version: "+this._Version);
  }
 
 return this._Version;
 };

EmpireBoard.Ikariam.Revision = function()
 {
 // Requires: DOM, Str
 if (this._Revision == null)
  {
  this._Revision = 0;
  
  this._Revision = this._Parent.Str.To_Integer(this._Parent.DOM.Get_First_Node_Title("//div[@id='GF_toolbar']//li[@class='version']//span[@class='textLabel']",'0'), 0);
  
  this._Parent.Log.Add("Ikariam server revision: "+this._Revision);
  }
 
 return this._Revision;
 };
 
// NB: return true if current version is higher or equal than requiredVersion
EmpireBoard.Ikariam.Is_Version = function(requiredVersion)
 {
 // Requires: Str
 var isHigher = false;
 
 if (requiredVersion == undefined)
  {
  isHigher = false;
  }
 else if (requiredVersion == '')
  {
  isHigher = false;
  }
 else
  {
  if (this._IsVersions[requiredVersion] == undefined)
   {
   if (this._Parent.Str.Compare_Versions(requiredVersion, this.Version()) >= 0)
    {
    isHigher = true;
    //this._Parent.Log.Add("Ikariam version is v."+requiredVersion+" or higher");
    }
   else
    {
    isHigher = false;
    }
   this._IsVersions[requiredVersion] = isHigher;
   }
  else
   {
   isHigher = this._IsVersions[requiredVersion];
   }
  }
 
 return isHigher;
 };

/* DEPRECATED
EmpireBoard.Ikariam.Is_Version_031x = function()
 {
 return this.Is_Version('0.3.1');
 };
 
EmpireBoard.Ikariam.Is_Version_032x = function()
 {
 return this.Is_Version('0.3.2');
 };
 
EmpireBoard.Ikariam.Is_Version_033x = function()
 {
 return this.Is_Version('0.3.3');
 };
 
EmpireBoard.Ikariam.Is_Version_034x = function()
 {
 return this.Is_Version('0.3.4');
 };
 
EmpireBoard.Ikariam.Is_Version_035x = function()
 {
 return this.Is_Version('0.3.5');
 };
 
EmpireBoard.Ikariam.Is_Version_040x = function()
 {
 return this.Is_Version('0.4.0');
 };
 
EmpireBoard.Ikariam.Is_Version_041x = function()
 {
 return this.Is_Version('0.4.1');
 };
 
EmpireBoard.Ikariam.Is_Version_042x = function()
 {
 return this.Is_Version('0.4.2');
 };
 
EmpireBoard.Ikariam.Is_Version_0424 = function()
 {
 return this.Is_Version('0.4.2.4');
 };
 
EmpireBoard.Ikariam.Is_Version_043x = function()
 {
 return this.Is_Version('0.4.3');
 };
 
EmpireBoard.Ikariam.Is_Version_044x = function()
 {
 return this.Is_Version('0.4.4');
 };
*/
 
EmpireBoard.Ikariam.Tab = function()
 {
 if (this._Tab == null)
  {
  this._Tab = '';
  var url_view = /[\?&]tab=([a-zA-Z0-9\-_]+)/.exec(document.URL);
  if (url_view != null) this._Tab = RegExp.$1;
  }
  
 return this._Tab;
 };
 
EmpireBoard.Ikariam.Trim_Coords = function(str)
 {
 // Require: Str
 return this._Parent.Str.Trim(this._Parent.Str.Trim_Accodances(str));
 };
 
EmpireBoard.Ikariam.Trim_PlayerName = function(str)
 {
 // Require: Str
 return this._Parent.Str.Trim(this._Parent.Str.Trim_Brackets(str));
 };
 
EmpireBoard.Ikariam.Trim_Unit = function(str)
 {
 // Require: Str
 str = str.replace("unit", "");
 str = str.replace("currentUnit", "");
  
 return this._Parent.Str.Trim(str);
 };

EmpireBoard.Ikariam.TwoDigit_Coords = function(str)
 {
 // Require: Str
 var a = str.indexOf('[');
 var b = str.indexOf(']');
 str = str.substring(a+1,b);
 var coords = str.split(':');
 res = '[';
 res += this._Parent.Str.TwoDigit(coords[0].substr(-2,2));
 res += ':';
 res += this._Parent.Str.TwoDigit(coords[1].substr(-2,2));
 res += ']';
 return res;
 };

EmpireBoard.Ikariam.City_Object = function()
 {
 var City = new Object;
 
 City.id    = 0;
 City.name   = '';
 //City.playername  = '';
 //City.islandid   = 0;
 
 City.knownTime  = new Date().getTime();
 
 //City.own    = false;
 //City.occupied   = false;
 //City.deployed   = false;
 
 //City.selected   = false;
 
 return City;
 };
 
EmpireBoard.Ikariam.Parse_Coords = function(str)
 {
 var res = null;
 
 if ((str != undefined) && (str != null) && (str != ''))
  {
  var resReg = /(\[[0-9:]+\])/.exec(str);
  if (resReg != null)
   {
   res = resReg[1];
   }
  }
  
 return res;
 };
   
EmpireBoard.Ikariam.Fetch_CitiesSelect = function(database, includeForeign)
 {
 // Requires: DOM, Str
 if (database == undefined)    database = {};
 if (includeForeign == undefined)  includeForeign = false;
 
 var Options = this._Parent.DOM.Get_Nodes("//select[@id='citySelect']/option");
 if (Options != null)
  {
  for (var i=0; i < Options.snapshotLength; i++)
   {
   var Option = Options.snapshotItem(i);
   
   // Occupied city ?
   var isOccupied = false;
   if (this._Parent.DOM.Has_ClassName(Option,'occupiedCities'))
    {
    isOccupied = true;
    }
   
   // Deployed troops into allied city
   var isDeployed = false;
   if (this._Parent.DOM.Has_ClassName(Option,'deployedCities'))
    {
    isDeployed = true;
    }
    
   if ((includeForeign == false) && ((isOccupied == true) || (isDeployed == true))) continue;
   
   var CityId = parseInt(Option.value);
   
   if (database[CityId] == undefined)
    {
    database[CityId] = new this.City_Object();
    }
   
   database[CityId].id = CityId;
   database[CityId].name = this.Trim_Coords(Option.textContent);
   if (isOccupied == true)
    {
    database[CityId].occupied = true;
    }
   else if (isDeployed == true)
    {
    database[CityId].deployed = true;
    }
   else
    {
    database[CityId].own = true;
    }
   
   if (Option.selected == true) database[CityId].selected = true;
   
   this._Parent.Log.Add('Fetch select list: city ['+CityId+'], '+database[CityId].name+', selected='+database[CityId].selected);
   }
  }
 
 return database;
 };

EmpireBoard.Ikariam.ActionRequest = function()
 {
 if (this._ActionRequest == null)
  {
  this._ActionRequest = this._Parent.DOM.Get_First_Node_Value("//form[@id='changeCityForm']//input[@type='hidden' and @name='actionRequest']" ,'');
  }
  
 return this._ActionRequest;
 };
 
EmpireBoard.Ikariam.Get_FleetMission_ImgSrc = function(mission)
 {
 // Values: deployarmy, deployfleet, plunder, blockade, defend, defend_port, trade, transport, occupy
 var tag = '';
 
 tag = 'skin/interface/mission_' + mission + '.gif';
 
 return tag;
 };
 
EmpireBoard.Ikariam.Get_Happiness_ImgSrc = function(growth)
 {
 if (growth == undefined) growth = 0;
 var imagen = '';
 var tag = '';
 
 if (growth < -6 )
  {
  imagen = 'outraged';
  }
 else if (growth < 0)
  {
  imagen = 'sad';
  }
 else if (growth < 1)
  {
  imagen = 'neutral';
  }
 else if (growth < 6)
  {
  imagen = 'happy';
  }
 else
  {
  imagen = 'ecstatic';
  }
 //tag = 'skin/smilies/' + imagen + '.gif';
 //tag = 'skin/smilies/'+imagen+'_x32.gif';
 tag = 'skin/smilies/'+imagen+'_x25.gif';
 
 return tag;
 };
 
EmpireBoard.Ikariam.Resource_Capacity = function(ResType, WarehouseLevel, DumpLevel, Bonus)
 {
 if (ResType == undefined) ResType = 'wine';
 if (WarehouseLevel == undefined) WarehouseLevel = 0;
 if (DumpLevel == undefined) DumpLevel = 0;
 if (Bonus == undefined) Bonus = 0;
 
 var result = 0;
 
 if (this.Is_Version('0.3.1') == true)
  {
  result = 1500;
  }
 else
  {
  if (ResType == 'wood')
   {
   result = 3000;
   }
  else
   {
   result = 1500;
   }
  }
 result = result + (WarehouseLevel * 8000);
 result = result + (DumpLevel * 32000);
 
 return result + (result/100*Bonus);
 };

EmpireBoard.Ikariam.Resource_SafeCapacity = function(ResType, WarehousesLevels, Bonus)
 {
 var _self = this;
 
 if (ResType == undefined) ResType = 'wine';
 if (WarehousesLevels == undefined) WarehousesLevels = 0;
 if (Bonus == undefined) Bonus = 0;
 
 function SafeCapacityPerWarehouse(ResType, WarehouseLevel)
  {
  if (_self.Is_Version('0.3.3') == true)
   {
   return (WarehouseLevel * 480);
   }
  else if (_self.Is_Version('0.3.1') == true)
   {
   return (WarehouseLevel * 80);
   }
  else
   {
   if (ResType == 'wood')
    {
    return (WarehouseLevel * 160);
    }
   else
    {
    return (WarehouseLevel * 80);
    }
   }
  }
  
 function isArray(obj)
  {
  if (obj.constructor.toString().indexOf("Array") == -1)
   return false;
  else
   return true;
  }
 
 var result = 0;
 
 if (this.Is_Version('0.3.4') == true)
  {
  result = 100;
  
  if (isArray(WarehousesLevels))
   {
   var WarehousesLevel = 0;
   if (WarehousesLevels.length <= 4)
    {
    var p;
    for (p in WarehousesLevels)
     {
     WarehousesLevel += WarehousesLevels[p];
     }
    }
   else
    {
    WarehousesLevels.sort(function(a,b){return b - a});
    for (var i=0; i<=3; i++)
     {
     WarehousesLevel += WarehousesLevels[i];
     }
    }
   result += SafeCapacityPerWarehouse(ResType, WarehousesLevel);
   }
  else
   {
   result += SafeCapacityPerWarehouse(ResType, parseInt(WarehousesLevels));
   }
  }
 else
  {
  var WarehousesLevel = 0;
  if (isArray(WarehousesLevels))
   {
   var p;
   for (p in WarehousesLevels)
    {
    WarehousesLevel += WarehousesLevels[p];
    }
   }
  else
   {
   WarehousesLevel = parseInt(WarehousesLevels);
   }
  
  if (this.Is_Version('0.3.1') == true)
   {
   result = 100;
   result += SafeCapacityPerWarehouse(ResType, WarehousesLevel);
   }
  else
   {
   if (ResType == 'wood')
    {
    result = 100;
    result += SafeCapacityPerWarehouse(ResType, WarehousesLevel);
    }
   else
    {
    result = 50;
    result += SafeCapacityPerWarehouse(ResType, WarehousesLevel);
    }
   }
  }
 
 return result + (result/100*Bonus);
 };
 
EmpireBoard.Ikariam.MerchantNavyBox_Object = function()
 {
 var MerchantNavyBox     = new Object;
 
 //MerchantNavyBox.id    = '';
 
 MerchantNavyBox.title    = '';
 //MerchantNavyBox.length     = ''; // Number of missions
 //MerchantNavyBox.missions     = {};
 
 return MerchantNavyBox;
 };

EmpireBoard.Ikariam.NavyTransport_Object = function()
 {
 var NavyTransport    = new Object;
 
 //NavyTransport.id    = '';
 
 //NavyTransport.oCityId    = 0;
 //NavyTransport.oCityName    = '';
 //NavyTransport.oPlayerName   = '';
 
 NavyTransport.ETA   = '';
 NavyTransport.RET   = '';
 
 return NavyTransport;
 };
 
EmpireBoard.Ikariam.Fetch_TimeCounters = function(database, objectName)
 {
 if (database == undefined)    database    = {};
 if (objectName == undefined)   objectName    = 'getCountdown';
 
 this._Parent.Log.Add("Start to fetch '"+objectName+"' time counters");
 // Fetch time counters
 var scripts = document.getElementsByTagName("script");
 for (var j = 0; j < scripts.length; j++)
  {
  var nScript = scripts[j];
  var sCode = nScript.innerHTML;
  if (sCode.indexOf(objectName) > 0)
   {
   var aCodeLines = sCode.split(';');
   for (var i=0; i < aCodeLines.length; i++)
    {
    var sValues = aCodeLines[i].substring(aCodeLines[i].indexOf('{')+1,aCodeLines[i].indexOf('}'));
    var sParts = sValues.split(',');
    if (sParts.length >= 3)
     {
     var CounterValues = new Object;
     var CounterId = '';
     for (var k=0; k < sParts.length; k++)
      {
      var sPartPeer = sParts[k].split(':');
      var sPartName = this._Parent.Str.Trim(sPartPeer[0]);
      var sPartValue = this._Parent.Str.Trim(sPartPeer[1]);
      
      if (sPartName == 'el')
       {
       sPartValue = this._Parent.Str.Trim_DoubleQuotes(sPartValue);
       CounterId = ''+sPartValue;
       }
      else
       {
       sPartValue = 1000*parseInt(sPartValue);
       }
       
      CounterValues[sPartName]=sPartValue;
      //this._Parent.Log.Add("TimeCounter."+sPartName+" = "+CounterValues[sPartName]);
      }
     
     if (CounterId != '')
      {
      database[CounterId] = CounterValues;
      
      //this._Parent.Log.Add("TimeCounter["+CounterId+"] found");
      }
     }
    }
   }
  }
  
 return database;
 };
 
EmpireBoard.Ikariam.Fetch_MerchantNavy_Boxes = function(boxesDB, includeMissions)
 {
 // Require: DOM, Str
 this._Parent.Log.Add('Start fetch MerchantNavy boxes...');
 var StartTime = new Date().getTime();
 if (boxesDB == undefined)    boxesDB    = {};
 if (includeMissions == undefined)  includeMissions  = false;
 
 function grabCityID(rootElt)
  {
  var resID = 0;
  var alinks = rootElt.getElementsByTagName("a");
  for (var k=0; k < alinks.length; k++)
   {
   var resReg = /[\?&]{1}cityId=([0-9]+)&?/i.exec(alinks[k].href);
   if (resReg != null)
    {
    resID = parseInt(resReg[1]);
    break;
    }
   }
  
  return resID;
  }
  
 var contentBoxes = this._Parent.DOM.Get_Nodes("//div[@id='mainview']/div[contains(@class, 'contentBox')]");
 if (contentBoxes.snapshotLength > 0)
  {
  this._Parent.Log.Add('Found '+contentBoxes.snapshotLength+' contentBox');
  
  for (var i=0; i < contentBoxes.snapshotLength; i++)
   {
   var contentBox = contentBoxes.snapshotItem(i);
   var boxId = contentBox.id;
   if (boxId == '')
    {
    boxId = 'contentBox'+(i+1);
    contentBox.id = boxId;
    }
   
   if (boxesDB[boxId] == undefined)
    {
    boxesDB[boxId] = new this.MerchantNavyBox_Object();
    }
   boxesDB[boxId].id = boxId;
    
   var h3s = contentBox.getElementsByTagName("h3");
   boxesDB[boxId].title = h3s[0].textContent;
   
   var Missions = this._Parent.DOM.Get_Nodes("//div[@id='mainview']/div[@id='"+boxId+"']//td[contains(@class, 'mission')]");
   boxesDB[boxId].length = Missions.snapshotLength;
   this._Parent.Log.Add('contentBox['+boxId+']: '+boxesDB[boxId].title+', '+boxesDB[boxId].length+' missions');

   if ((includeMissions == true) && (Missions.snapshotLength >= 1))
    {
    boxesDB[boxId].missions = {};
    for (var j=0; j < Missions.snapshotLength; j++)
     {
     var nMi = Missions.snapshotItem(j);
     var tr = nMi.parentNode;
     var tds = tr.getElementsByTagName("td");
     var tdslength = tds.length;
     //var tds = tr.childNodes;
     
     var missionId = '';
     if (tdslength == 6)
      {
      // pillaging under 0.4.3
      var ETA = tds[4].id;
      var RET = tds[4].id;
      }
     else if (this._Parent.DOM.Has_ClassName(tds[4],'speed'))
      {
      // transport under 0.4.3
      var ETA = tds[5].id;
      var RET = tds[5].id;
      }
     else if (this._Parent.DOM.Has_ClassName(tds[5],'speed'))
      {
      // transport under 0.4.2
      var ETA = tds[4].id;
      var RET = tds[6].id;
      }
     else
      {
      var ETA = tds[4].id;
      var RET = tds[5].id;
      }
     if (ETA != '')
      {
      missionId = ETA;
      }
     else if (RET != '')
      {
      missionId = RET;
      }
     
     if (missionId != '')
      {
      if (boxesDB[boxId].missions[missionId] == undefined)
       {
       boxesDB[boxId].missions[missionId] = new this.NavyTransport_Object();
       }
      boxesDB[boxId].missions[missionId].id = missionId;
      
      if (ETA != '')
       {
       boxesDB[boxId].missions[missionId].ETA = ETA;
       }
      
      if (RET != '')
       {
       boxesDB[boxId].missions[missionId].RET = RET;
       }
       
      boxesDB[boxId].missions[missionId].oCityId = grabCityID(tds[1]);
      
      //this._Parent.Log.Add('NavyTransport['+missionId+']: oCityId='+boxesDB[boxId].missions[missionId].oCityId);
      }
     }
    }
   }
  }
 
 return boxesDB;
 };

EmpireBoard.Ikariam.FleetMovement_Object = function()
 {
 var FleetMovement    = new Object;
 
 //FleetMovement.id     = '';
 
 //FleetMovement.own     = false;
 //FleetMovement.hostile    = false;
 
 FleetMovement.time    = 0;
 
 //FleetMovement.summary    = '';
 //FleetMovement.payload    = {};
 //FleetMovement.hasFleet    = false;
 //FleetMovement.hasGoods    = false;
 //FleetMovement.hasArmy    = false;
 
 //FleetMovement.oCityId    = 0;
 //FleetMovement.oCityName    = '';
 //FleetMovement.oPlayerName   = '';
 //FleetMovement.toLeft     = false;
 //FleetMovement.mission    = '';
 // Values: deployarmy, deployfleet, plunder, blockade, defend, defend_port, trade, transport, occupy
 //FleetMovement.subject    = '';
 //FleetMovement.toRight    = false;
 //FleetMovement.tCityId    = 0;
 //FleetMovement.tCityName    = '';
 //FleetMovement.tPlayerName    = '';
 
 //FleetMovement.hasAction    = false;
 
 return FleetMovement;
 };
 
EmpireBoard.Ikariam.Fetch_FleetMovements = function(database)
 {
 // Require: DOM, Str
 var StartTime = new Date().getTime();
 this._Parent.Log.Add('Start fetch movements...');
 if (database == undefined) database = {};
 
 var _self = this;
 
 function grabCityID(rootElt)
  {
  var resID = 0;
  var alinks = rootElt.getElementsByTagName("a");
  for (var k=0; k < alinks.length; k++)
   {
   var resReg = /[\?&]{1}cityId=([0-9]+)&?/i.exec(alinks[k].href);
   if (resReg != null)
    {
    resID = parseInt(resReg[1]);
    break;
    }
   }
  
  return resID;
  }
  
 function TrimIcon(src)
  {
  var str = '';

  var parsedURL = src.split('/');
  if (parsedURL.length > 0)
   {
   str = parsedURL[parsedURL.length-1];
   }
  
  str = str.replace(".gif", "");
  str = str.replace("40x40", "");
  str = str.replace("60x60", "");
  str = str.replace("_r_", "");
  str = str.replace("y40_", "");
  str = str.replace("_faceright", "");
  str = str.replace("icon_", "");
  
  return _self._Parent.Str.Trim(str);
  }

 var resMi = this._Parent.DOM.Get_Nodes("//div[@id='fleetMovements']//table[contains(@class, 'locationEvents')]/tbody/tr/td/img[contains(@src, 'mission_')]");
 if (resMi.snapshotLength > 0)
  {
  this._Parent.Log.Add('Found '+resMi.snapshotLength+' fleets');
  
  // heures
  var mTimers = {};
  var scripts = document.getElementsByTagName("script");
  for (var j = 0; j < scripts.length; j++)
   {
   // search getCountdown
   var nScript = scripts[j];
   var sCode = nScript.innerHTML;
   if (sCode.indexOf('getCountdown') >= 0)
    {
    var aCodeLines = sCode.split(';');
    for (var i=0; i < aCodeLines.length-1; i++)
     {
     if (aCodeLines[i].indexOf('getCountdown') >= 0)
      {
      var sValues = aCodeLines[i].substring(aCodeLines[i].indexOf('{')+1,aCodeLines[i].indexOf('}'));
      var sParts = sValues.split(',');
      if (sParts.length >= 3)
       {
       var sPart0 = sParts[0].split(':');
       var enddate = 1000*parseInt(this._Parent.Str.Trim(sPart0[1]));
       
       var sPart1 = sParts[1].split(':');
       var currentdate = 1000*parseInt(this._Parent.Str.Trim(sPart1[1]));
       
       var sID = sParts[2].substring(sParts[2].indexOf('"')+1,sParts[2].indexOf('"',sParts[2].indexOf('"')+2));
       
       if ((enddate - currentdate) > 0)
        {
        mTimers[sID] = StartTime + (enddate - currentdate);
        }
       }
      else
       {
       this._Parent.Log.Add("Failed to fetch getCountdown");
       }
      }
     }
    }
   }
  
  for (var i=0; i < resMi.snapshotLength; i++)
   {
   var tr = resMi.snapshotItem(i).parentNode.parentNode;
   var tds = tr.getElementsByTagName("td");
   //var tds = tr.childNodes;
    
   var fleetId = this._Parent.Str.Trim(tds[1].id);
   
   var tdinc = 0;
   // Fix for v. 0.4.3
   if (this.Is_Version('0.4.3'))
    {
    tdinc = 1;
    }
   
   if (fleetId != '')
    {
    if (database[fleetId] == undefined)
     {
     database[fleetId] = new this.FleetMovement_Object();
     }
    database[fleetId].id    = fleetId;
     
    database[fleetId].own    = this._Parent.DOM.Has_ClassName(tr,'own');
    database[fleetId].hostile   = this._Parent.DOM.Has_ClassName(tr,'hostile');
    
    if (mTimers[fleetId] != undefined)
     {
     database[fleetId].time    = mTimers[fleetId];
     }
    else 
     {
     database[fleetId].time    = mTimers['nexEventETA1'];
     }
    
    database[fleetId].summary = this._Parent.Str.Trim(tds[2+tdinc].childNodes[0].textContent);
    
    database[fleetId].payload = {};
    var hasFleet = false;
    var hasGoods = false;
    var hasArmy = false;
    
    var payloadDoc = this._Parent.DOM.Create_Document(tds[2+tdinc].innerHTML);
    var icons = this._Parent.DOM.Get_Nodes("//div[contains(@class, 'icon')]/img",payloadDoc);
    var iconsNb = 0;
    if (icons.snapshotLength >= 1)
     {
     iconsNb = icons.snapshotLength;
     for (var j=0; j < iconsNb; j++)
      {
      var iconIMG = icons.snapshotItem(j);
      var unitType = TrimIcon(iconIMG.src);
      
      var payloadDivs = iconIMG.parentNode.parentNode.getElementsByTagName("div");
      var unitQty = this._Parent.Str.To_Integer(payloadDivs[1].textContent);
      
      database[fleetId].payload[unitType] = unitQty;
      
      switch(this._LangCode)
       {
       case 'wood':
       case 'wine':
       case 'marble':
       case 'glass':
       case 'sulfur':
        hasGoods = true;
        break;
       
       case 'ship_ram':
       case 'ship_ballista':
       case 'ship_flamethrower':
       case 'ship_catapult':
       case 'ship_steamboat':
       case 'ship_mortar':
       case 'ship_submarine':
        hasFleet = true;
        break;
       
       case 'slinger':
       case 'swordsman':
       case 'phalanx':
       case 'spearman':
       case 'archer':
       case 'marksman':
       case 'gyrocopter':
       case 'steamgiant':
       case 'bombardier':
       case 'ram':
       case 'catapult':
       case 'mortar':
       case 'medic':
       case 'cook':
        hasArmy = true;
        break;
       
       default:
        break;
       }
      this._Parent.Log.Add('Payload['+unitType+']='+unitQty);
      }
     }
    
    if (hasFleet == true)
     {
     database[fleetId].hasFleet = true;
     }
    if (hasGoods == true)
     {
     database[fleetId].hasGoods = true;
     }
    if (hasArmy == true)
     {
     database[fleetId].hasArmy = true;
     }
    
    database[fleetId].oCityId = grabCityID(tds[3+tdinc]);
    database[fleetId].oCityName = this._Parent.Str.Trim(tds[3+tdinc].childNodes[0].textContent);
    var oPlayerName = this._Parent.Str.Trim(tds[3+tdinc].childNodes[1].textContent);
    oPlayerName = oPlayerName.substring(1,oPlayerName.length-1);
    database[fleetId].oPlayerName = oPlayerName;
    
    database[fleetId].toLeft = (tds[4+tdinc].innerHTML != '') ? true : false;
    database[fleetId].mission = /mission_([_a-z]+)\.[a-z]+/i.exec(resMi.snapshotItem(i).src)[1];
    database[fleetId].subject = this._Parent.Str.Trim(tds[5+tdinc].title);
    database[fleetId].toRight = (tds[6+tdinc].innerHTML != '') ? true : false;
    
    database[fleetId].tCityId = grabCityID(tds[7+tdinc]);
    database[fleetId].tCityName = this._Parent.Str.Trim(tds[7+tdinc].childNodes[0].textContent);
    var tPlayerName = this._Parent.Str.Trim(tds[7+tdinc].childNodes[1].textContent);
    tPlayerName = tPlayerName.substring(1,tPlayerName.length-1);
    database[fleetId].tPlayerName = tPlayerName;
    
    database[fleetId].hasAction = (tds[8+tdinc].innerHTML != '') ? true : false;
    
    this._Parent.Log.Add('Detect fleet['+fleetId+']: oCityId='+database[fleetId].oCityId+', tCityId['+database[fleetId].tCityId+']: '+database[fleetId].tCityName+' ('+database[fleetId].tPlayerName+'), time='+database[fleetId].time+', mission='+database[fleetId].mission+', payload: '+iconsNb+' units');
    }
   }
  }
 
 return database;
 };
 
EmpireBoard.Ikariam.LocalizationStrings = function(valueName,sectionName,subSectionName)
 {
 if (this._LocalizationStrings == null)
  {
  if (unsafeWindow && (unsafeWindow.LocalizationStrings != undefined))
   {
   this._LocalizationStrings = unsafeWindow.LocalizationStrings;
   }
  else
   {
   return undefined;
   }
  }
 
 if (sectionName == undefined)
  {
  if (valueName == undefined)
   {
   return this._LocalizationStrings;
   }
  else
   {
   if (this._LocalizationStrings[valueName] == undefined)
    {
    return undefined;
    }
   else
    {
    return this._LocalizationStrings[valueName];
    }
   }
  }
 else
  {
  if (this._LocalizationStrings[sectionName] == undefined)
   {
   return undefined;
   }
  else if (subSectionName != undefined)
   {
   if (this._LocalizationStrings[sectionName][subSectionName] == undefined)
    {
    return undefined;
    }
   else if (this._LocalizationStrings[sectionName][subSectionName][valueName] == undefined)
    {
    return undefined;
    }
   else
    {
    return this._LocalizationStrings[sectionName][subSectionName][valueName];
    }
   }
  else if (this._LocalizationStrings[sectionName][valueName] == undefined)
   {
   return undefined;
   }
  else
   {
   return this._LocalizationStrings[sectionName][valueName];
   }
  }
 };
 
EmpireBoard.Ikariam.phpSet = function(valueName)
 {
 if (this._phpSet == null)
  {
  if (unsafeWindow && (unsafeWindow.IKARIAM != undefined))
   {
   if (unsafeWindow.IKARIAM.phpSet != undefined)
    {
    this._phpSet = unsafeWindow.IKARIAM.phpSet;
    }
   else
    {
    return undefined;
    }
   }
  else
   {
   return undefined;
   }
  }
 
 if (valueName == undefined)
  {
  return this._phpSet;
  }
 else
  {
  if (this._phpSet[valueName] == undefined)
   {
   return undefined;
   }
  else
   {
   return this._phpSet[valueName];
   }
  }
 };

EmpireBoard.Ikariam.currentCity = function(valueName,sectionName)
 {
 if (this._currentCity == null)
  {
  if (unsafeWindow && (unsafeWindow.IKARIAM != undefined))
   {
   if (unsafeWindow.IKARIAM.currentCity != undefined)
    {
    this._currentCity = unsafeWindow.IKARIAM.currentCity;
    }
   else
    {
    return undefined;
    }
   }
  else
   {
   return undefined;
   }
  }
 
 if (sectionName == undefined)
  {
  if (valueName == undefined)
   {
   return this._currentCity;
   }
  else
   {
   if (this._currentCity[valueName] == undefined)
    {
    return undefined;
    }
   else
    {
    return this._currentCity[valueName];
    }
   }
  }
 else
  {
  if ((this._currentCity[sectionName] == undefined) || (this._currentCity[sectionName][valueName] == undefined))
   {
   return undefined;
   }
  else
   {
   return this._currentCity[sectionName][valueName];
   }
  }
 };

// From kChen script with some fixes
EmpireBoard.Ikariam.Change_currentCity = function(city_id)
 {
 var _self = this;
 
 function getFormInput(path, root)
  {
  var nodes = _self._Parent.DOM.Get_Nodes(path, root);
  if (nodes.snapshotLength <= 0) return null;
  
  var node0 = nodes.snapshotItem(0);
  var postdata = node0.name+"="+node0.value;
  
  for (var i = 1; i < nodes.snapshotLength; i++) 
   {
   var node = nodes.snapshotItem(i);
   postdata = postdata +"&" + node.name+"="+node.value;
   }
  
  return postdata;
  }
 
 var postdata = getFormInput("//form[@id='changeCityForm']//input");
 postdata = postdata + "&cityId="+city_id+"&view=city";
 var xmlhttp;
 if (window.XMLHttpRequest)
  {
  xmlhttp = new XMLHttpRequest();
  }
 xmlhttp.open('POST','http://' + window.location.host + '/index.php',false);
 xmlhttp.setRequestHeader('User-agent',window.navigator.userAgent);
 xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
 xmlhttp.setRequestHeader('Accept','text/html,application/xhtml+xml,application/xml');
 xmlhttp.setRequestHeader('Referer',window.location);
 xmlhttp.setRequestHeader('Cookie',document.cookie);
 xmlhttp.overrideMimeType('text/html; charset='+document.characterSet);
 xmlhttp.send(postdata);
 
 // Grab new ActionRequest value
 var node = this._Parent.DOM.Create_Document(xmlhttp.responseText);
 this._ActionRequest = this._Parent.DOM.Get_First_Node_Value("//input[@name='actionRequest']",node);
 
 return true;
 };

EmpireBoard.Ikariam.Insert_Warning = function(message, title)
 {
 var notices = document.getElementById('notices');
 if (notices == null)
  {
  notices = document.createElement('div');
  notices.id = 'notices';
  var mainview = document.getElementById("mainview");
  var buildingDescription = this._Parent.DOM.Get_Nodes("//div[@id='mainview']/div[contains(@class,'buildingDescription')]");
  if (buildingDescription.snapshotLength >= 1)
   {
   mainview.insertBefore(notices, buildingDescription.snapshotItem(0).nextSibling);
   }
  else
   {
   var contentBox = document.createElement('div');
   contentBox.setAttribute("class", "contentBox");
   contentBox.appendChild(notices);
   //mainview.appendChild(contentBox);
   mainview.insertBefore(contentBox, mainview.getElementsByTagName("h1")[0].nextSibling);
   }
  }
 notices.innerHTML = notices.innerHTML+'<div class="warning"><h5>'+title+'</h5><p>'+message+'</p></div>';
 };

EmpireBoard.DOM =
 {
 _Parent: null,
 };

EmpireBoard.DOM.Init = function(parent)
 {
 this._Parent = parent;
 };

EmpireBoard.DOM.Create_Document = function(responseText)
 {
 // Thank sizzlemctwizzle and Seniltai
 var dt = document.implementation.createDocumentType("html", "-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd");
 var doc = document.implementation.createDocument('', '', dt);
 var html = doc.createElement('html');

 html.innerHTML = responseText;
 doc.appendChild(html);

 return doc;
 };

EmpireBoard.DOM.Get_Nodes = function(path, root)
 {
 var contextNode = root ? root.evaluate ? root : root.ownerDocument : document;
 return contextNode.evaluate(path, contextNode, null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
 };
 
EmpireBoard.DOM.Has_Node = function(path, root)
 {
 var value = this.Get_Nodes(path, root);
 if (value.snapshotLength >= 1)
  {
  return true;
  }
 else
  {
  return false;
  }
 };
 
EmpireBoard.DOM.Get_First_Node = function(path, root)
 {
 var value = this.Get_Nodes(path, root);
 if (value.snapshotLength >= 1)
  {
  return value.snapshotItem(0);
  }
 return null;
 };
 
EmpireBoard.DOM.Get_Last_Node = function(path, root)
 {
 var value = this.Get_Nodes(path, root);
 if (value.snapshotLength >= 1)
  {
  return value.snapshotItem(value.snapshotLength-1);
  }
 return null;
 };
 
EmpireBoard.DOM.Get_First_Node_Value = function(path, defaultValue, root)
 {
 var value = this.Get_First_Node(path, root);
 if (value != null)
  {
  return value.value;
  }
 else return defaultValue;
 };
 
EmpireBoard.DOM.Get_Last_Node_Value = function(path, defaultValue, root)
 {
 var value = this.Get_Last_Node(path, root);
 if (value != null)
  {
  return value.value;
  }
 else return defaultValue;
 };
 
EmpireBoard.DOM.Get_First_Node_TextContent = function(path, defaultValue, root)
 {
 var value = this.Get_First_Node(path, root);
 if (value != null)
  {
  return value.textContent;
  }
 else return defaultValue;
 };

EmpireBoard.DOM.Get_First_Node_Title = function(path, defaultValue, root)
 {
 var value = this.Get_First_Node(path, root);
 if ((value != null) && (value.title != '')) 
  {
  return value.title;
  } 
 else return defaultValue;
 };
 
EmpireBoard.DOM.Has_ClassName = function(oElm, strClassName)
 {
 var arrayClassNames = oElm.className.split(' ');
 var Found = false;
 var arrayClassNamesLength = arrayClassNames.length;
 for (var k = 0; k < arrayClassNamesLength; k++)
  {
  if (arrayClassNames[k] == strClassName)
   {
   Found = true;
   break;
   }
  }
 return Found;
 };
 
/* Lib for strings processes */
EmpireBoard.Str =
 {
 _Parent:     null,
 _decimalPoint:    '.',
 _thousandSeparator:   ',',
 _timeunits_short_day:  'D',
 _timeunits_short_hour:  'h',
 _timeunits_short_minute: 'm',
 _timeunits_short_second: 's'
 };
 
EmpireBoard.Str.Init = function(parent)
 {
 this._Parent = parent;
 //this._decimalPoint = this.Get_LocaleDecimalPoint();
 };

// Replace any joker (%1, %2, %3, etc) with values from an array
EmpireBoard.Str.ValuesReplace = function(text, values)
 {
 if (text == undefined) text = '';
 if (values == undefined) values = [];
 
 var key;
 var i = 1;
 for (key in values)
  {
  text = text.replace('%'+i, values[key]);
  i++;
  }
 
 return text;
 }
 
EmpireBoard.Str.Trim = function(str)
 {
 if (str != undefined)
  {
  str = str.replace(/&nbsp;/gi, " ");
  str = str.replace(/\t/gi, " ");
  str = str.replace(/\v/gi, "");
  str = str.replace(/\f/gi, "");
  str = str.replace(/\n/gi, "");
  str = str.replace(/\r/gi, "");
  //str = str.replace(/\e/gi, "");
  str = str.replace(/\s/gi, " ");
  
  while(str.charAt(0) == (" "))
   { 
   str = str.substring(1);
   }
  while(str.charAt(str.length-1) == " " )
   { 
   str = str.substring(0,str.length-1);
   }
  }
 return str;
 };
 
EmpireBoard.Str.Trim_DoubleQuotes = function(str)
 {
 str = str.replace(/["]{1}/gi, "");
 
 return str;
 };
 
EmpireBoard.Str.Trim_Brackets = function(str)
 {
 str = str.replace(/\(.+\)/gi, "");
 
 return str;
 };
 
EmpireBoard.Str.Trim_Accodances = function(str)
 {
 str = str.replace(/\[.+\]/gi, "");
 
 return str;
 };
 
EmpireBoard.Str.TwoDigit = function(val)
 {
 val = parseInt(val);
 if (val == 0)
  {
  val = "00";
  }
 else if (val < 10)
  {
  return "0"+val;
  }
 return val;
 };

/*
v1 & v2 as "v.00.00.00 0000"

return 0 if v2 = v1
  1 if v2 > v1
 -1 if v2 < v1
*/
EmpireBoard.Str.Compare_Versions = function(v1, v2)
 {
 var result = 0;
 
 // remove "v."
 v1 = v1.replace(/v\./gi, "");
 v2 = v2.replace(/v\./gi, "");
 // remove "v"
 v1 = v1.replace(/v/gi, "");
 v2 = v2.replace(/v/gi, "");
 
 // build number use space separator
 v1 = v1.replace(/ /gi, ".");
 v2 = v2.replace(/ /gi, ".");

 // Parse numbers
 var vn1 = v1.split('.');
 var vn2 = v2.split('.');
 
 // Convert as integer
 for (var i = 0; i < vn1.length; i++)
  {
  vn1[i] = parseInt(vn1[i]);
  }
 for (var j = 0; j < vn2.length; j++)
  {
  vn2[j] = parseInt(vn2[j]);
  }
  
 for (var k = 0; k < vn1.length; k++)
  {
  if (vn2[k] == undefined)
   {
   if (vn1[k] > 0) result = -1;
   break;
   }
  else if (vn2[k] > vn1[k])
   {
   result = 1;
   break;
   }
  else if (vn2[k] < vn1[k])
   {
   result = -1;
   break;
   }
  }
 if ((result == 0) && (vn2.length > vn1.length))
  {
  if (vn2[vn1.length] > 0)
   {
   result = 1;
   }
  else if (vn2[vn2.length-1] > 0)
   {
   result = 1;
   }
  }
 
 return result;
 };
 
EmpireBoard.Str.To_Integer = function(str, defaultValue)
 {
 // Support signed integers
 var temp = ""+str;
 temp = temp.replace(/[^-0-9]+/g, "");
 temp = parseInt(temp,10);
 if (((temp == undefined) || (""+temp == "NaN")) && (defaultValue != undefined))
  {
  return defaultValue;
  }
 return temp;
 };

// decimalPoint = '.' or ','
EmpireBoard.Str.To_Float = function(str, defaultValue, decimalPoint)
 {
 if (decimalPoint == undefined) decimalPoint = this._decimalPoint;
 // Support signed integers
 var temp = ""+str;
 if (decimalPoint == '.')
  {
  temp = temp.replace(/[^-0-9\.]+/g, "");
  }
 else if (decimalPoint == ',')
  {
  temp = temp.replace(/[^-0-9\,]+/g, "");
  }
 else
  {
  temp = temp.replace(/[^-0-9]+/g, "");
  }
 temp = Number(temp);
 if (defaultValue != undefined && (temp == undefined || (""+temp == "NaN")))
  {
  return defaultValue;
  }
 return temp;
 };
 
EmpireBoard.Str.Get_LocaleDecimalPoint = function()
 {
 var _cachedDecimalPoint = new Number(1.5).toLocaleString().substring(1, 2);
 if (_cachedDecimalPoint == undefined || _cachedDecimalPoint == "")
  {
  _cachedDecimalPoint = ".";
  }
 return _cachedDecimalPoint;
 };

EmpireBoard.Str.FormatFloatNumber = function(num, fracdigits, alwaysShowSign, decimalPoint)
 {
 if (fracdigits == undefined) fracdigits = 2;
 if (alwaysShowSign == undefined) alwaysShowSign = false;
 if (decimalPoint == undefined) decimalPoint = this._decimalPoint;
 
 var s = ""+num;
 if (num == "?")
  {
  return num;
  }
 var negative = "";
 if (s.substring(0, 1) == "-")
  {
  negative = "-";
  s = s.substring(1);
  }
 else if (alwaysShowSign == true)
  {
  negative = "+";
  }
 var p = s.indexOf(".");
 if (p >= 0)
  {
  var i = s.substring(0, p);
  var frac = s.substring(p + 1, p + 1 + fracdigits);
  while (frac.length < fracdigits)
   {
   frac += "0";
   }
  s = i + decimalPoint + frac;
  }
 return negative + s;
 };

EmpireBoard.Str.FormatBigNumber = function(num, alwaysShowSign, thousandSeparator)
 {
 if (alwaysShowSign == undefined) alwaysShowSign = false;
 if (thousandSeparator == undefined) thousandSeparator = this._thousandSeparator;
 
 var s = ""+num;
 if (num == undefined || s == "NaN" || s == "?")
  {
  return "?";
  }
 else if (num == "-")
  {
  return num;
  }
  
 var negative = "";
 if (s.substring(0, 1) == "-")
  {
  negative = "-";
  s = s.substring(1);
  }
 else if (alwaysShowSign == true)
  {
  negative = "+";
  }
  
 var i = s.length-3;
 while (i > 0)
  {
  s = s.substring(0, i) + thousandSeparator + s.substring(i);
  i -= 3;
  }
 return negative + s;
 };

EmpireBoard.Str.FormatRemainingTime = function(timestamp,maxDigits,delimiter,approx,showunits,zerofill)
 {
 if(typeof timestamp=="undefined"){timestamp=0;}
 if(typeof maxDigits=="undefined"){maxDigits=2;}
 if(typeof delimiter=="undefined"){delimiter=" ";}
 if(typeof approx=="undefined"){approx="";}
 if(typeof showunits=="undefined"){showunits=true;}
 if(typeof zerofill=="undefined"){zerofill=false;}
 var timeunits=[];
 timeunits['day']=60*60*24;
 timeunits['hour']=60*60;
 timeunits['minute']=60;
 timeunits['second']=1;
 var loca=[];
 loca['day']   = (showunits) ? this._timeunits_short_day:"";
 loca['hour']  = (showunits) ? this._timeunits_short_hour:"";
 loca['minute']  = (showunits) ? this._timeunits_short_minute:"";
 loca['second']  = (showunits) ? this._timeunits_short_second:"";
 timestamp=Math.floor(timestamp/1000);
 var timestring="";
 for (var k in timeunits)
  {
  var nv=Math.floor(timestamp/timeunits[k]);
  if (maxDigits>0&&(nv>0||(zerofill&&timestring!="")))
   {
   timestamp=timestamp-nv*timeunits[k];
   if (timestring!="")
    {
    timestring+=delimiter;
    if (nv<10&&nv>0&&zerofill){nv="0"+nv;}
    if (nv==0){nv="00";}
    }
   timestring+=nv+loca[k];
   maxDigits--;
   }
  }
 if (timestamp>0) {timestring=approx+timestring;}
 return timestring;
 };

function smartDateFormat(time, showElapsedTime, elapsedTimeSeparator) {
  if (showElapsedTime != true) {
    showElapsedTime = false;
  }
  if (elapsedTimeSeparator == undefined) {
    elapsedTimeSeparator = ",";
  }
  var s = new Date();
  s.setTime(time);
  var now = new Date();
  var t = "";
  if ((1+now.getDate()) == s.getDate() && now.getYear() == s.getYear() && now.getMonth() == s.getMonth()) {
    t = 'tomorrow ' + EmpireBoard.Str.TwoDigit(s.getHours())+":"+EmpireBoard.Str.TwoDigit(s.getMinutes());
  } else if (now.getYear() != s.getYear() || now.getMonth() != s.getMonth() || now.getDate() != s.getDate()) {
    t = s.toLocaleString();
  } else {
    t = EmpireBoard.Str.TwoDigit(s.getHours())+":"+EmpireBoard.Str.TwoDigit(s.getMinutes());
  }
  if (showElapsedTime) {
    t += elapsedTimeSeparator;
    var d = (now.getTime() - s.getTime()) / 1000;
    if (d < 3600) {
      t += " " + Math.floor(d / 60) + "m";
    } else {
      if (d >= 86400) {
        t += " " + Math.floor(d / 86400) + "d";
      }
      t += " " + EmpireBoard.Str.FormatFloatNumber((d % 86400) / 3600, 1) + "h";
    }
  }
  return t;
}

EmpireBoard.Handlers =
 {
 _Parent: null
 };
 
EmpireBoard.Handlers.Init = function(parent)
 {
 this._Parent = parent;
 };
 
EmpireBoard.Handlers.Attach_Events = function()
 {
 // Common events
 this.Attach_ChangeCity_Events();
 
 if (this._Parent.DB.Options.Prefs.TABLE_BUILDINGS == true)
  {
  // Buildings table
  this.Attach_BuildingsHeader_Events();
  }
  
 if (this._Parent.DB.Options.Prefs.TABLE_RESOURCES == true)
  {
  // Resources table
  this.Attach_ArrivingGoods_Events();
  }
 
 if (this._Parent.DB.Options.Prefs.TABLE_ARMYFLEET == true)
  {
  // Army table
  this.Attach_ArmyFleetHeader_Events();
  this.Attach_Movements_Events();
  this.Attach_Attacks_Events();
  }
 };
 
EmpireBoard.Handlers.Attach_ChangeCity_Events = function()
 {
 var self = this;
 
 var nodes = this._Parent.DOM.Get_Nodes("//div[@id='"+this._Parent.MainID+"']//a[contains(@class,'changeCity')]");
 for (var i = 0; i < nodes.snapshotLength; i++)
  {
  var node = nodes.snapshotItem(i);
  if (current_city_id != parseInt(node.getAttribute("cityid")))
   node.addEventListener('click', function(e) { return self.ChangeCity_Click_Event(e); }, false);
  }
 };
 
EmpireBoard.Handlers.ChangeCity_Click_Event = function(e)
 {
 var obj = e.srcElement ? e.srcElement:e.target;
 obj.style.cursor="wait";
 document.getElementsByTagName("body")[0].style.cursor="wait";
 while (obj.hasAttribute('cityid') == false)
  {
  obj = obj.parentNode;
  }
 var city_id = obj.getAttribute("cityid");
 return this._Parent.Ikariam.Change_currentCity(city_id);
 };
 
EmpireBoard.Handlers.Attach_BuildingsHeader_Events = function()
 {
 var self = this;
 
 var nodes = this._Parent.DOM.Get_Nodes("//div[@id='"+this._Parent.MainID+"']//th[contains(@class,'build_name')]");
 for (var i = 0; i < nodes.snapshotLength; i++)
  {
  var node = nodes.snapshotItem(i);
  node.addEventListener('mouseover', function(e) { self.BuildingName_MouseOver_Event(e); }, false);
  node.addEventListener('mousemove', function(e) { self._Parent.Tooltip.mouseMove(e); }, false);
  node.addEventListener('mouseout', function(e) { self._Parent.Tooltip.hide(e); }, false);
  }
 };
 
EmpireBoard.Handlers.BuildingName_MouseOver_Event = function(e)
 {
 if (!e) { e = window.event; }
 var obj = e.srcElement ? e.srcElement : e.target;
 while (obj.hasAttribute('building') == false)
  {
  obj = obj.parentNode;
  }
 var building_id = obj.getAttribute('building');
 //window.status = 'building_id: '+building_id;
 
 var tooltipHTML = this._Parent.Tooltip.innerHTML(this._Parent.Renders.BuildingName_Tooltip_Content(building_id));
 this._Parent.Tooltip.show(tooltipHTML);
 };
 
EmpireBoard.Handlers.Attach_ArrivingGoods_Events = function()
 {
 var self = this;

 var nodes = this._Parent.DOM.Get_Nodes("//div[@id='"+this._Parent.MainID+"']//*[contains(@class,'MoreGoods')]");
 for (var i = 0; i < nodes.snapshotLength; i++)
  {
  var node = nodes.snapshotItem(i);
  node.addEventListener('mouseover', function(e) { self.ArrivingGoods_MouseOver_Event(e); }, false);
  node.addEventListener('mousemove', function(e) { self._Parent.Tooltip.mouseMove(e); }, false);
  node.addEventListener('mouseout', function(e) { self._Parent.Tooltip.hide(e); }, false);
  }
 };
 
EmpireBoard.Handlers.ArrivingGoods_MouseOver_Event = function(e)
 {
 if (!e) { e = window.event; }
 var obj = e.srcElement ? e.srcElement : e.target;
 //var targetObj = obj;
 while (obj.hasAttribute('resource') == false)
  {
  obj = obj.parentNode;
  }
 var resName = obj.getAttribute('resource');
 while (obj.hasAttribute('cityid') == false)
  {
  obj = obj.parentNode;
  }
 var city_id = parseInt(obj.getAttribute('cityid'));
 //window.status = 'Resource: '+resName+' City ID: '+city_id;
 var tooltipHTML = this._Parent.Tooltip.innerHTML(this._Parent.Renders.ArrivingGoods_Tooltip_Content(city_id, resName));
 
 this._Parent.Tooltip.show(tooltipHTML);
 };

EmpireBoard.Handlers.Attach_ArmyFleetHeader_Events = function()
 {
 var self = this;
 
 var nodes = this._Parent.DOM.Get_Nodes("//div[@id='"+this._Parent.MainID+"']//th[contains(@class,'unit_name')]");
 for (var i = 0; i < nodes.snapshotLength; i++)
  {
  var node = nodes.snapshotItem(i);
  node.addEventListener('mouseover', function(e) { self.UnitName_MouseOver_Event(e); }, false);
  node.addEventListener('mousemove', function(e) { self._Parent.Tooltip.mouseMove(e); }, false);
  node.addEventListener('mouseout', function(e) { self._Parent.Tooltip.hide(e); }, false);
  }
 };
 
EmpireBoard.Handlers.UnitName_MouseOver_Event = function(e)
 {
 if (!e) { e = window.event; }
 var obj = e.srcElement ? e.srcElement : e.target;
 while (obj.hasAttribute('unit') == false)
  {
  obj = obj.parentNode;
  }
 var unit_id = obj.getAttribute('unit');
 //window.status = 'unit_id: '+unit_id;
 
 var tooltipHTML = this._Parent.Tooltip.innerHTML(this._Parent.Renders.UnitName_Tooltip_Content(unit_id));
 this._Parent.Tooltip.show(tooltipHTML);
 };
 
EmpireBoard.Handlers.Attach_Movements_Events = function()
 {
 var self = this;
 
 var nodes = this._Parent.DOM.Get_Nodes("//div[@id='"+this._Parent.MainID+"']//*[contains(@class,'Movements')]");
 for (var i = 0; i < nodes.snapshotLength; i++)
  {
  var node = nodes.snapshotItem(i);
  node.addEventListener('mouseover', function(e) { self.Movements_MouseOver_Event(e); }, false);
  node.addEventListener('mousemove', function(e) { self._Parent.Tooltip.mouseMove(e); }, false);
  node.addEventListener('mouseout', function(e) { self._Parent.Tooltip.hide(e); }, false);
  }
 };
 
EmpireBoard.Handlers.Movements_MouseOver_Event = function(e)
 {
 if (!e) { e = window.event; }
 var obj = e.srcElement ? e.srcElement : e.target;
 while (obj.hasAttribute('cityid') == false)
  {
  obj = obj.parentNode;
  }
 var city_id = parseInt(obj.getAttribute('cityid'));
 //window.status = 'Movements of city by ID : '+city_id;
 
 var tooltipHTML = this._Parent.Tooltip.innerHTML(this._Parent.Renders.Movements_Tooltip_Content(city_id));
 this._Parent.Tooltip.show(tooltipHTML);
 };
 
EmpireBoard.Handlers.Attach_Attacks_Events = function()
 {
 var self = this;
 
 var nodes = this._Parent.DOM.Get_Nodes("//div[@id='"+this._Parent.MainID+"']//*[contains(@class,'Attacks')]");
 for (var i = 0; i < nodes.snapshotLength; i++)
  {
  var node = nodes.snapshotItem(i);
  node.addEventListener('mouseover', function(e) { self.Attacks_MouseOver_Event(e); }, false);
  node.addEventListener('mousemove', function(e) { self._Parent.Tooltip.mouseMove(e); }, false);
  node.addEventListener('mouseout', function(e) { self._Parent.Tooltip.hide(e); }, false);
  }
 };
 
EmpireBoard.Handlers.Attacks_MouseOver_Event = function(e)
 {
 if (!e) { e = window.event; }
 var obj = e.srcElement ? e.srcElement : e.target;
 while (obj.hasAttribute('cityid') == false)
  {
  obj = obj.parentNode;
  }
 var city_id = parseInt(obj.getAttribute('cityid'));
 //window.status = 'Movements of city by ID : '+city_id;
 
 var tooltipHTML = this._Parent.Tooltip.innerHTML(this._Parent.Renders.Attacks_Tooltip_Content(city_id));
 this._Parent.Tooltip.show(tooltipHTML);
 };
 
EmpireBoard.Handlers.Start_Timers = function()
 {
 // Common real-time counters
 window.setInterval(myTimeCounterF, 1100);
 
 if (this._Parent.DB.Options.Prefs.TABLE_RESOURCES == true)
  {
  // Resources timers
  window.setInterval(realtimeFactDisplayF, 10000);
  }
 };
 
EmpireBoard.Handlers.Deployment_Submit_Event = function(e)
 {
 var dType = this._Parent.DOM.Get_First_Node_Value("//form[@id='deploymentForm']/input[@name='function']", '');

 // Update units garrisoned
 var city = getCity(current_city_id);
 var duList = this._Parent.DOM.Get_Nodes("//form[@id='deploymentForm']//ul[@class='assignUnits']/li");
 if (duList.snapshotLength >= 1)
  {
  for (var i = 0; i < duList.snapshotLength; i++)
   {
   var uLI = duList.snapshotItem(i);
   var unit_id = 'unit '+uLI.className;
   
   if (this._Parent.Ikariam.Is_Version('0.4.4'))
    {
    var oAmount = this._Parent.Str.To_Integer(uLI.childNodes[1].childNodes[3].textContent);
    var dAmount = this._Parent.Str.To_Integer(uLI.childNodes[3].value,0);
    }
   else if (this._Parent.Ikariam.Is_Version('0.4.3'))
    {
    var oAmount = this._Parent.Str.To_Integer(uLI.childNodes[3].textContent);
    var dAmount = this._Parent.Str.To_Integer(uLI.childNodes[13].value,0);
    }
   else
    {
    var oAmount = this._Parent.Str.To_Integer(uLI.childNodes[3].textContent);
    if (dType == 'deployFleet')
     {
     var dAmount = this._Parent.Str.To_Integer(uLI.childNodes[7].value,0);
     }
    else
     {
     var dAmount = this._Parent.Str.To_Integer(uLI.childNodes[9].value,0);
     }
    }
   
   if (city.units[unit_id] == undefined) city.units[unit_id] = {};
   city.units[unit_id].count = oAmount - dAmount;
   this._Parent.Log.Add(unit_id+": oAmount="+oAmount+" dAmount="+dAmount);
   }
  }
 
 setViewRqTime('finances');
 setViewRqTime('militaryAdvisorMilitaryMovements');
 this._Parent.DB.Save();
 };
 
function myTimeCounterF()
 {
 var currenttime = new Date().getTime();
 var cs = EmpireBoard.DOM.Get_Nodes("//font[contains(@id, 'mytimecounter')]");
 for (var i = 0; i < cs.snapshotLength; i++)
  {
  var c = cs.snapshotItem(i);
  var abstime = Math.round(c.getAttribute('counter'));
  hdata = (abstime - currenttime) / 1000;
  if (hdata > 0)
   {
   var s = "";
   s = EmpireBoard.Str.FormatRemainingTime(hdata*1000);
   c.innerHTML = s;
   }
  else 
   {
   c.innerHTML = "-";
   }
  }
 }

function realtimeFactDisplayF()
 {
 var currenttime = new Date().getTime();
 var counters = EmpireBoard.DOM.Get_Nodes("//font[contains(@id, 'myresourcecounter')]");
 for(var i=0; i < counters.snapshotLength; i++)
  {
  var c = counters.snapshotItem(i);
  if (c.color != "#ff0000")
   {
   var arr = c.getAttribute('counter').split(",");
   var startTime = arr[0];
   var startAmount = parseFloat(arr[1]);
   var factPerHour = parseFloat(arr[2]);
   var maxAmount = arr[3];

   var currAmount = getCurrentResourceAmount(currenttime, startTime, startAmount, factPerHour);

   if ((maxAmount != '-') && (currAmount >= maxAmount))
    {
    c.innerHTML = EmpireBoard.Str.FormatBigNumber(maxAmount);
    c.color = "#ff0000";
    }
   else
    {
    c.innerHTML = EmpireBoard.Str.FormatBigNumber(currAmount);
    //+' ('+Math.floor((currenttime-startTime)/1000)+' s)'
    }
   }
  }
 return (counters.snapshotLength > 0);
 }

EmpireBoard.Log =
 {
 _Parent: null,
 _Enabled: false
 };
 
EmpireBoard.Log.Init = function(parent)
 {
 this._Parent = parent;
 };
 
EmpireBoard.Log.Add = function(msg)
 {
 if (this._Enabled == true)
  {
  GM_log(msg);
  }
 };

EmpireBoard.Updater =
 {
 _Parent:    null,
 _ScriptURL:    '',
 _availableVersion:  0
 };
 
EmpireBoard.Updater.Init = function(parent)
 {
 this._Parent = parent;
 };
 
// CallBackFct function receive available version number (or null value if failed) as argument
EmpireBoard.Updater.Check = function(ScriptURL, CallBackFct)
 {
 this._availableVersion  = 0;
 this._ScriptURL    = ScriptURL;
 var self = this;
 
 GM_xmlhttpRequest({
  method:    "GET",
  url:    ScriptURL,
  headers:   { Accept:"text/javascript; charset=UTF-8" },
  overrideMimeType: "application/javascript; charset=UTF-8",
  onload:    function(response) { self._ParseScript(response, CallBackFct); }
  });
 };
 
EmpireBoard.Updater._ParseScript = function(response, CallBackFct)
 {
 var availableVersion = 0;
 
 if (response.status == 200)
  {
  var resReg = /@version\s+(\d+)/.exec(response.responseText);
  if (resReg != null)
   {
   availableVersion = resReg[1];
   }
  }
  
 this._availableVersion = availableVersion;
 
 if (typeof CallBackFct == 'function')
  {
  CallBackFct.call(this._Parent, availableVersion, response);
  }
 };

// the tooltip object
EmpireBoard.Tooltip =
 {
 // setup properties of tooltip object
 _Parent:     null,
 id:       "TooltipContainer",
 idParent:     "",
 offsetx:     10,
 offsety:     10,
 _x:       0,
 _y:       0,
 _tooltipElement:   null,
 _saveonmouseover:   null
 };
 
EmpireBoard.Tooltip.Init = function(parent, IdName, IdParent)
 {
 if (parent != undefined) this._Parent = parent;
 
 if (IdName != undefined) this.id    = IdName;
 if (IdParent != undefined) this.idParent  = IdParent;
 };
 
EmpireBoard.Tooltip.CreateContainer = function(IdName, IdParent)
 {
 if (IdName != undefined) this.id    = IdName;
 if (IdParent != undefined) this.idParent  = IdParent;
 
 // create tooltip DIV
 var body = document.getElementById(this.idParent);
 var tooltipdiv = document.createElement('div');
 tooltipdiv.id = this.id;
 tooltipdiv.innerHTML = "";
 tooltipdiv.style.visibility = 'hidden';
 body.appendChild(tooltipdiv);
 };

EmpireBoard.Tooltip.innerHTML = function (Content, Title)
 {
 if (Content == undefined || Content == "")
  {
  return "";
  }
 else
  {
  var innerHTML = '';
  if (Title == undefined || Title == "")
   {
   Title = "";
   }
  else Title = "<div class=TTTitle>"+Title+"</div>";
  
  if (this._Parent.Intl.LangDir() == "rtl")
   {
   innerHTML = "<div dir=rtl class='TTContent RtoL'>"+Title+Content+"</div>";
   }
  else
   {
   innerHTML = "<div class=TTContent>"+Title+Content+"</div>";
   }
  
  return innerHTML;
  }
 };

EmpireBoard.Tooltip.show = function (htmlelement)
 {
 if (document.getElementById)
  {
  this._tooltipElement = document.getElementById(this.id);
  }
 else if ( document.all )
  {
  this._tooltipElement = document.all[this.id].style;
  }
 
 this._tooltipElement.innerHTML = htmlelement;

 this.moveTo(this._x + this.offsetx , this._y + this.offsety);

 if (this._tooltipElement.style)
  {
  this._tooltipElement.style.visibility ="visible";
  }
 else
  {
  this._tooltipElement.visibility = "visible";
  }
  
 return false;
 };

EmpireBoard.Tooltip.hide = function(e)
 {
 if (this._tooltipElement.style)
  {
  this._tooltipElement.style.visibility ="hidden";
  }
 else
  {
  this._tooltipElement.visibility = "hidden";
  }
 };

// Moves the tooltip element
EmpireBoard.Tooltip.mouseMove = function(e)
 {
 // we don't use "this" because this method is assign to an event of document
 // and so is dereferenced
 if (e == undefined) e = event;

 if (e.pageX != undefined)
  { // gecko, konqueror,
  this._x = e.pageX;
  this._y = e.pageY;
  }
 else if (event != undefined && event.x != undefined && event.clientX == undefined)
  { // ie4 ?
  this._x = event.x;
  this._y = event.y;
  }
 else if (e.clientX != undefined )
  { // IE6,  IE7, IE5.5
  if (document.documentElement)
   {
   this._x = e.clientX + ( document.documentElement.scrollLeft || document.body.scrollLeft);
   this._y = e.clientY + ( document.documentElement.scrollTop || document.body.scrollTop);
   }
  else
   {
   this._x = e.clientX + document.body.scrollLeft;
   this._y = e.clientY + document.body.scrollTop;
   }
  /*
  }
  else if(event != undefined && event.x != undefined)
  { // IE6,  IE7, IE5.5
  tooltip.x = event.x + ( document.documentElement.scrollLeft || document.body.scrollLeft);
  tooltip.y = event.y + ( document.documentElement.scrollTop || document.body.scrollTop);
  */
  }
 else
  {
  this._x = 0;
  this._y = 0;
  }

 var MovX = this._x + this.offsetx;
 if ((MovX+this.GetDivW(this._tooltipElement)) > (this.GetClientW() + this.GetScrollX() - 2))
  {
  MovX = this.GetClientW() + this.GetScrollX() - 2 - this.GetDivW(this._tooltipElement);
  }
 var MovY = this._y - this.offsety - this.GetDivH(this._tooltipElement);
 if (MovY < (this.GetScrollY() + 2))
  {
  MovY = this._y + this.offsety;
  }
 
 //window.status = "Scroll="+this.GetScrollX()+","+this.GetScrollY();
 //window.status = "Client="+this.GetClientW()+","+this.GetClientH();

 this.moveTo(MovX , MovY);
 };
 
EmpireBoard.Tooltip.GetDivH = function(el)
 {
 return (el ? (el.offsetHeight || el.style.pixelHeight || 0) : 0);
 };
 
EmpireBoard.Tooltip.GetDivW = function(el)
 {
 return (el ? (el.offsetWidth || el.style.pixelWidth || 0) : 0);
 };

EmpireBoard.Tooltip.GetClientW = function()
 {
 var tt_db = document.documentElement || document.body ||
    (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
    : null);
 return (document.body && (typeof(document.body.clientWidth) != 'undefined') ? document.body.clientWidth
   : (typeof(window.innerWidth) != 'undefined') ? window.innerWidth
   : tt_db ? (tt_db.clientWidth || 0)
   : 0);
 };

EmpireBoard.Tooltip.GetClientH = function()
 {
 var tt_db = document.documentElement || document.body ||
    (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
    : null);
 // Exactly this order seems to yield correct values in all major browsers
 return (document.body && (typeof(document.body.clientHeight) != 'undefined') ? document.body.clientHeight
   : (typeof(window.innerHeight) != 'undefined') ? window.innerHeight
   : tt_db ? (tt_db.clientHeight || 0)
   : 0);
 };

EmpireBoard.Tooltip.GetScrollX = function()
 {
 var tt_db = document.documentElement || document.body ||
    (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
    : null);
 return (window.pageXOffset || (tt_db ? (tt_db.scrollLeft || 0) : 0));
 };
 
EmpireBoard.Tooltip.GetScrollY = function()
 {
 var tt_db = document.documentElement || document.body ||
    (document.getElementsByTagName ? document.getElementsByTagName("body")[0]
    : null);
 return (window.pageYOffset || (tt_db ? (tt_db.scrollTop || 0) : 0));
 };

// Move the tooltip element
EmpireBoard.Tooltip.moveTo = function(xL,yL)
 {
 if (this._tooltipElement.style)
  {
  this._tooltipElement.style.left = xL +"px";
  this._tooltipElement.style.top = yL +"px";
  }
 else
  {
  this._tooltipElement.left = xL;
  this._tooltipElement.top = yL;
  }
 };

// Manage translation
EmpireBoard.Intl =
 {
 _Parent:     null,
 _AppName:     'AnyApp',
 _LangCode:     '',
 _LangDir:     'ltr'
 };
 
EmpireBoard.Intl.Init = function(parent, AppName)
 {
 this._Parent = parent;
 if (AppName != undefined) this._AppName = AppName;
 };

// Get text to translate
EmpireBoard.Intl.TT = function(stringName, contextName, stringValues, appName)
 {
 if ((stringName != undefined) && (stringName != ''))
  {
  if ((contextName == undefined) || (contextName == '')) contextName = 'misc';
  if ((appName == undefined) || (appName == '')) appName = this._AppName;
  
  var stringResult = stringName;
  switch(contextName)
   {
   case 'buildings':
    if ((buildings[stringName] != undefined) && (buildings[stringName][0] != undefined))
     stringResult = buildings[stringName][0];
    break;
   
   case 'buildings_short':
    if ((buildings[stringName] != undefined) && (buildings[stringName][1] != undefined))
     stringResult = buildings[stringName][1];
    break;
   
   case 'army_units':
    if (config["unitnames"] == undefined)
     {
     
     }
    else if (config["unitnames"][stringName] != undefined)
     {
     stringResult = config["unitnames"][stringName];
     }
    else if (config["unitnames"]['unit '+stringName] != undefined)
     {
     stringResult = config["unitnames"]['unit '+stringName];
     }
    break;
   
   case 'fleet_units':
    if (config["unitnames"] == undefined)
     {
     
     }
    else if (config["unitnames"][stringName] != undefined)
     {
     stringResult = config["unitnames"][stringName];
     }
    else if (config["unitnames"]['unit '+stringName] != undefined)
     {
     stringResult = config["unitnames"]['unit '+stringName];
     }
    break;
   
   case 'misc':
   default:
    if (texts[stringName] != undefined)
     stringResult = texts[stringName];
    break;
   }
  
  if ((stringValues != undefined) && (stringValues != ''))
   {
   stringResult = this._Parent.Str.ValuesReplace(stringResult, stringValues);
   }
   
  return this._Parent.Str.Trim(stringResult);
  }
 else return '';
 };

EmpireBoard.Intl.Languages = function()
 {
 var languages = {
  "": "Automatic",
  ae: "العربية",
  bg: "Bulgarian",
  cn: "Chinese",
  tw: "Chinese (traditional)",
  cz: "Czech",
  dk: "Danish",
  de: "Deutsch",
  nl: "Dutch",
  en: "English",
  es: "Espanol",
  fi: "Finnish",
  fr: "Français",
  gr: "Greek",
  il: "Hebrew",
  it: "Italiano",
  lv: "Latvian",
  hu: "Magyar",
  pl: "Polish",
  pt: "Portuguese",
  ro: "Romanian",
  ru: "Russian",
  rs: "Serbian",
  sk: "Slovak",
  sl: "Slovenian",
  se: "Swedish",
  tr: "Turkish",
  ua: "Ukrainian",
  vn: "Vietnamese"
  };
 
 return languages;
 };

EmpireBoard.Intl.SetLanguage = function(LangCode)
 {
 if (LangCode == undefined)
  {
  LangCode = '';
  }
  
 if (LangCode == '')
  {
  LangCode = this._Parent.Ikariam.Language();
  }
 
 if (LangCode == '')
  {
  var Host = this._Parent.Ikariam.Host();
  var arr = Host.split("\.");
  LangCode = arr[arr.length - 1];
  if (LangCode == "com" && arr.length == 4) 
   {
   //for example: http://s1.ba.ikariam.com
   LangCode = arr[1];
   }
   
  if ((LangCode == 'com') || (LangCode == 'org') || (LangCode == 'net')) LangCode = 'en';
  }
 
 if (LangCode == '')
  {
  LangCode = 'en';
  }
 
 this._Parent.Log.Add('Set language code: '+LangCode);
 
 this._LangCode = LangCode;
 };
 
EmpireBoard.Intl.LangCode = function()
 {
 if ((this._LangCode == undefined) || (this._LangCode == null) || (this._LangCode == ''))
  {
  this.SetLanguage('');
  }
 
 return this._LangCode;
 };

EmpireBoard.Intl.LangDir = function()
 {
 if ((this._LangDir == undefined) || (this._LangDir == null) || (this._LangDir == ''))
  {
  this._LangDir = 'ltr';
  }
 // Todo: detect like http://userscripts.org/scripts/diff/87680/326530
 
 return this._LangDir;
 };

EmpireBoard.Intl.Load_LocalizedTexts = function()
 {
 switch(this._LangCode)
  {
  case 'ae':
  case 'eg':
  case 'sa':
   this.Load_Texts_AE();
   break;
  
  case 'bg':
   this.Load_Texts_BG();
   break;
  
  case 'cn':
   this.Load_Texts_CN();
   break;
  
  case 'cz':
   this.Load_Texts_CZ();
   break;
  
  case 'de':
   this.Load_Texts_DE();
   break;
  
  case 'dk':
   this.Load_Texts_DK();
   break;
  
  case 'es':
  case 'ar':
  case 'mx':
  case 'cl':
  case 'co':
  case 've':
  case 'pe':
   this.Load_Texts_ES();
   break;
  
  case 'fi':
   this.Load_Texts_FI();
   break;
  
  case 'fr':
   this.Load_Texts_FR();
   break;
  
  case 'gr':
   this.Load_Texts_GR();
   break;
  
  case 'hu':
   this.Load_Texts_HU();
   break;
  
  case 'il':
   this.Load_Texts_IL();
   break;
   
  case 'ir':
   // Todo
   this.Load_Texts_PK();
   break;
  
  case 'it':
   this.Load_Texts_IT();
   break;
  
  case 'lv':
   this.Load_Texts_LV();
   break;
  
  case 'nl':
   this.Load_Texts_NL();
   break;
  
  case 'pk':
   // Todo
   this.Load_Texts_PK();
   break;
   
  case 'pl':
   this.Load_Texts_PL();
   break;
  
  case 'pt':
  case 'br':
   this.Load_Texts_PT();
   break;
  
  case 'ro':
   this.Load_Texts_RO();
   break;
  
  case 'rs':
   this.Load_Texts_RS();
   break;
   
  case 'ru':
   this.Load_Texts_RU();
   break;
  
  case 'se':
   this.Load_Texts_SE();
   break;
  
  case 'sk':
   this.Load_Texts_SK();
   break;
  
  case 'sl':
  case 'si':
   this.Load_Texts_SL();
   break;
  
  case 'tr':
   this.Load_Texts_TR();
   break;
  
  case 'tw':
  case 'hk':
   this.Load_Texts_TW();
   break;
  
  case 'ua':
   this.Load_Texts_UA();
   break;
  
  case 'vn':
   this.Load_Texts_VN();
   break;
  
  case 'ba':
  case 'yu':
   // Todo
  case 'by':
   // Todo
  case 'ee':
   // Todo
  case 'id':
   // Todo
  case 'lt':
   // Todo
  case 'ph':
   // Todo
  
  case 'en':
  case 'us':
  case 'uk':
  case 'org':
  case 'com':
  case 'net':
  default:
   this.Load_Texts_EN();
   break;
  }
  
 if (langtype == "rf")
  {
  this._LangDir = 'rtl';
  }
 else
  {
  this._LangDir = 'ltr';
  }
 };

EmpireBoard.Intl.Load_Texts_EN = function()
 {
 langtype = ""; // Set "rf" for Rigth-to-Left languages, or leave blank
 // Set short building name into second field 
 buildings = {
  "townHall"   : ["Town Hall", "T. Hall"],
  "temple"   : ["Temple", "Temple"],
  "academy"   : ["Academy", "Academy"],
  "port"    : ["Trading Port", "Port"],
  "shipyard"   : ["Shipyard", "Shipyard"],
  "warehouse"   : ["Warehouse", "Warehouse"],
  "dump"    : ["Dump", "Dump"],
  "wall"    : ["Wall", "Wall"],
  "tavern"   : ["Tavern", "Tavern"],
  "museum"   : ["Museum", "Museum"],
  "palace"   : ["Palace", "Palace"],
  "palaceColony"  : ["Governor's Residence", "Governor"],
  "embassy"   : ["Embassy", "Embassy"],
  "branchOffice"  : ["Trading Post", "Trading"],
  "safehouse"   : ["Hideout", "Hideout"],
  "barracks"   : ["Barracks", "Barracks"],
  "workshop"   : ["Workshop", "Workshop"],
  "carpentering"  : ["Carpenter", "Carpenter"],
  "forester"   : ["Forester", "Forester"],
  "stonemason"  : ["Stone Mason", "Mason"],
  "glassblowing"  : ["Glass Blowing", "Blowing"],
  "winegrower"  : ["Wine Grower", "Grower"],
  "alchemist"   : ["Alchemist", "Alchemist"],
  "architect"   : ["Architect", "Architect"],
  "optician"   : ["Optician", "Optician"],
  "vineyard"   : ["Vine Yard", "Yard"],
  "fireworker"  : ["Fireworker", "Fireworker"]
  };
 texts = {
  "Upkeep"     : "Upkeep",
  "Growth"     : "Growth",
  "Research"     : "Research",
  "cityName"     : "Cities",
  "currentlyBuilding"   : "Currently building",
  "summary"     : "Summary:",
  "hide_settings"    : "Hide settings",
  "show_settings"    : "Show settings",
  "Population"    : "Population",
  "finishedBuilding"   : "Finished building",
  "Incomes"     : "Incomes",
  "Trading"     : "Trading",
  "Wood"      : "Wood",
  "Wine"      : "Wine",
  "Marble"     : "Marble",
  "Crystal"     : "Crystal",
  "Sulfur"     : "Sulfur"
  };
 };

EmpireBoard.Intl.Load_Texts_AE = function()
 {
 //by wa7d and Moshakes 
 langtype = "rf";
 buildings = {
  "townHall" : ["البلدية", "البلدية"],
  "temple" : ["مركز", "مركز"],
  "academy" : ["الاكاديمية", "الاكاديمية"],
  "port" : ["المرفأ", "المرفأ"],
  "shipyard" : ["حوض السفن", "حوض السفن"],
  "warehouse" : ["المخزن", "المخزن"],
  "wall" : ["السور", "السور"],
  "tavern" : ["الاستراحة", "الاستراحة"],
  "museum" : ["المتحف", "المتحف"],
  "palace" : ["القصر", "القصر"],
  "palaceColony" : ["قائم مقام", "قائم مقام"],
  "embassy" : ["السفارة", "السفارة"],
  "branchOffice" : ["السوق", "السوق"],
  "safehouse" : ["المخبأ", "المخبأ"],
  "barracks" : ["الثكنة", "الثكنة"],
  "workshop" : ["المختبر", "المختبر"],
  "carpentering" : ["انخفاض في تكلفة الخشب", "النجار"],
  "forester" : ["إنتاج الخشب", "الحطاب"],
  "stonemason" : ["إنتاج الرخام", "الحجار"],
  "glassblowing" : ["نافخ الزجاج", "نافخ الزجاج"],
  "winegrower" : ["إنتاج العنب", "مزرعة"],
  "alchemist" : ["الكيمائي", "الكيمائي"],
  "architect" : ["انخفاض في تكلفة الرخام", "المهندس"],
  "optician" : ["انخفاض في تكلفة البلور", "صانع البصريات"],
  "vineyard" : ["تخفيض تكلفة العنب", "معصرة"],
  "fireworker" : ["عامل النار", "البارود"] 
  };
 texts = {
  "Upkeep":"التكاليف",
  "cityName": "المدينة",
  "currentlyBuilding": "أعمال بناء",
  "summary": "الإجمالي",
  "hide_settings": "إخفاء الخيارات",
  "show_settings": "إظهار الخيارات",
  "Population": "السكان",
  "Research": "الابحاث",
  "finishedBuilding": "مباني منجزة","Incomes":"الذهب","Trading":"التجارة",
  "Wood": "الخشب", "Wine": "العنب", "Marble": "الرخام", "Crystal": "البلور", "Sulfur": "الكبريت" 
  };
 };

EmpireBoard.Intl.Load_Texts_BG = function()
 {
 //Bulgarian translation by dsimeonov
 langtype = "";
 buildings = {
  "townHall" : ["Кметство", "Кметство"],
  "temple" : ["Храм", "Храм"],
  "academy" : ["Академия", "Академия"],
  "port" : ["Пристанище", "Пристанище"],
  "shipyard" : ["Корабостроителница", "Корабостроителница"],
  "warehouse" : ["Склад", "Склад"],
  "wall" : ["Градска стена", "Градска стена"],
  "tavern" : ["Кръчма", "Кръчма"],
  "museum" : ["Музей", "Музей"],
  "palace" : ["Дворец", "Дворец"],
  "palaceColony" : ["Губернаторска резиденция", "Губернаторска резиденция"],
  "embassy" : ["Посолство", "Посолство"],
  "branchOffice" : ["Пазар", "Пазар"],
  "safehouse" : ["Скривалище", "Скривалище"],
  "barracks" : ["Казарма", "Казарма"],
  "workshop" : ["Работилница", "Работилница"],
  "carpentering" : ["Дърводелец", "Дърводелец"],
  "forester" : ["Горска къща", "Горска къща"],
  "stonemason" : ["Каменоделна", "Каменоделна"],
  "glassblowing" : ["Стъклодув", "Стъклодув"],
  "winegrower" : ["Винар", "Винар"],
  "alchemist" : ["Кула на Алхимика", "Кула на Алхимика"],
  "architect" : ["Офис на Архитекта", "Офис на Архитекта"],
  "optician" : ["Оптика", "Оптика"],
  "vineyard" : ["Винена преса", "Винена преса"],
  "fireworker" : ["Тестова зона за фойерверки", "Тестова зона за фойерверки"]
  };
 texts = {
  "cityName" : "Град",
  "currentlyBuilding" : "В процес на разширение",
  "summary" : "Общо",
  "hide_settings" : "Скрий",
  "show_settings" : "Покажи",
  "Population" : "Популация",
  "finishedBuilding" : "Завършена",
  "Incomes" : "Доходи",
  "Trading" : "Търговия",
  "Wood" : "Дърво",
  "Wine" : "Вино",
  "Marble" : "Мрамор",
  "Crystal" : "Кристал",
  "Sulfur" : "Сяра"
  };
 };

EmpireBoard.Intl.Load_Texts_CN = function()
 {
 //chinese translation, thank Alphasong
 langtype = "";
 buildings = {
  "townHall" : ["市政厅", "市政厅"],
  "temple"      : ["Temple", "Temple"],
  "academy" : ["学院", "学院"],
  "port" : ["港口", "港口"],
  "shipyard" : ["船坞", "船坞"],
  "warehouse" : ["仓库", "仓库"],
  "wall" : ["城墙", "城墙"],
  "tavern" : ["酒馆", "酒馆"],
  "museum" : ["博物馆", "博物馆"],
  "palace" : ["皇宫", "皇宫"],
  "palaceColony" : ["总督府", "总督府"],
  "embassy" : ["使馆", "使馆"],
  "branchOffice" : ["市场", "市场"],
  "safehouse" : ["藏身处", "藏身处"],
  "barracks" : ["兵营", "兵营"],
  "workshop" : ["兵工厂", "兵工厂"],
  "carpentering" : ["木匠所", "木匠所r"],
  "forester" : ["林务官宅", "林务官宅"],
  "stonemason" : ["石匠屋", "石匠屋"],
  "glassblowing" : ["玻璃吹制厂", "玻璃吹制厂"],
  "winegrower" : ["葡萄种植园", "葡萄种植园"],
  "alchemist" : ["炼金塔", "炼金塔"],
  "architect" : ["建筑公署", "建筑公署"],
  "optician" : ["配镜商馆", "配镜商馆"],
  "vineyard" : ["藏酒窖", "藏酒窖"],
  "fireworker" : ["烟火实验场", "烟火实验场"]
  };
 texts = {
  "cityName": "城市",
  "currentlyBuilding": "正在建造",
  "summary": "总计",
  "hide_settings": "隐藏设置", "show_settings": "显示设置",
  "Population": "人口",
  "finishedBuilding": "建造完成","Incomes":"收入","Trading":"交易",
  "Wood": "木材", "Wine": "葡萄", "Marble": "大理石", "Crystal": "水晶", "Sulfur": "硫磺"
  };
 };

EmpireBoard.Intl.Load_Texts_CZ = function()
 {
 //Czech translation , thank Tetraedron, Assassin
 langtype = "";
 buildings = {
  "townHall"     : ["Městská radnice", "Radnice"],
  "temple"      : ["Temple", "Temple"],
  "academy"      : ["Akademie", "Akademie"],
  "port"         : ["Obchodní přístav", "Přístav"],
  "shipyard"     : ["Loděnice", "Loděnice"],
  "warehouse"    : ["Sklad", "Sklad"],
  "wall"         : ["Městská zeď", "Zeď"],
  "tavern"       : ["Hostinec", "Hostinec"],
  "museum"       : ["Muzeum", "Muzeum"],
  "palace"       : ["Palác", "Palác"],
  "palaceColony" : ["Guvernérova rezidence", "Guvernér"],
  "embassy"      : ["Ambasáda", "Ambasáda"],
  "branchOffice" : ["Tržiště", "Tržiště"],
  "safehouse"    : ["Úkryt", "Úkryt"],
  "barracks"     : ["Kasárna", "Kasárna"],
  "workshop"     : ["Dílna", "Dílna"],
  "carpentering" : ["Truhlárna", "Truhlárna"],
  "forester"     : ["Hájovna", "Hájovna"],
  "stonemason"   : ["Kameník", "Kameník"],
  "glassblowing" : ["Sklárna", "Sklárna"],
  "winegrower"   : ["Vinařství", "Vinařství"],
  "alchemist"    : ["Věž alchymisty", "Věž alchymisty"],
  "architect"    : ["Pracovna architekta", "Architekt"],
  "optician"     : ["Optik", "Optik"],
  "vineyard"     : ["Vinný sklep", "Vinný sklep"],
  "fireworker"   : ["Zkušebna ohňostroje", "Zkušebna ohňostroje"]
  };
 texts = {
  "cityName"          : "Město",
  "currentlyBuilding" : "Staví se",
  "summary"           : "Celkem",
  "hide_settings"     : "Skrýt nastavení",
  "show_settings"     : "Ukázat nastavení",
  "Population"        : "Populace",
  "finishedBuilding"  : "Dokončené stavby",
  "Incomes"           : "Příjmy",
  "Trading"           : "Obchod",
  "Wood"              : "Dřevo",
  "Wine"              : "Víno",
  "Marble"            : "Mramor",
  "Crystal"           : "Sklo",
  "Sulfur"            : "Síra"
  };
 };

EmpireBoard.Intl.Load_Texts_DK = function()
 {
 // Danish  translation, thank to LGO
 langtype = "";
 buildings = {
  "townHall" : ["Rådhus", "Rådhus"],
  "temple" : ["Temple", "Tempel"],
  "academy" : ["Akademi", "Akademi"],
  "port" : ["Handelshavn", "Havn"],
  "shipyard" : ["Skipsværft", "Værft"],
  "warehouse" : ["Lagerbygning", "Lager"],
  "wall" : ["Bymur", "Mur"],
  "tavern" : ["Værtshus", "Kro"],
  "museum" : ["Museum", "Museum"],
  "palace" : ["Palads", "Palads"],
  "palaceColony" : ["Guvernørens residens", "Guvernør"],
  "embassy" : ["Ambassade", "Ambassade"],
  "branchOffice" : ["Handelsstation", "Handel"],
  "safehouse" : ["Skjulested", "Spion"],
  "barracks" : ["Kaserne", "Kaserne"],
  "workshop" : ["Værksted", "Værksted"],
  "carpentering" : ["Tømrer", "Tømrer"],
  "forester" : ["Skovfodged", "Skov"],
  "stonemason" : ["Stenhugger", "Sten"],
  "glassblowing" : ["Glaspuster", "Glas"],
  "winegrower" : ["Vinplanter", "Vin"],
  "alchemist" : ["Alkymist", "Alkymist"],
  "architect" : ["Arkitekt", "Arkitekt"],
  "optician" : ["Optiker", "Optiker"],
  "vineyard" : ["Vinpresse", "Vin"],
  "fireworker" : ["Fyrværkerifabrik", "Fyrværk."]
  };
 texts = {
  "Upkeep" :"Vedligehold",
  "cityName": "Bynavn",
  "currentlyBuilding": "Bygger nu",
  "summary": "Total",
  "hide_settings": "Gem indstillinger", "show_settings": "Vis indstillinger",
  "Population": "Befolkning",
  "Research": "Forskning",
  "finishedBuilding": "Færdig bygget","Incomes":"Inkomst","Trading":"Handler",
  "Wood": "Træ", "Wine": "Vin", "Marble": "Marmor", "Crystal": "Krystal", "Sulfur": "Svovl"
  }; 
 };

EmpireBoard.Intl.Load_Texts_DE = function()
 {
 //german translation, thanks to Schneppi & xkaaay
 langtype = "";
 buildings = {
  "townHall"      : ["Rathaus", "Rathaus"],
  "temple"   : ["Tempel", "Tempel"],
  "academy"       : ["Akademie", "Akademie"],
  "port"          : ["Handelshafen", "Handelshafen"],
  "shipyard"      : ["Schiffswerft", "Schiffswerft"],
  "warehouse"     : ["Lagerhaus", "Lagerhaus"],
  "dump"    : ["Halde", "Halde"],
  "wall"          : ["Stadtmauer", "Stadtmauer"],
  "tavern"        : ["Taverne", "Taverne"],
  "museum"        : ["Museum", "Museum"],
  "palace"        : ["Palast", "Palast"],
  "palaceColony"  : ["Statthaltersitz", "Statthaltersitz"],
  "embassy"       : ["Botschaft", "Botschaft"],
  "branchOffice"  : ["Kontor", "Kontor"],
  "safehouse"     : ["Versteck", "Versteck"],
  "barracks"      : ["Kaserne", "Kaserne"],
  "workshop"      : ["Erfinderwerkstatt", "Erfinderwerkstatt"],
  "carpentering"  : ["Zimmerei", "Zimmerei"],
  "forester"      : ["Forsthaus", "Forsthaus"],
  "stonemason"    : ["Steinmetz", "Steinmetz"],
  "glassblowing"  : ["Glasbläserei", "Glasbläserei"],
  "winegrower"    : ["Winzerei", "Winzerei"],
  "alchemist"     : ["Alchimistenturm", "Alchimistenturm"],
  "architect"     : ["Architekturbüro", "Architekturbüro"],
  "optician"      : ["Optiker", "Optiker"],
  "vineyard"      : ["Kelterei", "Kelterei"],
  "fireworker"    : ["Feuerwerksplatz", "Feuerwerksplatz"]
  };
 texts = {
  "Upkeep"   : "Unterhalt",
  "cityName"          : "Stadtname",
  "currentlyBuilding" : "Zur Zeit im Bau",
  "summary"           : "Gesamt",
  "hide_settings"     : "Verstecke Optionen",
  "show_settings"     : "Zeige Optionen",
  "Population"        : "Bevölkerung",
  "finishedBuilding"  : "Bau abgeschlossen",
  "Incomes"           : "Einkommen",
  "Trading"           : "Handel",
  "Wood"              : "Baumaterial",
  "Wine"              : "Wein",
  "Marble"            : "Marmor",
  "Crystal"           : "Kristallglas",
  "Sulfur"            : "Schwefel",
  "Growth"    : "Wachstum",
  "Research"    : "Forschung"
  };
 };

EmpireBoard.Intl.Load_Texts_ES = function()
 {
 //Spanish translation, thanks to dragondeluz, graff86, Crom
 langtype = "";
 buildings = {
  "townHall" : ["Intendencia", "Intendencia"],
  "temple"      : ["Templo", "Templo"],
  "academy" : ["Academia", "Academia"],
  "port" : ["Puerto comercial", "Puerto"],
  "shipyard" : ["Astillero", "Astillero"],
  "warehouse" : ["Depósito", "Depósito"],
  "wall" : ["Muralla", "Muralla"],
  "tavern" : ["Taberna", "Taberna"],
  "museum" : ["Museo", "Museo"],
  "palace" : ["Palacio", "Palacio"],
  "palaceColony" : ["Residencia del Gobernador", "Residencia"],
  "embassy" : ["Embajada", "Embajada"],
  "branchOffice" : ["Tienda", "Tienda"],
  "safehouse" : ["Escondite", "Escondite"],
  "barracks" : ["Cuarteles", "Cuarteles"],
  "workshop" : ["Taller de invenciones", "Taller"],
  "carpentering" : ["Carpintería", "Carpintería"],
  "forester" : ["Cabaña del guardabosques", "Cabaña"],
  "stonemason" : ["Cantero", "Cantero"],
  "glassblowing" : ["Soplador de vidrio", "Soplador"],
  "winegrower" : ["Vinicultor", "Vinicultor"],
  "alchemist" : ["Torre del Alquimista", "Alquimista"],
  "architect" : ["Oficina del Arquitecto", "Arquitecto"],
  "optician" : ["Óptico", "Óptico"],
  "vineyard" : ["Prensa de Vino", "Prensa"],
  "fireworker" : ["Área de Pruebas Pirotécnicas", "Pirotécnica"]
  };
 texts = {
  "Upkeep"   :"Costes",
  "cityName": "Ciudad", "currentlyBuilding": "Construyendo", "summary": "Totales",
  "hide_settings": "Ocultar opciones", "show_settings": "Mostrar opciones",
  "Population": "Población",
  "Research": "Investigación",
  "finishedBuilding": "Edificios terminados","Incomes":"Ingresos","Trading":"Comercio",
  "Wood": "Madera",
  "Wine": "Vino",
  "Marble": "Mármol",
  "Crystal": "Cristal",
  "Sulfur": "Azufre"
  }; 
 };

EmpireBoard.Intl.Load_Texts_FI = function()
 {
 //Finnish translation by DeFe
 langtype = "";
 buildings = {
  "townHall" : ["Kaupungintalo", "K. Talo"],
  "temple" : ["Temppeli", "Temppeli"],
  "academy" : ["Akatemia", "Akatemia"],
  "port" : ["Kauppasatama", "Satama"],
  "shipyard" : ["Telakka", "Telakka"],
  "warehouse" : ["Varasto", "Varasto"],
  "dump" : ["Säilytysalue", "Säilytysalue"],
  "wall" : ["Muuri", "Muuri"],
  "tavern" : ["Taverna", "Taverna"],
  "museum" : ["Museo", "Museo"],
  "palace" : ["Palatsi", "Palatsi"],
  "palaceColony" : ["Kuvernöörin asunto", "Kuvernööri"],
  "embassy" : ["Lähetystö", "Lähetystö"],
  "branchOffice" : ["Kauppapaikka", "Kauppapaikka"],
  "safehouse" : ["Piilopaikka", "Piilopaikka"],
  "barracks" : ["Kasarmi", "Kasarmi"],
  "workshop" : ["Paja", "Paja"],
  "carpentering" : ["Puusepän Paja", "Puuseppä"],
  "forester" : ["Metsänhoitaja", "Metsänhoitaja"],
  "stonemason" : ["Kivenhakkaaja", "Kivenhakkaaja"],
  "glassblowing" : ["Lasinpuhaltaja", "Lasinpuhaltaja"],
  "winegrower" : ["Viinitarhuri", "Viinitarhuri"],
  "alchemist" : ["Alkemistin Torni", "Alkemisti"],
  "architect" : ["Arkkitehdin Toimisto", "Arkkitehti"],
  "optician" : ["Optikko", "Optikko"],
  "vineyard" : ["Viinipaino", "Viinipaino"],
  "fireworker" : ["Ilotulite Testialue", "Testialue"] 
  };
 texts = {
  "Upkeep": "Ylläpito",
  "Growth": "Kasvu",
  "cityName": "Kaupungin nimi",
  "currentlyBuilding": "Rakentumassa",
  "summary": "Yhteenveto",
  "hide_settings": "Piilota asetukset",
  "show_settings": "Näytä asetukset",
  "Population": "Populaatio",
  "finishedBuilding": "Rakennus valmis",
  "Incomes":"Tulot",
  "Trading":"kaupankäynti",
  "Wood": "Puu",
  "Wine": "Viini",
  "Marble": "Marmori",
  "Crystal": "Kristalli",
  "Sulfur": "Rikki" 
  }; 
 };

EmpireBoard.Intl.Load_Texts_FR = function()
 {
 //French translation, thanks to Chirel
 langtype = "";
 buildings = {
  "townHall"      : ["Hôtel de ville", "HdV"],
  "temple"      : ["Temple", "Temple"],
  "academy"       : ["Académie", "Ac."],
  "port"          : ["Port commercial", "Port"],
  "shipyard"      : ["Chantier naval", "Chtr"],
  "warehouse"     : ["Entrepôt", "Entp"],
  "dump"    : ["Dépôt", "Dépôt"],
  "wall"          : ["Mur d'enceinte", "Mur"],
  "tavern"        : ["Taverne", "Tvrn"],
  "museum"        : ["Musée", "Msé"],
  "palace"        : ["Palais", "Plais"],
  "palaceColony"  : ["Résidence du Gouverneur", "RdG"],
  "embassy"       : ["Ambassade", "Amb."],
  "branchOffice"  : ["Comptoir", "Cptr"],
  "safehouse"     : ["Cachette", "Ccht"],
  "barracks"      : ["Caserne", "Csrn"],
  "workshop"    : ["Atelier", "Atlr"],
  "carpentering" : ["Menuisier","Men."],
  "forester" : ["Maison forestière","Frst"],
  "stonemason" : ["Tailleur de pierres","Tail."],
  "glassblowing" : ["Verrier","Vrr"],
  "winegrower" : ["Pressoir à vin","Prsr"],
  "alchemist" : ["Tour des alchimistes","Alch."],
  "architect" : ["Bureau de l`architecte","Arch."],
  "optician" : ["Opticien","Opt."],
  "vineyard" : ["Cave à vin","Cave"],
  "fireworker" : ["Zone de test des artificiers","Artf"]
  };
 texts = {
  "Upkeep"     : "Coûts",
  "Growth"     : "Croissance",
  "cityName": "Villes",
  "currentlyBuilding": "Construction en cours",
  "summary": "Total",
  "hide_settings": "Cacher les options",
  "show_settings": "Voir les options",
  "Population": "Population",
  "Research": "Recherche",
  "finishedBuilding": "Construction terminée",
  "Incomes":"Revenus",
  "Trading":"Commerce",
  "Wood": "Bois",
  "Wine": "Vin",
  "Marble": "Marbre",
  "Crystal": "Cristal",
  "Sulfur": "Soufre"
  };
 };

EmpireBoard.Intl.Load_Texts_GR = function()
 {
 //greek translation, thanks to panospap and Napoleon I
 langtype = "";  
 buildings = {  
  "townHall" : ["Δημαρχείο", "Δημαρχείο"],  
  "temple"      : ["Ναός", "Ναός"],  
  "academy" : ["Ακαδημία", "Ακαδημία"],  
  "port" : ["Εμπορικός Λιμένας", "Εμπορικός Λιμένας"],  
  "shipyard" : ["Ναυπηγείο", "Ναυπηγείο"],  
  "warehouse" : ["Αποθήκη Εμπορευμάτων", "Αποθήκη Εμπορευμάτων"], 
  "dump"           : ["Αλάνα", "Αλάνα"],
  "wall" : ["Τείχη της Πόλης", "Τείχη της Πόλης"],  
  "tavern" : ["Ταβέρνα", "Ταβέρνα"],  
  "museum" : ["Μουσείο", "Μουσείο"],  
  "palace" : ["Παλάτι", "Παλάτι"],  
  "palaceColony" : ["Η Κατοικία του Κυβερνήτη", "Η Κατοικία του Κυβερνήτη"],  
  "embassy" : ["Πρεσβεία", "Πρεσβεία"],  
  "branchOffice" : ["Θέση Εμπορικών Συναλλαγών", "Θέση Εμπορικών Συναλλαγών"],  
  "safehouse" : ["Κρησφύγετο", "Κρησφύγετο"],  
  "barracks" : ["Στρατώνες", "Στρατώνες"],  
  "workshop" : ["Εργαστήριο", "Εργαστήριο"],  
  "carpentering" : ["Ξυλουργός", "Ξυλουργός"],  
  "forester" : ["Σπίτι Ξυλοκόπου", "Σπίτι Ξυλοκόπου"],  
  "stonemason" : ["Κτίριο Λατομείου", "Κτίριο Λατομείου"],  
  "glassblowing" : ["Υαλουργείο", "Υαλουργείο"],  
  "winegrower" : ["Αποστακτήριο", "Αποστακτήριο"],  
  "alchemist" : ["Πύργος Αλχημιστή", "Πύργος Αλχημιστή"],  
  "architect" : ["Αρχιτεκτονικό Γραφείο", "Αρχιτεκτονικό Γραφείο"],  
  "optician" : ["Οπτικός", "Οπτικός"],  
  "vineyard" : ["Πιεστήριο Σταφυλιού", "Πιεστήριο Σταφυλιού"],  
  "fireworker" : ["Περιοχή Δοκιμών Πυροτεχνημάτων", "Περιοχή Δοκιμών Πυροτεχνημάτων"]  
  };  
 texts = {  
  "Upkeep":"Συντήρηση",
  "Growth"         : "Ικανοποίηση", 
  "cityName": "Όνομα Πόλης",
  "currentlyBuilding": "Αναβαθμίζετε τώρα",
  "summary": "Σύνολο",  
  "hide_settings": "Κρύψε ρυθμίσεις",
  "show_settings": "Εμφάνισε ρυθμίσεις",  
  "Population": "Πληθυσμός",  
  "Research": "Έρευνες",  
  "finishedBuilding": "Ολοκληρωμένη Αναβαθμιση",
  "Incomes":"Εισοδήματα",
  "Trading":"Εμπόριο",  
  "Wood": "Οικοδομικό Υλικό",
  "Wine": "Κρασί",
  "Marble": "Μάρμαρο",
  "Crystal": "Κρύσταλλο",
  "Sulfur": "Θείο"  
  };  
 };

EmpireBoard.Intl.Load_Texts_HU = function()
 {
 // Thank Luzer
 langtype = "";
 buildings = {
  "townHall"      : ["Városháza", "Városháza"],
  "temple"      : ["Templom", "Templom"],
  "academy"       : ["Akadémia", "Akadémia"],
  "port"          : ["Kikötő", "Kikötő"],
  "shipyard"      : ["Hajógyár", "Hajógyár"],
  "warehouse"     : ["Raktár", "Raktár"],
  "wall"          : ["Városfal", "Fal"],
  "tavern"        : ["Fogadó", "Fogadó"],
  "museum"        : ["Múzeum", "Múzeum"],
  "palace"        : ["Palota", "Palota"],
  "palaceColony"  : ["Helytartó", "Helytartó"],
  "embassy"       : ["Nagykövetség", "Nagykövetség"],
  "branchOffice"  : ["Kereskedő", "Kereskedő"],
  "safehouse"     : ["Rejtekhely", "Rejtekhely"],
  "barracks"      : ["Barakk", "Barakk"],
  "workshop"    : ["Műhely", "Műhely"],
  "carpentering" : ["Ácsmester", "Ácsmester"],
  "forester" : ["Erdész", "Erdész"],
  "stonemason" : ["Kőműves", "Kőműves"],
  "glassblowing" : ["Üvegfúvó", "Üvegfúvó"],
  "winegrower" : ["Bortermelő", "Bortermelő"],
  "alchemist" : ["Alkimista", "Alkimista"],
  "architect" : ["Építész", "Építész"],
  "optician" : ["Optikus", "Optikus"],
  "vineyard" : ["Szőlőprés", "Szőlőprés"],
  "fireworker" : ["Tűzszerész", "Tűzszerész"],
  "dump" : ["Nyersanyag depó", "Depó"]
  };
 texts = {
  "Growth" : "Növekedés", 
  "Upkeep"   :"Fenntartás",
  "cityName": "Város neve",
  "currentlyBuilding": "Építés alatt",
  "summary": "Összesen",
  "hide_settings": "Beállítások elrejtése",
  "show_settings": "Beállítások megtekintése",
  "Population": "Lakosság",
  "Research": "Fejlesztés",
  "finishedBuilding": "Finished building",
  "Incomes":"Bevételek",
  "Trading":"Trading",
  "Wood": "Építőanyag",
  "Wine": "Bor",
  "Marble": "Márvány",
  "Crystal": "Kristály",
  "Sulfur": "Kénpor"
  };
 };

EmpireBoard.Intl.Load_Texts_IL = function()
 {
 //hebrew translation, thank Refael Ackermann, Yaakov Rothmann
 langtype = "rf";
 buildings = {
  "townHall"      : ["עיריה", "עיריה"],
  "temple" : ["מקדש", "מקדש"], 
  "academy"       : ["אקדמיה", "אקדמיה"],
  "port"          : ["נמל מסחר", "נמל"],
  "shipyard"      : ["מספנה", "מספנה"],
  "warehouse"     : ["מחסן", "מחסן"],
  "wall"          : ["חומה", "חומה"],
  "tavern"        : ["פונדק", "פונדק"],
  "museum"        : ["מוזאון", "מוזאון"],
  "palace"        : ["ארמון", "ארמון"],
  "palaceColony"  : ["מגורי המושל", "מושל"],
  "embassy"       : ["שגרירות", "שגרירות"],
  "branchOffice"  : ["תחנת סחר", "סחר"],
  "safehouse"     : ["מחבוא", "מחבוא"],
  "barracks"      : ["מגורי חיילים", "חיילים"],
  "workshop"      : ["סדנא", "סדנא"],
  "carpentering"  : ["נגר", "נגר"],
  "forester"      : ["יערן", "יערן"],
  "stonemason"    : ["חרש אבן", "אבן"],
  "glassblowing"  : ["נפח זכוכית", "זכוכית"],
  "winegrower"    : ["יינן", "יינן"],
  "alchemist"     : ["אלכימאי", "אלכימאי"],
  "architect"     : ["ארכיטקט", "ארכיטקט"],
  "optician"      : ["אופטיקאי", "אופטיקאי"],
  "vineyard"      : ["יקב", "יקב"],
  "fireworker"    : ["זיקוקים", "זיקוקים"],
  "dump" : ["מאגר", "לפרק"]
  };
 texts = {
  "Upkeep" : "אחזקה",
  "Growth" : "גידול", 
  "cityName": "שם עיר",
  "currentlyBuilding": "בבניה",
  "summary": "סיכום",
  "hide_settings": "הסתר אפשרויות",
  "show_settings": "הצג אפשרויות",
  "Population": "אוכלוסיה",
  "Research" : "מחקר", 
  "finishedBuilding": "הסתימה בניה",
  "Incomes":"הכנסה",
  "Trading":"סוחר",
  "Wood": "עץ",
  "Wine": "יין",
  "Marble": "שיש",
  "Crystal": "קריסטל",
  "Sulfur": "גופרית"
  };
 };

EmpireBoard.Intl.Load_Texts_IR = function()
 {
 // Todo
 this.Load_Texts_EN();
 langtype = "rf";
 };
 
EmpireBoard.Intl.Load_Texts_IT = function()
 {
 //Italian translation, thanks to Brucee and matteo466
 langtype = "";
 buildings = {
  "townHall" : ["Municipio", "Municipio"],
  "temple"      : ["Temple", "Temple"],
  "academy" : ["Accademia", "Accademia"],
  "port" : ["Porto", "Porto"],
  "shipyard" : ["Cantiere navale", "Cantiere navale"],
  "warehouse" : ["Magazzino", "Magazzino"],
  "wall" : ["Muro", "Muro"],
  "tavern" : ["Taverna", "Taverna"],
  "museum" : ["Museo", "Museo"],
  "palace" : ["Palazzo", "Palazzo"],
  "palaceColony" : ["Governatore", "Governatore"],
  "embassy" : ["Ambasciata", "Ambasciata"],
  "branchOffice" : ["Mercato", "Mercato"],
  "safehouse" : ["Nascondiglio", "Nascondiglio"],
  "barracks" : ["Caserma", "Caserma"],
  "workshop" : ["Officina", "Officina"],
  "carpentering" : ["Carpentiere", "Carpentiere"],
  "forester" : ["Guardaboschi", "Guardaboschi"],
  "stonemason" : ["Tagliapietre", "Tagliapietre"],
  "glassblowing" : ["Vetraio", "Vetraio"],
  "winegrower" : ["Viticoltore", "Viticoltore"],
  "alchemist" : ["Alchimista", "Alchimista"],
  "architect" : ["Architetto", "Architetto"],
  "optician" : ["Ottico", "Ottico"],
  "vineyard" : ["Cantina", "Cantina"],
  "fireworker" : ["Pirotecnico", "Pirotecnico"]
  };
 texts = {
  "cityName": "Città", "currentlyBuilding": "Costruzione in corso", "summary": "Sommario",
  "hide_settings": "Nascondi opzioni", "show_settings": "Mostra opzioni",
  "Population": "Popolazione",
  "finishedBuilding": "Costruzione completata","Incomes":"Saldo oro",
  "Wood": "Legno", "Wine": "Vino", "Marble": "Marmo", "Crystal": "Cristallo", "Sulfur": "Zolfo"
  };
 };

EmpireBoard.Intl.Load_Texts_LV = function()
 {
 //Latvian translation by aezaurs/sauron
 langtype = "";
 buildings = {
  "townHall" : ["Rātsnams", "Rātsnams"],
  "temple" : ["Templis", "Templis"],
  "academy" : ["Akadēmija", "Akadēmija"],
  "port" : ["Osta", "Osta"],
  "shipyard" : ["Kuģu būvētava", "Kuģu būvētava"],
  "warehouse" : ["Noliktava", "Noliktava"],
  "wall" : ["Mūris", "Mūris"],
  "tavern" : ["Krogs", "Krogs"],
  "museum" : ["Muzejs", "Muzejs"],
  "palace" : ["Pils", "Pils"],
  "palaceColony" : ["Gubernātora rezidence", "Gubernātora rezidence"],
  "embassy" : ["Vēstniecība", "Vēstniecība"],
  "branchOffice" : ["Tirgus", "Tirgus"],
  "safehouse" : ["Paslēptuve", "Paslēptuve"],
  "barracks" : ["Kazarmas", "Kazarmas"],
  "workshop" : ["Darbnīca", "Darbnīca"],
  "carpentering" : ["Namdaris", "Namdaris"],
  "forester" : ["Mežsarga māja", "Mežsargs"],
  "stonemason" : ["Akmeņkalis", "Akmeņkalis"],
  "glassblowing" : ["Stikla pūtējs", "Stiklinieks"],
  "winegrower" : ["Vīna audzētājs", "Vīna audzētājs"],
  "alchemist" : ["Alhīmiķa Tornis", "Alhīmiķa Tornis"],
  "architect" : ["Arhitekta Ofiss", "Arhitekts"],
  "optician" : ["Optiķis", "Optiķis"],
  "vineyard" : ["Vīna Gatavotājs", "Vīna Gatavotājs"],
  "fireworker" : ["Uguņošanas izmēģinājumu apgabals", "Uguņošanas apg."]
  };
 texts = {
  "Upkeep" :"Uzturēšana",
  "cityName" : "Pilsēta",
  "currentlyBuilding" : "Šobrīd ceļās",
  "summary" : "Kopā",
  "hide_settings" : "Slēpt iestatījumus",
  "show_settings" : "Rādīt iestatījumus",
  "Population" : "Apdzīvotība",
  "Research": "Izpēte",
  "finishedBuilding" : "Pabeigta celtniecība",
  "Incomes" : "Zelts",
  "Trading" : "Tirzniecība",
  "Wood" : "Koks",
  "Wine" : "Vīns",
  "Marble" : "Marmors",
  "Crystal" : "Kristāls",
  "Sulfur" : "Sērs"
  };
 };

EmpireBoard.Intl.Load_Texts_NL = function()
 {
 //Dutch translation, thanks to cremers
 langtype = "";
 buildings = {
  "townHall" : ["Stadhuis", "Stadhuis"],
  "temple"      : ["Temple", "Temple"],
  "academy" : ["Academie", "Academie"],
  "port" : ["Handelshaven", "Haven"],
  "shipyard" : ["Scheepswerf", "Werf"],
  "warehouse" : ["Opslagplaats", "Opslagplaats"],
  "wall" : ["Stadsmuur", "Muur"],
  "tavern" : ["Taverne", "Taverne"],
  "museum" : ["Museum", "Museum"],
  "palace" : ["Paleis", "Paleis"],
  "palaceColony" : ["Gouverneurswoning", "Gouverneurswoning"],
  "embassy" : ["Ambassade", "Ambassade"],
  "branchOffice" : ["Handelspost", "Handelspost"],
  "safehouse" : ["Schuilplaats", "Schuilplaats"],
  "barracks" : ["Barakken", "Barakken"],
  "workshop" : ["Werkplaats", "Werkplaats"],
  "carpentering" : ["Timmerman", "Timmerman"],
  "forester" : ["Houthakkers Loge", "Houthakkers Loge"],
  "stonemason" : ["Steenhouwer", "Steenhouwer"],
  "glassblowing" : ["Glasblazer", "Glasblazer"],
  "winegrower" : ["Wijnboer", "Wijnboer"],
  "alchemist" : ["De Alchemie Toren", "De Alchemie Toren"],
  "architect" : ["Architectenbureau", "Architectenburea"],
  "optician" : ["Opticien", "Opticien"],
  "vineyard" : ["Wijnpers", "Wijnpers"],
  "fireworker" : ["Vuurwerk Opslag", "Vuurwerk Opslag"]
  };
 texts = {
  "cityName": "Stadsnaam", "currentlyBuilding": "Huidige constructie", "summary": "Opgeteld",
  "hide_settings": "Verberg instellingen", "show_settings": "Instellingen",
  "Population": "Inwoners", "finishedBuilding": "Klaar","Incomes":"Inkomsten","Trading":"Handel",
  "Wood": "Hout", "Wine": "Wijn", "Marble": "Marmer", "Crystal": "Glas", "Sulfur": "Zwavel"
  }; 
 };
 
EmpireBoard.Intl.Load_Texts_PK = function()
 {
 // Todo
 this.Load_Texts_EN();
 langtype = "rf";
 };
 
EmpireBoard.Intl.Load_Texts_PL = function()
 {
 // thanks to Syjamek and Patibar
 langtype = "";
 buildings = {
  "townHall" : ["Ratusz", "Ratusz"],
  "temple"      : ["Świątynia", "Świątynia"],
  "academy" : ["Akademia", "Akademia"],
  "port" : ["Port", "Port"],
  "shipyard" : ["Stocznia", "Stocznia"],
  "warehouse" : ["Magazyn", "Magazyn"],
  "wall" : ["Mur", "Mur"],
  "tavern" : ["Tawerna ", "Tawerna"],
  "museum" : ["Muzeum", "Muzeum"],
  "palace" : ["Pałac", "Pałac"],
  "palaceColony" : ["Rezydencja", "Rezydencja"],
  "embassy" : ["Ambasada", "Ambasada"],
  "branchOffice" : ["Bazar", "Bazar"],
  "safehouse" : ["Kryjówka", "Kryjówka"],
  "barracks" : ["Koszary", "Koszary"],
  "workshop" : ["Warsztat", "Warsztat"],
  "carpentering" : ["Warsztat Cieśli", "Warsztat Cieśli"],
  "forester" : ["Leśniczówka", "Leśniczówka"],
  "stonemason" : ["Kamieniarz", "Kamieniarz"],
  "glassblowing" : ["Huta Szkła", "Huta Szkła"],
  "winegrower" : ["Winnica", "Winnica"],
  "alchemist" : ["Wieża Alchemika", "Wieża Alchemika"],
  "architect" : ["Biuro Architekta", "Biuro Architekta"],
  "optician" : ["Optyk", "Optyk"],
  "vineyard" : ["Winiarz", "Winiarz"],
  "fireworker" : ["Zakład Pirotechnika", "Zakład Pirotechnika"]
  };
 texts = {
  "Upkeep"   :"Koszty utrzymania",
  "cityName": "Nazwa", "currentlyBuilding": "W budowie", "summary": "Suma",
  "hide_settings": "Ukryj ustawieni", "show_settings": "Pokaż ustawienia",
  "Population": "Populacja",
  "Research": "Badania",
  "finishedBuilding": "Budowa zakończona","Incomes":"Bilans złota","Trading":"Handel",
  "Wood": "Drewno", "Wine": "Wino", "Marble": "Marmur", "Crystal": "Kryształ", "Sulfur": "Siarka"
  }; 
 };

EmpireBoard.Intl.Load_Texts_PT = function()
 {
 // Portuguese translation, thanks to alpha tester, Mr. Burns, Jeanipoo
 langtype = "";
 buildings = {
  "townHall"      : ["Câmara Municipal", "Câmara Municipal"],
  "temple"      : ["Temple", "Temple"],
  "academy"       : ["Academia", "Academia"],
  "port"          : ["Porto Mercantil", "Porto"],
  "shipyard"      : ["Estaleiro", "Estaleiro"],
  "warehouse"     : ["Armazém", "Armazém"],
  "wall"          : ["Muralha", "Muralha"],
  "tavern"        : ["Taberna", "Taberna"],
  "museum"        : ["Museu", "Museu"],
  "palace"        : ["Palácio", "Palácio"],
  "palaceColony"  : ["Residência do Governador", "Governador"],
  "embassy"       : ["Embaixada", "Embaixada"],
  "branchOffice"  : ["Mercado", "Mercado"],
  "safehouse"     : ["Espionagem", "Espionagem"],
  "barracks"      : ["Quartel", "Quartel"],
  "workshop" : ["Oficina", "Oficina"],
  "carpentering" : ["Carpintaria", "Carpintaria"],
  "forester" : ["Guarda Florestal", "Florestal"],
  "stonemason" : ["Pedreiro", "Pedreiro"],
  "glassblowing" : ["Fábrica de Vidro", "Vidro"],
  "winegrower" : ["Viticultor", "Viticultor"],
  "alchemist" : ["Torre do Alquimista", "Alquimista"],
  "architect" : ["Atelier de Arquitetura", "Arquitetura"],
  "optician" : ["Oculista", "Oculista"],
  "vineyard" : ["Caves de Vinho", "Caves"],
  "fireworker" : ["Fábrica de Pirotecnia", "Pirotecnia"]
  };
 texts = {
  "Upkeep"     : "Manutenção",
  "Growth"     : "Crescimento",
  "Research"     : "Pesquisa",
  "cityName": "Cidades",
  "currentlyBuilding": "Em Construçao",
  "summary": "Sumário",
  "hide_settings": "Ocultar Configuraçoes",
  "show_settings": "Ver Configuraçoes",
  "Population": "População",
  "Incomes":"Rendimento",
  "Wood": "Madeira",
  "Wine": "Vinho",
  "Marble": "Mármore",
  "Crystal": "Cristal",
  "Sulfur": "Enxofre"
  };
 };

EmpireBoard.Intl.Load_Texts_RO = function()
 {
 //Romanian translation, thanks to Peta
 langtype = "";
 buildings = {
  "townHall" : ["Primarie", "Primarie"],
  "temple"      : ["Temple", "Temple"],
  "academy" : ["Academie", "Academie"],
  "port" : ["Port comercial", "Port"],
  "shipyard" : ["Santier Naval", "S.Naval"],
  "warehouse" : ["Depozit", "Depozit"],
  "wall" : ["Zid", "Zid"],
  "tavern" : ["Taverna", "Taverna"],
  "museum" : ["Muzeu", "Muzeu"],
  "palace" : ["Palat", "Palat"],
  "palaceColony" : ["Resedinta Guvernatorului", "R.Guv."],
  "embassy" : ["Ambasada", "Ambasada"],
  "branchOffice" : ["Punct de negot", "Piata"],
  "safehouse" : ["Ascunzatoare", "Ascunzatoare"],
  "barracks" : ["Cazarma", "Cazarma"],
  "workshop" : ["Atelier", "Atelier"],
  "carpentering" : ["Dulgher", "Dulgher"],
  "forester" : ["Casa Padurarului", "Padurar"],
  "stonemason" : ["Cariera", "Cariera"],
  "glassblowing" : ["Sticlarie", "Sticlarie"],
  "winegrower" : ["Vinificator", "Vinificator"],
  "alchemist" : ["Turnul Alchimistului", "Alchimist"],
  "architect" : ["Biroul Arhitectului", "Architect"],
  "optician" : ["Optician", "Optician"],
  "vineyard" : ["Presa de Vin", "Presa Vin"],
  "fireworker" : ["Zona Pirotehnica de Test", "Poligon"]
  };
 texts = {
  "cityName": "Nume Oras", "currentlyBuilding": "In constructie", "summary": "Total",
  "hide_settings": "Ascunde Setari", "show_settings": "Arata Setari",
  "Population": "Populatie",
  "finishedBuilding": "Constructie Finalizata","Incomes":"Economii","Trading":"Comert",
  "Wood": "Lemn", "Wine": "Vin", "Marble": "Marmura", "Crystal": "Cristal", "Sulfur": "Sulf"
  };
 };

EmpireBoard.Intl.Load_Texts_RS = function()
 {
 //serbian translation by s-a-k-a 
 langtype = "";
 buildings = {
  "townHall"       : ["Градска кућа", "Г. кућа"],    
  "temple"         : ["Храм", "Храм"],    
  "academy"        : ["Академија", "Академија"],    
  "port"           : ["Трговачка лука", "Лука"],    
  "shipyard"       : ["Бродоградилиште", "Бродоградилиште"],    
  "warehouse"      : ["Складиште", "Складиште"],    
  "wall"           : ["Градски зид", "Зид"],    
  "tavern"         : ["Крчма", "Крчма"],    
  "museum"         : ["Музеј", "Музеј"],    
  "palace"         : ["Палата", "Палата"],    
  "palaceColony"   : ["Гувернерова резиденција", "Резиденција"],    
  "embassy"        : ["Амбасада", "Амбасада"],    
  "branchOffice"   : ["Трговина", "Трговина"],    
  "safehouse"      : ["Скровиште", "Скровиште"],    
  "barracks"       : ["Барака", "Барака"],    
  "workshop"       : ["Радионица", "Радионица"],    
  "carpentering"   : ["Тесар", "Тесар"],    
  "forester"       : ["Шумарова кућа", "Ш. кућа"],    
  "stonemason"     : ["Зидар", "Зидар"],    
  "glassblowing"   : ["Стаклара", "Стаклара"],    
  "winegrower"     : ["Виноградар", "Виноградар"],    
  "alchemist"      : ["Алхемичарев торањ", "Торањ"],    
  "architect"      : ["Архитектина канцеларија", "Архитекта"],    
  "optician"       : ["Оптичар", "Оптичар"],    
  "vineyard"       : ["Винска преса", "Преса"],    
  "fireworker"     : ["Област за тестирање ватромета", "Област"]    
  };
 texts = {
  "Upkeep"                 : "Одржавање",    
  "cityName"               : "Градови",    
  "currentlyBuilding"      : "Тренутно се гради",    
  "summary"                : "Кратак преглед",    
  "hide_settings"          : "Сакриј подешавања",    
  "show_settings"          : "Прикажи подешавања",    
  "Population"             : "Популација",    
  "Research"               : "Истраживање",    
  "finishedBuilding"       : "Завршена изградња",    
  "Incomes"                : "Приходи",    
  "Trading"                : "Трговински",    
  "Wood"                   : "Дрво",    
  "Wine"                   : "Вино",    
  "Marble"                 : "Мермер",    
  "Crystal"                : "Кристал",    
  "Sulfur"                 : "Сумпор"    
  };
 };

EmpireBoard.Intl.Load_Texts_RU = function()
 {
 //russian translation by Mugivara, GrAndAG
 langtype = "";
 buildings = {
  "townHall" : ["Ратуша", "Ратуша"],
  "temple" : ["Храм", "Храм"],
  "academy" : ["Академия", "Академия"],
  "port" : ["Торговый порт", "Порт"],
  "shipyard" : ["Верфь", "Верфь"],
  "warehouse" : ["Склад", "Склад"],
  "wall" : ["Стена", "Стена"],
  "tavern" : ["Таверна", "Таверна"],
  "museum" : ["Музей", "Музей"],
  "palace" : ["Дворец", "Дворец"],
  "palaceColony" : ["Резиденция губернатора", "Резиденция"],
  "embassy" : ["Посольство", "Посольство"],
  "branchOffice" : ["Торговый пост", "Пост"],
  "safehouse" : ["Укрытие", "Укрытие"],
  "barracks" : ["Казарма", "Казарма"],
  "workshop" : ["Мастерская", "Мастерская"],
  "carpentering" : ["Плотницкая мастерская", "Плотник"],
  "forester" : ["Хижина леничего", "Лесничий"],
  "stonemason" : ["Каменоломня", "Каменоломня"],
  "glassblowing" : ["Стеклодувная мастерская", "Стеклодув"],
  "winegrower" : ["Винодельня", "Винодельня"],
  "alchemist" : ["Башня алхимика", "Алхимик"],
  "architect" : ["Бюро архитектора", "Архитектор"],
  "optician" : ["Оптика", "Оптика"],
  "vineyard" : ["Винный погреб", "Погреб"],
  "fireworker" : ["Полигон пиротехника", "Полигон"]
  };
 texts = {
  "Upkeep": "Содерж.",
  "Growth": "Рост",
  "cityName": "Название города",
  "currentlyBuilding": "Текущее строительство",
  "summary": "Итого",
  "hide_settings": "Скрыть настройки",
  "show_settings": "Показать настройки",
  "Population": "Население",
  "Research": "Учёные",
  "finishedBuilding": "Строительство завершено",
  "Incomes":"Золото",
  "Trading":"Торговля",
  "Wood": "Стройматериалы",
  "Wine": "Виноград",
  "Marble": "Мрамор",
  "Crystal": "Хрусталь",
  "Sulfur": "Сера"
  };
 };

EmpireBoard.Intl.Load_Texts_SE = function()
 {
 // thank Dinfur
 langtype = "";
 buildings = {
  "townHall" : ["Rådhus", "Rådhus"],
  "temple"      : ["Temple", "Temple"],
  "academy" : ["Akademi", "Akademi"],
  "port" : ["Handelshamn", "Hamn"],
  "shipyard" : ["Skeppsvarv", "Varv"],
  "warehouse" : ["Lagerlokal", "Lager"],
  "wall" : ["Stadsmur", "Mur"],
  "tavern" : ["Taverna", "Taverna"],
  "museum" : ["Museum", "Museum"],
  "palace" : ["Palats", "Palats"],
  "palaceColony" : ["Guvernörsresidens", "Guvernör"],
  "embassy" : ["Ambassad", "Ambassad"],
  "branchOffice" : ["Handelsstation", "Handel"],
  "safehouse" : ["Gömställe", "Gömställe"],
  "barracks" : ["Kasern", "Kasern"],
  "workshop" : ["Verkstad", "Verkstad"],
  "carpentering" : ["Snickare", "Snickare"],
  "forester" : ["Skogsvaktare", "Skog"],
  "stonemason" : ["Stenhuggare", "Sten"],
  "glassblowing" : ["Glasblåsare", "Glas"],
  "winegrower" : ["Vinodlare", "Vin"],
  "alchemist" : ["Alkemist", "Alkemist"],
  "architect" : ["Arkitekt", "Arkitekt"],
  "optician" : ["Optiker", "Optiker"],
  "vineyard" : ["Vinpress", "Vin"],
  "fireworker" : ["Fyrverkerifabrik", "Fyrverk."]
  };
 texts = {
  "cityName": "Stadsnamn", "currentlyBuilding": "Bygger nu", "summary": "Summering",
  "hide_settings": "Göm inställningar", "show_settings": "Visa inställningar",
  "Population": "Befolkning",
  "finishedBuilding": "Byggt klart","Incomes":"Inkomster","Trading":"Handlar",
  "Wood": "Trä", "Wine": "Vin", "Marble": "Marmor", "Crystal": "Kristall", "Sulfur": "Svavel"
  };
 };

EmpireBoard.Intl.Load_Texts_SK = function()
 {
 //Slovak translation by RxR
 langtype = "";
 buildings = {
  "townHall" : ["Radnica", "Radnica"],
  "temple" : ["Kostol", "Kostol"],
  "academy" : ["Akadémia", "Akadémia"],
  "port" : ["Obchodný prístav", "Prístav"],
  "shipyard" : ["Lodenica", "Lodenica"],
  "warehouse" : ["Sklad", "Sklad"],
  "wall" : ["Mestský múr", "Múr"],
  "tavern" : ["Vináreň", "Vináreň"],
  "museum" : ["Múzeum", "Múzeum"],
  "palace" : ["Palác", "Palác"],
  "palaceColony" : ["Rezidencia guvernéra", "Guvernér"],
  "embassy" : ["Ambasáda", "Ambasáda"],
  "branchOffice" : ["Trhovisko", "Trh"],
  "safehouse" : ["Úkryt", "Úkryt"],
  "barracks" : ["Kasárne", "Kasárne"],
  "workshop" : ["Dielňa", "Dielňa"],
  "carpentering" : ["Tesár", "Tesár"],
  "forester" : ["Dom lesníka", "Lesník"],
  "stonemason" : ["Kameňolom", "Kamenár"],
  "glassblowing" : ["Fúkač skla", "Sklár"],
  "winegrower" : ["Vinár", "Vinár"],
  "alchemist" : ["Veža alchymistov", "Alchymista"],
  "architect" : ["Úrad architekta", "Architekt"],
  "optician" : ["Optik", "Optik"],
  "vineyard" : ["Vinica", "Vinica"],
  "fireworker" : ["Testovanie ohňostrojov", "Ohňostroje"]
  };
 texts = {
  "cityName" : "Mesto",
  "currentlyBuilding" : "Stavia sa",
  "summary" : "Spolu",
  "hide_settings" : "Skryť nastavenia",
  "show_settings" : "Zobraziť nastavenia",
  "Population" : "Obyvateľstvo",
  "finishedBuilding" : "Dokončené stavby",
  "Incomes" : "Príjmy",
  "Trading" : "Obchod",
  "Wood" : "Drevo",
  "Wine" : "Víno",
  "Marble" : "Mramor",
  "Crystal" : "Sklo",
  "Sulfur" : "Síra"
  };
 };

EmpireBoard.Intl.Load_Texts_SL = function()
 {
 //Slovenian translation, thanks to Americano, MazaM, kayz1
 langtype = "";
 buildings = {
  "townHall"   : ["Mestna hiša", "Mestna"],
  "temple"   : ["Tempelj", "Tempelj"],
  "academy"   : ["Akademija", "Akademija"],
  "port"    : ["Trgovska luka", "Luka"],
  "shipyard"   : ["Ladjedelnica", "Ladjedelnica"],
  "warehouse"   : ["Skladišče", "Skladišče"],
  "dump"    : ["Depot", "Depot"],
  "wall"    : ["Obzidje", "Obzidje"],
  "tavern"   : ["Krčma", "Krčma"],
  "museum"   : ["Muzej", "Muzej"],
  "palace"   : ["Palača", "Palača"],
  "palaceColony"  : ["Guvernerjeva rezidenca", "Guverner"],
  "embassy"   : ["Ambasada", "Ambasada"],
  "branchOffice"  : ["Tržnica", "Tržnica"],
  "safehouse"   : ["Skrivališče", "Skrivališče"],
  "barracks"   : ["Barake", "Barake"],
  "workshop"   : ["Delavnica", "Delavnica"],
  "carpentering"  : ["Tesar", "Tesar"],
  "forester"   : ["Gozdarska hiša", "Gozdar"],
  "stonemason"  : ["Kamnoseška delavnica", "Kamnosek"],
  "glassblowing"  : ["Steklopihač", "Steklopihač"],
  "winegrower"  : ["Vinogradnik", "Vinogradnik"],
  "alchemist"   : ["Stolp alkimista", "Alkimist"],
  "architect"   : ["Pisarna arhitekta", "Arhitekt"],
  "optician"   : ["Optika", "Optika"],
  "vineyard"   : ["Vinska preša", "Preša"],
  "fireworker"  : ["Testno območje ognjemetov", "Pirotehnik"]
  };
 texts = {
  "Upkeep"     : "Vzdrževanje",
  "Growth"     : "Rast",
  "Research"     : "Raziskave",
  "cityName"     : "Ime mesta",
  "currentlyBuilding"   : "Gradi se",
  "summary"     : "Povzetek:",
  "hide_settings"    : "Skrij nastavitve",
  "show_settings"    : "Pokaži nastavitve",
  "Population"    : "Prebivalci",
  "finishedBuilding"   : "Zgrajeno",
  "Incomes"     : "Prihodki",
  "Trading"     : "Trgovanje",
  "Wood"      : "Gradbeni material",
  "Wine"      : "Vino",
  "Marble"     : "Marmor",
  "Crystal"     : "Kristal",
  "Sulfur"     : "Žveplo"
  };  
 };

EmpireBoard.Intl.Load_Texts_TR = function()
 {
//Turkish translation, thanks to NailBey, regular6
 langtype = "";
 buildings = {
  "townHall"   : ["Belediye Binası", "Belediye"],
  "temple"   : ["Tapınak", "Tapınak"],
  "academy"   : ["Akademi", "Akademi"],
  "port"    : ["Ticaret Limanı", "Liman"],
  "shipyard"   : ["Donanma Tersanesi", "Donanma "],
  "warehouse"   : ["Depo", "Depo"],
  "dump"    : ["Yığın Sahası", "Yığın Sahası"],
  "wall"    : ["Sur", "Sur"],
  "tavern"   : ["Taverna", "Taverna"],
  "museum"   : ["Müze", "Müze"],
  "palace"   : ["Saray", "Saray"],
  "palaceColony"    : ["Vali Konağı", "Vali Konağı"],
  "embassy"   : ["Büyükelçilik", "Büyükelçilik"],
  "branchOffice"   : ["Ticaret Merkezi", "Ticaret Merkezi"],
  "safehouse"   : ["İstihbarat Merkezi", "İstihbarat Merkezi"],
  "barracks"   : ["Kışla", "Kışla"],
  "workshop"   : ["Mucit Atölyesi", "Mucit Atölyesi"],
  "carpentering"   : ["Marangoz Atölyesi", "Marangoz Atölyesi"],
  "forester"   : ["Ormancı Kulübesi", "Ormancı Kulübesi"],
  "stonemason"   : ["Mermer Atölyesi", "Mermer Atölyesi"],
  "glassblowing"   : ["Cam Eşya Atölyesi", "Cam Eşya Atölyesi"],
  "winegrower"   : ["Bağ Evi", "Bağ Evi"],
  "alchemist"   : ["Simya Kulesi", "Simya Kulesi"],
  "architect"   : ["Mimarlık Bürosu", "Mimarlık Bürosu"],
  "optician"   : ["Optik", "Optik"],
  "vineyard"   : ["Şarap Mahzeni", "Şarap Mahzeni"],
  "fireworker"   : ["Fişekçi", "Fişekçi"]
  };
 texts = {
  "Upkeep"     : "Bakım Masrafı",
  "Growth"     : "Büyüme",
  "Research"     : "Araştrma",
  "cityName"     : "Şehir Adı",
  "currentlyBuilding"    : "İnşaa Ediliyor",
  "summary"     : "Toplam:",
  "hide_settings"     : "Ayarları Gizle",
  "show_settings"     : "Ayarları Göster",
  "Population"     : "Nüfus",
  "finishedBuilding"    : "İnşaa Bitti",
  "Incomes"     : "Gelir",
  "Trading"     : "Ticaret",
  "Wood"      : "Odun",
  "Wine"      : "Şarap",
  "Marble"     : "Mermer",
  "Crystal"     : "Kristal",
  "Sulfur"     : "Sülfür"
  };
 };

EmpireBoard.Intl.Load_Texts_TW = function()
 {
 //traditional chinese translation by Whiskers, cherub
 langtype = "";
 buildings = {
  "townHall" : ["市政府", "市府"],
  "temple" : ["祭祀神殿", "神殿"],
  "academy" : ["學院", "學院"],
  "port" : ["港口", "港口"],
  "shipyard" : ["船塢", "船塢"],
  "warehouse" : ["倉庫", "倉庫"],
  "wall" : ["城牆", "城牆"],
  "tavern" : ["酒館", "酒館"],
  "museum" : ["博物館", "博物"],
  "palace" : ["皇宫", "皇宫"],
  "palaceColony" : ["總督府", "總督"],
  "embassy" : ["大使館", "使館"],
  "branchOffice" : ["市場", "市場"],
  "safehouse" : ["間諜小屋", "間諜"],
  "barracks" : ["兵營", "兵營"],
  "workshop" : ["兵工廠", "兵廠"],
  "carpentering" : ["木匠屋", "木-"],
  "forester" : ["林務官宅", "木+"],
  "stonemason" : ["石匠屋", "石+"],
  "glassblowing" : ["玻璃吹制廠", "晶+"],
  "winegrower" : ["葡萄樹園", "葡+"],
  "alchemist" : ["煉金塔", "硫+"],
  "architect" : ["建築公署", "石-"],
  "optician" : ["配鏡商館", "晶-"],
  "vineyard" : ["藏酒窖", "葡-"],
  "fireworker" : ["煙火測試區域", "硫-"],
  "dump"   : ["貨棧","貨棧"]
  };
 texts = {
  "cityName": "城鎮",
  "currentlyBuilding": "正在建造",
  "summary": "總計",
  "hide_settings": "隐藏設定",
  "show_settings": "顯示設定",
  "Population": "人口",
  "finishedBuilding": "建造完成",
  "Incomes":"收入",
  "Trading":"交易",
  "Wood": "木材",
  "Wine": "葡萄",
  "Marble": "大理石",
  "Crystal": "水晶",
  "Sulfur": "硫磺",
  "Growth":"成長率",
  "Research":"研究",
  "Upkeep":"軍費"
  }; 
 };

EmpireBoard.Intl.Load_Texts_UA = function()
 {
 //ukrainian Translation by feelimon http://www.ikariam.com.ua
 langtype = "";
 buildings = {
  "townHall" : ["Ратуша", "Ратуша"],
  "temple" : ["Храм", "Храм"],
  "academy" : ["Академія", "Академія"],
  "port" : ["Торговий порт", "Порт"],
  "shipyard" : ["Верф", "Верф"],
  "warehouse" : ["Склад", "Склад"],
  "wall" : ["Стіна", "Стіна"],
  "tavern" : ["Таверна", "Таверна"],
  "museum" : ["Музей", "Музей"],
  "palace" : ["Палац", "Палац"],
  "palaceColony" : ["Резиденція губернатора", "Резиденція"],
  "embassy" : ["Посольство", "Посольство"],
  "branchOffice" : ["Торговий пост", "Пост"],
  "safehouse" : ["Схованка", "Схованка"],
  "barracks" : ["Бараки", "Бараки"],
  "workshop" : ["Майстерня", "Майстерня"],
  "carpentering" : ["Теслярська майстерня", "Тесля"],
  "forester" : ["Дім лісничого", "Лісник"],
  "stonemason" : ["Дім каменяра", "Дім каменяра"],
  "glassblowing" : ["Склодувна майстерня", "Склодув"],
  "winegrower" : ["Виноградник", "Виноградник"],
  "alchemist" : ["Вежа алхіміка", "Алхімік"],
  "architect" : ["Офіс архітектора", "Архітектор"],
  "optician" : ["Оптик", "Оптик"],
  "vineyard" : ["Винний погріб", "Погріб"],
  "fireworker" : ["Полігон піротехніка", "Піротехнік"]
  };
 texts = {
  "Upkeep" :"Утримання",
  "cityName": "Назва міста", "currentlyBuilding": "Поточне будівництво", "summary": "Всього",
  "hide_settings": "Сховати налаштування", "show_settings": "Показати налаштування",
  "Population": "Населення",
  "Research": "Вчені",
  "finishedBuilding": "Будівництво завершено", "Incomes":"Золото", "Trading":"Торгівля",
  "Wood": "Дерево", "Wine": "Вино", "Marble": "Мармур",
  "Crystal": "Кришталь", "Sulfur": "Сірка"
  };
 };

EmpireBoard.Intl.Load_Texts_VN = function()
 {
 // Vietnamese translations, thank Gafs
 langtype = ""; 
 buildings = {
  "townHall"      : ["Tòa thị chính", "Tòa T.Chính"],
  "temple"      : ["Temple", "Temple"],
  "academy"       : ["Học viện", "Học viện"],
  "port"          : ["Cảng giao dịch", "Cảng GD"],
  "shipyard"      : ["Xưởng đóng tàu", "Xưởng tàu"],
  "warehouse"     : ["Kho hàng", "Kho"],
  "wall"          : ["Tường thành", "Tường"],
  "tavern"        : ["Quán rượu", "Quán rượu"],
  "museum"        : ["Viện bảo tàng", "V.B.Tàng"],
  "palace"        : ["Cung điện", "Cung điện"],
  "palaceColony"  : ["Phủ thủ hiến", "Phủ"],
  "embassy"       : ["Tòa đại sứ", "Tòa Đ.Sứ"],
  "branchOffice"  : ["Trạm giao dịch", "Trạm GD"],
  "safehouse"     : ["Nơi ẩn náu", "Nơi ẩn náu"],
  "barracks"      : ["Trại lính", "Trại lính"],
  "workshop"    : ["Xưởng", "Xưởng"],
  "carpentering" : ["Thợ mộc", "Thợ mộc"],
  "forester" : ["Nhà kiểm lâm", "Kiểm lâm"],
  "stonemason" : ["Thợ xây đá", "Thợ đá"],
  "glassblowing" : ["Người thổi thủy tinh", "Thổi TT"],
  "winegrower" : ["Máy ép nho", "Ép nho"],
  "alchemist" : ["Giả kim", "Giả kim"],
  "architect" : ["Tòa kiến trúc", "Kiến trúc"],
  "optician" : ["Thợ kính", "Thợ kính"],
  "vineyard" : ["Vườn nho", "V.Nho"],
  "fireworker" : ["Thử thuốc súng", "Thuốc súng"]
  };
 texts = {
  "cityName": "Thành phố", "currentlyBuilding": "Đang xây dựng", "summary": "Tổng",
  "hide_settings": "Ẩn thiết lập", "show_settings": "Hiển thị thiết lập",
  "Population": "Dân số",
  "finishedBuilding": "Công trình hoàn tất","Incomes":"Thu nhập","Trading":"Trao đổi",
  "Wood": "Gỗ", "Wine": "Rượu", "Marble": "Cẩm thạch", "Crystal": "Pha lê", "Sulfur": "Lưu huỳnh"
  };
 };

EmpireBoard.Init();

//lots of code to get the city id. The code trys to find the city id no matter which "city dropdown view" the user has chosen.
// Fix for v3.1
var city_id = EmpireBoard.Str.To_Integer(EmpireBoard.DOM.Get_Last_Node_Value("//select[@id='citySelect']/option[@selected='selected']"), 0);
var current_city_id = city_id;
EmpireBoard.Log.Add('current_city_id = '+current_city_id);

var city_name = EmpireBoard.DOM.Get_First_Node_TextContent("id('breadcrumbs')/*[@class='city']");
EmpireBoard.Log.Add('Main view city_name = "'+city_name+'"');
if (city_name != undefined)
 {
 var island_id = EmpireBoard.DOM.Get_First_Node_TextContent("id('breadcrumbs')//a[@class='island']");
 if ( island_id == undefined || island_id == 0 )
     island_id = /\[[0-9:]+\]/.exec(EmpireBoard.DOM.Get_First_Node("id('breadcrumbs')//a[contains(@href,'view=island')]").innerHTML)[0];
 
 var city_idmainView = 0;
 
 // Fix for v3.1
 if (city_idmainView == 0)
  {
  city_idmainView = EmpireBoard.DOM.Get_First_Node_Value("//select[@id='citySelect']/option[text()='"+EmpireBoard.Ikariam.TwoDigit_Coords(island_id)+" "+city_name+"']", 0);
  }
 if (city_idmainView == 0)
  {
  city_idmainView = EmpireBoard.DOM.Get_First_Node_Value("//select[@id='citySelect']/option[text()='"+city_name+"']", 0);
  }
 
 // Fix for v3.2
 if (city_idmainView == 0)
  {
  city_idmainView = EmpireBoard.DOM.Get_First_Node_Value("//select[@id='citySelect']/option[contains(text(),'"+EmpireBoard.Ikariam.TwoDigit_Coords(island_id)+"') and contains(text(),'"+city_name+"')]", 0);
  }
 if (city_idmainView == 0)
  {
  city_idmainView = EmpireBoard.DOM.Get_First_Node_Value("//select[@id='citySelect']/option[contains(text(),'"+city_name+"')]", 0);
  }
  
 EmpireBoard.Log.Add('city_idmainView['+EmpireBoard.Ikariam.TwoDigit_Coords(island_id)+' '+city_name+'] = '+city_idmainView);
 var city_positionmainView = -1;

 var a = EmpireBoard.DOM.Get_First_Node("//div[@id='breadcrumbs']/*[@class='island' and contains(text(), '[')]", "");
 if (a == null) {
   a = EmpireBoard.DOM.Get_First_Node("//a[contains(@href, '?view=island')]/span[contains(text(), '[')]", "");
   if (a != null) {
     a = a.parentNode;
   }
 }
 var city_coord = "";
 var island_id = "";
 if (a != null) {
   if (/(\[[0-9:]+\])/.exec(a.innerHTML)) {
     city_coord = RegExp.$1;
     if (/[?&]id=([0-9]+)/.exec(a.href) != null) {
       island_id = RegExp.$1;
     }
   }
 }
 if (island_id == "" && (/view=island&id=([0-9]+)/.exec(document.URL) != null)) { 
   island_id = RegExp.$1;
 }
 }
else
 {
 city_idmainView = 0;
 city_name = '';
 city_coord = '';
 island_id = '';
 }

function getCity(city_id)
 {
 city_id = "city_"+city_id;
 if (config[city_id] == undefined)
  {
  config[city_id] = new Resource();
  config[city_id].buildings  = {};
  config[city_id].units   = {};
  
  EmpireBoard.Log.Add('Create city id='+city_id);
  }
 return config[city_id];
 }

function digProducedResources(res) 
 {
 var scripts = document.getElementsByTagName("script");
 var found = false;
 for (var j = scripts.length-1; j >= 0; j--)
  {
  var nScript = scripts[j];
  var sCode = nScript.innerHTML;
  if (sCode.indexOf('getResourceCounter') > 0)
   {
   found = true;
   break;
   }
  }
 if (found == false)
  {
  return;
  }

 var aCodeLines = sCode.split(';');
 
 // by AubergineAnodyne (not used)
 function findResourceCounterData(name)
  {
  for (var i = 0; i < aCodeLines.length; i++)
   {
   if (aCodeLines[i].indexOf(name + 'Counter') >= 0)
    {
    return aCodeLines[i].substring(aCodeLines[i].indexOf('(') + 2, aCodeLines[i].indexOf(')') - 1);
    }
   }
  }
 
 var sWoodLine = 0;
 var sTradeGoodLine = 0;
 for (var j = 0; j <= aCodeLines.length-1; j++)
  {
  if (aCodeLines[j].indexOf('getResourceCounter') > 0)
   {
   if (aCodeLines[j].indexOf('woodCounter') > 0)
    {
    sWoodLine = j;
    if (sTradeGoodLine > 0) break;
    }
   if (aCodeLines[j].indexOf('tradegoodCounter') > 0)
    {
    sTradeGoodLine = j;
    if (sWoodLine > 0) break;
    }
   }
  }
  
 var startResourcesDelta = 0;
 if (sWoodLine > 0)
  {
  var sWood = aCodeLines[sWoodLine].substring(aCodeLines[sWoodLine].indexOf('(')+2,aCodeLines[sWoodLine].indexOf(')')-1);
  var prodRegExp = /production: *([0-9.\E\-]+)/.exec(sWood);
  if (prodRegExp != null)
   {
   startResourcesDelta = Math.floor(parseFloat(RegExp.$1) * 3600);
   } 
  }
 
 var startTradegoodDelta = 0;
 var sTradeGoodName = '';
 if (sTradeGoodLine > 0)
  {
  var sTradeGood = aCodeLines[sTradeGoodLine].substring(aCodeLines[sTradeGoodLine].indexOf('(')+2,aCodeLines[sTradeGoodLine].indexOf(')')-1);
  var prodRegExp = /production: *([0-9.\E\-]+)/.exec(sTradeGood);
  if (prodRegExp != null)
   {
   startTradegoodDelta = Math.floor(parseFloat(RegExp.$1) * 3600);
   }
  var sName = /valueElem: *\"(.*)\"/.exec(sTradeGood);
  sTradeGoodName = sName[1];
  }

 res.prodwood = startResourcesDelta;
 res.prodwine = 0;
 res.prodmarble = 0;
 res.prodglass = 0;
 res.prodsulfur = 0;
 res.prodtime = EmpireBoard.StartTime; 
 if (sTradeGoodName == "value_wine")
  {
  res.prodwine = startTradegoodDelta;
  res.prodgood = 'wine';
  }
 else if (sTradeGoodName == "value_marble")
  {
  res.prodmarble = startTradegoodDelta;
  res.prodgood = 'marble';
  }
 else if (sTradeGoodName == "value_crystal")
  {
  res.prodglass = startTradegoodDelta;
  res.prodgood = 'glass';
  }
 else if (sTradeGoodName == "value_sulfur")
  {
  res.prodsulfur = startTradegoodDelta;
  res.prodgood = 'sulfur';
  }
 }

function getCurrentResourceAmount(currenttime, startTime, startAmount, factPerHour) {
  var elapsedhours = (currenttime - startTime) / 1000.0 / 3600.0;
  return Math.max(0, Math.floor(startAmount + elapsedhours * factPerHour));
  /*
  TODO:
  spendings: [{amount: 197, tickInterval: 1200}], valueElem: "value_wine"
this.currentRes=this.startRes+this.production*Math.floor((this.currenttime-this.startdate)/1000);
this.currentRes=this.currentRes-this.spendings[i]['amount']*Math.floor((this.currenttime-this.startdate)/1000/this.spendings[i]['tickInterval'])*this.spendings[i]['tickInterval']/3600;}
197*floor(3600/1200)*1200/3600
  */
}

function createTooltipAttribute(tooltip, title, isFct) {
  if (tooltip == undefined || tooltip == "") {
    return "";
  }
  if (isFct == true)
 {
 html = tooltip;
 }
  else
 {
   if (title == undefined || title == "") {
      title = "";
   }
   else title = "<div class=TTTitle>"+title+"</div>";
   if (EmpireBoard.Intl.LangDir() == "rtl")
  {
  var html = "<div dir=rtl class='TTContent RtoL'>"+title+tooltip+"</div>";
  }
   else
  {
  var html = "<div class=TTContent>"+title+tooltip+"</div>";
  }
   html = "'"+html.replace(/'/g, "\\'")+"'";
 }
  return "onmouseover=\"Tip("+html+", ABOVE, true, BORDERWIDTH, 0, SHADOW, false, BGCOLOR, '');\"";
}

function createTooltip(content, tooltip, title) {
  if (tooltip == undefined || tooltip == "") {
    return content;
  }
  return "<font "+createTooltipAttribute(tooltip, title)+">"+content+"</font>";
}


function createTimeCounter(enddate) {
  if (enddate != undefined && enddate != "") {
    var s = smartDateFormat(enddate);
    return createTooltip("<font id='mytimecounter' counter='"+enddate+"'></font>", s);
  }
  return "";
}

function getArrValue(arr, key, defaultValue) {
  if (arr == undefined || arr[key] == undefined) {
    return defaultValue;
  }
  return arr[key];
}

function createLinkToChangeCity(text, city_id, city_index, sup_text, sup_class, sup_title) {
 var res = getCity(city_id);
 var rHTML = '';
 
 if (res.city_name != undefined)
  {
  cName = res.city_name;
  }
 else
  {
  cName = EmpireBoard.Ikariam.Trim_Coords(text);
  }
 if (current_city_id == city_id)
  {
  rHTML += '<b>'+cName+'</b>';
  }
 else
  {
  rHTML += createLink(cName, "?cityId="+city_id, "title=\"Change current city\" onclick=\"var s = document.getElementById('citySelect'); s.selectedIndex = "+city_index+"; s.form.submit(); return false;\"");
  }
 
 if ((sup_text != undefined) && (sup_text != '') && (sup_text != 0))
  {
  if (sup_class == undefined) sup_class = '';
  if (sup_title == undefined) sup_title = '';
  rHTML += '<sup class="'+sup_class+'" title="'+sup_title+'">'+sup_text+'</sup>';
  }
 
 return rHTML;
}

function setViewRqTime(view, city_id, newTime, force)
 {
 if (view == undefined) view = '';
 if (newTime == undefined) newTime = EmpireBoard.StartTime;
 if (force == undefined) force = false;
 
 if ((city_id == undefined) || (city_id <= 0))
  {
  if (view == 'premium')
   {
   if (config["premium"] == undefined) config["premium"] = {};
   
   if (config["premium"].rqtime == undefined)
    {
    config["premium"].rqtime = newTime;
    }
   else if (EmpireBoard.StartTime > config["premium"].rqtime)
    {
    config["premium"].rqtime = newTime;
    }
   else if (newTime < config["premium"].rqtime)
    {
    config["premium"].rqtime = newTime;
    }
   }
  else if (view == 'researchOverview')
   {
   if (config["research"] == undefined) config["research"] = {};
   
   if (config["research"].rqtime == undefined)
    {
    config["research"].rqtime = newTime;
    }
   else if (EmpireBoard.StartTime > config["research"].rqtime)
    {
    config["research"].rqtime = newTime;
    }
   else if (newTime < config["research"].rqtime)
    {
    config["research"].rqtime = newTime;
    }
   }
  else if (view == 'merchantNavy')
   {
   if (config.merchantNavyrqtime == undefined)
    {
    config.merchantNavyrqtime = newTime;
    }
   else if (EmpireBoard.StartTime > config.merchantNavyrqtime)
    {
    config.merchantNavyrqtime = newTime;
    }
   else if (newTime < config.merchantNavyrqtime)
    {
    config.merchantNavyrqtime = newTime;
    }
   else if (force == true)
    {
    config.merchantNavyrqtime = newTime;
    }
   }
  else if (view == 'finances')
   {
   if (config.financesrqtime == undefined)
    {
    config.financesrqtime = newTime;
    }
   else if (EmpireBoard.StartTime > config.financesrqtime)
    {
    config.financesrqtime = newTime;
    }
   else if (newTime < config.financesrqtime)
    {
    config.financesrqtime = newTime;
    }
   }
  else if (view == 'militaryAdvisorMilitaryMovements')
   {
   if (config.mAMMrqtime == undefined)
    {
    config.mAMMrqtime = newTime;
    }
   else if (EmpireBoard.StartTime > config.mAMMrqtime)
    {
    config.mAMMrqtime = newTime;
    }
   else if (newTime < config.mAMMrqtime)
    {
    config.mAMMrqtime = newTime;
    }
   }
  }
 else
  {
  var city = getCity(city_id);
  if (view == '')
   {
   if (city.rqtime == undefined)
    {
    city.rqtime = newTime;
    }
   else if (EmpireBoard.StartTime > city.rqtime)
    {
    city.rqtime = newTime;
    }
   else if (newTime < city.rqtime)
    {
    city.rqtime = newTime;
    }
   }
  else if (view == 'cityMilitary-army')
   {
   if (city.cityMilitaryarmyrqtime == undefined)
    {
    city.cityMilitaryarmyrqtime = newTime;
    }
   else if (EmpireBoard.StartTime > city.cityMilitaryarmyrqtime)
    {
    city.cityMilitaryarmyrqtime = newTime;
    }
   else if (newTime < city.cityMilitaryarmyrqtime)
    {
    city.cityMilitaryarmyrqtime = newTime;
    }
   }
  else if (view == 'cityMilitary-fleet')
   {
   if (city.cityMilitaryfleetrqtime == undefined)
    {
    city.cityMilitaryfleetrqtime = newTime;
    }
   else if (EmpireBoard.StartTime > city.cityMilitaryfleetrqtime)
    {
    city.cityMilitaryfleetrqtime = newTime;
    }
   else if (newTime < city.cityMilitaryfleetrqtime)
    {
    city.cityMilitaryfleetrqtime = newTime;
    }
   }
  else if (city.buildings[view] != undefined)
   {
   if (city.buildings[view].rqtime == undefined)
    {
    city.buildings[view].rqtime = newTime;
    }
   else if (EmpireBoard.StartTime > city.buildings[view].rqtime)
    {
    city.buildings[view].rqtime = newTime;
    }
   else if (newTime < city.buildings[view].rqtime)
    {
    city.buildings[view].rqtime = newTime;
    }
   else if (force == true)
    {
    city.buildings[view].rqtime = newTime;
    }
   }
  }
 }

function reportViewToSurvey(view, city_id)
 {
 if (view == undefined)   view = '';
 if (city_id == undefined)  city_id = 0;
 var report = false;
 
 if ((city_id == undefined) || (city_id <= 0))
  {
  if (view == 'premium')
   {
   if (config["premium"] == undefined) config["premium"] = {};
   
   if (config["premium"].uptime == undefined)
    {
    report = true;
    }
   else if (config["premium"].uptime == 0)
    {
    report = true;
    }
   else if ((config["premium"].rqtime != undefined) && (config["premium"].rqtime <= EmpireBoard.StartTime) && (config["premium"].rqtime > config["premium"].uptime))
    {
    report = true;
    }
   }
  else if (view == 'researchOverview')
   {
   if (config["research"] == undefined) config["research"] = {};
   
   if (config["research"].uptime == undefined)
    {
    report = true;
    }
   else if (config["research"].uptime == 0)
    {
    report = true;
    }
   else if ((config["research"].rqtime != undefined) && (config["research"].rqtime <= EmpireBoard.StartTime) && (config["research"].rqtime > config["research"].uptime))
    {
    report = true;
    }
   }
  else if (view == 'finances')
   {
   if (config.financestime == undefined)
    {
    report = true;
    }
   else if (config.financestime == 0)
    {
    report = true;
    }
   else if ((config.financesrqtime != undefined) && (config.financesrqtime <= EmpireBoard.StartTime) && (config.financesrqtime > config.financestime))
    {
    report = true;
    }
   }
  else if (view == 'merchantNavy')
   {
   if (config.merchantNavytime == undefined)
    {
    report = true;
    }
   else if (config.merchantNavytime == 0)
    {
    report = true;
    }
   else if ((config.merchantNavyrqtime != undefined) && (config.merchantNavyrqtime <= EmpireBoard.StartTime) && (config.merchantNavyrqtime > config.merchantNavytime))
    {
    report = true;
    }
   }
  else if (view == 'militaryAdvisorMilitaryMovements')
   {
   if (config.mAMMtime == undefined)
    {
    report = true;
    }
   else if (config.mAMMtime == 0)
    {
    report = true;
    }
   else if ((config.mAMMrqtime != undefined) && (config.mAMMrqtime <= EmpireBoard.StartTime) && (config.mAMMrqtime > config.mAMMtime))
    {
    report = true;
    }
   }
  }
 else
  {
  var city = getCity(city_id);
  if (view == '')
   {
   if (city.prodtime == undefined)
    {
    report = true;
    }
   else if (city.prodtime == 0)
    {
    report = true;
    }
   else if ((city.rqtime != undefined) && (city.rqtime <= EmpireBoard.StartTime) && (city.rqtime > city.prodtime))
    {
    report = true;
    }
   else if (city.prodtime <= (EmpireBoard.StartTime - 1000*60*60*24*7))
    {
    report = true;
    }
   }
  else if (view == 'city')
   {
   if (city.citytime == undefined)
    {
    report = true;
    }
   else if (city.citytime == 0)
    {
    report = true;
    }
   }
  else if ((view == 'cityMilitary-army') || (view == 'barracks'))
   {
   var recentTime = 0;
   if (city.cityMilitaryarmytime != undefined) recentTime = city.cityMilitaryarmytime;
   if ((city.buildings['barracks'] != undefined) && (city.buildings['barracks'].uptime > recentTime)) recentTime = city.buildings['barracks'].uptime;
   
   if (recentTime == undefined)
    {
    report = true;
    }
   else if (recentTime == 0)
    {
    report = true;
    }
   else if ((city.buildings['barracks'] != undefined) && (city.buildings['barracks'].rqtime != undefined) && (city.buildings['barracks'].rqtime <= EmpireBoard.StartTime) && (city.buildings['barracks'].rqtime > city.buildings['barracks'].uptime))
    {
    report = false;
    }
   else if ((city.cityMilitaryarmyrqtime != undefined) && (city.cityMilitaryarmyrqtime <= EmpireBoard.StartTime) && (city.cityMilitaryarmyrqtime > recentTime))
    {
    report = true;
    }
   else if (recentTime <= (EmpireBoard.StartTime - 1000*60*60*24*30))
    {
    report = true;
    }
   }
  else if ((view == 'cityMilitary-fleet') || (view == 'shipyard'))
   {
   var recentTime = 0;
   if (city.cityMilitaryfleettime != undefined) recentTime = city.cityMilitaryfleettime;
   if ((city.buildings['shipyard'] != undefined) && (city.buildings['shipyard'].uptime > recentTime)) recentTime = city.buildings['shipyard'].uptime;
   
   if (recentTime == undefined)
    {
    report = true;
    }
   else if (recentTime == 0)
    {
    report = true;
    }
   else if ((city.buildings['shipyard'] != undefined) && (city.buildings['shipyard'].rqtime != undefined) && (city.buildings['shipyard'].rqtime <= EmpireBoard.StartTime) && (city.buildings['shipyard'].rqtime > city.buildings['shipyard'].uptime))
    {
    report = false;
    }
   else if ((city.cityMilitaryfleetrqtime != undefined) && (city.cityMilitaryfleetrqtime <= EmpireBoard.StartTime) && (city.cityMilitaryfleetrqtime > recentTime))
    {
    report = true;
    }
   else if (recentTime <= (EmpireBoard.StartTime - 1000*60*60*24*30))
    {
    report = true;
    }
   }
   
  // Any buildings
  if (EmpireBoard.Ikariam.Get_BuildingUsage(view) != '')
   {
   if (city.buildings[view] != undefined)
    {
    if (view == 'townHall')
     {
     if (city.buildings[view].uptime == undefined)
      {
      report = true;
      }
     else if (city.buildings[view].uptime == 0)
      {
      report = true;
      }
     else if ((city.buildings[view].rqtime != undefined) && (city.buildings[view].rqtime <= EmpireBoard.StartTime) && (city.buildings[view].rqtime > city.buildings[view].uptime))
      {
      report = true;
      }
     else if (city.buildings[view].uptime <= (EmpireBoard.StartTime - 1000*60*60*24*30))
      {
      report = true;
      }
     }
    else if (view == 'tavern')
     {
     if (city.buildings[view].uptime == undefined)
      {
      report = true;
      }
     else if (city.buildings[view].uptime == 0)
      {
      report = true;
      }
     }
    else if (view == 'academy')
     {
     if (city.buildings[view].uptime == undefined)
      {
      report = true;
      }
     else if (city.buildings[view].uptime == 0)
      {
      report = true;
      }
     }
    else if (view == 'palace')
     {
     if (config.government == undefined)
      {
      report = true;
      }
     else if (city.buildings[view].uptime == undefined)
      {
      report = true;
      }
     else if (city.buildings[view].uptime == 0)
      {
      report = true;
      }
     else if ((city.buildings[view].rqtime != undefined) && (city.buildings[view].rqtime <= EmpireBoard.StartTime) && (city.buildings[view].rqtime > city.buildings[view].uptime))
      {
      report = true;
      }
     }
    else if (view == 'branchOffice')
     {
     if (city.buildings[view].uptime == undefined)
      {
      report = true;
      }
     else if (city.buildings[view].uptime == 0)
      {
      report = true;
      }
     else if ((city.buildings[view].rqtime != undefined) && (city.buildings[view].rqtime <= EmpireBoard.StartTime) && (city.buildings[view].rqtime > city.buildings[view].uptime))
      {
      report = true;
      }
     }
    else
     {
     if (city.buildings[view].uptime == undefined)
      {
      
      }
     else if (city.buildings[view].uptime == 0)
      {
      
      }
     else if ((city.buildings[view].rqtime != undefined) && (city.buildings[view].rqtime <= EmpireBoard.StartTime) && (city.buildings[view].rqtime > city.buildings[view].uptime))
      {
      report = true;
      }
     }
    }
   }
  }
 
 return (report == true ? '!' : '');
 }

function dropUndeliveredLoadingGoods()
 {
 var arrivinggoods = getArrValue(config, 'arrivinggoods', []);
 var city_id;
 var i = 0;
 for (city_id in arrivinggoods)
  {
  var rows = getArrValue(arrivinggoods, city_id, []);
  var city = getCity(city_id);
  var key;
  for (key in rows)
   {
      var row = rows[key];
   var quest = getArrValue(row, "quest", "");
   if (quest == 'loading')
    {
    if (delete config.arrivinggoods[city_id][key]) i++;
    continue;
    }
      var arrivetime = parseInt(getArrValue(row, "arrivetime", 0));
   if (EmpireBoard.StartTime < arrivetime)
    {
    if (delete config.arrivinggoods[city_id][key]) i++;
    continue;
    }
   }
  }
 }
 
function dropDeliveredGoods(city_id)
 {
 var rows = getArrValue(config.arrivinggoods, city_id, []);
 var city = getCity(city_id);
 var key;
 var i = 0;
 for (key in rows)
  {
     var row = rows[key];
     var arrivetime = parseInt(getArrValue(row, "arrivetime", 0));
  if (arrivetime <= city.prodtime)
   {
   if (delete config.arrivinggoods[city_id][key]) i++;
   }
  }
 }
 
function getDeliveredGoodsTransports(city_id, resName)
 {
 var sum = 0;
 var city = getCity(city_id);
 var rows = getArrValue(config.arrivinggoods, city_id, []);
 var key;
 for (key in rows)
  {
     var row = rows[key];
     var res = row["res"];
     var a = getArrValue(res, resName, 0);
     var arrivetime = parseInt(getArrValue(row, "arrivetime", ""));
  if ((a > 0) && (arrivetime > city.prodtime) && (EmpireBoard.StartTime >= arrivetime)) sum++;
  }
 return sum;
 }
 
function getBuildingPosition(city_id, name, defaultValue)
 {
 if (defaultValue == undefined) defaultValue = -1;
 var position = -1;
 var city = getCity(city_id);
 
 if ((city.buildings == undefined) || (city.buildings[name] == undefined))
  {
  if (name == 'townHall') position = 0;
  }
 else if ((city.buildings[name].link != undefined) && (city.buildings[name].link != ''))
  {
  // will deprecated
  var link = city.buildings[name].link;
  position = parseInt(/position=([0-9]+)/.exec(link)[1]);
  }
 else if (city.buildings[name].position != undefined)
  {
  position = city.buildings[name].position;
  }
 else if (name == 'townHall') position = 0;
 
 if (position == -1) position = defaultValue;
 return position;
 }
 
function getCityBuildingsCount(city_id, defaultValue)
 {
 if (defaultValue == undefined) defaultValue = 0;
 var count = 0;
 var city = getCity(city_id);

 if (city.citytime != undefined)
  {
  for (name in city.buildings)
   {
   if (city.buildings[name].levels != undefined)
    {
    var p;
    for (p in city.buildings[name].levels)
     {
     count++;
     }
    }
   else if (city.buildings[name].level != undefined)
    {
    count++;
    }
   }
  }

 if (count == 0) count = defaultValue;
 return count;
 }
 
// Get level instead building upgrading is finished
function getBuildingLevel(city_id, name, defaultValue, position)
 {
 if (defaultValue == undefined) defaultValue = 0;
 if (position == undefined) position = -1;
 var level = 0;
 var city = getCity(city_id);
 
 if ((city.buildings == undefined) || (city.buildings[name] == undefined))
  {
  if (name == 'townHall') level = 1;
  if (city.underConstructionName == name)
   {
   if (city.underConstructionTime <= EmpireBoard.StartTime) level++;
   }
  }
 else if (position == -1)
  {
  if (city.buildings[name].levels != undefined)
   {
   var p;
   for (p in city.buildings[name].levels)
    {
    level += city.buildings[name].levels[p];
    }
   }
  else
   {
   // deprecated
   level = getArrValue(city.buildings[name], "level", 0);
   }
  if (city.underConstructionName == name)
   {
   if (city.underConstructionTime <= EmpireBoard.StartTime) level++;
   }
  }
 else if (city.buildings[name].levels != undefined)
  {
  if (city.buildings[name].levels[position] != undefined)
   level = city.buildings[name].levels[position];
  if ((city.underConstructionName == name) && (city.underConstructionPosition == position))
   {
   if (city.underConstructionTime <= EmpireBoard.StartTime) level++;
   }
  }
  
 if (level == 0) level = defaultValue;
 return level;
 }

function getOnePeopleGrowthTime(happiness) {
  if (happiness != 0) {
    return Math.abs(3600/0.02/happiness*1000);
  }
  return "NaN";
}

function getEstimatedPopulationOld(population, startTime, currenttime, startHappiness) {
  var thappiness = startHappiness;
  startTime = Number(startTime);
  while (thappiness > 0) {
    var t = getOnePeopleGrowthTime(thappiness);
    if (t == "NaN" || startTime + t > currenttime) {
      break;
    }
    population++;
    thappiness--;
    startTime += t;
  }
  return population;
}

function getEstimatedPopulation(population, startTime, currenttime, startHappiness) {
  var thappiness = startHappiness;
  startTime = Number(startTime);
  if (thappiness != 0)
 {
 var t = getOnePeopleGrowthTime(thappiness);
 while (startTime + t < currenttime)
  {
  if (thappiness == 0)
   {
   break;
   }
  else if (thappiness > 0)
   {
      population++;
      thappiness--;
   startTime += t;
   }
  else
   {
      population--;
      thappiness++;
   startTime += t;
   }
  
  t = getOnePeopleGrowthTime(thappiness);
  }
 }
  
  return population;
}

function getGrowthRemainingHours(population, maxPopulation, startTime, happiness) {
  if (maxPopulation - population > happiness) {
    return "&#8734;"+EmpireBoard.Ikariam.LocalizationStrings('hour','timeunits','short');
  }
  var time = Number(startTime);
  while (population < maxPopulation) {
    var t = getOnePeopleGrowthTime(happiness);
    if (t == "NaN") {
      return "&#8734;"+EmpireBoard.Ikariam.LocalizationStrings('hour','timeunits','short');
    }
    time += t;
    population++;
    happiness--;
  }
  return EmpireBoard.Str.FormatRemainingTime(time - Number(startTime));
}

// Current selected city
if (current_city_id > 0)
 {
 var res = getCity(current_city_id);
 
 /* Update current city */
 
 // Stored resources
 res.wood = EmpireBoard.Ikariam.currentCity('wood','resources');
 if (res.wood == undefined)
  res.wood   = EmpireBoard.Str.To_Integer(EmpireBoard.DOM.Get_First_Node_TextContent("id('value_wood')"));
 
 res.wine = EmpireBoard.Ikariam.currentCity('wine','resources');
 if (res.wine == undefined)
  res.wine   = EmpireBoard.Str.To_Integer(EmpireBoard.DOM.Get_First_Node_TextContent("id('value_wine')"));
 
 res.marble = EmpireBoard.Ikariam.currentCity('marble','resources');
 if (res.marble == undefined)
  res.marble = EmpireBoard.Str.To_Integer(EmpireBoard.DOM.Get_First_Node_TextContent("id('value_marble')"));
 
 res.glass = EmpireBoard.Ikariam.currentCity('crystal','resources');
 if (res.glass == undefined)
  res.glass  = EmpireBoard.Str.To_Integer(EmpireBoard.DOM.Get_First_Node_TextContent("id('value_crystal')"));
 
 res.sulfur = EmpireBoard.Ikariam.currentCity('sulfur','resources');
 if (res.sulfur == undefined)
  res.sulfur = EmpireBoard.Str.To_Integer(EmpireBoard.DOM.Get_First_Node_TextContent("id('value_sulfur')"));
 
 
 if (EmpireBoard.Ikariam.Is_Version('0.4.1'))
  {
  // Couldn't recognize fields
  }
 else
  {
  // Resources to sold
  var wareNode = EmpireBoard.DOM.Get_First_Node_TextContent("//div[@id='cityResources']//li[@class='wood']/div[@class='tooltip']");
  if (/: [0-9,.]+[^0-9]+: ([0-9,.]+)/.exec(wareNode) != null)
   {
   res.tradewood = parseInt((RegExp.$1).replace(/[^0-9]/g, ""));
   }
  else
   {
   res.tradewood = 0;
   }
  var wareNode = EmpireBoard.DOM.Get_First_Node_TextContent("//div[@id='cityResources']//li[@class='wine']/div[@class='tooltip']");
  if (/: [0-9,.]+[^0-9]+: ([0-9,.]+)/.exec(wareNode) != null)
   {
   res.tradewine = parseInt((RegExp.$1).replace(/[^0-9]/g, ""));
   }
  else
   {
   res.tradewine = 0;
   }
  var wareNode = EmpireBoard.DOM.Get_First_Node_TextContent("//div[@id='cityResources']//li[@class='marble']/div[@class='tooltip']");
  if (/: [0-9,.]+[^0-9]+: ([0-9,.]+)/.exec(wareNode) != null)
   {
   res.trademarble = parseInt((RegExp.$1).replace(/[^0-9]/g, ""));
   }
  else
   {
   res.trademarble = 0;
   }
  var wareNode = EmpireBoard.DOM.Get_First_Node_TextContent("//div[@id='cityResources']//li[@class='glass']/div[@class='tooltip']");
  if (/: [0-9,.]+[^0-9]+: ([0-9,.]+)/.exec(wareNode) != null)
   {
   res.tradeglass = parseInt((RegExp.$1).replace(/[^0-9]/g, ""));
   }
  else
   {
   res.tradeglass = 0;
   }
  var wareNode = EmpireBoard.DOM.Get_First_Node_TextContent("//div[@id='cityResources']//li[@class='sulfur']/div[@class='tooltip']");
  if (/: [0-9,.]+[^0-9]+: ([0-9,.]+)/.exec(wareNode) != null)
   {
   res.tradesulfur = parseInt((RegExp.$1).replace(/[^0-9]/g, ""));
   }
  else
   {
   res.tradesulfur = 0;
   }
  }
  
 digProducedResources(res);
 
 if (res.buildings["townHall"] == undefined) res.buildings["townHall"] = {};
 var inhabitantsNode = EmpireBoard.DOM.Get_First_Node_TextContent("//span[@id='value_inhabitants']");
 if (/([0-9,.]+) \(([0-9,.]+)\)/.exec(inhabitantsNode) != null)
  {
  cizReg = RegExp.$1;
  popReg = RegExp.$2;
  res.buildings["townHall"].population = EmpireBoard.Str.To_Integer(popReg);
  res.buildings["townHall"].citizens = EmpireBoard.Str.To_Integer(cizReg);
  } else { 
  res.buildings["townHall"].population = 0;
  res.buildings["townHall"].citizens = 0;
  }
 
 res.actions = EmpireBoard.DOM.Get_First_Node_TextContent("//span[@id='value_maxActionPoints']");
 
 dropDeliveredGoods(current_city_id);
 
 if (EmpireBoard.Ikariam.View() == "plunder")
  {
  function reportPlunder()
   {
   setViewRqTime('finances');
   setViewRqTime('militaryAdvisorMilitaryMovements');
   EmpireBoard.DB.Save();
   }
  
  var n = document.getElementById("plunderbutton");
  n.addEventListener("click", reportPlunder, false);
  }
 else if (EmpireBoard.Ikariam.View() == "transport")
  {
  function reportTransport()
   {
   setViewRqTime('merchantNavy');
   EmpireBoard.DB.Save();
   }
  
  var n = document.getElementById("submit");
  n.addEventListener("click", reportTransport, false);
  }
 else if (EmpireBoard.Ikariam.View() == 'deployment')
  {
  EmpireBoard.ViewIsActionDeployment();
  }
 else if (EmpireBoard.Ikariam.View() == 'resource')
  {
  EmpireBoard.ViewIsIslandResource();
  }
 else if (EmpireBoard.Ikariam.View() == 'tradegood')
  {
  EmpireBoard.ViewIsIslandTradeGood();
  }
 }

// If main view is a city
if (city_idmainView > 0) 
 {
 var res = getCity(city_idmainView);
 
 // Update city info
 if (city_name != "") 
  {
  res.city_name = city_name;
  }
 if (city_coord != "") 
  {
  res.city_coord = city_coord;
  }
 if (island_id != "") 
  {
  res.island_id = island_id;
  }
  
 // Vue ville
 if (EmpireBoard.Ikariam.View() == 'city')
  {
  var orderedBuildings = EmpireBoard.Ikariam.BuildingsList();
  
  // Add new buildings
  var nodes = EmpireBoard.DOM.Get_Nodes("//li[contains(@id, 'position')]/a[contains(@href, 'view=')]");
  for(var i = 0; i < nodes.snapshotLength; i++)
   {
   var node = nodes.snapshotItem(i);
   var li = node.parentNode;
   
   var name = li.getAttribute("class");
   if (orderedBuildings[name] != undefined)
    {
    if (res.buildings[name] == undefined)
     {
     res.buildings[name] = {};
     }
    }
   else
    {
    if (res.buildings[name] != undefined)
     {
     // fix if not building...
     if (delete config["city_"+city_idmainView].buildings[name])
      EmpireBoard.Log.Add('Remove unknown building: '+name);
     }
    }
   }
  
  // Reset levels
  var res = getCity(city_idmainView);
  for (name in res.buildings)
   {
   res.buildings[name].position = -1; // Soon deprecated
   res.buildings[name].level = 0; // Soon deprecated
   res.buildings[name].levels = {};
   res.buildings[name].link = ''; // Soon deprecated
   }
    
  // Fetch levels & positions
  //var nodes = EmpireBoard.DOM.Get_Nodes("//li[contains(@id, 'position')]/a[contains(@href, 'view=')]");
  for (var i = 0; i < nodes.snapshotLength; i++)
   {
   var node = nodes.snapshotItem(i);
   var li = node.parentNode;
   
   // name
   var name = li.getAttribute("class");
   if (orderedBuildings[name] != undefined)
    {
    var position = parseInt(/position=([0-9]+)/.exec(node.href)[1]);
    // deprecated
    res.buildings[name].position = position;
    
    // level
    var level = "-";
    if (/([0-9]+)/.exec(node.title) != null)
     {
     level = RegExp.$1;
     }
    
    res.buildings[name].level = res.buildings[name].level + parseInt(level); // deprecated
    res.buildings[name].levels[position] = parseInt(level);
      
    res.buildings[name].link = node.href;// link, will deprecated
    }
   }
    
  // Nouvelle construction
    var node = EmpireBoard.DOM.Get_Nodes("//div[@class='constructionSite']/following-sibling::a[contains(@href, 'view=')]");
    if (node.snapshotLength >= 1) {
   //res.underConstruction = node.snapshotItem(0).title;
   res.underConstructionName = node.snapshotItem(0).parentNode.getAttribute("class");
   res.underConstructionPosition = /position=([0-9]+)/.exec(node.snapshotItem(0).href)[1];
   
   // Search cityCountdown
   var scripts = document.getElementsByTagName("script");
   var found = false;
   var sCode = '';
   for (var j = 0; j < scripts.length; j++)
    {
    var nScript = scripts[j];
    sCode = nScript.innerHTML;
    if (sCode.indexOf('cityCountdown') >= 0)
     {
     found = true;
     break;
     }
    }
   if (found == true)
    {
      var enddate = 0;
      var currentdate = 0;
      if (/enddate[^0-9]*([0-9]+)/.exec(sCode) != null) 
      {
     enddate = parseFloat(RegExp.$1) * 1000; 
      }
      if (/currentdate[^0-9]*([0-9]+)/.exec(sCode) != null) 
      {
     currentdate = parseFloat(RegExp.$1) * 1000; 
      }
      if (enddate != 0 && currentdate != 0) 
      {
     res.underConstructionTime = enddate - currentdate + new Date().getTime();
      }
    }
    }
    else 
    {
     //res.underConstruction = "-";
     res.underConstructionName = "";
     res.underConstructionPosition = -1;
     res.underConstructionTime = 0;
    }
  
  // Remove deleted buildings
  for (name in res.buildings)
   {
   var buildingsNb = 0;
   for (position in res.buildings[name].levels)
    {
    buildingsNb++;
    }
   
   if (buildingsNb == 0)
    {
    if (delete config["city_"+city_idmainView].buildings[name])
     EmpireBoard.Log.Add('Building removed: '+name);
    }
   }
  var res = getCity(city_idmainView);
   
  res.citytime = EmpireBoard.StartTime;
  
  EmpireBoard.ViewIsCity();
  }
  
 if ((EmpireBoard.Ikariam.View() == "cityMilitary-army") || (EmpireBoard.Ikariam.View() == "cityMilitary-fleet"))
  {
   //military-army and fleet unit counts
  
  if (res.units == undefined) { res.units = {}; }
  
  var names = EmpireBoard.DOM.Get_Nodes("//table/tbody/tr/th");
  var counts = EmpireBoard.DOM.Get_Nodes("//table/tbody/tr[@class='count']/td");
  if (names.snapshotLength >= counts.snapshotLength)
   {
   for(var i = 0; i < counts.snapshotLength; i++)
    {
    var n = EmpireBoard.Str.Trim(names.snapshotItem(i).title);
    
    var unit_id = '';
    if (EmpireBoard.Ikariam.View() == "cityMilitary-fleet")
     {
     var url_unit = /([a-z]+_[a-z]+)_faceright/.exec(names.snapshotItem(i).firstChild.src);
     if (url_unit != null)
      {
      unit_id = 'unit ' + RegExp.$1;
      }
     }
    else
     {
     var url_unit = /y60_([a-z]+)_/.exec(names.snapshotItem(i).firstChild.src);
     if (url_unit != null)
      {
      unit_id = 'unit ' + RegExp.$1;
      }
     }

    config["unitnames"][unit_id] = n;
    
    var c = counts.snapshotItem(i);
    var cnt = EmpireBoard.Str.To_Integer(c.innerHTML, 0);
    if (res.units[unit_id] == undefined)
     {
     res.units[unit_id] = {};
     }
    res.units[unit_id].count = cnt;
    if (cnt > 0) EmpireBoard.Log.Add('Unit['+unit_id+'] named "'+n+'": '+cnt);
    }
   }
  
  if (EmpireBoard.Ikariam.View() == "cityMilitary-army")
   {
   res.cityMilitaryarmytime = EmpireBoard.StartTime;
   }
  else if (EmpireBoard.Ikariam.View() == "cityMilitary-fleet")
   {
   res.cityMilitaryfleettime = EmpireBoard.StartTime;
   }
  }
 
 // view is a building ; common parsing
 if ((EmpireBoard.Ikariam.Get_BuildingUsage(EmpireBoard.Ikariam.View()) != '') && (EmpireBoard.Ikariam.Tab() == ''))
  {
  if (res.buildings[EmpireBoard.Ikariam.View()] == undefined) {
   res.buildings[EmpireBoard.Ikariam.View()] = {};
   }
  
  // Fetch position
  var position = -1;
  var node = EmpireBoard.DOM.Get_Nodes("//*[@id='buildingUpgrade']//ul[@class='actions']//a[contains(@href, 'position=')]");
  if (node.snapshotLength == 0)
   {
   node = EmpireBoard.DOM.Get_Nodes("//*[@id='buildingUpgrade']//a[@class='cancelUpgrade']");
   }
  if (node.snapshotLength >= 1)
   {
   var url_position = /position=([0-9]+)/.exec(node.snapshotItem(0).href);
   if (url_position != null) position = parseInt(RegExp.$1);
   }
  else if ((res.buildings[EmpireBoard.Ikariam.View()].position != undefined) && (res.buildings[EmpireBoard.Ikariam.View()].position != -1))
   {
   position = res.buildings[EmpireBoard.Ikariam.View()].position;
   }
  else
   {
   var url_position = /[\?&]position=([0-9]+)/.exec(document.URL);
   if (url_position != null) position = parseInt(RegExp.$1);
   }
  city_positionmainView = position;
  // deprecated
  res.buildings[EmpireBoard.Ikariam.View()].position = position;
  
  // Fetch level & detect upgrading
  var n = EmpireBoard.DOM.Get_First_Node("//*[@id='buildingUpgrade']//*[@class='buildingLevel']");
  if (n != null)
   {
   if (position != -1)
    {
    // Fetch level
    if (res.buildings[EmpireBoard.Ikariam.View()].levels == undefined) res.buildings[EmpireBoard.Ikariam.View()].levels = {};
    res.buildings[EmpireBoard.Ikariam.View()].levels[position] = EmpireBoard.Str.To_Integer(n.innerHTML,0);
    }
   
   EmpireBoard.Log.Add('View '+EmpireBoard.Ikariam.View()+' building level '+EmpireBoard.Str.To_Integer(n.innerHTML,0)+' at position '+position);
   
   // Ignorer ancien upgrade du batiment
   if (res.underConstructionPosition == undefined) res.underConstructionPosition = -1; // Deprecated
   if ((res.underConstructionName == EmpireBoard.Ikariam.View()) && (res.underConstructionPosition == position))
    {
    //res.underConstruction = '';
    res.underConstructionName = '';
    res.underConstructionTime = 0;
    res.underConstructionPosition = -1;
    }
   
   var scripts = document.getElementsByTagName("script");
   var found = false;
   var sCode = '';
   for (var j = 0; j < scripts.length; j++)
    {
    // search upgradeCountDown
    var nScript = scripts[j];
    sCode = nScript.innerHTML;
    if (sCode.indexOf('upgradeCountDown') >= 0)
     {
     found = true;
     break;
     }
    }
   if (found == true)
    {
    // buildings under upgrading
    var enddate = 0;
    var currentdate = 0;
    if (/enddate[^0-9]*([0-9]+)/.exec(sCode) != null)
     {
     enddate = parseFloat(RegExp.$1) * 1000; 
     }
    if (/currentdate[^0-9]*([0-9]+)/.exec(sCode) != null)
     {
     currentdate = parseFloat(RegExp.$1) * 1000; 
     }
    if (enddate != 0 && currentdate != 0)
     {
     // First, apply previous upgrading of other building
     if (res.underConstructionName != '')
      {
      if ((res.buildings[res.underConstructionName].uptime != undefined) && (res.buildings[res.underConstructionName].uptime > res.underConstructionTime))
       {
       // Ignore
       }
      else if ((res.citytime != undefined) && (res.citytime > res.underConstructionTime))
       {
       // Ignore
       }
      else if ((res.buildings[res.underConstructionName].uptime != undefined) && (res.citytime != undefined))
       {
       if ((res.underConstructionPosition != undefined) && (res.underConstructionPosition != -1))
        {
        if (res.buildings[res.underConstructionName].levels == undefined) res.buildings[res.underConstructionName].levels = {};
        res.buildings[res.underConstructionName].levels[res.underConstructionPosition] = parseInt(res.buildings[res.underConstructionName].levels[res.underConstructionPosition])+1;
        }
       else
        {
        // deprecated
        res.buildings[res.underConstructionName].level = parseInt(res.buildings[res.underConstructionName].level)+1;
        }
       }
      }
     
     // Define new upgrading
     //res.underConstruction = buildings[EmpireBoard.Ikariam.View()][0] + " level " + EmpireBoard.Str.To_Integer(n.innerHTML,0);
     res.underConstructionName = EmpireBoard.Ikariam.View();
     res.underConstructionPosition = position;
     res.underConstructionTime = enddate - currentdate + new Date().getTime();
     }
    }
   else
    {
    // Not upgrading
    }
   }
  res.buildings[EmpireBoard.Ikariam.View()].uptime = EmpireBoard.StartTime;
  }
  
 if (EmpireBoard.Ikariam.View() == 'townHall')
  {
  EmpireBoard.ViewIsBuildingTownHall();
  }
 else if (EmpireBoard.Ikariam.View() == 'branchOffice')
  {
  EmpireBoard.ViewIsBuildingBranchOffice();
  }
  else if (EmpireBoard.Ikariam.View() == "tavern")
  {
  EmpireBoard.ViewIsBuildingTavern();
  }
 else if (EmpireBoard.Ikariam.View() == 'academy')
  {
  EmpireBoard.ViewIsBuildingAcademy();
  }
 else if (EmpireBoard.Ikariam.View() == 'temple')
  {
  EmpireBoard.ViewIsBuildingTemple();
  }
 else if (EmpireBoard.Ikariam.View() == 'museum')
  {
  EmpireBoard.ViewIsBuildingMuseum();
  }
 else if (EmpireBoard.Ikariam.View() == 'workshop')
  {
  EmpireBoard.ViewIsBuildingWorkshop();
  }
 else if (EmpireBoard.Ikariam.View() == 'palace')
  {
  EmpireBoard.ViewIsBuildingPalace();
  }
 else if ((EmpireBoard.Ikariam.View() == "barracks") || (EmpireBoard.Ikariam.View() == "shipyard"))
  {
  //military-army unit counts
  var idx = 0;
  if (EmpireBoard.Ikariam.View() == "shipyard") { idx = 13; }
  if (res.units == undefined) { res.units = {}; }
  
  var hasNotices = false;
  if (document.getElementById('notices')) hasNotices = true;
  
  // Fetch units counters
  var names = EmpireBoard.DOM.Get_Nodes("//ul[@id='units']/li[contains(@class, 'unit')]/div[@class='unitinfo']/h4");
  var counts = EmpireBoard.DOM.Get_Nodes("//ul[@id='units']/li[contains(@class, 'unit')]/div[@class='unitinfo']/div[@class='unitcount']");
  var upkeeps = EmpireBoard.DOM.Get_Nodes("//ul[@id='units']/li[contains(@class, 'unit')]/div[@class='costs']/ul/li[@class='upkeep']");
  if (names.snapshotLength == counts.snapshotLength)
   {
   for (var i = 0; i < names.snapshotLength; i++)
    {
    var node = names.snapshotItem(i);
    var unit_id = '';
    try
     { unit_id = node.parentNode.parentNode.getAttribute("class"); }
    catch(e) { }
    
    var uKey = EmpireBoard.Ikariam.Trim_Unit(unit_id);
    
    var n = node.innerHTML;
    config["unitnames"][unit_id] = n;
    
    var c = counts.snapshotItem(i);
    var cnt = EmpireBoard.Str.To_Integer(c.innerHTML.replace(/<.+>/g, ""), 0);
    if (res.units[unit_id] == undefined)
     {
     res.units[unit_id] = {};
     }
    res.units[unit_id].count = cnt;
    EmpireBoard.Log.Add('Count['+unit_id+'] = '+cnt);
    
    // Init units under construction
    res.units[unit_id].construction = 0;
    
    if (hasNotices != true)
     {
     var upkeepElt = upkeeps.snapshotItem(i);
     var upkeep = EmpireBoard.Str.To_Integer(upkeepElt.innerHTML.replace(/<.+>/g, ""), 0);
     config["upkeeps"][uKey] = upkeep;
     EmpireBoard.Log.Add('Upkeep['+uKey+'] = '+upkeep);
     }
    }
   }
   
  // Search units under construction
  if (EmpireBoard.Ikariam.Is_Version('0.3.3'))
   {
   // Construction list
   var ucList = EmpireBoard.DOM.Get_Nodes("//div[@id='unitConstructionList']//div[@class='army_wrapper']/div[contains(@class,'army')]/div[@class='unitcounttextlabel']");
   EmpireBoard.Log.Add('Units construction lists = '+ucList.snapshotLength);
   if (ucList.snapshotLength >= 1)
    {
    var unitsIdClass = EmpireBoard.Ikariam.UnitsClassNames();
    for (var i = 0; i < ucList.snapshotLength; i++)
     {
     var uDIVcount = ucList.snapshotItem(i);
     var uDIV = uDIVcount.parentNode;
     var unit_num = EmpireBoard.Str.To_Integer(uDIV.className);
     if (unitsIdClass[unit_num] != undefined)
      {
      var unit_id = 'unit '+unitsIdClass[unit_num];
      var AmountInt = EmpireBoard.Str.To_Integer(uDIVcount.textContent, 1);
      
      EmpireBoard.Log.Add('Construction['+unit_id+'] = '+AmountInt);
      res.units[unit_id].construction = res.units[unit_id].construction + AmountInt;
      }
     }
     
    if (unsafeWindow && unsafeWindow.tmppbar)
     {
     //var startdate = unsafeWindow.tmppbar['startdate'];
     var currentdate = unsafeWindow.tmppbar['currenttime'];
     var enddate = unsafeWindow.tmppbar['enddate'];
     setViewRqTime(EmpireBoard.Ikariam.View(), city_idmainView, EmpireBoard.StartTime + (enddate - currentdate), true);
     }
    }
   }
  else
   {
   var currentUnit = EmpireBoard.DOM.Get_First_Node("//div[@id='unitConstructionList']//div[contains(@class, 'currentUnit')]");
   if (currentUnit != null)
    {
    var currentUnit_id = 'unit '+EmpireBoard.Ikariam.Trim_Unit(currentUnit.className);
    res.units[currentUnit_id].construction = 1;
     
    // Fetch queue
    var simUnits = 0;
    var Amounts = EmpireBoard.DOM.Get_Nodes("//div[@id='unitConstructionList']//li/div[@class='amount']");
    if (Amounts.snapshotLength >= 1)
     {
     for (var i = 0; i < Amounts.snapshotLength; i++)
      {
      var Amount = Amounts.snapshotItem(i);
      var AmountInt = EmpireBoard.Str.To_Integer(Amount.textContent, 1);
      var unit_id = 'unit '+EmpireBoard.Ikariam.Trim_Unit(Amount.parentNode.className);

      res.units[unit_id].construction = res.units[unit_id].construction + AmountInt;
      if (unit_id == currentUnit_id)
       {
       simUnits = simUnits + AmountInt;
       }
      }
     } 
    
    var scripts = document.getElementsByTagName("script");
    var found = false;
    for (var j = scripts.length-1; j >= 0; j--)
     {
     var nScript = scripts[j];
     var sCode = nScript.innerHTML;
     if (sCode.indexOf('buildProgress') > 0)
      {
      found = true;
      break;
      }
     }
    if (found == true)
     {
     var enddate = 0;
     if (/enddate[^0-9]*([0-9]+)/.exec(sCode) != null) {
      enddate = parseFloat(RegExp.$1) * 1000; 
      }
     var currentdate = 0;
     if (/currentdate[^0-9]*([0-9]+)/.exec(sCode) != null) {
      currentdate = parseFloat(RegExp.$1) * 1000; 
      }
     var startdate = 0;
     if (/startdate[^0-9]*([0-9]+)/.exec(sCode) != null) {
      startdate = parseFloat(RegExp.$1) * 1000; 
      }

     setViewRqTime(EmpireBoard.Ikariam.View(), city_idmainView, EmpireBoard.StartTime + (enddate - currentdate) + simUnits * (enddate - startdate), true);
     }
    }
   }
  }
 }
else
 {
 // Global views
 if (EmpireBoard.Ikariam.View() == "militaryAdvisorMilitaryMovements")
  {
  EmpireBoard.ViewIsMilitaryMovements();
  }
 else if (EmpireBoard.Ikariam.View() == 'premium')
  {
  EmpireBoard.ViewIsPremium();
  }
 else if (EmpireBoard.Ikariam.View() == 'researchAdvisor')
  {
  EmpireBoard.ViewIsResearchAdvisor();
  }
 else if (EmpireBoard.Ikariam.View() == 'researchOverview')
  {
  EmpireBoard.ViewIsResearchOverview();
  }
 else if (EmpireBoard.Ikariam.View() == "finances")
  {
  EmpireBoard.ViewIsFinances();
  }
 else if (EmpireBoard.Ikariam.View() == "diplomacyAdvisorTreaty")
  {
  EmpireBoard.ViewIsDiplomacyAdvisorTreaty();
  }
 else if (EmpireBoard.Ikariam.View() == "merchantNavy")
  {
  if (config["arrivinggoods"] == undefined) config["arrivinggoods"] = {};
  dropUndeliveredLoadingGoods();
  
  function grab_City_ID(rootElt)
   {
   var resID = 0;
   var alinks = rootElt.getElementsByTagName("a");
   for (var k=0; k < alinks.length; k++)
    {
    var resReg = /[\?&]{1}cityId=([0-9]+)&?/i.exec(alinks[k].href);
    if (resReg != null)
     {
     resID = parseInt(resReg[1]);
     break;
     }
    }
   
   return resID;
   }
  
  EmpireBoard.Log.Add("Fetch arriving goods");
  var foundLoading = false;
  var takeSomething = false;
  var resMi = EmpireBoard.DOM.Get_Nodes("//div[@id='mainview']//td[contains(@class, 'mission')]");
  if (resMi.snapshotLength > 0)
   {
   EmpireBoard.Log.Add("Found "+resMi.snapshotLength+" missions");
   // Villes du joueur
   var citiesIDs = {};
   var citiesNames = {};
   var res = EmpireBoard.DOM.Get_Nodes("//select[@id='citySelect']/option");
   for(var i = 0; i < res.snapshotLength; i++)
     {
     var n = res.snapshotItem(i);
     var cName = EmpireBoard.Ikariam.Trim_Coords(n.textContent);
     var cID = parseInt(n.value);
     citiesIDs[cName] = cID;
     citiesNames[cID] = cName;
     }
   
   // heures
   var mTimers = {};
   var scripts = document.getElementsByTagName("script");
   for (var j = 0; j < scripts.length; j++)
    {
    // search getCountdown
    var nScript = scripts[j];
    var sCode = nScript.innerHTML;
    if (sCode.indexOf('getCountdown') > 0)
     {
     var aCodeLines = sCode.split(';');
     for (var i=0; i < aCodeLines.length-1; i++)
      {
      var sValues = aCodeLines[i].substring(aCodeLines[i].indexOf('{')+1,aCodeLines[i].indexOf('}'));
      var sParts = sValues.split(',');
      if (sParts.length >= 3)
       {
       var sPart0 = sParts[0].split(':');
       var enddate = 1000*parseInt(EmpireBoard.Str.Trim(sPart0[1]));
       
       var sPart1 = sParts[1].split(':');
       var currentdate = 1000*parseInt(EmpireBoard.Str.Trim(sPart1[1]));
       
       var sID = sParts[2].substring(sParts[2].indexOf('"')+1,sParts[2].indexOf('"',sParts[2].indexOf('"')+2));
       
       mTimers[sID] = EmpireBoard.StartTime + Math.abs(enddate - currentdate);
       //EmpireBoard.Log.Add("mTimers["+sID+"] = "+(enddate - currentdate));
       }
      else
       {
       //EmpireBoard.Log.Add("Failed to fetch getCountdown");
       }
      }
     }
    }
    
   // infos
   for (var i = 0; i < resMi.snapshotLength; i++)
    {
    var nMi = resMi.snapshotItem(i);
    var tr = nMi.parentNode;
    var tds = tr.getElementsByTagName("td");
    var tdslength = tds.length;
    //var tds = tr.childNodes;

    var nSource = tds[1];
    var nTarget = tds[3];
    if (tdslength == 6)
     {
     // pillaging under 0.4.3
     var nETA = tds[4];
     var nRET = tds[4];
     var nAc = tds[5];
     }
    else if (EmpireBoard.DOM.Has_ClassName(tds[4],'speed'))
     {
     // transport under 0.4.3
     var nETA = tds[5];
     var nRET = tds[5];
     var nAc = tds[6];
     }
    else if (EmpireBoard.DOM.Has_ClassName(tds[5],'speed'))
     {
     // transport under 0.4.2
     var nETA = tds[4];
     var nRET = tds[6];
     var nAc = tds[7];
     }
    else
     {
     var nETA = tds[4];
     var nRET = tds[5];
     var nAc = tds[6];
     }
    
    if (nETA.id == '') continue;
    if (nRET.id == '') continue;
    //EmpireBoard.Log.Add('nETA.id = '+nETA.id);
    
    var trPayload = tr.nextSibling;
    var payload = trPayload.getElementsByTagName("img");
    var foundGoods = false;
    var foundArmy = false;
    var PayloadGoods = {};
    if (payload.length > 0)
     {
     var rKey = ''; 
     for (var j = 0; j < payload.length; j++)
      {
      if (payload[j].src.indexOf('wood') > 0)
       {
       if (rKey == 'wood') continue;
       rKey = 'wood';
       foundGoods = true;
       }
      else if (payload[j].src.indexOf('wine') > 0)
       {
       if (rKey == 'wine') continue;
       rKey = 'wine';
       foundGoods = true;
       }
      else if (payload[j].src.indexOf('marble') > 0)
       {
       if (rKey == 'marble') continue;
       rKey = 'marble';
       foundGoods = true;
       }
      else if (payload[j].src.indexOf('glass') > 0)
       {
       if (rKey == 'glass') continue;
       rKey = 'glass';
       foundGoods = true;
       }
      else if (payload[j].src.indexOf('sulfur') > 0)
       {
       if (rKey == 'sulfur') continue;
       rKey = 'sulfur';
       foundGoods = true;
       }
      else if (payload[j].src.indexOf('slinger') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('swordsman') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('phalanx') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('spearman') > 0)
       {
       // v 3.2 unit
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('archer') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('marksman') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('gyrocopter') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('steamgiant') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('bombardier') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('ram') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('catapult') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('mortar') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('medic') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else if (payload[j].src.indexOf('cook') > 0)
       {
       rKey = '';
       foundArmy = true;
       continue;
       }
      else
       {
       rKey = '';
       continue;
       }
       
      if ((PayloadGoods[rKey] == undefined) && ((rKey == 'wood') || (rKey == 'wine') || (rKey == 'marble') || (rKey == 'glass') || (rKey == 'sulfur')))
       {
       var rAmnt = EmpireBoard.Str.To_Integer(payload[j].title);
       PayloadGoods[rKey] = rAmnt;
       }
      }
     }
    
    var citySource;
    var citySourceID = 0;
    var cityTarget;
    var cityTargetID = 0;
    var quest;
    
    citySourceID = grab_City_ID(nSource);
    cityTargetID = grab_City_ID(nTarget);
    
    if (nMi.className.indexOf('returning') > 0)
     {
     quest = 'returning';
     if (tr.parentNode.parentNode.parentNode.parentNode.id == 'plunderingTransports')
      {
      if (foundGoods == true)
       {
       citySource = EmpireBoard.Str.Trim(nTarget.textContent);
       cityTarget = citySourceID;
       if (citiesNames[cityTargetID] == undefined)
        {
        citySource = EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent);
        cityTarget = cityTargetID;
        }
       }
      else continue;
      }
     else if ((foundArmy == true) && (foundGoods == false))
      {
      continue;
      }
     else
      {
      if (mTimers[nETA.id] == undefined)
       {
       mTimers[nETA.id] = EmpireBoard.StartTime + (1 * 20 * 60 * 1000);
       quest = 'loading';
       }
      citySource = EmpireBoard.Str.Trim(nTarget.textContent);
      cityTarget = citySourceID;
      //if (foundArmy == false) addTransport(citiesIDs[EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent)], nETA.id, mTimers[nETA.id]);
      if (foundGoods == false) continue;
      }
     }
    else if ((nMi.className.indexOf('gotoown') > 0) || (citiesNames[cityTargetID] != undefined))
     {
     if (foundArmy == true)
      {
      continue;
      }
     else 
      {
      citySource = EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent);
      cityTarget = cityTargetID;
      quest = 'gotoown';
      if (mTimers[nETA.id] == undefined)
       {
       mTimers[nETA.id] = EmpireBoard.StartTime + (1 * 20 * 60 * 1000);
       quest = 'loading';
       }
      else if (nAc.innerHTML == '')
       {
       citySource = EmpireBoard.Ikariam.Trim_PlayerName(nTarget.textContent);
       cityTarget = citySourceID;
       quest = 'halfturn';
       }
      //addTransport(citiesIDs[EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent)], nETA.id, mTimers[nETA.id]);
      if (foundGoods == false) continue;
      }
     }
    else if (nMi.className.indexOf('gotoforeign') > 0)
     {
     quest = 'gotoforeign';
     if (tr.parentNode.parentNode.parentNode.parentNode.id == 'plunderingTransports')
      {
      quest = 'plundering';
      if ((mTimers[nETA.id] != undefined) && (mTimers[nETA.id] > EmpireBoard.StartTime))
       {
       takeSomething = true;
       setViewRqTime('merchantNavy', 0, parseInt(mTimers[nETA.id]) + (1000*60*15));
       }
      else if ((mTimers[nRET.id] != undefined) && (mTimers[nRET.id] > EmpireBoard.StartTime))
       {
       takeSomething = true;
       setViewRqTime('merchantNavy', 0, EmpireBoard.StartTime + (1000*60*15));
       }
      continue;
      }
     else if (foundArmy == true)
      {
      continue;
      }
     else
      {
      if (mTimers[nRET.id] != undefined)
       {
       //addTransport(citiesIDs[EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent)], nETA.id, mTimers[nRET.id]);
       }
      else if (mTimers[nETA.id] != undefined)
       {
       //addTransport(citiesIDs[EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent)], nETA.id, mTimers[nETA.id]);
       }
      else
       {
       //addTransport(citiesIDs[EmpireBoard.Ikariam.Trim_PlayerName(nSource.textContent)], nETA.id, EmpireBoard.StartTime + (1000*60*15));
       }
      
      if ((foundGoods == true) && (nAc.innerHTML != ''))
       {
       continue;
       }
      else if ((foundGoods == true) && (nAc.innerHTML == '') && (mTimers[nETA.id] == undefined))
       {
       citySource = EmpireBoard.Str.Trim(nTarget.textContent);
       cityTarget = citySourceID;
       if (mTimers[nRET.id] != undefined)
        {
        mTimers[nETA.id] = mTimers[nRET.id];
        }
       else 
        {
        mTimers[nETA.id] = EmpireBoard.StartTime + (1 * 20 * 60 * 1000);
        }
       quest = 'loading';
       }
      else if ((foundGoods == false) && (nAc.innerHTML != ''))
       {
       if (mTimers[nETA.id] != undefined)
        {
        takeSomething = true;
        setViewRqTime('merchantNavy', 0, parseInt(mTimers[nETA.id]));
        }
       }
       
      if (foundGoods == false) continue;
      }
     }
    else continue;
    
    if ((foundGoods == true) && (cityTarget != undefined) && (mTimers[nETA.id] != undefined))
     {
     if (config["arrivinggoods"][cityTarget] == undefined) config["arrivinggoods"][cityTarget] = {};
     var idx = nETA.id;
     if (config["arrivinggoods"][cityTarget][idx] == undefined) config["arrivinggoods"][cityTarget][idx] = {};
     config["arrivinggoods"][cityTarget][idx]["startcity"] = citySource;
     if (config["arrivinggoods"][cityTarget][idx]["res"] == undefined) config["arrivinggoods"][cityTarget][idx]["res"] = PayloadGoods;
     config["arrivinggoods"][cityTarget][idx]["quest"] = quest;
     config["arrivinggoods"][cityTarget][idx]["arrivetime"] = parseInt(mTimers[nETA.id]);
     
     if (quest != 'loading')
      {
      setViewRqTime('', cityTarget, parseInt(mTimers[nETA.id]));
      }
     else
      {
      foundLoading = true;
      setViewRqTime('merchantNavy', 0, EmpireBoard.StartTime + (1000*60*10));
      }
     }
    }
   }
  
  // disable attention
  if ((foundLoading != true) && (takeSomething != true))
   {
   setViewRqTime('merchantNavy', 0);
   }
   
  config.merchantNavytime = EmpireBoard.StartTime;
  
  EmpireBoard.ViewIsMerchantNavy();
  }
  
  }

/**************************************************************************************************
 * Render tables
 *************************************************************************************************/
function renderTables()
 {
 var s = "";

 if (EmpireBoard.DB.Options.Prefs.TABLE_BUILDINGS == true) 
  {
  s += "<div id='EmpireBoardBuildings' class='Table'>";
  s += EmpireBoard.Renders.Buildings_Table_Content();
  s += "<p class='Caption'>"+
   "<span dir='ltr'>(<span class=Green>1-14</span>)</span> available free spaces for new buildings."+
   " <span dir='ltr'>(<span class=Red>!</span>)</span> require your attention to update overview's data."+
   "</p>";
  s += "</div>";
  }

 if (EmpireBoard.DB.Options.Prefs.TABLE_RESOURCES == true)
  {
  s += "<div id='EmpireBoardResources' class='Table'>";
  s += EmpireBoard.Renders.Resources_Table_Content();
  s += "<p class='Caption'>"+
   "<span dir='ltr'>(<span class=Green>1-9</span>)</span> available action points."+
   " <span dir='ltr'>(<span class=Red>!</span>)</span> require your attention to update overview's data."+
   " <span dir='ltr'>(<img src='skin/layout/icon-wall.gif' class='Safe' />)</span> resources safe against pillaging."+
   " <span dir='ltr'>(<span class=Green>*</span>)</span> some resources delivered."+
   "</p>";
  s += "</div>";
  }

 if (EmpireBoard.DB.Options.Prefs.TABLE_ARMYFLEET == true)
  {
  s += "<div id='EmpireBoardArmy' class='Table'><table class='Overview Army'>";
  s += EmpireBoard.Renders.ArmyFleet_Table_Content();
     s += "<p class='Caption'>"+
   "<span dir='ltr'>(<span class=Green>1-9</span>)</span> available action points."+
   " <span dir='ltr'>(<span class=Red>!</span>)</span> require your attention to update overview's data."+
   "</p>";
  s + "</div>";
  }

 var body = EmpireBoard.DOM.Get_First_Node("//body");
 var span = document.getElementById(EmpireBoard.MainID);
 if (span == null)
  {
  span = document.createElement('div');
  span.id = EmpireBoard.MainID;
  span.setAttribute("version", EmpireBoard.Version);
  if (EmpireBoard.Intl.LangDir() == "rtl")
   {
   span.setAttribute("dir", "rtl");
   span.setAttribute("class", "RtoL");
   }
  else
   {
   span.setAttribute("dir", "ltr");
   span.setAttribute("class", "LtoR");
   }
  span.innerHTML = s;
  body.appendChild(span);
  }
 else
  {
  if (EmpireBoard.Intl.LangDir() == "rtl")
   {
   span.setAttribute("dir", "rtl");
   span.setAttribute("class", "RtoL");
   }
  else
   {
   span.setAttribute("dir", "ltr");
   span.setAttribute("class", "LtoR");
   }
  span.innerHTML = s;
  }

 //settings table
 function reset_all_data()
  {
  var answer = confirm(EmpireBoard.ScriptName+":\n\nAre you sure you want to delete ALL stored data ?");
  if (answer)
   {
   config = {};
   EmpireBoard.DB.Save();

   EmpireBoard.DB.Options = {};
   EmpireBoard.DB.Save_Options();

   window.location.href = window.location.href;
   }
  }

 function myChkEventHandler()
  {
  this.value = (this.value == '1' ? '0' : '1');
  EmpireBoard.DB.Options.Prefs[this.lang] = (this.value == '1');
  EmpireBoard.DB.Save_Options();
  }

 function myChgEventHandler() 
  {
  EmpireBoard.DB.Options.Prefs[this.lang] = this.value;
  EmpireBoard.DB.Save_Options();
  }

 function createChk(propertyName, propertyValue)
  {
  var btn = document.createElement('input');
  btn.type = "checkbox";
  btn.lang = propertyName;
  btn.value = (propertyValue == true ? '1' : '0');
  if (propertyValue == true) 
   {
   btn.checked = "checked";
   }
  btn.addEventListener('click', myChkEventHandler, false);
  return btn;
  }

 function createInp(propertyName, propertyValue) 
  {
  var btn = document.createElement('input');
  btn.type = "text";
  btn.lang = propertyName;
  btn.value = propertyValue;
  btn.addEventListener('change', myChgEventHandler, false);
  return btn;
  }

 function createTxtr(propertyName, propertyValue, rows, cols) 
  {
  var btn = document.createElement('textarea');
  btn.cols = (cols != undefined) ? cols : 50;
  btn.rows = (rows != undefined) ? rows : 15;
  btn.lang = propertyName;
  btn.value = propertyValue;
  btn.addEventListener('change', myChgEventHandler, false);
  return btn;
  }

 function createSlct(propertyName, propertyValue, items)
  {
  var btn = document.createElement('select');
  btn.lang = propertyName;
  for(key in items) 
   {
   var o = document.createElement("option");
   o.value = key;
   o.text = items[key];
   btn.add(o, null);
   }
  btn.value = propertyValue;
  btn.addEventListener('change', myChgEventHandler, false);
  return btn;
  }

 function createRow(title, input) 
  {
  var tr = document.createElement('tr');
  var td = document.createElement('td');
  td.setAttribute("align", "right");
  td.setAttribute("style", "border-style: dotted; border-width: 1px;");
  td.innerHTML = title;
  tr.appendChild(td);
  var td = document.createElement('td');
  td.setAttribute("align", "left");
  td.setAttribute("style", "border-style: dotted; border-width: 1px;");
  td.appendChild(input);
  tr.appendChild(td);
  return tr;
  }

 function createRowChk(title, propertyName, propertyValue) 
  {
  return createRow(title, createChk(propertyName, propertyValue));
  }

 function createRowInput(title, propertyName, propertyValue) 
  {
  return createRow(title, createInp(propertyName, propertyValue));
  }

 function createRowTxtr(title, propertyName, propertyValue, rows, cols) 
  {
  return createRow(title, createTxtr(propertyName, propertyValue, rows, cols));
  }

 function createRowSlct(title, propertyName, propertyValue, items) 
  {
  return createRow(title, createSlct(propertyName, propertyValue, items));
  }

 var t = document.createElement('table');
 t.id = EmpireBoard.MainID+"Settings";
 t.setAttribute("style", "display: none;");
 t.setAttribute("align", "right");
 t.appendChild(createRowChk("Show resources table:", "TABLE_RESOURCES", EmpireBoard.DB.Options.Prefs.TABLE_RESOURCES));
 t.appendChild(createRowChk("Show buildings table:", "TABLE_BUILDINGS", EmpireBoard.DB.Options.Prefs.TABLE_BUILDINGS));
 t.appendChild(createRowChk("Show army and fleet table:", "TABLE_ARMYFLEET", EmpireBoard.DB.Options.Prefs.TABLE_ARMYFLEET));
 t.appendChild(createRowSlct("Resource progress bar mode:", "PROGRESS_BAR_MODE", EmpireBoard.DB.Options.Prefs.PROGRESS_BAR_MODE, {off: "off", time: "based on remaining time", percent: "based on fullness percentage"}));
 t.appendChild(createRowSlct("Language:", "LANGUAGE", EmpireBoard.DB.Options.Prefs.LANGUAGE, EmpireBoard.Intl.Languages()));

 var tr = document.createElement('tr');
 t.appendChild(tr);
 var td = document.createElement('td');
 tr.appendChild(td);
 td.setAttribute("colspan", "2");
 var buttonsPanel = document.createElement('div');
 td.appendChild(buttonsPanel);

 //reset button
 var n = document.createElement('input');
 n.type = "button";
 n.value = "Reset all data";
 n.setAttribute("class", "button");
 n.setAttribute("style", "display: inline !important;");
 n.addEventListener("click", reset_all_data, false);
 buttonsPanel.appendChild(n);

 function show_hide_table()
  {
  var n = document.getElementById(EmpireBoard.MainID+"Settings");
  var m = document.getElementById(EmpireBoard.MainID+"Addons");
  if (n.style.display == 'none')
   {
   n.style.display = 'table';
   m.style.display = 'block';
   this.value = EmpireBoard.Intl.TT("hide_settings");
   }
  else
   {
   n.style.display = 'none';
   m.style.display = 'none';
   this.value = EmpireBoard.Intl.TT("show_settings");
   }
  }

 //now adds table
 span.appendChild(t);

 var ul = document.createElement('ul');
 ul.id = EmpireBoard.MainID+'Addons';
 ul.setAttribute("style", "display: none;");
 ul.innerHTML = '<u>Registered add-ons :</u>';
 span.appendChild(ul);

 var p = document.createElement('p');
 p.setAttribute("class", "Footer");

 var n = document.createElement('span');
 n.innerHTML = 'Powered by <a href="http://userscripts.org/scripts/show/41051" target="_blank"><b>'+EmpireBoard.ScriptName+'</b></a> <span dir="ltr">(<span>v. <i>' + EmpireBoard.Version + '</i></span> - <a target="_blank" href="http://feeds.feedburner.com/ikariam-v3-empire-board">last changes</a>)</span>. ';
 if (EmpireBoard.DB.Options['AvailableVersion'] > EmpireBoard.Version)
  n.innerHTML += '<a href="'+EmpireBoard.ScriptURL+'?version='+EmpireBoard.DB.Options['AvailableVersion']+'.user.js'+'" style="color: red;"><b>NEW RELEASE V. <i>'+EmpireBoard.DB.Options['AvailableVersion']+'</i> AVAILABLE !</b></a> ';
 p.appendChild(n);

 var n = document.createElement('input');
 n.type = "button";
 n.value = EmpireBoard.Intl.TT("show_settings");
 n.setAttribute("class", "button");
 n.addEventListener("click", show_hide_table, false);
 p.appendChild(n);

 // footer
 span.appendChild(p);
 }

if ((EmpireBoard.Ikariam.Is_Logged() == true) && (EmpireBoard.Ikariam.View() != '') && (EmpireBoard.Ikariam.View() != 'errorLoggedOut') && (EmpireBoard.Ikariam.View() != 'no-login-umod'))
 {
 // Fix for v3
 var body = EmpireBoard.DOM.Get_First_Node("//body");
 var script = document.createElement('script');
 script.type = "text/javascript";
 script.src = "/js/wz_tooltip.js";
 body.appendChild(script);
 
 EmpireBoard.Renders.Set_Common_Styles();

 renderTables();

 EmpireBoard.Tooltip.CreateContainer(EmpireBoard.MainID+'Tooltip', EmpireBoard.MainID);
 EmpireBoard.Handlers.Attach_Events();
 
 EmpireBoard.Handlers.Start_Timers();
 
 EmpireBoard.DB.GarbageCollector();
 EmpireBoard.DB.Save();
 };
 
EmpireBoard.EndTime = new Date().getTime();
EmpireBoard.Log.Add('Ended after '+((EmpireBoard.EndTime - EmpireBoard.StartTime)/1000)+'s');


Continue reading...

ScrobbleSmurf


// ==UserScript==
// @name           SrobbleSmurf
// @namespace      scrobble
// @description    Scrobble songs from YouTube.
// @include        http://youtube.com/watch?*v=*
// @include        http://www.youtube.com/watch?*v=*
// @include        http://youtube.com/watch#!*v=*
// @include        http://www.youtube.com/watch#!*v=*
// Version 1.1.2
// ==/UserScript==
/* You can contact me on Twitter @DDaanV or Last.FM (DDaan90).
 * - Don't steal all of my code and say it's yours. 
 * - You may steal parts of my code. Credits are not required. 
 * - Suggestions and improvements are welcome. 
 * - This code is free, when you take parts of my code expect it will remain free.
 */
/* TODO's: 
 * - Create more reliable timer (use system time).
 * - Use JSON parser instead of 'eval' which should increase performance.
 * - Server-side: Attemp to swap artist and title when scrobbling failed.
 * - Scrobble from YouTube user channels. (http://www.youtube.com/user/* && http://youtube.com/user/*)
 * - Better error handling. 
 */
var cosmicPanda = false;
var showTime = 0;
var scrobLength = -1;
var noScrobble = false;
var iTunesArtistAndTitleFound = false;

var scrobbleAutoCollapse = true;
var scrobblePercentage = 50;
var scrobbleEnabled = true;
var scrobbleFilter = "";

var apiKey = "870da3cecaf2a63062b474a93ace2285";
var lastFmAuthenticationUrl = "http://www.last.fm/api/auth";
var authenticationSessionUrl = "http://daan.hostei.com/lastfm/auth/getSession";
var scrobbleSongUrl = "http://daan.hostei.com/lastfm/scrobbleSong";
var altScrobbleSongUrl = "http://ddaan.nl/lastfm/scrobbleSong";
var youtubeApiUrl = "http://gdata.youtube.com/feeds/api/videos/";

//--General functions.
/**
 * Initialisation function, should be called only once when the document is loaded. 
 * The ScrobbleSmurf plug-in will be added to the YouTube page.
 */
function initialize() {
 try {
  localStorageEnabledCheck();
  fixVideoEmbedOpaqueness();
  loadSavedFormValues();
  cosmicPandaLayout();
  addStyle();
  addLastFmOptions();
  addLastFmButton();
  addMenuPop();
  activateLastFmButtons();
  var song = getSongInformation();
  fillSongInformation(song);
  videoApiRequest();
  
  if(!isLoggedIn()) {
   showLoginHideReset();
   tryGetAuthToken();
  } else {
   setUsernameSpan();
   hideLoginShowReset();
  }
 } catch (e) {
  console.log(e);
 }
}

/**
 * Shows a message in the ScrobbleSmurf menu.
 */
function menuAlert(text) {
 text = text.replace(/\n/gi, "<br/>");
 var scrobbCount = document.getElementById("scrobble-counter");
 var scrobbMessg = document.getElementById("scrobble-message");
 var scrobbMsg = document.getElementById("scrobble-msg");
 scrobbCount.style.display = "none";
 scrobbMessg.style.display = "block";
 scrobbMsg.innerHTML = text + ".";
}
//--Google Chrome compatibility functions.
/**
 * Alerts the user when the browser does not support HTML5 local storage.
 */
function localStorageEnabledCheck()
{
 var localStorageEnabled = window.localStorage;
 if(!localStorageEnabled) {
  alert("Your browser does not support HTML5 local storage.\n" +
   "This is required to use ScrobbleSmurf V1.1 and up.");
 }
}
/**
 * Adds wmode=opaque to which the video is embedded. 
 * Used to overlay the options in Google Chrome.
 */
function fixVideoEmbedOpaqueness()
{
  var wmodeParam = document.createElement("param");
  wmodeParam.setAttribute("name", "wmode");
  wmodeParam.setAttribute("value", "opaque");

  var div = document.getElementById("watch-player");
  var videoEmbed = div.getElementsByTagName("embed")[0];
  var parent = videoEmbed.parentNode;
  
  parent.removeChild(videoEmbed);
  
  videoEmbed.setAttribute("wmode", "opaque");
  videoEmbed.appendChild(wmodeParam);
  
  parent.appendChild(videoEmbed);
}

//--Functions for the additional menu pop up.
/**
 * Adds the more options pop up and background to the YouTube page. 
 * By default the pop up is hidden, to show it call the moreOptions method.
 */
function addMenuPop()
{
 var page = document.getElementById("page");
 var pop = document.createElement("div");
 pop.setAttribute("id", "lastfm-moreoptions-pop");
 pop.style.visibility = "hidden";
 pop.innerHTML = "<h2>More Last FM Options</h2>\n" + 
 "<form id=\"lastfm-moreoptions-form\">\n" +
 "<table class=\"lastfm-moreoptions-table\"><tr>\n" +
 " <td>Collapse ScrobbleSmurf menu</td>\n" +
 " <td><input name=\"lastfm-moreoptions-collapse\" type=\"radio\" value=\"collapse\">Collapse the menu by default.<br/>\n" + 
 " <input name=\"lastfm-moreoptions-collapse\" type=\"radio\" value=\"expand\">Expand the menu by default.</td>\n" +
 "</tr><tr>\n" +
 " <td>Scrobble percentage</td>\n" +
 " <td><select style=\"width:100%\" name=\"lastfm-moreoptions-percentage\">\n" +
 "  <option value=\"20\">20 percent</option>\n" +
 "  <option value=\"30\">30 percent</option>\n" +
 "  <option value=\"40\">40 percent</option>\n" +
 "  <option value=\"50\">50 percent</option>\n" +
 "  <option value=\"60\">60 percent</option>\n" +
 "  <option value=\"70\">70 percent</option>\n" +
 "  <option value=\"80\">80 percent</option>\n" +
 " </select></td>\n" +
 "</tr><tr>\n" +
 " <td>Words to remove<br/><i>(separate by semicolon)<i></td>\n" +
 " <td><input style=\"width:100%\" id=\"lastfm-moreoptions-filter\" name=\"lastfm-moreoptions-filter\" type=\"text\"></input></td>\n" +
 "</tr><tr>\n" +
 " <td>Enable all scrobbling</td>\n" +
 " <td><input name=\"lastfm-moreoptions-scrobble\" type=\"radio\" value=\"yes\">Yes, scrobble my songs to Last FM<br/>\n" + 
 " <input name=\"lastfm-moreoptions-scrobble\" type=\"radio\" value=\"no\">No, do not scrobble my songs</td>\n" +
 "</tr></table>\n" +
 "</form>\n" +
 "<div class=\"lastfm-moreoptions-controls\">\n" + 
 " <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-moreoptions-ok\" title=\"Save changes\"><span class=\"yt-uix-button-content\">Save</span></button>\n" +
 " <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-moreoptions-cancel\" title=\"Discard changes\" style=\"margin-left: 14px;\"><span class=\"yt-uix-button-content\">Cancel</span></button>\n" +
 "</div>\n"; 
 page.appendChild(pop);
 addMenuBack(pop);
 centerPopup(pop);
 
 setDefaultSelectValue("lastfm-moreoptions-percentage", scrobblePercentage);
 activatePopupControls();
}
/**
 * Add the more options pop up background to the YouTube page.
 */
function addMenuBack(menuElement)
{
 var overlay = document.createElement("div");
 overlay.setAttribute("id", "lastfm-moreoptions-back");
 overlay.style.visibility = "hidden";
 menuElement.parentNode.appendChild(overlay);
 
 var body = document.body, html = document.documentElement;
 var height = Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight);
 overlay.style.height = height + "px";
}
/**
 * Attemps to center the more options pop up.
 */
function centerPopup(popup) {
 var windowWidth = document.documentElement.clientWidth;
 var windowHeight = document.documentElement.clientHeight;
 
 var popupWidth = parseInt(popup.clientWidth);
 var popupHeight = parseInt(popup.clientHeight);
 
 popup.style.position = "absolute";
 var top = windowHeight/2-popupHeight/2;
 var left = windowWidth/2-popupWidth/2;
 popup.style.top = (top > 0 ? top : 0) + "px";
 popup.style.left = (left > 0 ? left : 0) + "px";
}
/**
 * Attemps to center the more options pop up.
 */
function activatePopupControls()
{
 var okButton = document.getElementById("lastfm-moreoptions-ok");
 var cancelButton = document.getElementById("lastfm-moreoptions-cancel");
 
 okButton.addEventListener("click", saveCurrentForm, false);
 cancelButton.addEventListener("click", function() { moreOptions(true); }, false);
}
/**
 * Saves the currently selected values from the more options menu pop up to the user's hard disk.
 */
function saveCurrentForm()
{
 var sform = document.getElementById("lastfm-moreoptions-form");
 
 var collapse = getSelectedRadioButton("lastfm-moreoptions-collapse");
 var percentage = sform.elements["lastfm-moreoptions-percentage"].value;
 var filter = sform.elements["lastfm-moreoptions-filter"].value;
 var enable = getSelectedRadioButton("lastfm-moreoptions-scrobble");
 
 localStorage.setItem("lastfmExpand", (collapse != "expand"));
 localStorage.setItem("lastfmPercentage", percentage);
 localStorage.setItem("lastfmFilter", filter);
 localStorage.setItem("lastfmScrobble", enable != "no");
  
 moreOptions(true); 
 loadSavedFormValues();
}
/**
 * Loads values from the more options menu pop up the user saved to it's hard disk. 
 */
function loadSavedFormValues()
{
 scrobbleAutoCollapse = localStorage.getItem("lastfmExpand");
 scrobblePercentage = localStorage.getItem("lastfmPercentage");
 scrobbleFilter = localStorage.getItem("lastfmFilter");
 scrobbleEnabled = localStorage.getItem("lastfmScrobble");
}
//--Functions to get additional video information from the YouTube API.
/**
 * Updates the cosmicPanda variable which is a different version of the YouTube layout.
 * Different layout requires different handling.
 */
function cosmicPandaLayout() {
 var r = document.getElementById("watch-frame-bottom");
 if(r != null) {
  cosmicPanda = true;
 }
}
/**
 * Gets the current YouTube video ID from the browser URL.
 */
function getYouTubeVideoId() {
 var regex = /(\?|&)v=[^\?&#]*/gi;
 var matches = document.URL.match(regex);
 if(matches == null) {
  return null;
 }
 var videoCode = matches[0].substring(3);
 return videoCode;
}
/**
 * Uses the YouTube API to get more information from the current video.
 */
function videoApiRequest() {
 var vidId = getYouTubeVideoId();
 if(vidId == null) {
  return;
 }
 GM_xmlhttpRequest({
  method: "GET",
  url: youtubeApiUrl + vidId + "?v=2&alt=jsonc",
  headers: {
   "Accept": "application/json"
  },
  onload: videoApiResponse,
  onerror: function() { "menuAlert(\"Could not connect \nto YouTube API.\")" }
 });
}
/**
 * Handles data returned from the YouTube API which provides more data from the video.
 */
function videoApiResponse(response) {
 var jsonObject = eval("(" + response.responseText + ")");
 var category = jsonObject.data.category.toLowerCase();
 if(countOccurencesInString(category, "music") < 1) {
  noScrobble = true;
  menuAlert("No music video");
  return;
 }
 
 if(scrobbleEnabled !== true && scrobbleEnabled !== "true") {
  dontScrobble();
 }
 
 scrobLength = Math.round(jsonObject.data.duration / (100 / scrobblePercentage) );
 timePlus();
 
 if(!iTunesArtistAndTitleFound) {
  var vidTitle = jsonObject.data.title;
  if(filterWords != null)
  {
   var filterWords = scrobbleFilter.split(";");
   
   for(word in filterWords) {
    var escapedFilterWords = escapeAllRegexSpecialChars(filterWords[word].trim());
    var filterRegex = new RegExp(escapedFilterWords, "gi");
    vidTitle = vidTitle.replace(filterRegex, "");
   }
  }
  
  var song = tryStripSongFromTitle(vidTitle);
  fillSongInformation(song);
 }
}
/**
 * Escapes all characters with a special meaning in Regular Expressions.
 */
function escapeAllRegexSpecialChars(regexString)
{
 var specials = [
      '/', '.', '*', '+', '?', '|',
      '(', ')', '[', ']', '{', '}', '\\'
    ];
    var regex = new RegExp(
      '(\\' + specials.join('|\\') + ')', 'g'
    );
 
 regexString= regexString.replace(regex, '\\$1'); 
 return regexString;
}
//--Scrobbling functions.
/**
 * Adds one to timer and updates the textspans. When the timeLeft is 0 (or less the song will be scrobbled).
 */
function timePlus() {
 showTime++;
 var timeLeft = scrobLength - showTime;
 
 var timeSpan = document.getElementById("scrobble-time");
 timeSpan.innerHTML = timeLeft;
 
 if(timeLeft > 0) {
  if(!noScrobble) {
   setTimeout(timePlus, 1000);
  }
 } else {
  scrobbleSong();
 }
}
/**
 * Srobbles a song using the values from the two textinput's from the form.
 */
function scrobbleSong() {
 var artist = document.getElementById("lastfm-artist").value;
 var title = document.getElementById("lastfm-title").value;
 if(artist == "" || title == "") {
  menuAlert("Insufficient artist \nand title information");
  return;
 }

 if(!isLoggedIn())
 {
  menuAlert("Please authenticate \nbefore scrobbling");
 }
 else
 {
  var user = getUserCredentials();
  var timestamp = Math.round(new Date().getTime()/1000.0);
  
  var args = "?artist=" + encodeURIComponent(artist) + "&sk=" + user.sessionkey + 
  "&timestamp=" + timestamp + "&track=" + encodeURIComponent(title);
  
  menuAlert("Scrobbling song");
   
  GM_xmlhttpRequest({
   method: "GET",
   url: altScrobbleSongUrl + args,
   onload: scrobbleFeedback,
   onerror: function() {
    GM_xmlhttpRequest({
     method: "GET",
     url: scrobbleSongUrl + args,
     onload: scrobbleFeedback,
     onerror: function() {
      menuAlert("Scrobbling failed");
     }
    });
   }
  });
 }
}
/**
 * Show the user a response to their Scrobble attempt.
 */
function scrobbleFeedback(response) {
 var text;
 if(countOccurencesInString(response.responseText, "\r?\n") > 0) {
  //Split the response, since my hosting puts in some spam.
  text = response.responseText.split(/\r?\n/gim)[0].replace(/#/g, "");
 } else {
  text = response.responseText;
 }
 var jsonObject = eval("(" + text + ")");
 
 if(jsonObject.error != null) {
  menuAlert("Error connecting to Last.FM.\n" + 
  "Error code: " + jsonObject.error + "\n" +
  "Message: " + jsonObject.message + ".");
 } else {
  var artist = jsonObject.scrobbles.scrobble.artist.text;
  var title = jsonObject.scrobbles.scrobble.track.text;
  menuAlert("Scrobbled song\nArtist: " + artist + "\nTitle: " + title);
 }
}
//--Login functions.
/**
 * Attempts to get a Last FM token from the URL. If so authenticate the user.
 */
function tryGetAuthToken() {
 var url = document.URL;
 var tokenRegex = /(\?|&)token=[0-9a-fA-F]{32}/gi;
 var matches = url.match(tokenRegex);
 if(matches == null) {
  return;
 }
 var rawToken = matches[0];
 var token = rawToken.substring(7); //7, based on '?' or '&' and 'token='.
 GM_xmlhttpRequest({
  method: "GET",
  url: authenticationSessionUrl + "?token=" + token,
  headers: {
   "Accept": "text/html" //My hosting puts in html spam
  },
  onload: getSessionKey
 });
}
/**
 * Gets a Last FM session key and store it for later reference.
 */
function getSessionKey(response) {
 //Split the response, since my hosting puts in some spam.
 var text = response.responseText.split(/\r?\n/gim)[0];
 var jsonObject = eval("(" + text + ")");
 
 if(jsonObject.error != null) {
  menuAlert("Error connecting to Last.FM.\n" + 
  "Error code: " + jsonObject.error + "\n" +
  "Message: " + jsonObject.message + ".");
 } else {
  localStorage.setItem("lastfmUsername", jsonObject.session.name);
  localStorage.setItem("lastfmSessionkey", jsonObject.session.key);
  
  setUsernameSpan();
  hideLoginShowReset();
 }
}
/**
 * Check whether user credentials are stored or not.
 */
function isLoggedIn() {
 var username = localStorage.getItem("lastfmUsername");
 var sessionk = localStorage.getItem("lastfmSessionkey");
 if(username == null || sessionk == null) {
  return false;
 }
 return true;
}
/**
 * Gets the user's stored credentials.
 */
function getUserCredentials() {
 var user = new Object();
 user.username = localStorage.getItem("lastfmUsername");
 user.sessionkey = localStorage.getItem("lastfmSessionkey");
 return user;
}
/**
 * Fills in the user's username on the Last FM form.
 */
function setUsernameSpan() {
 var usernameSpan = document.getElementById("lastfm-username");
 usernameSpan.innerHTML = getUserCredentials().username;
}
/**
 * Hides the 'login'-form, shows the 'reset login'-form
 */
function hideLoginShowReset() {
 var reset = document.getElementById("lastfm-options-resetlogin");
 var login = document.getElementById("lastfm-options-login");
 login.style.display = "none";
 reset.style.display = "block";
}
/**
 * Shows the 'login'-form, hides the 'reset login'-form
 */
function showLoginHideReset() {
 var reset = document.getElementById("lastfm-options-resetlogin");
 var login = document.getElementById("lastfm-options-login");
 reset.style.display = "none";
 login.style.display = "block";
}
//--Functions to edit the YouTube lay-out.
/**
 * Adds CSS style to the page used by this plug in.
 */
function addStyle() {
 var head = document.getElementsByTagName("head")[0];
 var style = document.createElement("style");
 head.appendChild(style);
 style.setAttribute("type", "text/css");
 style.innerHTML = "#masthead-lastfm { border: 1px solid #CCC; background: #F6F6F6; }\n" +
 "#lastfm-container { margin: 0 auto; width: 970px; }\n" +
 "ul#lastfm-options li { height: 90px; float: left; margin: 8px 0px; padding: 0px 24px; border-right: 1px solid #CCCCCC; }\n" + 
 "ul#lastfm-options p { padding-left: 1px; }\n" +
 "#lastfm-moreoptions { margin-bottom: 6px; }\n" +
 "#lastfm-moreoptions-pop { height:296px; width:432px; background:#FFF; border:2px solid #CCC; z-index:4; padding:12px; font-size:13px; }\n" +
 "#lastfm-moreoptions-back { position:absolute; height:100%; width:100%; top:0; left:0; background:#000; border:1px solid #333; z-index:3; opacity: 0.6; }\n" + 
 ".lastfm-moreoptions-table { border-collapse:collapse; }\n" + 
 ".lastfm-moreoptions-table td { border-bottom:1px solid #EEE; padding:8px 6px 10px; }\n" +
 ".lastfm-moreoptions-controls { text-align:center; margin-top:6px; }\n"; 
}
/**
 * Adds a button to the page to toggle the Last FM form.
 */
function addLastFmButton() {
 var buttonId = "lastfm-button";
 var container = document.getElementById("masthead-user-bar-container");
 var lastFmImgCode = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/gD+AP7rGNSCAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAACVElEQVQ4y6WRXUiTURjHDxVFlkxsqZub4twMm5mxydbWjBXZB2QRrSCJuuwygi68E6K7oJsI8qIo0vmx6d50i80MLaTYtGRuM2XMbY7NyhnWdH6s/p33nTPxTjvw45zn+b3/95zDIb/dLrJ8px7L56s2B82wWZKs1yN5rnJr0Cz5VVuB/4HMnihHhjhlRp8mvq6fcd/1adY7Mq0rQ5QS0EgxqiqF55Ieo2dV8KlLEdLKOBemM1t7rtbCYzjJrdlejDoSpIWvugRfGu9iZT6BzPjpH8fI9Tp4qRu5cByJ0OSam4+E4aa9gEoCMnakCMPX6jgx5bChv6YKg4YzmAv4sRifQZ9ShhDTgYVvX2E/dRTvL5/GQjQC/70GsFniPFiIiWdN+JNKoU8txyd5IVy0N3jjCvdTV2MDJhkTVpJJDN6+hV5NJRxlBfhYLoRbLgIZkOYhaGWw+GMWdkkehqkcovTKBEjEoog5P6BHr8LsmHftCkGLCQOqCjhlBSBvivZhvOUFJywHRHhXzOewiXPhfZo+GaOrBiPKxWutAs77jdy3vieP8JZmiUOQg/6b9VzT+/I5WkuE6NYoMdb0GB3KQ/ToC5geHoJFo0BLPg9tOjVSS0uYaDfCRrPEvj8bnfy9+PzwAbdbZsS9HpikYjgMFzEX/PcC3AtNhWHVH4OVnw3Sk5OFV5R23m4YRflgajRolYhhpHUnLwtmSjNdmxWH0UVdl1bF1azrpjnSuWcXMpgpHavzxr5p1W30hCkWo23nji3BZknEZiNmoQDN27dtCjbDZv8CFCxvhvx1W58AAAAASUVORK5CYII%3D";
 var htmlCode = "<div style=\"margin-left: 6px;\" id=\"masthead-user-bar\">" +
 "   <div id=\"masthead-user\">" +
 " <span  name=\"lastfm-expander\" class=\"yt-uix-expander yt-uix-expander-collapsed\" id=\"masthead-user-expander\">" +
 "     <span id=\"lastfm-button\">" +
 "     <span tabindex=\"1\" class=\"yt-uix-expander-head yt-rounded\" id=\"masthead-user-wrapper\">" +
 "  <button role=\"button\" class=\"yt-uix-button yt-uix-button-text yt-uix-button-toggle\" id=\"masthead-user-button\" type=\"button\">" +
 "      <span class=\"yt-uix-button-content\">" +
 "   <span id=\"masthead-user-image\">" +
 "       <span class=\"clip\">" +
 "    <span class=\"clip-center\">" +
 "        <img alt=\"Last.FM\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/gD+AP7rGNSCAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAACVElEQVQ4y6WRXUiTURjHDxVFlkxsqZub4twMm5mxydbWjBXZB2QRrSCJuuwygi68E6K7oJsI8qIo0vmx6d50i80MLaTYtGRuM2XMbY7NyhnWdH6s/p33nTPxTjvw45zn+b3/95zDIb/dLrJ8px7L56s2B82wWZKs1yN5rnJr0Cz5VVuB/4HMnihHhjhlRp8mvq6fcd/1adY7Mq0rQ5QS0EgxqiqF55Ieo2dV8KlLEdLKOBemM1t7rtbCYzjJrdlejDoSpIWvugRfGu9iZT6BzPjpH8fI9Tp4qRu5cByJ0OSam4+E4aa9gEoCMnakCMPX6jgx5bChv6YKg4YzmAv4sRifQZ9ShhDTgYVvX2E/dRTvL5/GQjQC/70GsFniPFiIiWdN+JNKoU8txyd5IVy0N3jjCvdTV2MDJhkTVpJJDN6+hV5NJRxlBfhYLoRbLgIZkOYhaGWw+GMWdkkehqkcovTKBEjEoog5P6BHr8LsmHftCkGLCQOqCjhlBSBvivZhvOUFJywHRHhXzOewiXPhfZo+GaOrBiPKxWutAs77jdy3vieP8JZmiUOQg/6b9VzT+/I5WkuE6NYoMdb0GB3KQ/ToC5geHoJFo0BLPg9tOjVSS0uYaDfCRrPEvj8bnfy9+PzwAbdbZsS9HpikYjgMFzEX/PcC3AtNhWHVH4OVnw3Sk5OFV5R23m4YRflgajRolYhhpHUnLwtmSjNdmxWH0UVdl1bF1azrpjnSuWcXMpgpHavzxr5p1W30hCkWo23nji3BZknEZiNmoQDN27dtCjbDZv8CFCxvhvx1W58AAAAASUVORK5CYII%3D\">" +
 "        <span class=\"vertical-center\">" +
 "        </span>" +
 "    </span>" +
 "       </span>" +
 "   </span>" +
 "   <span class=\"yt-uix-expander-arrow\">" +
 "   </span>" +
 "      </span>" +
 "  </button>" +
 "     </span>" +
 "  </span>" +
 " </span>" +
 " </div>" +
 "</div>";
 
 container.innerHTML += htmlCode;
 var button = document.getElementById(buttonId);
 button.addEventListener("click", toggleLastFmForm, false);
 
 if(scrobbleAutoCollapse !== true && scrobbleAutoCollapse !== "true") {
  toggleLastFmForm();
  var buttonCont = document.getElementById("lastfm-button").parentNode;
  var newClass = buttonCont.getAttribute("class") + "yt-uix-expander-collapsed";
  buttonCont.setAttribute("class", newClass);
 }
}
/**
 * Adds a division with the Last FM menu. 
 */
function addLastFmOptions() {
 var swapImgCode = "data:image/png;base64,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";
 var scrobbleSmurfImgCode = "data:image/png;base64,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%3D";
 var htmlCode = "<div id=\"masthead-lastfm\" style=\"display: none;\">\n" +
 " <div id=\"lastfm-container\">\n" +
 "  <ul id=\"lastfm-options\">\n" +
 "  <li id=\"lastfm-options-resetlogin\">\n" +
 "   <h3>Authenticate</h3>\n" +
 "   <p>Logged in as: <br/><span id=\"lastfm-username\"></span></p>\n" +
 "   <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-reset\" title=\"Log out from Last FM\"><span class=\"yt-uix-button-content\">Reset</span></button>\n" +
 "  </li>\n" +
 "  <li id=\"lastfm-options-login\">" +
 "   <h3>Authenticate</h3>\n" +
 "   <p>To log in this page <br/>will be closed.</p>" +
 "   <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-login\" title=\"Log in to Last FM\"><span class=\"yt-uix-button-content\">Authenticate</span></button>" +
 "  </li>\n" +
 "  <li>\n" +
 "   <h3>Miscellaneous</h3>\n" +
 "   <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-moreoptions\" title=\"More options menu\"><span class=\"yt-uix-button-content\">More options</span></button><br/>\n" +
 "   <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-man-scrobble\" title=\"Scrobble now\"><span class=\"yt-uix-button-content\">Scrobble manual</span></button>\n" +
 "  </li>\n" +
 "  <li>\n" +
 "   <h3>Scrobbling</h3>\n" +
 "   <table>\n" +
 "    <tbody>\n" +
 "    <tr><td><p>Artist:</p></td><td><input type=\"text\" id=\"lastfm-artist\"></td><td rowspan=\"2\">" +
 "     <img src=\"" + swapImgCode + "\" id=\"lastfm-swap-songinfo\" width=\"20px\" height=\"41px\"></td></tr>\n" +
 "    <tr><td><p>Title:</p></td><td><input type=\"text\" id=\"lastfm-title\"></td></tr>\n" +
 "    </tbody>\n" +
 "   </table>\n" +
 "  </li>\n" +
 "  <li style=\"max-width: 228px; border-right: none;\">\n" +
 "   <h3>Status</h3>\n" +
 "   <div id=\"scrobble-counter\">\n" +
 "    <p><span id=\"scrobble-in\">Scrobble in:</span> <span id=\"scrobble-time\"></span></p>\n" +
 "    <button class=\"yt-uix-button yt-uix-tooltip\" id=\"lastfm-noscrobble\" title=\"Stops the automatic scrobble timer\"><span class=\"yt-uix-button-content\">Don't scrobble</span></button>\n" +
 "   </div>\n" +
 "   <div id=\"scrobble-message\" style=\"display: none;\">\n" +
 "    <p id=\"scrobble-msg\"></p>\n" + 
 "   </div>\n" +
 "  </li>\n" +
 "  <li style=\"float: right; border-right: none;\">" +
 "   <div id=\"scrobblesmurf-logo\">\n" +
 "    <img src=\"" + scrobbleSmurfImgCode + "\"/>\n" +
 "   </div>\n" +
 "  </li>\n" +
 "  </ul>\n" +
 "  <div style=\"clear: both;\"></div>\n" +
 " </div>\n" +
 "</div>\n";
 var container = document.getElementById("masthead-container");
 container.innerHTML += htmlCode;
}
/**
 * Toggles the Last FM form added by this plug in. 
 * The stated is based on the Last FM button at the right top.
 */
function toggleLastFmForm() {
 var container = document.getElementById("masthead-lastfm");
 var buttonCont = document.getElementById("lastfm-button").parentNode;
 if(countOccurencesInString(buttonCont.getAttribute("class"), "yt-uix-expander-collapsed") >= 1) {
  container.style.display = "block";
 } else { 
  container.style.display = "none";
 }
}
//--Last FM form button listeners and actions.
/**
 * Add event listeners to all the menubuttons added by this plug-in.
 */
function activateLastFmButtons() {
 authenticateButton();
 resetAuthenicateButton();
 dontScrobbleButton();
 moreOptionsButton();
 manScrobbleButton();
 swapSongInfoButton();
}
/**
 * Add the event listener to the 'authenticate'-button.
 */
function authenticateButton() {
 var authButton = document.getElementById("lastfm-login");
 authButton.addEventListener("click", authenticate, false);
}
/**
 * Redirects the user to Last FM to authenticate. When they allow they will 
 * be directed back and an authentication token will be added to the URL.
 */
function authenticate() {
 var tokenRegex = /(\?|&)token=[^&\?]*/gi;
 var currentURL = document.URL.replace(tokenRegex, "");
 if(!stringContainsChar(currentURL, "?")) {
  currentURL = currentURL.replace("&", "?");
 }
 var redirectURL = lastFmAuthenticationUrl + "?api_key=" + apiKey +"&cb=" + currentURL;
 window.location.href = redirectURL;
}
/**
 * Add the event listener to the 'reset login'-button.
 */
function resetAuthenicateButton() {
 var resetButton = document.getElementById("lastfm-reset");
 resetButton.addEventListener("click", resetAuth, false);
}
/**
 * Resets the authentication. A user would have to authenticate again to scrobble.
 */
function resetAuth() {
 localStorage.removeItem("lastfmUsername");
 localStorage.removeItem("lastfmSessionkey");
 showLoginHideReset();
}
/**
 * Adds the event listener to the 'do not scrobble'-button.
 */
function dontScrobbleButton() {
 var dontScrobbleButton = document.getElementById("lastfm-noscrobble");
 dontScrobbleButton.addEventListener("click", dontScrobble, false);
}
/**
 * Disables scrobbling for this time.
 */
function dontScrobble() {
 noScrobble = true;
 
 var dontScrobbleButton = document.getElementById("lastfm-noscrobble");
 dontScrobbleButton.className += " yt-uix-button-toggled";
}
/**
 * Adds the event listener to the 'options'-button.
 */ 
function moreOptionsButton()
{
 var moreOptionsButton = document.getElementById("lastfm-moreoptions");
 moreOptionsButton.addEventListener("click", function(){ moreOptions(false); }, false);
}
/**
 * Shows or hides a pop-up containing some less common options for this plug-in.
 */
function moreOptions(hide)
{
 var back = document.getElementById("lastfm-moreoptions-back");
 var pop = document.getElementById("lastfm-moreoptions-pop");
 
 if(hide) {
  back.style.visibility = "hidden";
  pop.style.visibility = "hidden";
 } else {
  if(scrobbleAutoCollapse === true || scrobbleAutoCollapse === "true") {
   setRadioButtonChecked("lastfm-moreoptions-collapse", "collapse");
  } else {
   setRadioButtonChecked("lastfm-moreoptions-collapse", "expand");
  }
  document.getElementById("lastfm-moreoptions-filter").value = scrobbleFilter;
  if(scrobbleEnabled === true || scrobbleEnabled === "true") {
   setRadioButtonChecked("lastfm-moreoptions-scrobble", "yes");
  } else {
   setRadioButtonChecked("lastfm-moreoptions-scrobble", "no");
  }
 
  pop.style.visibility = "visible";
  back.style.visibility = "visible";
 }
}
/**
 * Adds the event listener to the 'manual scrobble'-button.
 */ 
function manScrobbleButton()
{
 var manScrobbButton = document.getElementById("lastfm-man-scrobble");
 manScrobbButton.addEventListener("click", scrobbleManual, false);
}
/**
 * Disables scrobbling for this time.
 */
function scrobbleManual() {
 noScrobble = true;
 scrobbleSong();
 
 var manScrobbButton = document.getElementById("lastfm-man-scrobble");
 manScrobbButton.removeEventListener('click', scrobbleManual, false);
 manScrobbButton.className += " yt-uix-button-toggled";
}
/**
 * Adds the event listener to the two arrows, the 'swap song info'-button.
 */
function swapSongInfoButton()
{
 var swapSongButton = document.getElementById("lastfm-swap-songinfo");
 swapSongButton.addEventListener("click", swapSongInfo, false);
}
/**
 * Swaps the artist field's value with the title field's value.
 */
function swapSongInfo()
{
 var artistInput = document.getElementById("lastfm-artist");
 var titleInput = document.getElementById("lastfm-title");
 
 var oldArtist = artistInput.value;
 var oldTitle = titleInput.value;
 
 artistInput.value = oldTitle;
 titleInput.value = oldArtist;
}
//--Functions to for song information.
/**
 * Fills the 'song'-form with the passed song.
 */
function fillSongInformation(song) {
 var artistInput = document.getElementById("lastfm-artist");
 var titleInput = document.getElementById("lastfm-title");
 
 if(song.artist != null) {
  artistInput.value = song.artist;
 }
 if(song.title != null) {
  titleInput.value = song.title;
 }
}
/**
 * Gets song information from the currently played YouTube video using the iTunes metadata.
 */
function getSongInformation() {
 var song = new Object();
 song.artist = tryGetArtistMeta();
 song.title = tryGetTitleMeta();
 if(song.artist && song.title) {
  iTunesArtistAndTitleFound = true;
 }
 return song; 
}
/**
 * Gets song artist from the metadata in the video description.
 */
function tryGetArtistMeta() {
 var xPath = "//ul[@id='watch-description-extra-info']/li[@class='full-link']/a/span[@class='metadata-info']/span";
 try { 
  var artistNodes = document.evaluate(xPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  var artist = artistNodes.singleNodeValue.firstChild.nodeValue;
 } catch (e) {
 }
 return artist;
}
/**
 * Gets song title from the metadata in the video description.
 */
function tryGetTitleMeta() {
 var xPath, title;
 if(cosmicPanda) {
  xPath = "//ul[@id='watch-description-extra-info']/li[2]/span[@class='metadata-info']";
 } else {
  xPath = "//ul[@id='watch-description-extra-info']/li[3]/span[@class='metadata-info']";
 }
 try {
  var songNodes = document.evaluate(xPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
  var rawTitle = songNodes.singleNodeValue.firstChild.nodeValue; //rawSong still contains 'buy on' text.
  rawTitle = removeBreaks(rawTitle);
  title = stringBetweenChars(rawTitle, "\"");
  if(typeof(title) === "undefined") {
   title = stringBetweenChars(rawTitle, "'");
  }
 } catch (e) {
 }
 return title;
}
/**
 * Tries to strip a song's information from the passed video title. 
 * First looks for quoted text which will be used as song title. 
 * The rest of the title will then be used as artist. 
 * If it fails it split the title between a dash and uses the first part as artist. 
 * The second part will be used as title. 
 */
function tryStripSongFromTitle(title) {
 var song = new Object();
 if(countOccurencesInString(title, "\"") >= 2) {
  song = getSongFromQuotedTitle(title, "\"");
 } else if(countOccurencesInString(title, "'") >= 2) {
  song = getSongFromQuotedTitle(title, "'");
 } else if(stringContainsChar(title, "-")) {
  var split = title.split("-");
  song.artist = trim(split[0]);
  song.title = trim(split[1]);
 }
 return song;
}
/**
 * Gets a song from a video title that contains quotes.
 */
function getSongFromQuotedTitle(vidTitle, quoteString) {
 var song = new Object();
 song.title = stringBetweenChars(vidTitle, quoteString);
 var regex = new RegExp(quoteString + song.title + quoteString);
 song.artist = vidTitle.replace(regex, "");
 return song;
}
//--JavaScript common utilization functions.
/**
 * Removes breaks from a text.
 */
function removeBreaks(text) {
 return text.replace(/(\n|\r)/gm, "");
}
/**
 * Checks whether a text contains a character.
 */
function stringContainsChar(text, charac) {
 for(var i = 0; i < text.length; i++) {
  if(text[i] == charac) {
   return true;
  }
 }
 return false;
}
/**
 * Counts the occurences of a certain object in a text.
 */
function countOccurencesInString(text, toMatch) {
 var regex = new RegExp(toMatch, "g");
 var matches = text.match(regex);
 if(matches == null) {
  return 0;
 }
 return matches.length;
}
/**
 * Finds a text between two characters.
 */
function stringBetweenChars(text, charac) {
 var part, results = [];
 var regex = new RegExp(charac + "([^" + charac +"]+)", "g");
 while(part = regex.exec(text)) {
  results.push(part[1]);
 }
 results = results.splice(0, 1);
 if(typeof(results) === "string") {
  return results;
 } else {
  return results[0];
 }
}
/**
 * Trims a text from spaces.
 */
function trim(text) {
 return text.replace(/^\s*/, "").replace(/\s*$/, "");
}
/**
 * Gets the selected value from a radio button group.
 */
function getSelectedRadioButton(name) {
 var radioButtons = document.getElementsByName(name);
 for(x in radioButtons) {
  if(radioButtons[x].checked) {
   return radioButtons[x].value;
  }
 }
 return null;
}
/**
 * Sets all values from a radio button group to unchecked except the passed value's radio button.
 */
function setRadioButtonChecked(name, value) {
 var radioButtons = document.getElementsByName(name);
 for(x in radioButtons) {
  if(radioButtons[x].value == value) {
   radioButtons[x].checked = true;
  } else {
   radioButtons[x].checked = false;
  }
 }
}
/**
 * Sets a select input to a default value.
 */
function setDefaultSelectValue(name, value) {
 var selectInput = document.getElementsByName(name)[0];
 var options = selectInput.getElementsByTagName("option");
 for(var i = 0; i < options.length; i++) {
  if(options[i].value == value) {
   options[i].setAttribute("selected", "");
  } else {
   options[i].removeAttribute("selected");
  }
 }
 
 var parent = selectInput.parentNode;
 parent.removeChild(selectInput);
 parent.appendChild(selectInput);
}

initialize();

Continue reading...