var undefined; // undefined

/* DOM */
/*@cc_on @*/

var DOM={
	doc:document,

	get:function (sId) {
		return this.doc.getElementById(sId);
	},

	create:function (sTag) {
/*@if (@_jscript_version<5.5)
	oEl=this.doc.createElement(sTag);
@else @*/
		if (Browser.moz && sTag.indexOf("<")!=-1 && /<(\w*?)( |>)/.test(sTag)) {
			oEl=this.doc.createElement(RegExp.$1);
			var rxAttr=/ ([\w-\.]*?)=("|')(.*?)("|')/g;

			while (aMatch=rxAttr.exec(sTag)) oEl.setAttribute(aMatch[1],aMatch[3]);
		}
		else oEl=this.doc.createElement(sTag);
/*@end @*/

		return oEl;
	},

	event:function (sEvent,fFunction,oEl) {
		(oEl || window).attachEvent("on"+sEvent,fFunction);
	},

	pos:{
		x:function (oEl) {
			if (Browser.ie) iX=oEl.getClientRects()[0].left-2+DOM.doc.body.scrollLeft;
			else for (var iX=0;oEl;iX+=oEl.offsetLeft,oEl=oEl.offsetParent);

			return iX;
		},

		y:function (oEl) {
			if (Browser.ie) iY=oEl.getClientRects()[0].top-2+DOM.doc.body.scrollTop;
			else for (var iY=0;oEl;iY+=oEl.offsetTop,oEl=oEl.offsetParent);
			return iY;
		}
	},

	find:function (oEl,sTag,sProp,sEq) {
		sTag=sTag.toLowerCase();

		while (
			oEl &&
			oEl!=this.doc.documentElement &&
			(
				(
					!sProp &&
					oEl.tagName.toLowerCase()!=sTag
				) ||
				(
					sProp &&
					(
						oEl.tagName.toLowerCase()!=sTag ||
						oEl[sProp]!=sEq
					)
				)
			)
		) oEl=oEl.parentNode;

		return oEl.tagName.toLowerCase()==sTag ? oEl : null;
	},

	classes:{
		add:function (oEl,sClass) {
			if (oEl) return !this.contains(oEl,sClass) ? oEl.className+=" "+sClass : oEl.className;
		},

		remove:function (oEl,sClass) {
			if (oEl) return oEl.className=oEl.className.replace(new RegExp("(\\b|\\s)"+sClass.toRX()+"(\\b|\\s)"),"");
		},
		
		contains:function (oEl,sClass) {
			if (oEl) return new RegExp("\\b"+sClass.toRX()+"\\b").test(oEl.className);
		},

		current:function (oEl,sProp) {
			if (document.defaultView && document.defaultView.getComputedStyle) return document.defaultView.getComputedStyle(oEl,"").getPropertyValue(sProp);
			if (oEl.currentStyle) return oEl.currentStyle[sProp];
			return null;
		},

		toggle:function (oEl,sClass) {
			sClass=sClass || "hidden";
			DOM.classes[DOM.classes.contains(oEl,sClass) ? "remove" : "add"](oEl,sClass);
		}
	}
}

/* Browser */

var sAgent=navigator.userAgent.toLowerCase(),
	aVersion=sAgent.match(/msie ([^;]+);/);

var Browser={
	agent:sAgent,
	ie:sAgent.indexOf("msie")!=-1,
	moz:sAgent.indexOf("gecko")!=-1,
	other:sAgent.search(/(msie|mozilla)/i)==-1,

	version:aVersion && aVersion.length ? +aVersion[1] : null,
	
	xmlprefix:function () {
		if (Browser.xmlprefix.prefix) return Browser.xmlprefix.prefix;

		var aPrefixes=["MSXML2","Microsoft","MSXML","MSXML3"],
			oXML, oXH;

		for (var iPrefix=0;iPrefix<aPrefixes.length;iPrefix++) {
			try {
				oXML=new ActiveXObject(aPrefixes[iPrefix]+".XMLDOM");
				oXH=new ActiveXObject(aPrefixes[iPrefix]+".XMLHTTP");
				return Browser.xmlprefix.prefix=aPrefixes[iPrefix];
			}
			catch (oErr) {};
		}

		return null;
	},

	xmldom:function () {
		try {
			if (document.implementation && document.implementation.createDocument) {
				var oXML=document.implementation.createDocument("","",null);

				if (oXML.readyState==null) {
					oXML.readyState=1;
					oXML.addEventListener(
						"load",
						function () {
							oXML.readyState=4;
							if (typeof oXML.onreadystatechange=="function") oXML.onreadystatechange();
						},
						false
					);
				}

				return oXML;
			}

			if (window.ActiveXObject) return new ActiveXObject(this.xmlprefix()+".XMLDOM");
		}
		catch (oErr) {}

		return null;
	},

	xmlhttp:function () {
		try {
			if (window.XMLHttpRequest) {
				var oXH=new XMLHttpRequest();

				if (oXH.readyState==null) {
					oXH.readyState=1;
		            oXH.addEventListener(
						"load",
						function () {
							oXH.readyState=4;
							if (typeof oXH.onreadystatechange=="function") oXH.onreadystatechange();
						},
						false
					);
				}

				return oXH;
			}

			if (window.ActiveXObject) return new ActiveXObject(this.xmlprefix()+".XMLHTTP");
		}
		catch (oErr) {}

		return null;
	}
}

/* Moz Implementation by webfx.eae.net */

if (Browser.moz) {
	Window.prototype.attachEvent=Document.prototype.attachEvent=HTMLElement.prototype.attachEvent=function (sType,fHandler) {
		this.addEventListener(
			sType.replace(/on/,""),
			function (oEvent) {
				window.event=oEvent;
				return fHandler(oEvent);
			},
			false
		);
	}

	Event.prototype.__defineGetter__(
		"srcElement",
		function () {
			var oNode=this.target;
			if (oNode==null) return null;
			while (oNode.nodeType!=1) oNode=oNode.parentNode;
			return oNode;
		}
	);

	Event.prototype.__defineGetter__(
		"fromElement",
		function () {
			var oNode;

			if (this.type=="mouseover") oNode=this.relatedTarget;
			else if (this.type=="mouseout") oNode=this.target;
			else return null;

			oNode=this.target;
			while (oNode.nodeType!=1) oNode=oNode.parentNode;
			return oNode;
		}
	);

	Event.prototype.__defineGetter__(
		"toElement",
		function () {
			var oNode;

			if (this.type=="mouseout") oNode=this.relatedTarget;
			else if (this.type=="mouseover") oNode=this.target;
			else return null;

			oNode=this.target;
			while (oNode.nodeType!=1) oNode=oNode.parentNode;
			return oNode;
		}
	);

	// dom

	Document.prototype.createStyleSheet=function (sURL) {
		var oXH=Browser.xmlhttp();
		oXH.open("GET",sURL,true);

		oXH.onreadystatechange=function () {
			 if (oXH.readyState==4) {
				oStyle=DOM.create("link");
				oStyle.rel="stylesheet";
				oStyle.href="data:text/css,"+escape(oXH.responseText);
				DOM.doc.getElementsByTagName("head")[0].appendChild(oStyle);
			 }
		}

		oXH.send(null);
	}

	Object.prototype.removeNode=Node.prototype.removeNode=function (bRemoveChildren) {
		if (Boolean(bRemoveChildren)) return this.parentNode.removeChild(this);
		else {
			var oRange=document.createRange();
			oRange.selectNodeContents(this);
			return this.parentNode.replaceChild(oRange.extractContents(),this);
		}
	}

	HTMLElement.prototype.__defineGetter__(
		"innerText",
		function () {
			var oRange=this.ownerDocument.createRange();
			oRange.selectNodeContents(this);
			return oRange.toString();
		}
	);

	HTMLElement.prototype.__defineSetter__(
		"innerText",
		function (sText) {
			this.innerHTML=(""+sText).replace(/\&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
		}
	);

	HTMLElement.prototype.__defineGetter__(
		"outerHTML",
		function () {
			var sHTML="<"+this.nodeName;

			for (var iAtt=0;iAtt<this.attributes.length;iAtt++) {
				if (this.attributes.item(iAtt).nodeValue!=null) {
					sHTML+=" "+this.attributes.item(iAtt).nodeName+"=\""+this.attributes.item(iAtt).nodeValue+"\"";
				}
			}
/*@if (!@_jscript_version<5.5) @else @*/
			sHTML+=this.childNodes.length==0 && !this.nodeName.toLowerCase() in { "img":0,"input":0,"br":0,"col":0,"hr":0 } ? ">" : ">"+this.innerHTML+"</"+this.nodeName+">";
/*@end @*/
			return sHTML;
		}
	);

	HTMLElement.prototype.contains=function (oEl) {
	   if (oEl==this) return true;
	   if (oEl==null) return false;
	   return this.contains(oEl.parentNode);		
	};

	HTMLElement.prototype.__defineSetter__(
		"unselectable",
		function (sVal) {
			this.style.MozUserSelect=sVal=="on" ? "none" : "text";
		}
	);

	// xml

	Array.prototype.item=function (iItem) {
		return this[iItem];
	}

	Document.prototype.loadXML=function (sXML) {
	   var oXMLParser=new DOMParser().parseFromString(sXML,"text/xml");
		  
	   while (this.hasChildNodes()) this.removeChild(this.lastChild);

	   for (var iNode=0; iNode<oXMLParser.childNodes.length;iNode++) this.appendChild(this.importNode(oXMLParser.childNodes[iNode],true));
	}

	Document.prototype.__defineGetter__(
		"xml",
		function () {
			return new XMLSerializer().serializeToString(this);
		}
	);

	Document.prototype.transformNodeToObject=function (oXSL,oResult) {
		var oXSLProcessor=new XSLTProcessor();

		try {
			oXSLProcessor.transformDocument(this,oXSL,oResult,null);
		}
		catch (oErr) { alert("Error: transformNodeToObject\n"+oErr); }
	}

	Document.prototype.transformNode=function (oXSL) {
		var oDoc=document.implementation.createDocument("","",null);

		this.transformNodeToObject(oXSL,oDoc);
		var oSerializer=new XMLSerializer();
	
		try {
			return oSerializer.serializeToString(oDoc);
		}
		catch (oErr) { alert("Error: transformNode"); }
	}

	XMLDocument.prototype.__defineGetter__(
		"xml",
		function () {
			return new XMLSerializer().serializeToString(this);
		}
	);

    Node.prototype.__defineGetter__(
		"xml",
		function () {
			return new XMLSerializer().serializeToString(this);
		}
	);

	Array.prototype.expr="";

	XMLDocument.prototype.setProperty=function (x,y) {
	}

	XMLDocument.prototype.selectNodes=function (sExpr,oContextNode) {
		var oResult=this.evaluate(sExpr,oContextNode ? oContextNode : this,this.createNSResolver(this.documentElement),XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null),
			oNodes=new Array(oResult.snapshotLength);

		oNodes.expr=sExpr;

		for (var iNode=0;iNode<oNodes.length;iNode++) oNodes[iNode]=oResult.snapshotItem(iNode);

		return oNodes;
	}

	Element.prototype.selectNodes=function (sExpr) {
		var oDoc=this.ownerDocument;
		if (oDoc.selectNodes) return oDoc.selectNodes(sExpr, this);
		else throw "Method selectNodes is only supported by XML Nodes";
	}

	XMLDocument.prototype.selectSingleNode=function (sExpr,oContextNode) {
		var oContextNode=oContextNode || null;

		sExpr+="[1]";

		var oNodes=this.selectNodes(sExpr,oContextNode);
		
		return oNodes.length>0 ? oNodes[0] : null;
	}

	Element.prototype.selectSingleNode=function (sExpr) {
		var oDoc=this.ownerDocument;
		if(oDoc.selectSingleNode) return oDoc.selectSingleNode(sExpr, this);
		else throw "Method selectSingleNode is only supported by XML Nodes. (original exception: "+e+")";
	}
}

// creating links from spans

DOM.event(
	"load",
	function () {
		DOM.event(
			"mouseover",
			function (oEvent) {
				var oSrc=oEvent.srcElement;

				if (oSrc && oSrc.tagName.toLowerCase()=="span" && oSrc.getAttribute("link")!=null) {
					DOM.classes.add(oSrc,"hand");
					DOM.classes.add(oSrc,"ah");
				}
			},
			DOM.doc
		);
		DOM.event(
			"mouseout",
			function (oEvent) {
				var oSrc=oEvent.srcElement;

				if (oSrc && oSrc.tagName.toLowerCase()=="span" && oSrc.getAttribute("link")!=null) DOM.classes.remove(oSrc,"ah");
			},
			DOM.doc
		);

		var aSpans=DOM.doc.getElementsByTagName("span"),
			oSpan;

		for (var iSpan=0;iSpan<aSpans.length;iSpan++) {
			oSpan=aSpans[iSpan];
			if (oSpan.getAttribute("link")!=null) {
				DOM.classes.add(oSpan,"hand");
				DOM.classes.add(oSpan,"a");
			}
		}
	}
);