Travian3 Beyond SC

By codelovers Last update 8 hours ago — Installed 47,021 times.

There are 22 previous versions of this script.

the source is over 100KB, syntax highlighting in the browser is too slow

// ==UserScript==
// @name Travian3 Beyond SC
// @author originally written by Travian3 Beyond 2.6c Victor Garcia (aka Croc) updated by bluelovers
// @version sc updated by bluelovers
// @description  Enables some Travian v3 features updated by bluelovers

// @include http://*.travian*/*.php*
// @include http://*.travian.*/*.php*
// @exclude http://*.travian*.*/hilfe.php*
// @exclude http://*.travian*.*/index.php*
// @exclude http://*.travian*.*/anleitung.php*
// @exclude http://*.travian*.*/impressum.php*
// @exclude http://*.travian*.*/anmelden.php*
// @exclude http://*.travian*.*/gutscheine.php*
// @exclude http://*.travian*.*/spielregeln.php*
// @exclude http://*.travian*.*/links.php*
// @exclude http://*.travian*.*/geschichte.php*
// @exclude http://*.travian*.*/tutorial.php*
// @exclude http://*.travian*.*/manual.php*
// @exclude http://*.travian*.*/ajax.php*
// @exclude http://*.travian*.*/ad/*
// @exclude http://*.travian*.*/chat/*
// @exclude http://forum*.travian*
// @exclude http://board*.travian*
// @exclude http://shop*.travian*
// @exclude *.css
// @exclude *.js
// ==/UserScript==

/*
 * This script is licensed under the
 * Creative Commons Attribution-NonCommercial-ShareAlike 2.5 Spain License.
 * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.5/es/
 */

/**
 * xingulin: 載入 jQuery
 * 參考網址︰http://joanpiedra.com/jquery/greasemonkey/
 * Begin
 */
// Add jQuery
//var GM_JQ = elem('script');
//GM_JQ.src = 'http://jquery.com/src/jquery-latest.pack.js';
//GM_JQ.type = 'text/javascript';
//document.getElementsByTagName('head')[0].appendChild(GM_JQ);
//
//// Check if jQuery's loaded
//function GM_wait() {
//	if(typeof unsafeWindow.jQuery == 'undefined') { window.setTimeout(GM_wait,100); }
//	else { $ = unsafeWindow.jQuery; letsJQuery(); }
//}
//GM_wait();
//
//// All your GM code must be inside this function
//function letsJQuery() {
//	funcionPrincipal();
//}
///**
// * End
//*/

function getInnerText(who) {
//	return (who['textContent'] ? who['textContent'] : who['innerHTML']);
	return (who.textContent ? who.textContent : who.innerHTML);
}

var aLang = new Array();
var aLangTroops = new Array();
var aLangBattleAnalyse = new Array();

// Funcion principal ejecutada cuando se ha cargado toda la pagina
function funcionPrincipal(e){
	// Momento de inicio de ejecucion del script
	var tiempo_ejecucion = new Date().getTime();

	var version = "2.6c MunLightDoll updated by  by bluelovers";

	var arrayRecursosCasilla = new Array();

	var XPFirst = XPathResult.FIRST_ORDERED_NODE_TYPE;		// Constante que devuelve el primer elemento por XPath
	var XPList  = XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE;		// Constante que devuelve una lista de elementos por XPath
	var XPIter  = XPathResult.UNORDERED_NODE_ITERATOR_TYPE;		// Constante que deuvelve un iterador de elementos por XPath

	var actual = new Array(4);		// Informacion de recursos almacenados
	var total = new Array(4);		// Capacidad de los almacenes y granero
	var produccion = new Array(4);		// Produccion por segundo
	var imagenes = new Array();		// Imagenes pre-cargadas

	// Indica para que servidores esta disponible el servicio de Travian World
	// IMPORTANTE: Por favor, no cambiar / Please, don't change. Travian World is only available for the servers indicated below
	var tw_server = new Array();

	// Se estima cada linea como una altura de 20 pixeles
	var pixelsPorLinea = 20;

	var timestamp = new Date();

	var idioma2;

	if (find("//input[@name='login']", XPFirst)) {
		setTimeout(function() {
			if (document.getElementsByName('login')){
				var ex = ".//input[@value='login']";
				tag = document.evaluate(
				  	ex,
						document,
						null,
						XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
						null);

				var ex = ".//input[@type='password' and contains(@value, '*')]";
				tag2 = document.evaluate(
				  	ex,
						document,
						null,
						XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
						null);

				if(tag.snapshotLength && tag2.snapshotLength)
				{
					loginButton = tag.snapshotItem(0);
					loginButton.click();
				}
			} } , 10000);

		return false;
	} else if (location.href.match(/karte2.php($|\?z=)/)) {

		var areas = find("//area[@href='#']", XPList);
			for (var j = 0; j < areas.snapshotLength; j++){
				var area = areas.snapshotItem(j);

//				opener.location.href="karte.php?d=269313&c=0d", self.close()

				area.getAttribute('onclick').search(/karte.php\?d=(\d+)/);
				var z = RegExp.$1;

				area.setAttribute('z', z);
				area.onclick = false;
				area.setAttribute('onclick', '');

				_attachEvent(area, 'click', function (e) {
					window.location.href = 'karte2.php?z=' + e.target.getAttribute('z');
//					alert(e.target.getAttribute('z'));
					return doane(e);
				});

//				area.href = 'javascript:void(0);';
				area.href = 'karte.php?z='+z;
			}

		return false;
	}

	getGeneralData();

	getlocalStr(idioma);

	var buildingCost = new Array();
	initBuildCost();

	var uc, ats, dts, romans, teutons, gauls, nature;
	initTroopData();

	initImagenes();

	var cssStyle = "";
	cssStyle += "#tabla_mapa {width:800px;}";
	cssStyle += ".bttable {width:100%; height:129px;}";
	cssStyle += ".dcol {color:#A0A0A0;}";
	cssStyle += ".tb_coords { word-break: keep-all; font: 11px/1.5em Tahoma,Verdana,Arial !important; color:grey; }";

	cssStyle += '::selection {background-color: #DD0044;color: #FFFFFF;}::-moz-selection {background-color: #DD0044;color: #FFFFFF;}';

	cssStyle += '.inline {clear: both; display: inline;}';

	GM_addStyle(cssStyle);

	/* Acciones generales a todas las paginas */

//	getGeneralData();
	sanearEnlaces();
	hideAd();
	quickLinks();
	buildingLinks();
//	playerLinks();
	calculateFillTime();
	cityLinks();
	crearTooltip();
//	createMenu();
	borrarCuenta();
	confirmDelete();

	/* Acciones especificas para algunas paginas */
	if (location.href.indexOf('build.php?') != -1){
		quickCity();
		recursosMercado();
		tiempoExplorarUnidades();
		tiempoExplorar();
		QP_addOwnTownTotalTroopsTable();
	}
	if (location.href.indexOf('build.php') != -1){
		try {
			calculateBuildTime();
			tiempoExplorarUnidades();
			tiempoExplorar();
			mostrarVentas();
			getTransport_time_arrival();
		} catch (e) {}
	}
	if (location.href.indexOf('dorf1') != -1)		preCalculate1();
	if (location.href.indexOf('dorf2') != -1)		preCalculate2();
//	if (location.href.indexOf('berichte.php?id=') != -1)	reportBatalla();
	if (location.href.indexOf('a2b.php') != -1){
		quickCity();
		ataqueDefecto();

		// Travian: Battle Analyse
		genreporta2b();

		_attachEvent(document, 'keyup', a2b);
		_attachEvent(document, 'click', a2b);

		// Travian: Battle Analyse
	}
	if (location.href.indexOf('nachrichten.php') != -1)	{
		opcionOcultaMensajes();

		if (location.href.match(/nachrichten.php\?(.*&)?id=/) && location.href.indexOf('nachrichten.php?t=1') <= 0) _attachEvent(window, 'load', convertToBBLetters);
	}

	if (location.href.match(/allianz.php\?(.*&)?s=2&aid=(\d+)&tid=(\d+)/)) convertToBBLetters(1);
	if (location.href.match(/allianz.php\?(.*&)?ac=(newtopic|newpost)/)) convertToBBLetters_menu();

	if (location.href.indexOf('berichte.php') != -1)	{ opcionOcultaInformes(); }
//	if (location.href.match(/dorf3.php($|\?newdid=(\d+)$)/)) resumenAldeas();

	if (location.href.match(/dorf3.php/)) {
		if (location.href.search(/dorf3.php\?(.*&)?s=(\d+)/)) {
			var a = parseInt(RegExp.$2);

			switch (a) {
				case 2:
					resumenAldeas6();
					break;
				case 0:
					resumenAldeas3();
					break;
				case 5:
					resumenAldeas4();
					break;
				case 4:
					resumenAldeas5();
					break;
				case 3:
					resumenAldeas2();
					break;
				case 7:
					resumenAldeas7();
					break;
				case 8:
					resumenAldeas8();
					break;
				default:
					resumenAldeas();
					break;
			}
		} else {
			resumenAldeas();
		}

		resumomenu();
	}

	if (location.href.match(/build.php\?(.*)&s=2/))		puntosCultura();
	if (location.href.match(/build.php\?(.*)&t=1/)){	alianzaMercado(); filtrosMercado(); }
	if (location.href.match(/karte.php($|\?z=|\?new)/)){

		_attachEvent(window, 'load', function () {
			preCalculate3();

//			installMapEventHandler();
			desplazarMapa();
			infoRecursos();
			playerLinks();
		});
	}
	if (location.href.match(/karte.php($|\?d=)/)){
		MapaQuickSave();

		kartec();
	}
	if (location.href.match(/nachrichten.php($|\?t=|\?s=)/) || location.href.match(/berichte.php($|\?t=|\?s=)/)) opcionesMensajes();

	//if (location.href.match(/nachrichten.php$/))		blocNotas();
	if (location.href.match(/nachrichten.php$/) || location.href.match(/nachrichten.php($|\?.*s=)/))		archiveIGM();

	if (location.href.match(/spieler.php\?s=2/))			mostrarConfiguracion();
	if (location.href.match(/plus.php\?id=3/))		checkUpdate();


	if (location.href.match(/warsim.php/)) {
		parseBattleAnalyse();
	}

	if (location.href.match(/berichte.php\?(.*&)?id=/)) {
		parseBattleAnalyse();
	}

	/* Mas acciones generales */
	mostrarMarcadores();
	setTimers();
	calcularTiempoEjecucion();
	playerLinks();
	fix_title();

	/**
	 * Funcion que no hace absolutamente nada. Usada cuando no hay mas remedio que usar alguna funcion
	 */
	function dummy(){}

	function getRandTimeRange(maxrange){ // input in milliseconds output in milliseconds
		var nr = Math.floor(maxrange * (0.6+0.4*Math.random()));
		//log(3, "Calculated RandTimeRange : "+nr+" ms.");
		return nr;
	}

	function getRandom(n,m){ return n+Math.floor(Math.random()*(m-n)); }

	/**
	 * Funcion que extrae el nombre de un fichero de una ruta o URL
	 *
	 * Params:
	 * 	path: Ruta o URL para extraer el nombre del fichero
	 *
	 * Returns:
	 *	El nombre del fichero al que apunta la ruta o URL
	 */
	function basename(path) { return path.replace( /.*\//, "" ); }

	/**
	 * Funcion que convierte un numero en su version de 2 digitos. Anyade un 0 si solo tiene un digito
	 *
	 * Params:
	 *	n	Numero a convertir
	 *
	 * Returns:
	 * 	El numero convertido con al menos dos digitos
	 */
	function LZ(n){	return (n > 9 ? n : '0' + n); }

	/**
	 * Crea un nuevo elemento de tipo DIV con un contenido prefijado
	 *
	 * Params:
	 *	content	Contenido del nuevo elemento creado
	 *
	 * Returns:
	 * 	Referencia al nuevo elemento
	 */
	function div(content){ return elem("div", content); }

	/**
	 * Wrapper para la funcion getElementById
	 *
	 * Params:
	 *	id	Texto del ID del elemento a buscar
	 *
	 * Returns:
	 * 	Elemento del documento con el ID especificado
	 */
	function get(id){ return $(id); }

	function $(id){ return document.getElementById(id); }

	/**
	 * Multiplica cada elemento de un array por un valor
	 *
	 * Params:
	 *	a	Array con los elementos a procesar
	 *	n	Valor numero por el que multiplicar el array
	 *
	 * Returns:
	 *	Nuevo array con los valores calculados
	 */
	function arrayByN(a, n){
		var b = arrayClone(a);
		for(var i in b){ b[i] *= n; }
		return b;
	}

	/**
	 * Realiza una copia por valor de un array
	 *
	 * Params:
	 *	a	Array a copiar
	 *
	 * Returns:
	 *	Referencia a un nuevo array con el mismo contenido que el original
	 */
	function arrayClone(a){
		var b = new Array();
		for(var i in a){ b[i] = a[i]; }
		return b;
	}

	/**
	 * Suma el contenido de dos arrays. Si cualquiera de los dos tiene valor nulo, se devuelve una copia del otro
	 *
	 * Params:
	 *	a	Primer array sumando
	 *	b	Segundo array sumando
	 *
	 * Returns:
	 *	Referencia a un nuevo array con la suma
	 */
	function arrayAdd(a, b){
		if(!a){ return arrayClone(b); }
		if(!b){ return arrayClone(a); }
		var c = new Array();
		for(var i = 0; i < Math.max(a.length,b.length); c[i] = a[i] + b[i++]);
		return c;
	}

	/**
	 * Comprueba si un valor esta presente en un array determinado
	 *
	 * Params:
	 *	array	Array a comprobar
	 *	value	Valor a buscar en el array
	 *
	 * Returns:
	 *	true si el valor esta en el array, false en caso contrario
	 */
	function arrayValueExist(array, value){
		for(var i = 0; i < array.length; i++) if (array[i] == value) return true;

		return false;
	}

	/**
	 * Convierte ciertas entidades HTML en su equivalente ASCII
	 *
	 * Params:
	 *	string: Cadena a convertir
	 *
	 * Returns:
	 *	Cadena convertida
	 */
	function decodeEntity(string){
		return string.replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&apos;/g,"'").replace(/&quot;/g,"\"").replace(/&amp;/g, "&");
	}

	/**
	* Elimina un elemento
	*
	* Param:
	*	elem	El elemento a eliminar
	*/

	function removeElement(elem){ if (elem) elem.parentNode.removeChild(elem) }

	/**
	 * Mueve un elemento de lugar en un arbol DOM
	 *
	 * Params:
	 *	elem: Elemento a desplazar
	 *	dest: Nuevo padre del elemento
	 */
	function moveElement(elem, dest){
		removeElement(elem);
		dest.appendChild(elem);
	}

	/**
	 * Suma todos los valores de un array
	 *
	 * Params:
	 *	a	Array a sumar
	 *
	 * Returns:
	 *	Valor con la suma de todos los elementos del array
	 */
	function arrayToInt(a){
		var h = 0;
		for(var i in a){ h += a[i]; }
		return h;
	}

	/**
	 * Inserta un nodo despues de otro
	 *
	 * Params:
	 *	node		Nodo de referencia
	 *	referenceNode	Nodo a insertar
	 */
	function insertAfter(node, referenceNode) {
		node.parentNode.insertBefore(referenceNode, node.nextSibling);
	}

	function insertBefore(node, referenceNode) {
		node.parentNode.insertBefore(referenceNode, node);
	}

	/**
	 * Crea un elemento cualquiera con un contenido
	 *
	 * Params:
	 *	tag	Etiqueta del nuevo elemento
	 *	content	Contenido del nuevo elemento en formato texto
	 *
	 * Returns:
	 *	Referencia al nuevo elemento creado
	 */
	function elem(tag, content, idt, idv, class){
		var ret = document.createElement(tag);
//		ret.innerHTML = content;

		if(content) {
			switch (tag.toLowerCase()) {
				case 'img':
					ret.src = content;
					break;
				case 'input':
					ret.name = content;
					break;
				default:
					ret.innerHTML = content;
					break;
			}
		}
		if(idt) {
			if (typeof idt != 'array') {
				ret.setAttribute(idt, idv);
			} else {
				for (a in idt)
					ret.setAttribute(a, idt[a]);
			}
		}

		if (idv && typeof idv == 'array') {
			for (a in style)
				ret.style[a] = style[a];
		}

		if(class) ret.className = class;

		return ret;
	}

	function textelem(s) {
		return document.createTextNode(s);
	}

	function $names(name, doc)
	{
		if(!doc) var doc = document;
		return doc.getElementsByName(name);
	}

	function $tags(tag, doc) {
		if(!doc) var doc = document;
		return doc.getElementsByTagName(tag);
	}

	/**
	 * Realiza una busqueda en el documento usando XPath
	 *
	 * Params:
	 *	xpath	Expresion de busqueda
	 *	xpres	Tipo de busqueda
	 *
	 * Returns:
	 *	Referencia a un elemento resultado de XPath
	 */
	function find(xpath, xpres, startnode, doc){
		if (!startnode) {startnode=document;}
		doc = doc != null ? doc : document;

		xpres = xpres ? xpres : XPFirst;

		var ret = doc.evaluate(xpath, startnode, null, xpres, null);
		return  xpres == XPFirst ? ret.singleNodeValue : ret;
	}

	/**
	 * xingulin︰
	 * 注意︰
	 *	原始程式有中文亂碼的問題,因為 GM_setValue()  與 GM_getValue() 不支援 UTF-8 字集,修改如下︰
	 *		GM_setValue(name, encodeURI(value))
	 *		decodeURI(GM_getValue(name, null))
	 * 參考網址︰
	 *	http://angusdev.mysinablog.com/index.php?op=ViewArticle&articleId=513171
	 *	http://www.nabble.com/-greasemonkey-users--GM_setValue-loses-unicode-characters-t2840046.html
	 */

	/**
	 * Crea o actualiza el valor de una cookie con una determinada duracion
	 *
	 * 變量:
	 *	name	Nombre de la cookie
	 *	value	Contenido de la cookie
	 *	days	Duracion de la validez de la cookie
	 */
	function createCookie(name, value, days){
		if (typeof GM_setValue == "undefined"){
			if (days){
				var date = new Date();
				date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
				var expires = "; expires=" + date.toGMTString();
			}else{ var expires = ""; }
			document.cookie = name + "=" + value + expires + "; path=/";
		}else GM_setValue(name, encodeURI(value));
	}

	function setOption(key, value) {
		var options = readCookie("options");
		if(options != '') options = options.split(",");
		else options = [];
		var myOption = options.indexOf(key);
		if(myOption < 0) {
		  options.push(key);
		  options.push(encodeURIComponent(value));
		} else {
		  options[myOption + 1] = encodeURIComponent(value);
		}
		options.join(",");
		createCookie("options", options);
	}

	/**
	 * @param key: name of the parameter in the cookie.
	 * @param defaultValue: this is returned if the parameter is not found in the cookie.
	 * @param type: if set, type conversion occurs. Values {string, integer, boolean} The conversion occurs only if it is not the defaultValue being returned.
	 */
	function getOption(key, defaultValue, type) {
		var options = readCookie('options');
		options = options.split(",");
		var myOption = options.indexOf(key);
		if(myOption < 0) {return defaultValue;}
		switch(type) {
		  case "boolean":
			 var myOption = ( options[myOption + 1] == "true" || options[myOption + 1] == "1") ? true:false;
		  break;
		  case "integer":
			 var myOption = parseInt(options[myOption + 1]);
		  break;
		  case "string":
		  default:
			 var myOption = decodeURIComponent(options[myOption + 1]);
			 break;
		}
		return myOption;
	}


	/**
	 * Recupera el valor de una cookie
	 *
	 * 變量:
	 *	name	Nombre de la cookie
	 *
	 * 返回值:
	 *	Contenido de la cookie o null si no existe
	 */
	function readCookie(name, defaultVal){
		if (typeof GM_getValue == 'undefined'){
			var ca = document.cookie.split(';');
			var nameEQ = name + "=";
			for(var i = 0; i < ca.length; i++) {
				var c = ca[i];
				while (c.charAt(0) == ' ') c = c.substring(1, c.length); // Elimina espacios
				if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
			}
			return defaultVal;
		}else return decodeURI(GM_getValue(name, defaultVal));
	}

	/**
	 * Elimina una cookie
	 *
	 * 變量:
	 *	name	Nombre de la cookie
	 */
	function eraseCookie(name){ createCookie(name, "", -1); }

	/**
	 * Crea una ruta a una imagen basandose en el path del pack grafico
	 *
	 * Params:
	 *	ref	Ruta relativa a la imagen
	 *
	 * Returns:
	 *	Ruta absoluta a la imagen
	 */
	function img(ref, lang_dependant){ return (!lang_dependant ? pack_grafico + "img/un/" + ref : pack_grafico + "img/" + idioma + '/' + ref); }

	/**
	 * Calcula el identificador de una casilla partiendo de sus coordenadas X e Y
	 *
	 * Params:
	 *	x	Coordenada X
	 *	y	Coordenada Y
	 *
	 * Returns:
	 *	ID de la casilla correspondiente a las coordenadas
	 */
	function xy2id(x, y){ return (1 + (parseInt(x) + 400) + (801 * Math.abs(parseInt(y) - 400))); }
	function zid2x(z){ return (((z - 1) % 801) - 400); }
	function zid2y(z){ return (400 - (parseInt(((z - 1) / 801)))); }

	/**
	 * Calcula el numero de segundos de una hora expresada en formato xx:xx:xx
	 *
	 * Params:
	 *	myElement	Texto con la hora a calcular
	 *
	 * Returns:
	 *	Numero de segundos que expresa la hora
	 */
	function calcular_segundos(myElement) {
		var p = myElement.split(":");
		return (p[0] * 3600) + (p[1] * 60) + (p[2] * 1);
	}

	/**
	 * Convierte una cantidad en segundos en su representacion en horas.
	 * Funcion inversa de "calcular_segundos"
	 *
	 * Params:
	 *	s	Numero de segundos
	 *
	 * Returns:
	 *	Texto con la representacion en horas o la cadena "0:00:0?" si es negativo
	 */
	function formatear_tiempo(s){
		if(s > -1){
			var horas = Math.floor(s/3600);
			var minutos = Math.floor(s/60) % 60;
			var segundos = s % 60;
			var t = horas + ":" + LZ(minutos) + ":" + LZ(segundos);
		}else var t = "0:00:0?";
		return t;
	}

	function formatear_tiempo2(s){
		if(s > -1){
			var horas = Math.floor(s/3600);
			var minutos = Math.floor(s/60) % 60;
			var segundos = s % 60;
			var t = horas + ":" + LZ(minutos);
		}else var t = "00:0?";
		return t;
	}

	/**
	 * Funcion encargada de mostrar el texto de recursos restantes para una construccion
	 */
	function calculateBuildTime(){
		// Las celdas son los enlaces susceptibles de ser sustituidos por la nueva informacion
		var celdas = find("//span[@class='c']", XPList);
		// Las tablas son por cada uno de los edificios ampliables que se han detectado en la pagina
		var tablas = find("//table[@class='f10' and not(@width)]", XPList);
		var k = celdas.snapshotLength - 1;

		// Se comienza por el final para evitar confusiones con otra informacion, ya que suele
		// estar lo ultimo en el caso de un unico edificio
		for(j = tablas.snapshotLength - 1; j >= 0; j--) {
			var tabla = tablas.snapshotItem(j);
			var celda = tabla.rows[0].firstChild;
			var recursos = celda.textContent.split("|").splice(0,4);
			if(recursos.length != 4) continue;

			var a = calculateResourceTime(recursos);
			var b = celdas.snapshotItem(k);
			// Por si hay mas tablas que celdas
			if (b){
				// Si lo que hay antes de la celda es un enlace, entonces se trata de la cola del Plus
				if (b.firstChild && b.previousSibling && b.previousSibling.previousSibling.nodeName == 'A') continue;
				// Se elimina la informacion existente antes de poner la nueva
				if (a != null){
					if (b.firstChild && b.previousSibling && b.previousSibling.previousSibling.nodeName == 'TABLE') while(b.hasChildNodes()) b.removeChild(b.firstChild);
					b.appendChild(div(a));
					k--;
				}
			}
		}
	}

	/**
	 * Recupera el identificador de la aldea activa
	 *
	 * Returns:
	 *	El ID de la aldea o 0 si es la unica aldea
	 */
	function getIdAldea(mode){
//		var a = find("//span[@class='c2']/a", XPFirst);

		var a = find("//a[@class='active_vl']", XPFirst);

		if (a){
			if (mode) {
				return a.parentNode.innerHTML;
			} else {
				a.getAttribute("href").search(/\?newdid=(\d+)/);
				return RegExp.$1;
			}
		} else return 0;
	}

	/**
	 * Calcula el desplazamiento en pixeles a partir del 23� enlace
	 * lateral (aldeas o enlaces personalizados)
	 *
	 * Returns:
	 *	El desplazamiento en pixeles
	 */
	function longitudPantalla(){
		var enlaces = 0;

		// Se estima que caben 19 enlaces hasta que empiecen a ser demasiados y a ser tenidos en cuenta
		var a = find("//div[@id='lright1']//span[text()]", XPList).snapshotLength;
		if (a > 0) a += 3;

		var b = obtenerValorCookie("marcadores").length;
		if (b > 0) a += b + 2;

		var c = find("//ul/li", XPList);
		if (c > 0) a += c + 2;

		a -= 23;
		if (a > 0) enlaces += a * pixelsPorLinea;

		// Se tiene en cuenta el numero de construcciones
		var a = find("//div[@id='ba']//table[@class='f10' and @width='100%']//tr", XPList).snapshotLength - 2;
		if (a) enlaces += pixelsPorLinea * (a > 0 ? a : 0);

		// Se tiene en cuenta el banner de publicidad
		var a = find("//iframe", XPFirst);
		if (a != null) enlaces += parseInt(a.height);


		return enlaces;
	}

	/**
	 * Calcula los recursos restantes y el tiempo necesario para unas cantidades deseadas y devuelve
	 * una cadena de texto en HTML con esa informacion
	 *
	 * Params:
	 *	necesario:	Array con la cantidad deseada de cada tipo de recurso
	 *
	 * Returns:
	 *	Cadena de texto en HTML con la informacion sobre el tiempo y recursos que faltan
	 */

//	//計算資源時間
//	function calculateResourceTime(necesario){
//		var texto_restante = '';
//		var tiempo_max = 0;
//		var a = null;
//
//		// Calcula y crea una cadena con lo que falta de cada recurso
//		for (i = 0; i < 4; i++){
//			restante = necesario[i] - actual[i];
//			if (restante > 0){
//				texto_restante += '<img src="' + img('r/' + (i+1) + '.gif') + '" width="18" height="12" border="0" title="' + T('RECURSO' + (i+1)) + '"><span id="timeout' + i + '">' + restante + '</span> | ';
//				var tiempo = Math.round(restante / produccion[i]);
//				if (tiempo > tiempo_max) tiempo_max = tiempo;
//				if (tiempo < 0) tiempo_max = 'Infinity';
//								if (total[i] - actual[i] == 0) tiempo_max = 'Infinity';
//			}
//		}
//
//		// Calcula y crea una cadena con el tiempo que falta hasta conseguir los recursos
//		if (tiempo_max == 'Infinity'){
//			a = T('FALTA') + ' ' + texto_restante + ' <br><img src="' + img('a/clock.gif') + '" width="18" height="12" title="' + T('TIEMPO') + '"> ' + T('NUNCA');
//		}else if (tiempo_max > 0){
//			var tiempo2 = formatear_tiempo(tiempo_max + 5); // Introduce un margen de 5 segundos para compensar la desviancion de los temporizadores de javascript
//			var fecha = new Date();
//			fecha.setTime(fecha.getTime() + (tiempo_max * 1000));
//
//			a = T('FALTA') + ' ' + texto_restante + ' <br><img src="' + img('a/clock.gif') + '" width="18" height="12" title="' + T('TIEMPO') + '"> <span id="timeout">' + tiempo2 + '</span><br/> ' + T('LISTO') + ' ' + calcularTextoTiempo(fecha);
//		}
//		return a;
//	}

	//計算資源時間
	function calculateResourceTime(necesario, special_case)
	{
		var texto_restante = '';
		var tiempo_max = 0;
		var a = null;

		// Calcula y crea una cadena con lo que falta de cada recurso
		for (i = 0; i < 4; i++){
			restante = necesario[i] - actual[i];
			if (restante > 0){

				var tiempo = Math.round(restante / produccion[i]);

				if ((total[i] - actual[i] <= 0) || (total[i] - restante < 0)) tiempo_max = 'Infinity';

				if (tiempo < 0 || tiempo_max == 'Infinity' || produccion[i] < 0) {
					tiempo_max = 'Infinity';
				} else if (tiempo > tiempo_max) tiempo_max = tiempo;

				texto_restante += '<div class="inline" removeable="1">';

				texto_restante += '<img '+'_title="'+total[i]+':'+actual[i]+':'+restante+':'+produccion[i]+'"'+' src="' + img('r/' + (i+1) + '.gif') + '" width="18" height="12" border="0" title="' + T('RECURSO' + (i+1)) + '"><span ' + (total[i] != actual[i] ? 'id="timeout' + (i) + '"' : '') + (tiempo_max == 'Infinity' ? ' noreload="1"' : '') + '>' + restante + '</span> ';

				texto_restante += '( ' + (tiempo_max == 'Infinity' ? T('NUNCA') : '<span id="timeout" noreload="1">' + formatear_tiempo(Math.round(restante / produccion[i])) + '</span>') + ' )';
				texto_restante += ((special_case) ? '<br />' : ' | ');

				texto_restante += '</div>';
			}
		}

		// Calcula y crea una cadena con el tiempo que falta hasta conseguir los recursos
		if (tiempo_max == 'Infinity'){
			a = T('FALTA') + ' ' + texto_restante + ' <img src="' + img('a/clock.gif') + '" width="18" height="12" title="' + T('TIEMPO') + '"> ' + T('NUNCA');
		}else if (tiempo_max > 0){
			var tiempo2 = formatear_tiempo(tiempo_max); // Introduce un margen de 5 segundos para compensar la desviancion de los temporizadores de javascript
			var fecha = new Date();
//			fecha.setTime(fecha.getTime() + (tiempo_max * 1000));
			fecha.setTime(timestamp.getTime() + (tiempo_max * 1000));

			a = T('FALTA') + ((special_case) ? '<br />' : '  ') + '' + texto_restante + ' <img src="' + img('a/clock.gif') + '" width="18" height="12" title="' + T('TIEMPO') + '"> <span id="timeout">' + tiempo2 + '</span><br/> ' + T('LISTO') + ' ' + calcularTextoTiempo(fecha);
		}
		//資源時間
		/*
		if ((tiempo_max == 'Infinity')||(tiempo_max > 0)){
			a='<div style="color:#999">' + a + '</div>';
		}
		*/
		return a;
	}

	/**
	 * Formatea el tiempo necesario hasta alcanzar determinada fecha
	 *
	 * Params:
	 *	fecha:	Objeto de tipo Date con la fecha futura
	 *
	 * Returns:
	 *	Cadena de texto con el calculo de tiempo restante
	 */
	function calcularTextoTiempo(fecha){
//		ahora = new Date();
		ahora = timestamp;

		// Calcula la diferencia de horas entre la fecha dada y la actual
		// para saber si se trata de las proximas 72 horas
		horas = ((fecha.getTime() - ahora.getTime()) / 1000 / 60 / 60);
		horas += ahora.getHours() + (ahora.getMinutes() / 60);
		if (horas < 24) tiempo_restante = T('HOY');
		else if (horas < 48) tiempo_restante = T('MANYANA');
		else if (horas < 72) tiempo_restante = T('PAS_MANYANA');
		else tiempo_restante = T('EL') + " " + LZ((fecha.getMonth()+1)) + "/" + LZ(fecha.getDate());

		return tiempo_restante + " " + T('A_LAS') + " " + LZ(fecha.getHours()) + ":" + LZ(fecha.getMinutes()) + ":" + LZ(fecha.getSeconds());
	}

	/**
	 * Calcula el tiempo maximo estimado hasta conseguir los recursos especificados basandose
	 * en la cantidad actual y en la produccion de cada tipo de recurso
	 *
	 * Params:
	 *	necesario:	Array con la cantidad deseada de cada tipo de recurso
	 *
	 * Returns:
	 *	Tiempo maximo en segundos hasta conseguir los recursos deseados
	 */
	function calculateTime(necesario){
		var tiempo_max = 0;
		var tiempo = 0;

		for (i = 0; i < 4; i++){
			var restante = necesario[i] - actual[i];
			if (restante > 0){
				tiempo = Math.round(restante / produccion[i]);
				if (tiempo > tiempo_max) tiempo_max = tiempo;
				if (tiempo < 0) tiempo_max = 'Infinity';
			}
		}

		if (tiempo_max > 0 && tiempo_max != 'Infinity') tiempo_max = formatear_tiempo(tiempo_max + 5); // Se introduce un margen de 5 segundos para compensar posibles desviaciones en los temporizadores de javascript
		return tiempo_max;
	}

	function calculateHighlight (produccionHora, tiempo, tiempoRestante) {
		var color = '';

		if (produccionHora < 0) {
			color = '#FF0000';
		} else if (tiempo <= 3600) {
			color = 'Magenta';
		} else if (tiempo <= 18000) {
			color = '#ffa500';
		} else if (tiempo <= 36000) {
			color = '#7b68ee';
		}

		var ret = tiempoRestante;
		if (color != '') ret = '<font color="' + color + '">' + ret + '</font>';

		return ret;
	}

	/**
	 * Calcula y muestra el tiempo estimado hasta el llenado/vaciado de los almacenes y graneros
	 */
	function calculateFillTime(){
		// Por cada tipo de recurso calcula el tiempo hasta el llenao
		for (var i = 0; i < 4; i++){
			if (produccion[i] < 0) var tiempo = Math.round(actual[i] / -produccion[i]);
			// Si la produccion es 0, el tiempo es infinito
			else if (produccion[i] == 0) var tiempo = -1;
			// Si la produccion es negativa, se calcula el tiempo hasta el vaciado
			else var tiempo = Math.round((total[i] - actual[i]) / produccion[i]);
						if(getv2()!=1){
						var produccionHora = get('l' + (4-i)).title;} else{
						var produccionHora = get('l' + (1+i)).title;}
						var tiempoRestante = "<span id='timeouta' style='font-weight:bold' noreload='1'>" + formatear_tiempo(tiempo) + "</span>";
						var celda = elem("span", "<span style='font-size:9px; color:#909090; position: absolute; top:13px; height: 20px; text-align:left;'>(" + (produccionHora > 0 ? '+' : '') + produccionHora + ', ' + calculateHighlight(produccionHora, tiempo, tiempoRestante) + ')</span>');
						//var celda = elem("DIV", "<span style='font-size:9px; color:#909090; position: absolute; top:13px; height: 20px; text-align:left;'>(" + (produccionHora > 0 ? '+' : '') + produccionHora + ', ' + (produccionHora < 0 ? '<font color="#FF0000">' + tiempoRestante + '</font>' : tiempoRestante) + ')</span>');
			if(getv2()!=1){
				var a = get('l'+(4-i)).previousSibling;
			} else {
				var a = get('l'+(1+i)).previousSibling;
			}
			// FIXME: Apanyo para Firefox. FF mete nodos de tipo texto vacios
			if (a.nodeName == '#text') a = a.previousSibling;
			a.appendChild(celda);
		}

		get('l1').style.cssText = 'padding-bottom: 5px;';
	}

	/**
	 * Traduce una cadena de texto usando el idioma global detectado
	 *
	 * Params:
	 *	texto:	Cadena de texto a traducir
	 *
	 * Returns:
	 *	Cadena de texto traducida
	 */
	function T(texto){
		// Intenta usar el array del idioma, y si no esta disponible utiliza el castellano por defecto
//		try{
//			eval('var language = lang_' + idioma);
//		}catch(e){
//			eval('var language = lang_hk');
//		}
//
//		texto = texto.toUpperCase();
//
//		// Si una cadena concreta no esta traducida en el idioma, utiliza por defecto el castellano
//		if (language[texto] == undefined) {
//			return language[texto] == undefined ? '!'+texto+'!' : lang_hk[texto];
//		} else {
//			return language[texto];
//		}

		texto = texto.toUpperCase();

		try{
			return aLang[texto] == undefined ? '!'+texto+'!' : aLang[texto];
		}catch(e){
			return '!'+texto+'!';
		}

	}

	function Traduz(texto) {
		return T(texto);
	}

	/**
	 * Traduce una cadena de texto usando el idioma global detectado
	 *
	 * Params:
	 *	texto: Cadena de texto a traducir
	 *	args: Argumentos a sustituir en la cadena a traducir
	 *
	 * Returns:
	 * 	Cadena de texto traducida
	 */
	function F(texto, args){
//		// "args" debe ser un array asociativo del tipo {'a':'b', 'c':'d'} y puede ser opcional
//		try{ eval('var language = lang_' + idioma); }
//		catch(e){ eval('var language = lang_es'); }
//		if (language[texto] == undefined) texto = lang_es[texto]; else texto = language[texto];

		texto = aLang[texto] == undefined ? '!'+texto+'!' : aLang[texto];

		if (args != undefined) for(var i in args) texto = texto.replace(i, args[i]);
		return texto;
	}

	/**
	 * Recupera informacion generica inicial para el resto de funciones
	 */
	function getv2(){
	//			find("//script[@type='text/javascript']", XPFirst).src.search(/(\d).js$/);
				var a=document.title;
				if (a=="Travian cnt") {
				return 1 }else {
				return 3}
		}
	function getGeneralData(){
		// Idioma
//		find("//script[@type='text/javascript']", XPFirst).src.search(/\/([^\/]+)?3.js$/);
		var xtemp = find("//img[contains(@src, 'plus.gif')]", XPFirst);

		if (xtemp) {
			xtemp.src.search(/\/img\/([^\/]+)\//);
			idioma = RegExp.$1;
		} else {
			idioma = 'tw';
		}

		document.title.search(/travian\s(\w+$)/i);
		idioma2 = RegExp.$1;

		// Ruta al pack grafico
		find("//link[@rel='stylesheet'][2]", XPFirst).href.search(/^(.*\/)(.*)\.css$/);
		pack_grafico = RegExp.$1;

//		alert(find("//link[@rel='stylesheet'][2]", XPFirst).href);

		// Identificador de aldea actual
		id_aldea = getIdAldea();

		// Identificador de usuario
		find("//td[@class='menu']", XPFirst).innerHTML.search(/spieler.php\?uid=(\d+)/);
		uid = RegExp.$1;

		// Nombre del servidor
		location.href.search(/http:\/\/(.*)\//);
		server = RegExp.$1;

		// Por cada tipo de recurso: cantidad actual almacenada, capacidad total del almacen / granero y produccion por segundo
		for (var i = 0; i < 4; i++){
			var a = get('l' + (4-i));
			actual[i] = a.innerHTML.split("/")[0];
			total[i] = a.innerHTML.split("/")[1];
			produccion[i] = a.title/3600;
		}

		// Plus
		if (find("//img[contains(@src, 'travian1.gif')]", XPFirst)) plus = true; else plus = false;


		storeurl=readCookie("storeurl", '');
	}
	/**
	 * Oculta el anuncio de publicidad
	 */
	function hideAd(){
		var ad = find("//iframe", XPFirst);
		if (ad) ad.style.display = 'none';
	}

	/**
	 * Crea nuevos enlaces en la barra de menu izquierda. Son enlaces internos y externos al juego separados por una linea
	 */
	function quickLinks(){
		var menu = find("//td[@class='menu']", XPFirst);
		for (var j = 0; j < 2; j++) for (var i = 0; i < menu.childNodes.length; i++) if (menu.childNodes[i].nodeName == 'BR') removeElement(menu.childNodes[i]);
		var links = [	0,
				[T('LOGIN'), "login.php"],
				[T('ENV_TROPAS'), "a2b.php"],
				["聯盟概況", "allianz.php"],
				[" " + T('ALIANZA_ATTACK'), "allianz.php?s=3"],
				[T('SIM'), "warsim.php"],
				[T('MAPA'), "http://travmap.shishnet.org/?lang=zh", "_blank"],
				0,
				["行宮", "build.php?gid=25"],
				["皇宮", "build.php?gid=26"],
				["英雄園", "build.php?gid=37"],
//				["市鎮廳", "build.php?gid=24"],
				["中心大樓", "build.php?gid=15"],
				[T('CHECKNEW'), "http://userscripts.org/users/51651/scripts", "_blank"],
		];

		for(var i = 0; i < links.length; i++){
			if(links[i]){
				var a = elem("A", links[i][0]);
				a.href = links[i][1];
				if(links[i][2]) a.setAttribute('target', links[i][2]);
				menu.appendChild(a);
			}else menu.appendChild(elem('HR'));
		}

		GM_registerMenuCommand('Travian Beyond > '+T('CHECKNEW'), function(){ GM_openInTab("http://userscripts.org/users/51651/scripts")});
	}

	/**
	 * Anyade un dialogo de confirmacion a los enlaces de cancelacion de construcciones
	 */
	function confirmDelete(){
		var links = find("//img[contains(@src, 'del.gif')]", XPList);
		for (var i = 0; i < links.snapshotLength; i++){
			links.snapshotItem(i).setAttribute('onClick', 'javascript:return confirm("' + T('SEGURO') + '");');
		}
	}

	/**
	 * Anyade nuevos enlaces a edificios en la barra superior
	 */
	function buildingLinks(){
		// Localiza la barra de enlaces superiores
		var barra = find("//div[@id='ltop5']", XPFirst);

		// Asocia el mapa del mercado con la imagen especifica creada
		barra.innerHTML += '<img usemap="#mercado" class="fl2" src="data:image/gif;base64,' + imagenes["mercado"] + '" border="0" title="' + T('MERCADO') + '">';

		// Asocia el mapa de los edificios militares con la imagen creada a tal efecto
		barra.innerHTML += '<img usemap="#militar" class="fl2" src="data:image/gif;base64,' + imagenes["militar"] + '" border="0" title="' + T('CUARTEL') + '">';

		// Mapa para el mercado
		barra.innerHTML += '<map name="mercado"><area shape="rect" coords="0,0,70,50" href="build.php?gid=17" title="' + T('ENVIAR') + '"><area shape="rect" coords="0,50,35,100" href="build.php?gid=17&t=1" title="' + T('COMPRAR') + '"><area shape="rect" coords="35,50,70,100" href="build.php?gid=17&t=2" title="' + T('VENDER') + '"></map>';

		// Mapa para los edificios militares
		barra.innerHTML += '<map name="militar"><area shape="rect" coords="0,0,35,50" href="build.php?gid=16" title="' + T('PUNTO') + '"><area shape="rect" coords="35,0,70,50" href="build.php?gid=19" title="' + T('CUARTEL') + '"><area shape="rect" coords="0,50,35,100" href="build.php?gid=20" title="' + T('CORRAL') + '"><area shape="rect" coords="35,50,70,100" href="build.php?gid=21" title="' + T('TALLER') + '"></map>';

		// Desplaza el menu del Plus a la izquierda para hacer hueco a las nuevas imagenes
		var a = find("//a[contains(@href, 'plus.php')]", XPFirst);
		a.style.marginLeft = '0px';
		a.style.position = 'absolute';
		a.style.left = '-250px';
	}

	/**
	 * Crea un enlace al servicio de estadisticas de Travian World que recibe la busqueda como parametro
	 *
	 * Params:
	 *	param	Parametro de busqueda para la estadistica
	 */
	function createStatLink(param){
		var statlink = elem('a', "<img src='data:image/gif;base64," + imagenes["stat"] + "' style='margin:0px 1px 0px 1px; display: inline' title='" + T('STAT') + "' alt='Stat' border=0>");
		statlink.href = "javascript:void(0);";
		var ref = 'http://www.denibol.com/proyectos/travian_world/stat2.php?server=' + server + '&' + param;
		statlink.addEventListener("mouseover", function(){ timeout = setTimeout(function(){ var a = get("tb_tooltip"); a.innerHTML = "<img src='" + ref + "' border='0'/>"; a.style.display = 'block'; }, 1000); }, 0);
		statlink.addEventListener("mouseout", function(){ clearTimeout(timeout); get("tb_tooltip").style.display = 'none'; }, 0);
		statlink.addEventListener("click", function(){ var popup = window.open(ref, 'popup', 'width=350, height=250'); popup.focus(); return false; }, 0);
		return statlink;
	}

	//show distance from all villages in tooltip
	function getVillageDist(x,y)  {
		return function(e) {
			var cities = find("//div[@id='lright1']//table[@class='f10']", XPFirst);
			if(cities){
				var txt1=new Array();
				txt1.push('<tr><td colspan=2 align=center><b>'+x+'|'+y+'</b><tr><td style="border-bottom:solid 1px #00C000;"><b>'+T('ALDEA')+'</b><td align=right style="border-bottom:solid 1px #00C000;"><b>'+T('Dist')+'</b>');
				cities = cities.firstChild;
				for (var j = 0; j < cities.childNodes.length; j++){
					var city = cities.childNodes[j];
					var cityname=city.childNodes[0].childNodes[2].textContent;
					city.textContent.search(/\((.*)\n?\|\n?(.*)\)/);
					var x2=parseInt(RegExp.$1,10);
					var y2=parseInt(RegExp.$2,10);
					var dist=Math.sqrt(Math.pow(x-x2,2)+Math.pow(y-y2,2)).toFixed(2);
					txt1.push('<tr><td>'+cityname+'<td align=right>'+dist);
				}
//				var table = elem('table', txt1.join(''));
//				var tooltip = get('tb_tooltip');
////				document.body.appendChild(tooltip);
//
//				tooltip.innerHTML = "";
//				tooltip.appendChild(table);
//				tooltip.style.display = 'block';

				timeout = setTimeout(function(){
					var div = get("tb_tooltip");

					div.innerHTML = "";
					div.appendChild(elem('table', txt1.join('')));

					div.style.display = 'block';
				}, 100);


			}
		}
	}

	/**
	 * Crea un enlace para mandar un IGM cuando aparece un enlace al perfil de un jugador, un enlace de
	 * ataque rapido cuando aparece un enlace a una ubicacion del mapa, y otro enlace de estadisticas si
	 * esta soportado para el idioma del servidor activo
	 */
	function playerLinks(){
		var links = document.getElementsByTagName("a");

		var arrayplayerLinks = new Array();

		if (!idioma2) {
			document.title.search(/travian\s(\w+$)/i);
			idioma2 = RegExp.$1;
		}

		var vx = 0, vy = 0;

		if(find("//a[@class='active_vl']",XPFirst) != null) {
			find("//a[@class='active_vl']",XPFirst).parentNode.nextSibling.textContent.match(/\(([-\d]+)\n\|\n([-\d]+)\)/);
			vx = RegExp.$1;
			vy = RegExp.$2;
		}

		for(var i = 0; i < links.length; i++){

//			if (links[i].className == 'done') continue;
			if (links[i].className == 'done' || links[i].getAttribute('done')) continue;

			// Por cada enlace a una ficha de jugador
			if(links[i].href.search(/spieler.php\?uid=(\d+$)/) > 0) {
				var a = RegExp.$1;
				if (a == 0) continue;
				if (links[i].parentNode.className == 'menu') continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('uid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>", 'target', '_blank', 'done');
					igmlink2.href = 'spieler.php?uid=' + a;
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					// Introduce el enlace para enviar mensajes usando su ID
					var igmlink2 = elem('a', "<img src='data:image/gif;base64," + imagenes["igm"] + "' style='margin:3px 0px 1px 3px; display: inline' _title='" + T('ENVIAR_IGM') + "' _alt='" + T('ENVIAR_IGM') + "' border=0>", 'target', '_blank', 'done');
					igmlink2.href = 'nachrichten.php?t=1&id=' + a;
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a', '<img src="'+img('a/b1.gif')+'">', 'target', '_blank', 'done');
					igmlink2.href = "http://www.travutils.com/?s=" + idioma2 + "&idu=" + a;

					igmlink2.style.cssText = 'display: inline; margin-left: 5px; color: #6F84FF';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a', '<img src="'+img('a/b2.gif')+'">', 'target', '_blank', 'done');
					igmlink2.href = "http://travian.ws/analyser.pl?s=" + idioma2 + "&uid=" + a;

					igmlink2.style.cssText = 'display: inline; margin-left: 5px; color: #6F84FF';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			// Por cada enlace a una localizacion del mapa

			}else if (links[i].href.search(/karte.php\?z=(\d+)/) > 0){
				var a = RegExp.$1;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('id=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('span', ' ( ' + zid2x(a) + ' | ' + zid2y(a) + ' ) ', null, null, 'done tb_coords');
//					igmlink2.style.cssText = 'word-break: keep-all; font: 11px/1.5em Tahoma,Verdana,Arial !important; color:grey;';
//					igmlink2.className = 'tb_coords';

					igmlink2.setAttribute('done', 1);

					if (vx || vy) {
						igmlink2.addEventListener("mouseover", getVillageDist(zid2x(a), zid2y(a)), 0);
						igmlink2.addEventListener("mouseout", function(){ clearTimeout(timeout); timeout = 0; get("tb_tooltip").style.display = 'none'; }, 0);
					}

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',"<img src='" + img("a/att_all.gif") + "' style='margin:3px 0px 1px 3px; display: inline' height='10' width='10' _title='" + T('ATACAR') + "' _alt='" + T('ATACAR') + "' border='0'>");
					igmlink2.href = 'a2b.php?z=' + a;
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',T('ALDEA_EXTRA2'));
					igmlink2.href = 'build.php?z=' + a + '&gid=17';
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',T('ALDEA_EXTRA3'));
					igmlink2.href = 'karte.php?z=' + a;
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',"<img src='" + imagenes["cropfinder"] + "' style='margin:3px 0px 1px 3px; display: inline' height='12' border='0'>");
					igmlink2.href = 'http://crop-finder.com/' + idioma2 + '/' + zid2x(a) + '|' + zid2y(a) + '/';
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);


					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);
			}else if (links[i].href.search(/karte.php\?d=(\d+)/) > 0){
				var a = RegExp.$1;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('id=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('span', ' ( ' + zid2x(a) + ' | ' + zid2y(a) + ' ) ', null, null, 'done tb_coords');
//					igmlink2.style.cssText = 'word-break: keep-all; font: 11px/1.5em Tahoma,Verdana,Arial !important; color:grey;';
//					igmlink2.className = 'tb_coords';

					igmlink2.setAttribute('done', 1);

					if (vx || vy) {
						igmlink2.addEventListener("mouseover", getVillageDist(zid2x(a), zid2y(a)), 0);
						igmlink2.addEventListener("mouseout", function(){ clearTimeout(timeout); timeout = 0; get("tb_tooltip").style.display = 'none'; }, 0);
					}

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',"<img src='" + img("a/att_all.gif") + "' style='margin:3px 0px 1px 3px; display: inline' height='10' width='10' _title='" + T('ATACAR') + "' _alt='" + T('ATACAR') + "' border='0'>");
					igmlink2.href = 'a2b.php?z=' + a;
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',T('ALDEA_EXTRA2'));
					igmlink2.href = 'build.php?z=' + a + '&gid=17';
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',T('ALDEA_EXTRA3'));
					igmlink2.href = 'karte.php?z=' + a;
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a',"<img src='" + imagenes["cropfinder"] + "' style='margin:3px 0px 1px 3px; display: inline' height='12' border='0'>");
					igmlink2.href = 'http://crop-finder.com/' + idioma2 + '/' + zid2x(a) + '|' + zid2y(a) + '/';
					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);


					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

				links[i].addEventListener("mouseover", crearEventoRecursosCasilla(links[i].href, links[i]), 0);
				links[i].addEventListener("mouseout", function(){ clearTimeout(timeout); timeout = 0; get("tb_tooltip").style.display = 'none'; }, 0);

//				var atklink = elem('span',
//					"<a href='a2b.php?z=" + a + "'><img src='" + img("a/att_all.gif") + "' style='margin:3px 0px 1px 3px; display: inline' height='10' width='10' title='" + T('ATACAR') + "' alt='" + T('ATACAR') + "' border='0'></a>"
//					+ "<a href='build.php?z=" + a + "&gid=17'>" + T('ALDEA_EXTRA2') + "</a>"
//					+ "<a href='karte.php?z=" + a + "'>" + T('ALDEA_EXTRA3') + "</a>"
//				);
//
//				links[i].parentNode.insertBefore(atklink, links[i].nextSibling);

//				city.appendChild(elem("TD", "<a href='build.php?z=" + id + "&gid=17'>" + T('ALDEA_EXTRA2') + "</a>"));
//				city.appendChild(elem("TD", "<a href='karte.php?z=" + id + "'>" + T('ALDEA_EXTRA3') + "</a>"));

			// Por cada enlace a la ficha de una alianza
			}else if (links[i].href.search(/allianz.php\?aid=(\d+$)/) > 0){
				var a = RegExp.$1;
				if (a == 0) continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('aid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a', '<img src="'+img('a/b1.gif')+'">');
					igmlink2.href = "http://www.travutils.com/?s=" + idioma2 + "&ida=" + a;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);
					igmlink2.style.cssText = 'display: inline; margin-left: 5px; color: #6F84FF';

					linkspan.appendChild(igmlink2);

					var igmlink2 = elem('a', '<img src="'+img('a/b2.gif')+'">');
					igmlink2.href = "http://travian.ws/analyser.pl?s=" + idioma2 + "&aid=" + a;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);
					igmlink2.style.cssText = 'display: inline; margin-left: 5px; color: #6F84FF';

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			}else if (links[i].href.search(/allianz.php\?s=2/) > 0){

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			} else if (links[i].href.search(/berichte.php\?id=(\d+$)/) > 0){
				var a = RegExp.$1;
				if (a == 0) continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('aid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = 'berichte.php?id=' + a;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			} else if (links[i].href.search(/nachrichten.php\?id=(\d+$)/) > 0){
				var a = RegExp.$1;
				if (a == 0) continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('aid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = 'nachrichten.php?id=' + a;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			} else if (links[i].href.search(/build.php\?id=\d+&t=1&a=(.+$)/) > 0){
				var a = RegExp.$1;
				if (a == 0) continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('aid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);
			} else if (links[i].href.search(/a2b.php\?d=(\d+)&c=.+$/) > 0){
				var a = RegExp.$1;
				if (a == 0) continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('aid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			} else if (links[i].href.search(/build.php\?id=(\d+)&a=(\d+)&t=.+$/) > 0){
//			http://s4.travian.tw/build.php?id=39&a=4&t=11813131

				var a = RegExp.$1;
				if (a == 0) continue;
				if (arrayValueExist(tw_server, server)) links[i].parentNode.insertBefore(createStatLink('aid=' + a), links[i].nextSibling);

				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);

			} else if (links[i].href.search(/travilog.org.ua/i) > 0) {
				if (arrayplayerLinks[links[i].href]) {
					var linkspan = elem('span', arrayplayerLinks[links[i].href]);
				} else {
					var linkspan = elem('span', "");

					var igmlink2 = elem('a', "<img src='" + img("a/external.gif") + "' style='margin:3px 0px 1px 3px; display: inline' border=0>");
					igmlink2.href = links[i].href;

					igmlink2.target = '_blank';
					igmlink2.className = 'done';
					igmlink2.setAttribute('done', 1);

					linkspan.appendChild(igmlink2);

					arrayplayerLinks[links[i].href] = linkspan.innerHTML;
				}

				links[i].parentNode.insertBefore(linkspan, links[i].nextSibling);
			}

			if (!links[i].className) links[i].className = 'done';
			links[i].setAttribute('done', 1);
		}
	}

	/**
	 * Anyade un nuevo boton en la vista de informes y mensajes para marcar todas las casillas
	 */
	function opcionesMensajes(){

		var a = find("//*[@class='s7']", XPList);
		var fila;

		for (var i = 0; i < a.snapshotLength - 1; i++){
			fila = a.snapshotItem(i);
			if ((fila.firstChild != null) && (fila.firstChild.nodeName == "INPUT")){
				fila.innerHTML += ' <input class="std" name="mtodo" type="button" value="' + T('MARK') + '" onClick="for(var x = 0; x < document.msg.elements.length; x++) document.msg.elements[x].checked = \'checked\';"/>';
				if (!plus) fila.innerHTML += ' <input class="std" name="archive" type="Submit" value="' + T('ARCHIVE') + '"/>';
				break;
			}
		}

		var a = find("//p[@class='txt_menue']", XPFirst);
		if (a && location.href.indexOf('nachrichten.php?t=1') <= 0) {

			var Input3 = elem('input', null, 'value', getOption("opcionesmensajespreload",0,"integer"), 'fm');
			Input3.size = 4;
			Input3.addEventListener('change', function(){
				setOption('opcionesmensajespreload', this.value);
				document.location.reload();

			}, false);

			if (location.href.match(/berichte.php/)) {
				var Input4 = elem('input', null, 'value', getOption("deleteberichte_t3",0,"integer"), 'fm');
				Input4.size = 4;
				Input4.addEventListener('change', function(){
					setOption('deleteberichte_t3', this.value);

				}, false);
				insertAfter(a, Input4);
				insertAfter(a, document.createTextNode(' ' + T('deleteberichte_t3')));

//				fila.innerHTML += ' <input class="std" type="button" value="' + T('deleteberichte_t3_button') + '"/>';

				var Input5 = createElementAppend('input', fila, null, 'type', 'button', 'std');
				Input5.value = T('deleteberichte_t3_button');
				_attachEvent(Input5, 'click', function () {

					if (getOption("deleteberichte_t3",0,"integer") <= 0) return;

					var ids = find("//form[@name='msg']//input[contains(@name, 'n') and @type='checkbox']", XPList);

					for (var i = 0; i < ids.snapshotLength ; i++){
						var linkid = ids.snapshotItem(i).value;

						ajaxRequest('berichte.php?id='+linkid, "GET", null, function (t) {
							var ajaxdoc = new ajaxCreateDocument(t);
							var ans = ajaxdoc.ans;
							var ansdoc = ajaxdoc.ansdoc;


							var tab=find("//table[@class='tbg']/tbody", XPList, ans, ansdoc);

							if(tab.snapshotItem(1)==undefined)return;
							if(tab.snapshotItem(1).parentNode.id=='MeXaon_ver_table')return;
							if(tab.snapshotItem(1).parentNode.getElementsByTagName("td").length < 24)return;
							if(tab.snapshotItem(1).getElementsByTagName("td")[0].textContent.charCodeAt(0)==160) return;

							// fix anchors
							var fa = tab.snapshotItem(0).getElementsByTagName('a');
							for( var i = 0; i < fa.length; i++) {
								fa[i].href = fa[i].href;
							}
							//

							var table=tab.snapshotItem(1).getElementsByTagName("td");

							var troops=0; //1-romans 2-teutons 3-gauls
							var tm;

							if(table[3].innerHTML.indexOf("u/1.gif")>0) troops=1;
							if(table[3].innerHTML.indexOf("u/11.gif")>0) troops=2;
							if(table[3].innerHTML.indexOf("u/21.gif")>0) troops=3;
							switch (troops){
								case 1:tm=romans;break;
								case 2:tm=teutons;break;
								case 3:tm=gauls;break;
								default:tm=null;break;
							}

							var statushero=0;

							if(table[13].innerHTML.indexOf("img")>0) {statushero=1;}
							var tda=14+statushero;

							var eat = 0;

							for(var i=0;i<=(9+statushero);i++){
								eat = eat + table[tda+i].textContent*tm[i][7];
							}

//							alert(eat);
							var deleteberichte_t3 = getOption("deleteberichte_t3",0,"integer");

							if (eat <= deleteberichte_t3 || !deleteberichte_t3) {
								t.url.match(/\?id=(\d+)/);
								var linkid = RegExp.$1;

								var ids = find("//form[@name='msg']//input[@value='"+linkid+"' and @type='checkbox']", XPFirst);
								ids.checked = true;
							}

						}, dummy);

//						alert(linkid);

//						alert(linkid);
					}
				});

				insertBefore(Input5, document.createTextNode(' '));
			}

			insertAfter(a, Input3);
			insertAfter(a, document.createTextNode(T('PRELOAD')));
			insertAfter(a, elem("P"));
		}

		opcionesMensajesPage();
	}

	function opcionesMensajesPage (page) {
		var prepage = 10;
		var opcionesmensajespreload = getOption("opcionesmensajespreload",0,"integer");

		if (!opcionesmensajespreload) {
			return 1;
		} else if (!page) {
			return opcionesMensajesPage (1);
		}

		location.href.match(/\?(.*&)?s=(\d+)/);
		var pagenow = RegExp.$2;
		pagenow = pagenow ? pagenow : 0;

		var pagelink = find("//form[@name='msg']//table[@class='tbg']//tr[@class='rbg'][2]//td[@class='r7']//a", XPList);

		if (page <= opcionesmensajespreload) {
//			 setTimeout(opcionesMensajesPage(1),getRandTimeRange(600));

//			var linkpages = xpathEvaluate("//form[@name='msg']//table[@class='tbg']//tr[@class='rbg'][2]//td[@class='r7']//a[contains(@href, 's=')]");

			var linkxpres = "//form[@name='msg']//table[@class='tbg']//tr[@class='rbg'][2]//td[@class='r7']//a[contains(@href, 's=')]";
			var linkpages = find(linkxpres, XPList);
			if (!linkpages.snapshotLength) {
				linkxpres = "//form[@name='msg']//table[@class='tbg']//tr[@class='rbg'][2]//td[3]//a[contains(@href, 's=')]";
				linkpages = find(linkxpres, XPList);
			}

			if (linkpages.snapshotLength > 0) {
				for (var i=0; i<linkpages.snapshotLength; i++) {
					if (linkpages.snapshotItem(i).href.search(/s=(\d+)/)) {
						var a = parseInt(RegExp.$1);
						if (a == 0) continue;

						var npage = 0;

						if (a <= pagenow || (i == 0 && linkpages.snapshotLength > 1)) {
							npage = a - prepage * opcionesmensajespreload;
							if (npage <= 0) npage = 0;
							linkpages.snapshotItem(i).href = linkpages.snapshotItem(i).href.replace(/(s=(\d+))/igm, "s="+npage);
						} else {
							npage = a + prepage;
						}

						if (npage <= 0) npage = 0;

//						alert(a+':'+npage);

//						linkpages.snapshotItem(i).href = linkpages.snapshotItem(i).href.replace(/(s=(\d+))/igm, "s="+npage);
					}
				}

//				if (!a || npage <= (pagenow + page * prepage)) return;
				if (!a || a < pagenow) return;

//				alert(a +':' + npage + ':' + (pagenow + (page) * prepage));

				ajaxRequest(linkpages.snapshotItem(i-1).href, "GET", null,
					function (t) {
//						var prepage = 10;
//						var opcionesmensajespreload = getOption("opcionesmensajespreload",0,"integer");

						pagenow = parseInt(pagenow) + (page * prepage);

						var ajaxdoc = new ajaxCreateDocument(t);
						var ans = ajaxdoc.ans;
						var ansdoc = ajaxdoc.ansdoc;

						var xpres = ansdoc.evaluate("//form[@name='msg']//table[@class='tbg']//tr", ans, null, XPList, null);

						var linktr = find("//form[@name='msg']//table[@class='tbg']//tr[@class='rbg'][2]", XPFirst);

						for(var i=1;i<xpres.snapshotLength-1; i++) {
							var mrow = xpres.snapshotItem(i);

							insertBefore(linktr, mrow);
						}

						var linkpages2 = find(linkxpres, XPList, ans, ansdoc);
						var linkpages = find(linkxpres, XPList);
//						if (linkpages.snapshotLength > 0) {

							if (linkpages.snapshotLength > 0 && linkpages2.snapshotLength > 0) {
								for (var i=0; i<linkpages.snapshotLength; i++) {
									if (linkpages.snapshotItem(i).href.search(/s=(\d+)/)) {
										var a = parseInt(RegExp.$1);
										if (a == 0) continue;

//										var npage = 0;

										if (a < pagenow || (i == 0 && linkpages.snapshotLength > 1)) {
											npage = a - prepage;

//											alert(a+':'+npage+':'+opcionesmensajespreload+':'+prepage+':'+pagenow);
										} else {
											npage = a + prepage * (opcionesmensajespreload + 0);


//											alert(a+':'+npage+':'+opcionesmensajespreload);

											linkpages.snapshotItem(i).href = linkpages.snapshotItem(i).href.replace(/(s=(\d+))/igm, "s="+npage);
										}
									}

//									alert(a+':'+npage+':'+opcionesmensajespreload);
								}

								page++;
								if (page <= opcionesmensajespreload && linkpages2.snapshotLength > 1) {
									opcionesMensajesPage(page);

//									alert(page);
								}
							}


//							for (var i=0; i<linkpages.snapshotLength; i++) {
//								if (linkpages2.snapshotItem(i).href.search(/s=(\d+)/)) {
//									var a = parseInt(RegExp.$1);
//									if (a == 0) continue;
//
//									var npage = 0;
//
//									if (a <= pagenow || (i == 0 && linkpages.snapshotLength > 1)) {
//										npage = a - prepage;
//									} else {
//										npage = a + prepage;
//									}
//
//									if (npage <= 0) npage = 0;
//
//									linkpages2.snapshotItem(i).href = linkpages.snapshotItem(i).href.replace(/(s=(\d+))/igm, "s="+npage);
//								}
//							}
//
//							page++;
//							if (page <= opcionesmensajespreload && npage > pagenow) {
//								opcionesMensajesPage(page);
//							}
//						}

						playerLinks();

//						alert(i + xpres.snapshotItem(i).innerHTML);
					}
				, dummy);
			}
		}



	}

	function ajaxCreateDocument (xmlHttpRequest) {
		this.ans = elem("DIV", xmlHttpRequest.responseText);
		this.ansdoc = document.implementation.createDocument("", "", null);
		this.ansdoc.appendChild(this.ans);
	}

	/**
	 * Crea eventos para enviar al formulario de envio de materias primas del mercado las coordenadas
	 * de las propias aldeas.
	 *
	 * Codigo sugerido por Bafox
	 */
	function quickCity(){
		// Comprueba si esta el formulario de envio
		if (find("//form[@name='snd']", XPFirst) == null) return;
		var ciudades = new Array();

		// Recupera la coordenada X
		var n = find("//table[@class='dtbl']//td[@class='right dlist1']", XPList);
		for(var i = 0; i < n.snapshotLength; i++){
			ciudades[i] = new Object();
			try{ ciudades[i].x = n.snapshotItem(i).innerHTML.split('(')[1]; }catch(e){}
		}

		// Recupera la coordenada Y
		n = find("//table[@class='dtbl']//td[@class='left dlist3']", XPList);
		for(var i = 0; i < n.snapshotLength; i++){
			try{ ciudades[i].y = n.snapshotItem(i).innerHTML.split(')')[0]; } catch(e){}
		}

		// Por cada par de coordenadas crea un evento para copiarlas al formulario
		n = find("//table[@class='dtbl']//tr", XPList);
		for (var i = 0; i < ciudades.length; i++){
			var elem = n.snapshotItem(i);
			elem.setAttribute('onClick',"snd.x.value='" + ciudades[i].x + "';snd.y.value='" + ciudades[i].y + "'");
			elem.setAttribute('onMouseOver', 'this.style.color="red"');
			elem.setAttribute('onMouseOut', 'this.style.color="black"');
			elem.style.cursor = "pointer";
		}
	}

	/**
	 * Calcula y muestra informacion adicional en los informes de los ataques
	 * Codigo inicial de Bafox
	 */
	function reportBatalla(){
		var t = find("//table[@class='tbg']//table[@class='tbg']", XPList);
		if (t.snapshotLength < 2) return;

		// Encuentra y suma todas las cantidades del botin
		var botin = null;
		var a = find("//tr[@class='cbg1']", XPList);
		if (a.snapshotLength >= 3){
			// FIXME: Apanyo para Firefox. FF mete nodos de tipo texto vacios
			if (a.snapshotItem(1).childNodes.length == 4){
				var b = a.snapshotItem(1).childNodes[3];
			}else{
				var b = a.snapshotItem(1).childNodes[1];
			}
			if (b.childNodes.length == 8){
				var cantidades_botin = new Array();
				cantidades_botin[0] = parseInt(b.childNodes[1].nodeValue);
				cantidades_botin[1] = parseInt(b.childNodes[3].nodeValue);
				cantidades_botin[2] = parseInt(b.childNodes[5].nodeValue);
				cantidades_botin[3] = parseInt(b.childNodes[7].nodeValue);
				botin = arrayToInt(cantidades_botin);
				var info_botin = '';
				for (var i = 0; i < 4; i++){
					info_botin += '<img src="' + img('r/' + (i + 1) + '.gif') + '" width="18" height="12" border="0" title="' + T('RECURSO' + (i+1)) + '">';
					info_botin += cantidades_botin[i];
					if (i < 3) info_botin += ' + '; else info_botin += ' = ';
				}
				info_botin += botin;
				b.innerHTML = info_botin;
			}
		}

		var perds = new Array();
		var carry = new Array();
		// Por cada participante en la batalla (atacante, defensor y posibles apoyos)
		for(var g = 0; g < t.snapshotLength; g++){
			carry[g] = 0;
			var tt = t.snapshotItem(g);
			var num_elementos = tt.rows[1].cells.length - 1;
			for(var j = 1; j < 11; j++){
				// Recupera la cantidades de tropa de cada tipo que han intervenido
				var u = uc[tt.rows[1].cells[j].getElementsByTagName('img')[0].src.replace(/.*\/.*\//,'').replace(/\..*/,'')];
				var p = tt.rows[3] ? tt.rows[3].cells[j].innerHTML : 0;
				// Basandose en el coste por unidad y su capacidad, se calculan las perdidas y la capacidad de carga total
				var ptu = arrayByN(u, p);
				perds[g] = arrayAdd(perds[g], ptu.slice(0, 4));
				carry[g] += (tt.rows[2] ? tt.rows[2].cells[j].innerHTML - p : 0) * u[4];
			}

			// Anyade la nueva informacion como una fila adicional en cada tabla
//			另有插件  將其移除
//			var informe = elem("TD");
//			for (var i = 0; i < 4; i++){
//				informe.innerHTML += '<img src="' + img('r/' + (i + 1) + '.gif') + '" width="18" height="12" border="0" title="' + T('RECURSO' + (i+1)) + '">';
//				informe.innerHTML += perds[g][i];
//				if (i < 3) informe.innerHTML += ' + '; else informe.innerHTML += ' = ';
//			}
//			var perdidas = arrayToInt(perds[g]);
//			informe.innerHTML += perdidas;
//			informe.colSpan = num_elementos;
//			informe.className = "s7";
//			var fila = elem("TR");
//			fila.className = "cbg1";
//			fila.appendChild(elem("TD", T('PERDIDAS')));
//			fila.appendChild(informe);
//			tt.appendChild(fila);

			// Solo para el atacante se calcula y muestra la rentabilidad y eficiencia del ataque
			if (g == 0 && botin != null){
				var datos = elem("TD");
				var fila_datos = elem("TR");
				datos.colSpan = num_elementos;

				// La rentabilidad muestra el botin en comparacion con las perdidas

				var rentabilidad = Math.round((botin - perdidas) * 100 / botin);
				if (botin == 0)	if (perdidas == 0) rentabilidad = 0; else rentabilidad = -100;
				datos.innerHTML = rentabilidad + "%";
				datos.className = "s7";
				fila_datos.className = "cbg1";
				fila_datos.appendChild(elem("TD", T('RENT')));
				fila_datos.appendChild(datos);
				tt.appendChild(fila_datos);

				var datos = elem("TD");
				var fila_datos = elem("TR");
				datos.colSpan = num_elementos;

				// La eficiencia muestra el botin en comparacion con la cantidad de tropas utilizadas

				var eficiencia = 100 - Math.round((carry[g] - botin) * 100 / carry[g]);
				if (carry[g] == 0) eficiencia = 0;
				datos.innerHTML = eficiencia + "%";
				datos.className = "s7";
				fila_datos.className = "cbg1";
				fila_datos.appendChild(elem("TD", T('EFICIENCIA')));
				fila_datos.appendChild(datos);
				tt.appendChild(fila_datos);

			}
		}
	}

	/**
	 * Realiza un resumen de la pagina de produccion
	 * It makes a summary of the production page
	 * 生産
	 */
	function preCalculate1(){
		var datos = 0;

		// Crea una matriz inicializada a 0 con todos los posibles niveles de cada tipo de recurso
		var grid = new Array(4);
		for(i = 0; i < 4; i ++) {
			grid[i] = new Array(26);
			for(j = 0; j <= 25; j++) {
				grid[i][j] = 0;
			}
		}

		// Solo hay 6 tipos de aldeas de 15 casillas cada uno. Se describe el tipo de recurso por casilla
		var dist = [
			[3, 3, 0, 3, 3, 1, 2, 3, 3, 2, 2, 3, 3, 0, 3, 1, 0, 1], // 9 cereales
			[2, 3, 0, 2, 1, 1, 2, 3, 3, 2, 2, 3, 3, 0, 3, 1, 0, 1],
			[0, 3, 0, 2, 1, 1, 2, 3, 3, 2, 2, 3, 3, 0, 3, 1, 0, 1],
			[0, 3, 0, 1, 1, 1, 2, 3, 3, 2, 2, 3, 3, 0, 3, 1, 0, 1],
			[0, 3, 0, 2, 0, 1, 2, 3, 3, 2, 2, 3, 3, 0, 3, 1, 0, 1],
			[3, 3, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3] // 15 cereales
		];

		find("//div[starts-with(@id, 'f')]", XPFirst).id.search(/f(\d)/);
		var tipo = RegExp.$1;

		// Recupera todas las casillas y rellena la matriz con los niveles detectados
		for (var i = 1; i <= 18; i++){
			var a = find("//img[@class='rf" + i + "']", XPFirst);
			if (a){
				a.src.search(/\/s(\d+).gif$/);
				grid[dist[tipo - 1][i - 1]][RegExp.$1]++;
			}else{
				grid[dist[tipo - 1][i - 1]][0]++;
			}
		}
		// Crea una tabla mostrando por cada tipo de recurso un representante de cada nivel que se ha encontrado
		// Muestra al lado de cada uno los recursos y tiempo restantes hasta poder subirlo de nivel
		var table = elem('TABLE');
		table.setAttribute("class", "tbg");
		table.setAttribute("align", "center");
		table.setAttribute("cellspacing", "1");
		table.setAttribute("cellpadding", "2");
		var fila1 = elem('TR');
		var fila2 = elem('TR');
		fila1.setAttribute("class", "rbg");
		table.appendChild(fila1);
		table.appendChild(fila2);
		for (var i = 0; i < 4; i++)
		{
			var td1 = elem('TD', '<img src="' + img('r/' + (i+1) + '.gif') + '" width="18" height="12" border="0" title="' + T('RECURSO' + (i+1)) + '">');
			fila1.appendChild(td1);

			var td2 = elem('TD');
			td2.setAttribute('valign', 'top');
			fila2.appendChild(td2);

			var table2 = elem('TABLE');
			table2.setAttribute("align", "center");
			td2.appendChild(table2);
			for (var j = 0; j < 25; j++)
			{
				if (grid[i][j] > 0 && buildingCost[i][j+1] != null)
				{
					datos = 1;
					var fila3 = elem('TR');
					//var tipDiv = elem('DIV');
					fila3.setAttribute('id', 'tip_' + i + '_' + j);
					var imagen = '<div style="width: 0%;"><img src="data:image/gif;base64,' + imagenes["r" + i] + '" border="0" title="' + T('RECURSO' + (i+1)) + '">';
					if (j > 0) imagen += '<img src="' + img('g/s/s' + j + '.gif') + '" style="position:relative; bottom:52px; left: 27px;" border="0">';
					imagen += '</div>';
					var td = elem("TD", imagen);
					fila3.appendChild(td);

					var restante = calculateResourceTime(buildingCost[i][j+1], true);
					var td3 = elem('TD');
					//td3.setAttribute('class', 'c f7');
					td3.setAttribute('style','color:#333; font-size: 12px; vertical-align: top');

					fila3.appendChild(td3);
					table2.appendChild(fila3);

					if (restante != null) td3.innerHTML = restante;
					else td3.innerHTML = '<span style="color: #FF6F0F; font-weight: bold;">' + T('SUBIR_NIVEL') + '</span>';

					var cpPerDay = [buildingCost[i][j][4], buildingCost[i][j + 1][4]];
					td3.innerHTML += '<br>' + T('CPPERDAY') + ": " + cpPerDay[0] + " → " + cpPerDay[1];
				}
			}
		}
//		table.style.position = 'absolute';
		table.setAttribute("id", "resumen");
		// Se desplaza la tabla hacia abajo para no interferir con la lista de aldeas / enlaces derecha
//		table.style.top = 580 + longitudPantalla() + 'px';
		if (datos == 1) {

			var divt = elem('DIV');
			divt.style.display = 'block';
			divt.style.position = 'absolute';




			var oh = 290;
			var height = get('ltrm') ? get('ltrm').clientHeight : 0;
			var height2 = get('lbau1') ? get('lbau1').clientHeight : 0;
			var height3 = get('ltbw0') ? get('ltbw0').clientHeight - 60 : 0;

			oh = oh - (height3 > 0 ? height3 : 0);

			divt.style.top = 610 + ((oh - height - height2) >= 0 ? 0 : (height + height2 - oh)) + 'px';

			divt.appendChild(table);
			document.body.appendChild(divt);

//			document.body.appendChild(table);
		}

//		/**
//		* xingulin︰加上資源田提示 tip
//		* Begin
//		*/
//		// 加入 tip 區塊
//		if($('#lbau1').length != 0)
//		{
//			$('#lbau1').after("<div id='stateTip'  style='border: 1px solid #CCC;  color: #333; display: none; font-size: 12px; width: 500px; height: 75px;'></div>");
//		}
//		else
//		{
//			$('#lmid2').append("<div id='stateTip' style='position: absolute; left: 30px;  color: #333;  top: 350px;  font-size: 12px; width: 500px; height: 75px; border: 1px solid #CCC; display: none;'></div>");
//		}
//
//		// 幫每個資源田加上 Hover Event Handler,處理 tip 的顯示與隱藏
//		//for (var i = 1; i <= 18; i++)
//		$('//map[@name="rx"]/area').each(function(i)
//		{
//			if(i != 18) // 跳過最後一個<area />(村莊中心)
//			{
//				var resource;
//				var resource_level;
//				var resource_type;
//				if ( resource = $('img.rf' + (i + 1) + ':eq(0)') )
//				{
//					$(resource).attr('src').search(/\/s(\d+).gif$/);
//					resource_level = parseInt(RegExp.$1);
//					resource_type = parseInt(dist[tipo - 1][i]);
//					$($('//map[@name="rx"]/area:eq(' + i + ')')).hover
//					(
//						function()
//						{
//							var imagen = '<div style="width: 0%;"><img src="data:image/gif;base64,' + imagenes["r" + resource_type] + '" border="0" title="' + T('RECURSO' + (resource_type + 1)) + '">';
//							if (resource_level > 0)
//								imagen += '<img src="' + img('g/s/s' + resource_level + '.gif') + '" style="position:relative; bottom:52px; left: 27px;" border="0">';
//							imagen += '</div>';
//
//							var restante = calculateResourceTime(buildingCost[resource_type][resource_level + 1], false);
//							if(restante == null)
//							{
//								restante = '<span style="color: #FF6F0F; font-weight: bold;">' + T('SUBIR_NIVEL') + '</span>';
//							}
//
//							$('#stateTip').attr('innerHTML', '<div style="float: left; display: table-cell">' + imagen + '</div><div style="float: left; display: table-cell; padding-top: 10px; width: 400px;">' + restante + '</div>');
//							if($('#lbau1').length != 0)
//							{
//								$('#summary').css('top', parseInt($('#summary').css('top')) + (parseInt($('#lbau1').attr('height')) + $('#stateTip').height() - 115));
//							}
//							else
//							{
//								$('#summary').css('top', parseInt($('#summary').css('top')) + ($('#stateTip').height() - 115));
//							}
//							$('#stateTip').show();
//						},
//						function()
//						{
//							$('#summary').css('top', 580 + longitudPantalla() + 'px');
//							$('#stateTip').hide();
//							$('#stateTip').attr('innerHTML', '');
//						}
//					);
//
//				}
//			}
//		});
//		/**
//		* END
//		*/
	}

	/**
	 * It makes a summary of the page of buildings of the village
	 * 建築物列表
	 */
//	function preCalculate2(){
//		var data = 0;
//		var buildingsImages = new Array();
//		var buildingsDescs = new Array();
//		var buildingsLinks = new Array();
//
//		// recoge los nombres de cada uno
//		xpathResult = find('//map[@name="map1"]/area/@title', XPIter);
//		while ((buildingsDescs[buildingsDescs.length] = xpathResult.iterateNext())) {}
//
//		// los enlaces para acceder directamente a ellos
//		xpathResult = find('//map[@name="map1"]/area/@href', XPIter);
//		while ((buildingsLinks[buildingsLinks.length] = xpathResult.iterateNext())) {}
//
//
//		// Procesa as imagenes de los edificios
//		//var xpathResult = find('//td[@class="s3"]/img/@src', XPIter);
//		var xpathResult = find('//div[@id="lmid2"]/img/@src', XPIter);
//		buildingsImages[0] = document.createTextNode(img("g/g16.gif"));
//		while ((buildingsImages[buildingsImages.length] = xpathResult.iterateNext())) {}
//		// Soporte para murallas
//		var a = find("//div[starts-with(@class, 'd2_x')]", XPFirst);
//		if (a){
//			switch(a.className){
//				case 'd2_x d2_0': break;
//				case 'd2_x d2_1': var b = "g/g31.gif"; break;
//				case 'd2_x d2_11': var b = "g/g32.gif"; break;
//				case 'd2_x d2_12': var b = "g/g33.gif"; break;
//			}
//			if (b) buildingsImages[buildingsDescs.length - 4] = document.createTextNode(img(b));
//		}
//
//		//主層表格
//		var rowcell = 3;
//		var table = elem('TABLE');
//		//table.setAttribute("class", "tbg");
//		//table.setAttribute("align", "center");
//		table.setAttribute("cellspacing", "0");
//		table.setAttribute("cellpadding", "3");
//		table.setAttribute("style", "width:100%;border-collapse:collapse;");
//		var colgroup = elem('COLGROUP');
//		var col = elem('COL');
//		col.setAttribute("style", 'width:' + Math.floor(100 /rowcell) +'%;');
//		col.setAttribute("span", rowcell);
//		colgroup.appendChild(col);
//		table.appendChild(colgroup);
//
//		var tablecell  = new Array();
//		var j = 0;
//		//顯示方式
//		for(var i = 0; i < buildingsDescs.length - 3; i++)
//		{
//			if(buildingsDescs[i] != null && basename(buildingsImages[i].nodeValue) != 'iso.gif')
//			{
//				// Por cada edificio se recoge su nivel y su codigo en el juego
//				buildingLevel = buildingsDescs[i].nodeValue.split(" ");
//				buildingLevel = parseInt(buildingLevel[buildingLevel.length-1]);
//
//				buildingCode = buildingsImages[i].nodeValue.split("/");
//				buildingCode = buildingCode[buildingCode.length-1].split(".");
//				buildingCode = parseInt(buildingCode[0].substring(1, buildingCode[0].length));
//
//				// Si es actualizable se muestra junto con los recursos que necesita
//				if (buildingCost[buildingCode] != null && buildingCost[buildingCode][buildingLevel+1] != null)
//				{
//					data = 1;
//					tablecell[j] = elem("TD");
//					//tablecell[j].setAttribute('class', 'f10');
//					tablecell[j].setAttribute("style", "border:1px solid #C0C0C0;vertical-align:top;");
//					var title = elem("DIV");
//					var state = elem("DIV");
//					var state2 = elem("DIV");
//
//					title.setAttribute('class', 'f10');
//					title.innerHTML = '<a href="' + buildingsLinks[i].nodeValue + '">' + buildingsDescs[i].nodeValue + '</a>&nbsp;&nbsp;<span>(<a href="javascript:void(null)" class="tip" style="color: #387AD7;">展開/折疊</a>)</span>';
//
//					var restante = calculateResourceTime(buildingCost[buildingCode][buildingLevel+1]);
//					//將此處更改為升級2級 by Arrack
//					if (buildingCost[buildingCode] != null && buildingCost[buildingCode][buildingLevel+2] != null)
//					{
//
//						var restante_temp=[0,0,0,0];
//
//						for (var ii = 0; ii < 4; ii++){
//							restante_temp[ii] = buildingCost[buildingCode][buildingLevel+1][ii]+buildingCost[buildingCode][buildingLevel+2][ii];
//						}
//
//						var restante2 = calculateResourceTime(restante_temp);
//
//						//var restante2 = calculateResourceTime(buildingCost[buildingCode][buildingLevel+2]);
//					}
//					//state.setAttribute('class', 'c f10');
//					state.setAttribute('style','color:#333; font-size: 12px; margin-top: 5px;');
//
//					state.innerHTML += T('UPLV') + (buildingLevel+1) + '<br>';
//
//					if (restante != null)
//					{
//						state.innerHTML += restante;
//					}
//					else // 可升級
//					{
//						//明顯的連結標示
//						state.innerHTML += '<a href="' + buildingsLinks[i].nodeValue + '" style="color: #FF6F0F;">' + T('SUBIR_NIVEL') + '</a>';
//					}
//
//					//state.innerHTML += '<br>--<br>' + T('UPLV') + (buildingLevel+2) + '<br>';
//					state2.setAttribute('style', 'display: none; font-size: 12px; color: #333; margin-top: 10px; padding-top: 10px; border-top: 1px dashed');
//					state2.setAttribute('class', 'state2');
//					state2.innerHTML = T('UPLV') + (buildingLevel+2) + '<br>';
//
//					if (restante2 != null)
//					{
//						state2.innerHTML += restante2;
//					}
//					else // 可升級
//					{
//						//明顯的連結標示
//						state2.innerHTML += '<a href="' + buildingsLinks[i].nodeValue + '" style="color: #FF6F0F;">' + T('SUBIR_NIVEL') + '</a>';
//					}
//
//
//					tablecell[j].appendChild(title);
//					tablecell[j].appendChild(state);
//					tablecell[j].appendChild(state2);
//					j++;
//				}
//
//			}
//		}
//
//
//		var tablerow = new Array();
//		var rowno = Math.ceil(tablecell.length / rowcell);
//		for(var i = 0; i < rowno; i++)
//		{
//			tablerow[i] = elem("TR");
//
//			// xingulin: 奇數行加上背景色
//			if(i % 2 == 0) {
//				tablerow[i].setAttribute('style', 'background-color: #E5EDF7');
//			}
//		}
//
//		var k = 0;
//		var l = 0;
//		for(var i = 0; i < tablecell.length; i++) {
//			tablerow[k].appendChild(tablecell[i]);
//			l++;
//			if(l % rowcell == 0) {k++;}
//		}
//		//填補空格
//		if(tablecell.length%rowcell != 0){
//			for(var i = 0; i < rowcell-(tablecell.length % rowcell); i++) {
//				var emptycell = elem("TD");
//				emptycell.setAttribute("style", "border:1px solid #C0C0C0;vertical-align:top;");
//				tablerow[rowno - 1].appendChild(emptycell);
//			}
//		}
//		for(var i = 0; i < rowno; i++) {
//			 table.appendChild(tablerow[i]);
//		}
//		table.style.position = 'absolute';
//		//table.setAttribute("id", "resumen");
//		// Se desplaza la table hacia abajo para no interferir con la lista de aldeas / enlaces derecha
//		table.style.top = 625 + longitudPantalla() + 'px';
//		if (data == 1) document.body.appendChild(table);
//
//		/**
//		 * xingulin︰加入切換升兩級的提示區塊的 Click Event Handler
//		 * Begin
//		 */
//		$("a.tip").each(function(i)
//		{
//			$(this).click
//			(
//				function()
//				{
//					$($("div.state2").get(i)).toggle();
//				}
//			);
//		});
//		/**
//		 * End
//		 */
//	}

	function preCalculate2(){
		var edificiosPorFila = 3; // hany epulet legyen egy sorban
		var datos = 0;
		var buildingsImages = new Array();
		var buildingsDescs = new Array();
		var buildingsLinks = new Array();

		var ii = 0;

		var xpathResult = find("//div[@id='lmid2']/img[contains(@src, 'img\/un\/special\/')]");
		if (!xpathResult) {
			xpathResult = find("//div[@id='lmid2']/div[@class='dname']");

			var v = {
				'NewyearRocket_turquoise_1a.gif' : 'position: absolute; z-index: 20; left: 161px; top: 168px;',
				'NewyearRocket_purple_1a.gif' : 'position: absolute; z-index: 20; left: 265px; top: 148px;',
				'NewyearRocket_yellow_1a.gif' : 'position: absolute; z-index: 20; left: 200px; top: 248px;',
				'NewyearRocket_orange_1a.gif' : 'position: absolute; z-index: 20; left: 300px; top: 0px;',
				'NewyearRocket_green_1a.gif' : 'position: absolute; z-index: 20; left: 110px; top: 230px;',
				'NewyearRocket_red_1a.gif' : 'position: absolute; z-index: 20; left: 328px; top: 210px;'
			};

			for (k in v) {
				var imge = elem('img');
				imge.src = 'img/un/special/' + k;
				imge.style.cssText = v[k];
				imge.height = 140;
				imge.width = 75;
				imge.border = 0;

				insertAfter(xpathResult, imge);
			}
		}

		// recoge los nombres de cada uno
		var xpathResult = find('//map[@name="map1"]/area/@title', XPIter);
		while ((buildingsDescs[buildingsDescs.length] = xpathResult.iterateNext())) {}

		// los enlaces para acceder directamente a ellos
		xpathResult = find('//map[@name="map1"]/area/@href', XPIter);
		while ((buildingsLinks[buildingsLinks.length] = xpathResult.iterateNext())) {}

		// Procesa as imagenes de los edificios
//		var xpathResult = find('//div[@id="lmid2"]/img/@src', XPIter);
		var xpathResult = find("//div[@id='lmid2']/img[contains(@class, 'd')]/@src", XPIter);

		buildingsImages[0] = document.createTextNode(img("g/g16.gif"));
		while ((buildingsImages[buildingsImages.length] = xpathResult.iterateNext())) {}

		// Soporte para murallas
		var a = find("//div[starts-with(@class, 'd2_x')]", XPFirst);
		if (a){
			switch(a.className){
				case 'd2_x d2_0': break;
				case 'd2_x d2_1': var b = "g/g31.gif"; break;
				case 'd2_x d2_11': var b = "g/g32.gif"; break;
				case 'd2_x d2_12': var b = "g/g33.gif"; break;
			}
			if (b) buildingsImages[buildingsDescs.length - 4] = document.createTextNode(img(b));
		}

		var table = elem('TABLE');
		table.setAttribute("class", "tbg");
		table.setAttribute("align", "left");
		table.setAttribute("cellspacing", "1");
		table.setAttribute("cellpadding", "2");



		var j = 0;
		for(var i = 0; i < buildingsDescs.length - 3; i++) {
			if(buildingsDescs[i] != null && basename(buildingsImages[i].nodeValue) != 'iso.gif') {
				// Por cada edificio se recoge su nivel y su codigo en el juego
				var buildingLevel = buildingsDescs[i].nodeValue.split(" ");
				buildingLevel = parseInt(buildingLevel[buildingLevel.length-1]);

				var buildingCode = buildingsImages[i].nodeValue.split("/");
				buildingCode = buildingCode[buildingCode.length-1].split(".");
				if (buildingCode[0].search(/(\d+)/)) buildingCode = parseInt(RegExp.$1);
//				buildingCode = parseInt(buildingCode[0].substring(1, buildingCode[0].length));

				// Si es actualizable se muestra junto con los recursos que necesita
				if (buildingCost[buildingCode] != null && buildingCost[buildingCode][buildingLevel+1] != null){
					// Se reparten los edificios entre las columnas disponibles en las filas que haga falta
					if (j % edificiosPorFila == 0){
						var fila = elem('TR');

						if(j % 2 == 0) {
							fila.setAttribute('style', 'background-color: #E5EDF7');
						}

						table.appendChild(fila);
					}
					j++;
					datos = 1;

					// Soporte para murallas
					switch(buildingCode){
						case 31: buildingsImages[i].nodeValue = 'data:image/gif;base64,' + imagenes["empalizada"]; break;
						case 32: buildingsImages[i].nodeValue = 'data:image/gif;base64,' + imagenes["muralla"]; break;
						case 33: buildingsImages[i].nodeValue = 'data:image/gif;base64,' + imagenes["terraplen"]; break;
					}



					var td = elem("TD");
					td.setAttribute('width','25%');
					td.setAttribute('valign','bottom');
					fila.appendChild(td);

					var table2 = elem('TABLE');
					table2.setAttribute("align", "left");
					table2.setAttribute('class','bttable');

//					table2.setAttribute("height", "100%");
//					table2.setAttribute("width", "100%");

					table2.setAttribute("cellspacing", "0");
					table2.setAttribute("cellpadding", "0");

					td.appendChild(table2);

					var nametr = elem('TR');
					table2.appendChild(nametr);
					var nametd = elem('TD','<a href="' + buildingsLinks[i].nodeValue + '" title="'+ buildingsDescs[i].nodeValue +'">' + buildingsDescs[i].nodeValue+'</a>' );
					nametd.setAttribute('colspan',"2");
					nametd.setAttribute('class', 'f10');
					nametr.appendChild(nametd);

					var fila2 = elem('TR');
					table2.appendChild(fila2);

					var td2 = elem("TD");
					td2.setAttribute('class', 'f10');
					td2.innerHTML = '<a href="' + buildingsLinks[i].nodeValue + '" title="'+ buildingsDescs[i].nodeValue +'"><img src="' + buildingsImages[i].nodeValue + '" border="0"></a>';
					fila2.appendChild(td2);

					var cpPerDay = [buildingCost[buildingCode][buildingLevel][4], buildingCost[buildingCode][buildingLevel + 1][4]];

					var restante = calculateResourceTime(buildingCost[buildingCode][buildingLevel+1], 1);
					var td3 = elem("TD");
//					td3.setAttribute('class', 'dcol f7');
					td3.setAttribute('style','color:#333; font-size: 12px; padding-bottom: 5px;');
					td3.setAttribute('valign','bottom');
					fila2.appendChild(td3);

					if (restante != null) {
						td3.setAttribute('valign', 'bottom');
// 						td3.setAttribute('align', 'left');
						td3.innerHTML = restante;
					} else {
						td3.setAttribute('valign', 'center');
//					 td3.innerHTML = T('SUBIR_NIVEL');

						td3.innerHTML += '<a href="' + buildingsLinks[i].nodeValue + '" style="color: #FF6F0F;">' + T('SUBIR_NIVEL') + '</a>';
					}

					td3.innerHTML += '<br>' + T('CPPERDAY') + ": " + cpPerDay[0] + " → " + cpPerDay[1];
				}
			}
		}

		while (j % edificiosPorFila != 0) {
			fila.appendChild(elem("TD", '', 'style', 'background-color: #FFFFFF'));
			j++;
		}
		//table.style.position = 'absolute';
		table.setAttribute("id", "resumen");
		// Se desplaza la tabla hacia abajo para no interferir con la lista de aldeas / enlaces derecha
		//table.style.top = 625 + longitudPantalla() + 'px';
		if (datos == 1)  {
			var middleblock = get('lmidall');
			middleblock.appendChild(elem('BR'));
			middleblock.appendChild(table);
		}
	}

	/**
	 * Realiza un resumen de la pagina del mapa
	 * 地圖預處理
	 */
	function preCalculate3(){

//		return;
//
//		var datos = 0;
//		var a = find("//*/area[@onmouseover]", XPList);
//		//fix by arrack 移動地圖的問題
//		var b=document.getElementById('table_map');
//		if(b){
//			//alert(b.innerHTML);
//			b.innerHTML='';
//		}
//		var table = elem('TABLE');
//		table.setAttribute("id", "table_map");
//		table.setAttribute("sortCol", -1);
//		table.setAttribute("class", "tbg");
//		table.setAttribute("align", "center");
//		table.setAttribute("cellspacing", "1");
//		table.setAttribute("cellpadding", "2");
//		var thead = elem("THEAD");
//		var tbody = elem("TBODY");
//		var row = elem('TR');
//		row.setAttribute('class', "rbg");
//		thead.appendChild(row);
//		table.appendChild(thead);
//		var etiquetas_table = ["JUGADOR", "ALIANZA", "ALDEAS", "HAB", "COORD", "ACCION"];
//
//		for (var i = 0; i < 6; i++){
//			var td = elem('TD', T(etiquetas_table[i]));
//			if (i < 4){
//				switch(i){
//					case 3: td.addEventListener("click", sortTable('table_map', i, 'int'), 0); break;
//					//有待除錯
//					default: td.addEventListener("click", sortTable('table_map', i), 0);
//				}
//				td.style.cursor = "pointer";
//			}
//			row.appendChild(td);
//		}
//		// Procesa todas las casillas visibles del mapa
//		for(var i = 0; i < a.snapshotLength; i++) {
//			var aldea = a.snapshotItem(i);
//			var mouseOver = aldea.getAttribute("onmouseover");
//			// Por cada aldea se muestra toda la informacion posible y enlaces rapidos para atacar y enviar recursos
//			if(mouseOver.substring(0,1) != "x") {
//				datos = 1;
//				var row = elem('TR');
//				tbody.appendChild(row);
//				datos_aldea = mouseOver.substring(4, mouseOver.length - 1).split(",");
//				var href = aldea.getAttribute("href");
//				row.appendChild(elem('TD', datos_aldea[1].substring(1, datos_aldea[1].length - 1)));
//				row.appendChild(elem('TD', datos_aldea[3].substring(1, datos_aldea[3].length - 1)));
//				row.appendChild(elem('TD', datos_aldea[0].substring(1, datos_aldea[0].length - 1)));
//				row.appendChild(elem('TD', datos_aldea[2].substring(1, datos_aldea[2].length - 1)));
//				row.appendChild(elem('TD', '<a href="' + href + '">' + datos_aldea[4].substring(1, datos_aldea[4].length - 1) + ", " + datos_aldea[5].substring(1, datos_aldea[5].length - 1) + '</a>'));
//				row.appendChild(elem('TD', '<a href="' + href.replace("karte.php?d", "a2b.php?z") + '">' + T('ATACAR') + '</a> / <a href="' + href.replace("karte.php?d", "build.php?ze") + '&gid=17">' + T('COMERCIAR') + '</a>'));
//			}
//		}
//		table.appendChild(tbody);
//		table.style.position = 'absolute';
//		//table.setAttribute("id", "resumen");
//		table.style.top = 580 + longitudPantalla() + 'px';
//		if (datos == 1) document.body.appendChild(table);

		installMapEventHandler();
	}

	function eventtableover(ev){
		marker=get('mapmarker');
		var tar=ev.target
		for(var i=0;i<5;i++){if(tar.nodeName!='TR'){tar=tar.parentNode;}else break;}
		marker.className=tar.getAttribute('mt');
		marker.style.display='';
	};

	function area_onmouseover (e) {
		for(var i = 6; i > -1; i--)
		{
			for(var j = 0; j < 7; j++)
			{
				$('i_'+j+'_'+i).style.cssText = '';

				if (e.target.id == 'a_'+j+'_'+i) {
					$('i_'+j+'_'+i).style.cssText = 'padding: 3px; margin-left: -3px;';
				}
			}
		}
	}

	function area_onmouseout (e) {
		e.target.style.cssText = '';
	}

	function installMapEventHandler() {
//		var origpe = unsafeWindow.ve;
//		unsafeWindow.ve = function(pd,qd) {
//			var rv = origpe(pd,qd);
//			setTimeout(infoRecursos,10);
//
////			setTimeout(preCalculate3, 10);
//			return rv;
//		};

		var allArrows = find("//area[starts-with(@id, 'ma_n')]", XPList);
		for (var xi = 0; xi < allArrows.snapshotLength; xi++) {
			_attachEvent(allArrows.snapshotItem(xi), 'click', function () {
				infoRecursos();
				playerLinks();
				});
		}

		for(var i=1;i<50;i++){
			var k1=(i-1)%7;
			var k2=Math.floor((49-i)/7);

			var area = get("a_"+k1+"_"+k2);
			var mevobj = createMapInfoObj(area,i-1);
			area.addEventListener("mouseover",mevobj.mouseOverEvent,false);
			area.addEventListener("mouseout", mevobj.mouseOutEvent,false);

//			area.addEventListener("mouseover", crearEventoRecursosCasilla(area.href, links[i]), 0);
//			area.addEventListener("mouseout", function(){ clearTimeout(timeout); timeout = 0; get("tb_tooltip").style.display = 'none'; }, 0);
		}
	}

	function createMapInfoObj(area,pos){
		var mev = new Object();
		mev.area=area;
		mev.pict=get("i_"+area.id.substring(2));
		mev.pos=pos;
		mev.timeout=0;

		mev.mouseOverEvent = function(){
//			if (mev.pict.src.match(/\/(d|t)\d*.gif$/)) {
//				mev.timeout = setTimeout(function(){
//				ajaxRequest(mev.area.href, "GET", null, function(t) {if (mev.timeout!=0) procesarCasilla(t,mev)}, dummy); }
//				, 300);
//			}

			var mapdata = arrayRecursosCasilla[mev.area.href] ? arrayRecursosCasilla[mev.area.href] : mev.area.getAttribute("casilla");

			if (mapdata) {
				timeout = setTimeout(function(){
					var div = get("tb_tooltip");
					div.style.display = 'block';
					div.innerHTML = mapdata;
				}, 100);
			} else {
				if (mev.pict.src.match(/\/(d|t)\d*.gif$/)) {
					mev.timeout = setTimeout(function(){
					ajaxRequest(mev.area.href, "GET", null, function(t) {if (mev.timeout!=0) procesarCasilla(t,mev)}, dummy); }
					, 300);
				}
			}

			};
		mev.mouseOutEvent = function(){ clearTimeout(mev.timeout); mev.timeout = 0; get("tb_tooltip").style.display = 'none'; };
		mev.scan = function(){

			var mapdata = arrayRecursosCasilla[mev.area.href] ? arrayRecursosCasilla[mev.area.href] : mev.area.getAttribute("casilla");

			if (mapdata) {
				timeout = setTimeout(function(){
					var div = get("tb_tooltip");
					div.style.display = 'block';
					div.innerHTML = mapdata;
				}, 100);
			} else {
//				ajaxRequest(mev.area.href, "GET", null, function(t) {parseFieldType(t,mev)}, dummy);
				ajaxRequest(mev.area.href, "GET", null, function(t) {procesarCasilla2(t,mev.area)}, dummy);
			}
		};
		return mev;
	}

	/**
	* Ordena en orden ascendete y descendente
	*
	* Params:
	* 	sTableID: 	ID de la tabla a ordenar
	* 	iCol: 		Indice de la columna a ordenar
	* 	sDataType:	Tipo de datos de la columna, valor por defecto:texto
	*/
	function sortTable(sTableID, iCol, sDataType) {
		return function(){
			var oTable = document.getElementById(sTableID);
			var oTBody = oTable.tBodies[0];
			var colDataRows = oTBody.rows;
			var aTRs = new Array;

			for (var i = 0; i < colDataRows.length; i++) aTRs[i] = colDataRows[i];
			if (oTable.getAttribute("sortCol") == iCol) aTRs.reverse();
			else aTRs.sort(generateCompareTRs(iCol, sDataType));

			var oFragment = document.createDocumentFragment();
			for (var i = 0; i < aTRs.length; i++) oFragment.appendChild(aTRs[i]);

			oTBody.appendChild(oFragment);
			oTable.setAttribute("sortCol", iCol);
		};
	}

	/**
	 * Convierte un elemento a un determinado tipo segun un argumento
	 *
	 * Params:
	 *	elemento: elemento a convertir
	 *	sDataType: nuevo tipo de datos (int o float)
	 *
	 * Returns:
	 *	El elemento convertido al nuevo tipo de datos
	 */
	function convert(element, sDataType) {
		switch(sDataType) {
			case "int": return ((element.nodeValue == null) || !element.nodeValue.match(/\d+/)) ? 0 : parseInt(element.nodeValue);
			case "float": return ((element.nodeValue == null) || !element.nodeValue.match(/\d+/)) ? 0 : parseFloat(element.nodeValue);
			default: return (element == null) ? '' : element.textContent.toLowerCase();
		}
	}

	/**
	 * Realiza una comparaci�n entre las casillas de la misma columna en distintas filas
	 *
	 * Params:
	 *	iCol: numero de columna dentro de la fila a comparar
	 *	sDataType: tipo de datos de la comparacion
	 *
	 * Returns:
	 * 	Devuelve -1, 1 o 0 segun el resultado de la comparacion
	 */
	function generateCompareTRs(iCol, sDataType) {
		return function compareTRs(oTR1, oTR2) {
			var vValue1 = convert(oTR1.cells[iCol].firstChild, sDataType);
			var vValue2 = convert(oTR2.cells[iCol].firstChild, sDataType);

			if (vValue1 < vValue2) return -1;
			else if (vValue1 > vValue2) return 1;
			else return 0;
		};
	}

	/**
	 * Implementa y muestra un bloc de notas. Guarda las notas como cookies en el navegador local
	 */
	function blocNotas(){
		var a = find("//form[@name='msg']", XPFirst);

		// Carga las notas previas si existen
		var notas = readCookie("notas_" + server);
		if (notas == null) notas = ''; else notas = unescape(notas);

		// Crea la estructura HTML del bloc
		var tabla = elem("TABLE");
		var tr = elem("TR");
		var td = elem("TD");
		var p1 = elem("P");
		var p2 = elem("P");
		var textarea = elem("TEXTAREA", notas);
		var input = elem("INPUT");

		tabla.setAttribute("width", "430");
		td.setAttribute("align", "center");
		td.setAttribute("background", img('msg/block_bg.gif', true));
		textarea.setAttribute("cols", "30");
		textarea.setAttribute("rows", "16");
		textarea.setAttribute("style", 'background-image: url(' + img('msg/underline.gif', true) + '); border : 0px; overflow:auto');
		input.setAttribute("type", "image");
		input.setAttribute("border", "0");
		input.setAttribute("src", img('b/s1.gif', true));
		// En el evento del boton de guardado actualiza el valor de la cookie (1 a�o de duracion por defecto)
		input.addEventListener("click", function(){ createCookie("notas_" + server, escape(textarea.value), 365); alert(T('GUARDADO')); }, 0);

		td.appendChild(elem("P", "&nbsp;"));

		p1.appendChild(textarea);
		td.appendChild(p1);
		p2.appendChild(input);
		td.appendChild(p2);
		tr.appendChild(td);
		tabla.appendChild(tr);
		a.parentNode.appendChild(elem("P"));
		a.parentNode.appendChild(tabla);
	}

	/**
	* Crea una funcion que se encarga del evento al desplazarse en el mapa. Actualiza la direccion destino en
	* base al desplazamiento configurado
	*
	* Params:
	* 	i:	Ordinal sobre la orientacion de la flecha
	*
	* Returns
	*	La funcion que gestiona el evento
	**/

	function createEventoMapa(e, i, href){
		var funcion = function (){

//			alert(href);

			if (href == 'javascript:void(0)' || href == 'javascript: void(0)') {

//				infoRecursos();
//				desplazarMapa();
//				preCalculate3();

				return 0;
			}


			var despl = [-801, 1, 801, -1];
//			var d = document.getElementsByName("desp")[0].value;
//			var d = parseInt(document.getElementsByName("desp")[0].value);

			var d = readCookie("desp");

//			if (d < 1) d = 1;
			if (d < 1 || d > 20 || d == 'NaN' || d == NaN || !d || d == null || d == 'null') d = 3;
			// Actualiza el valor de la cookie
			createCookie("desp", d, 365);
			var base = parseInt(e.href.split("=")[1]);
			ajaxRequest("ajax.php?action=map_content&z=" + (base + (despl[i] * (d - 1))), "GET", null,
				function(t){
					try {
						if (t.responseText) get("map_content").innerHTML = t.responseText;
						infoRecursos();
						desplazarMapa();
						removeElement(get("tabla_mapa"));
						preCalculate3();
					} catch (E) {}
				}
			, dummy);
		};
		return funcion;
	}

	/**
	 * Crea una casilla para introducir el desplazamiento deseado en el mapa e inserta los
	 * eventos en las flechas de direccion
	 */
	function desplazarMapa(){
		// Crea y anyade la casilla del desplazamiento
//		var b = find("//form[@method='post']", XPFirst).parentNode;

		// bluelovers
		var b = find("//form[@action='karte.php']", XPFirst);
		if (b) {
			b = b.parentNode;
		} else {
			return;
		}
		// bluelovers

//		var tr = elem("TR");
//		// Carga el ultimo valor utilizado si existe
//		var d = readCookie("desp");
//
//		// bluelovers
//		d = parseInt(d);
//		if (d < 1 || d > 20 || d == 'NaN' || d == NaN || !d) d = 5;
//		// bluelovers
//
//		var td1 = elem("TD", "<b>" + T('DESP_ABR') + "</b>");
//		var td2 = elem("TD", '<input name="desp" value="' + (d == null ? '1' : d) + '" size="2" maxlength="4" class="fm fm25">');
//		td1.setAttribute("colspan", 2);
//		td2.setAttribute("colspan", 2);
//		tr.appendChild(td1);
//		tr.appendChild(td2);
//		b.appendChild(tr);

//		if (location.href.match(/karte.php($|\?z=)/) && arrayValueExist(tw_server, server)){
//			var center_id = xy2id(find("//input[@name='xp']", XPFirst).value, find("//input[@name='yp']", XPFirst).value);
//			var href = "http://www.denibol.com/proyectos/travian_world/karte3.php?z=" + center_id + "&server=" + server + "&user=" + uid;
//			var td3 = elem("TD", '<a href="' + href + '" onClick="pop(\'' + href + '\'); return false;" target="_blank"><img src="' + img('m/max.gif') + '" width="33" height="25" border="0" alt="' + T('MAP_EXT') + '" title="' + T('MAP_EXT') + '"></a>');
//			td3.setAttribute("colspan", 2);
//			tr.appendChild(td3);
//		}

		// Inserta los eventos para manipular los desplazamientos
		var a = find("//map/area[@onclick]", XPList);
		for (var i = 0; i < a.snapshotLength; i++){
			var b = a.snapshotItem(i);
			b.setAttribute("onclick", '');
			b.addEventListener("click", createEventoMapa(b, i % 4, b.href), 0);
//			b.href = 'javascript:void(0)';
		}
	}

	/**
	 * Crea una nueva columna en las ofertas del mercado para mostrar la alianza de los
	 * vendedores
	 */
	function alianzaMercado(){
		var a = find("//tr[@class='rbg']", XPFirst).parentNode;

		// Prepara la insercion de la nueva columna
		var b = a.getElementsByTagName("TR");
		// FIXME: Apanyo para Firefox. FF mete nodos de tipo texto vacios
		b[0].childNodes[b[0].childNodes.length == 3 ? 1 : 0].setAttribute('colspan', '8');
		b[b.length - 1].childNodes[0].setAttribute("colspan", "8");

		// Crea e inserta la columna
		var columna = elem("TD");
		columna.innerHTML = T('ALIANZA');
		b[1].appendChild(columna);

		// Rellena la columna con los nombres de las alianzas

		for(var i = 2; i < b.length - 1; i++){
			var alianza = elem("TD");
			// FIXME: Apanyo para Firefox. FF mete nodos de tipo texto vacios
			var alianza_txt = b[i].childNodes[b[i].childNodes.length == 12 ? 8 : 4].getAttribute('title');
			if (alianza_txt != null) alianza.innerHTML = alianza_txt;
			b[i].appendChild(alianza);
		}
	}

	/**
	 * Crea una funcion que procesa el evento al seleccionar una cantidad de un recurso al enviar materias primas
	 * desde el mercado
	 *
	 * Params:
	 *	recurso:	Ordinal del recurso
	 *	cantidad:	Cantidad a incrementar del determinado recurso
	 *
	 * Returns:
	 *	La funcion que gestiona el evento
	 */
	function crearEventoRecursosMercado(recurso, cantidad){
		return function(){
//			var a = document.getElementsByTagName('input')[recurso + 1].value;
			var a = get('r' + (recurso + 1)).value;
			if (a == '') var suma = 0; else var suma = parseInt(a);
			suma += cantidad;
			// La cantidad a enviar no puede superar lo disponible
			if (suma > actual[recurso]) suma = actual[recurso];
			// La cantidad a enviar no debe poder superar la capacidad de los comerciantes disponibles
			var max_capacidad = parseInt(find("//p//b", XPFirst).innerHTML);
			var max_comercian = parseInt(find("//table[@class='f10']//tr//td[@colspan='2']", XPFirst).innerHTML.split(' ')[1].split('/')[0]);
			var max_transport = max_capacidad * max_comercian;
			if (suma > max_transport) suma = max_transport;

//			document.getElementsByTagName('input')[recurso + 1].value = suma;
			get('r' + (recurso + 1)).value = suma;
		}
	}

	/**
	 * Inserta nuevas cantidades seleccionables al enviar recursos desde el mercado
	 商人
	 */
	function recursosMercado(){
		if (find("//input[@type='text']", XPList).snapshotLength != 7) return;

		// Array con las nuevas cantidades
		var max_capacidad = parseInt(find("//p//b", XPFirst).innerHTML);
		/*
		var cantidades = [100, 250, 500, 1000];
		var repetido = false;
		for (var i = 0; i < cantidades.length; i++) if (max_capacidad == cantidades[i]){ repetido = true; break; }
		if (!repetido) cantidades = [100, 500, 1000, max_capacidad];
		*/
		if(max_capacidad ==null){max_capacidad=500;}

		var cpcty = readCookie('cpcty', 0);
		max_capacidad = cpcty <= 0 ? max_capacidad : cpcty;

		var cantidades =[max_capacidad,max_capacidad*2,max_capacidad*3,max_capacidad*4]

		var a = find("//table[@class='f10']", XPFirst);
		var k = 0;
		// FIXME: Apanyo para Firefox. FF mete nodos de tipo texto vacios
		a = a.childNodes[a.childNodes.length == 2 ? 1 : 0].childNodes;
		for (var i = 0; i < a.length; a.length == 8 ? i += 2 : i++){
			// Se eliminan las posibilidades originales
			// FIXME: Apanyo para Firefox. FF mete nodos de tipo texto vacios
			a[i].removeChild(a[i].childNodes[a[i].childNodes.length > 4 ? 5 : 3]);

			// Por cada nueva cantidad y recurso se crea un enlace con el evento asociado
			for(var j = 0; j < cantidades.length; j++){
				var enlace = elem('A');
				enlace.href = "javascript:void(0)";
				enlace.innerHTML = '(' + cantidades[j] + ')';
				enlace.addEventListener('click', crearEventoRecursosMercado(k, cantidades[j]), false);

				a[i].appendChild(enlace);
			}
			k++;
		}

		//add code by Arrack
		//var a = elem('DIV');
		//商人全部增加
		var a = find("//p[@class='txt_menue']", XPFirst);
		var b = elem('DIV');
		b.setAttribute("style","padding-top::5px;background-color: #FFFFCC;");
		//a.setAttribute("style","position:relative; top:999px;");
		//setAttribute("style","position:relative; bottom:52px;");
		b.innerHTML=T('ADD_ALL')+':';
		for(var j = 0; j < cantidades.length; j++){
			var enlace = elem('A');
			enlace.href = "javascript:void(0)";
			enlace.innerHTML = '(' + cantidades[j] + ')';
			enlace.addEventListener('click', crearEventoRecursosMercado_ALL(cantidades[j]), false);

			b.appendChild(enlace);
		}

		var enlace = elem('A');
		enlace.href = "javascript:void(0)";
		enlace.innerHTML = '(CLEAR)';
		enlace.addEventListener('click', crearEventoRecursosMercado_ALL(0), false);

		b.appendChild(enlace);
		a.appendChild(b);

		var form = document.getElementsByName('id')[0].parentNode;

		var inputCpcty = elem('input');
			inputCpcty.value = cpcty;
			inputCpcty.className = 'fm';
			inputCpcty.size = 4;
			inputCpcty.addEventListener('change', function(){
				createCookie('cpcty', this.value);
				cpcty = this.value;

				document.location.reload();
			}, false);

			var setCpctyBar = elem('span');
			setCpctyBar.appendChild(document.createTextNode(T('CPCTY1')));
			setCpctyBar.appendChild(inputCpcty);
			form.parentNode.insertBefore(setCpctyBar, form);
	}
	//function crearEventoRecursosMercado(recurso, cantidad){
	function crearEventoRecursosMercado_ALL(cantidad){
		return function(){
			var recurso=0;

			var max_capacidad = parseInt(find("//p//b", XPFirst).innerHTML);
			var max_comercian = parseInt(find("//table[@class='f10']//tr//td[@colspan='2']", XPFirst).innerHTML.split(' ')[1].split('/')[0]);
			var max_transport = max_capacidad * max_comercian;

			for(var j = 0; j < 4; j++){
				recurso=j;

//				var a = document.getElementsByTagName('input')[recurso + 1].value;
				var a = get('r' + (recurso + 1)).value;

				if (a == '') var suma = 0; else var suma = parseInt(a);
				if(cantidad!=0){
					suma += cantidad;
				}else{
					suma=0;
				}
				// La cantidad a enviar no puede superar lo disponible
				if (suma > actual[recurso]) suma = actual[recurso];
				// La cantidad a enviar no debe poder superar la capacidad de los comerciantes disponibles

				if (suma > max_transport) suma = max_transport;

//				document.getElementsByTagName('input')[recurso + 1].value = suma;
				get('r' + (recurso + 1)).value = suma;
			}
		}
	}

	/*
	 * Check if this is a 3X speed server
	 * TeYoU: 檢查是否為SPEED伺服器
	 */
	 function check3X(){
		var url = location.href;
		if(url.match("speed"))
			return true;
		return false;
	 }

	/**
	 * Calcula el numero de aldeas que se posee en funcion de los puntos de cultura disponibles.
	 * Funcion estandard no valida para version Speed
	 *
	 * Params:
	 *	puntos: cantidad de puntos de cultura
	 *
	 * Returns:
	 * 	el numero de aldeas que se dispone con esos puntos
	 */
	 //TeYoU: 計算文明點的 (Point)
	function pc2aldeas(puntos){ return Math.round(Math.pow((puntos / 1000) / 1.6, 1 / 2.3)); }
	function pc2aldeas3X(puntos){ return Math.round(Math.pow((puntos / 100) / 16 * 3, 1 / 2.3)); }

	/**
	 * Calcula el numero de puntos necesarios para obtener un determinada cantidad de aldeas
	 * Funcion estandard no valida para version Speed
	 *
	 * Params:
	 *	aldeas: numero de aldeas
	 *
	 * Returns:
	 * 	cantidad de puntos de cultura necesarios
	 */
	 //TeYoU: 計算文明點的 (Village)
	function aldeas2pc(aldeas){ return Math.round(1.6 * Math.pow(aldeas, 2.3)) * 1000; }
	function aldeas2pc3X(aldeas){ return Math.round(16 / 3 * Math.pow(aldeas, 2.3)) * 100; }

	/**
	 * puntosCultura = CulturePoints
	 * Calcula y muestra los puntos de cultura necesarios para la siguiente aldea y el tiempo para conseguirlo, o
	 * las aldeas adicionales que se pueden fundar con los puntos actuales
	 */
	function puntosCultura(){
		var a = find("//div[@id='lmid2']//b", XPList);
		if (a.snapshotLength != 5) return;

		// Produccion de puntos de cultura de todas las aldeas
		var pc_prod_total = parseInt(a.snapshotItem(2).innerHTML);
		// Cantidad de puntos de cultura actuales
		var pc_actual = parseInt(a.snapshotItem(3).innerHTML);
		// Puntos de cultura necesarios para fundar la siguiente aldea
		var pc_aldea_prox = parseInt(a.snapshotItem(4).innerHTML);

		// 下一個的村莊數
		var aldeas_actuales = (check3X() )? pc2aldeas3X(pc_aldea_prox) : pc2aldeas(pc_aldea_prox) ;
		// 目前村莊數
		var aldeas_posibles = (check3X() )? pc2aldeas3X(pc_actual) : pc2aldeas(pc_actual) ;

		var texto = '<table class="tbg" align="center" cellspacing="1" cellpadding="2"><tr class="rbg"><td>' + T('ALDEA') + '</td><td>' + T('PC') + "</td></tr>";
		var j = pc_f = 0;
		for (var i = 0; i < 3; i++){
			var idx = i + j;

			texto += '<tr><td>' + (aldeas_actuales + idx + 1) + '</td><td>';

			// 下一級需要的文明
			var pc_necesarios = (check3X() )? aldeas2pc3X(aldeas_actuales + idx) : aldeas2pc(aldeas_actuales + idx) ;

			// Si hay PC de sobra
			if (pc_necesarios < pc_actual) {
				texto += T('FUNDAR');
				pc_f = 1;
			}
			else{
				// Tiempo en segundos hasta conseguir los puntos de cultura necesarios
				var tiempo = ((pc_necesarios - pc_actual) / pc_prod_total) * 86400;

				var fecha = new Date();
//				fecha.setTime(fecha.getTime() + (tiempo * 1000));
				fecha.setTime(timestamp.getTime() + (tiempo * 1000));
				var texto_tiempo = calcularTextoTiempo(fecha);

				texto += T('FALTA') + ' <b>' + (pc_necesarios - pc_actual) + '</b> ' + T('PC') +'<br/>';
				texto += T('LISTO') + " " + texto_tiempo;
			}
			texto += '</td></tr>';

			if (pc_f && pc_necesarios >= pc_actual) {
				j = idx + 1;
				pc_f = i = 0;
			}
		}
		texto += '</table>';

		a.snapshotItem(4).parentNode.innerHTML += "<p>" + texto + "</p>";
	}

	/**


	 * Oculta un elemento y le asgina un atributo de tipo filtro
	 *
	 * Params:
	 *	oferta: elemento a modificar
	 *	filtro: nombre del filtro que se le aplicara como atributo
	 */