var javascriptFiles = null;

function fixRoot(file) {
    if(file.indexOf('/') == 0) {
        if(location.host.indexOf('localhost:') == 0) {
            return '/ZorapDotCom' + file;
        }
    }
    // for local debugging
    if(location.href.indexOf('file://') == 0) {
        var i = location.href.toLowerCase().indexOf('zorapdotcom');
        if(i > 0) {
            file = location.href.substring(0, i + 11) + file;

        }
    }
    return file;
}

// include a js file
function includeJavascriptFile(javascriptFile) {
    javascriptFile = fixRoot(javascriptFile);
    if(javascriptFiles == null) {
        javascriptFiles = new Object();
    }
    if(javascriptFiles[javascriptFile] != null) {
        return;
    }
    javascriptFiles[javascriptFile] = new Object();
    javascriptFiles[javascriptFile].file = javascriptFile;
    
    var scriptElement = document.createElement('script');
    scriptElement.type = 'text/javascript';
    scriptElement.src = javascriptFile + '?' + Math.floor(Math.random()*1000000000);
    scriptElement.defer = false;
    document.getElementsByTagName('head')[0].appendChild(scriptElement);  
}

String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/,"");
}

function replaceAll(source, replaceThis, withThis) {
	var s = source;
	while(s.indexOf(replaceThis) >= 0) {
		s = s.replace(replaceThis, withThis);
	}
	return s;
}

function jsonEncode(s)
{
	s = s.replace(/\\/g, '\\\\');
	s = s.replace(/\"/g, '\\"');
	s = s.replace(/\//g, '\/');
	return s;
}

function jsonReplace(s, what, withWhat)
{
	return s.replace(what, jsonEncode(withWhat));
}

function isKey(e, num)
{
    e = e || window.event;

    var keynum;
    if(window.event) { // IE
        keynum = e.keyCode
    }
    else if(e.which) { // Netscape/Firefox/Opera
        keynum = e.which
    }
    if(keynum == num) {
        return true;
    }
    return false;
}

function isEnterKey(e)
{
	return isKey(e, 13);
}

function isEscKey(e)
{
	return isKey(e, 27);
}

function addEventSimple(obj,evt,fn) {
	if (obj.addEventListener)
		obj.addEventListener(evt,fn,false);
	else if (obj.attachEvent)
		obj.attachEvent('on'+evt,fn);
}

function removeEventSimple(obj,evt,fn) {
	if (obj.removeEventListener)
		obj.removeEventListener(evt,fn,false);
	else if (obj.detachEvent)
		obj.detachEvent('on'+evt,fn);
}

function getEvent(e) {
	var evt = e || window.event;
	return evt;
}

function eventGetTarget(e) {
	var evt = getEvent(e);
	var target = evt.target || evt.srcElement;
	return target;
}

function eventTargetIsElementOrChild(element, evt)
{
	var target = eventGetTarget(evt);
	
	while(true)
	{
		if(target == element)
		{
			return true;
		}
		target = target.parentNode;
		if(!target) break;
	}
	return false;
}

function eventIsRightClick(e) {
	var evt = getEvent(e);
	if(evt.which) {
		return (evt.which == 3);
	}
	else if(evt.button) {
		return (evt.button == 2);
	}
	return false;
}

function eventGetAbsX(e) {
    var evt = getEvent(e);
	var x;
	if (document.all) // IE
		x = evt.clientX + document.body.scrollLeft;
	else // not IE
		x = evt.pageX;
	return x;
}

function getWindowScrollX()
{
	var ScrollLeft = document.body.scrollLeft;
	if (ScrollLeft == 0)
	{
		if (window.pageXOffset)
			ScrollLeft = window.pageXOffset;
		else
			ScrollLeft = (document.body.parentElement) ? document.body.parentElement.scrollLeft : 0;

	}
	return ScrollLeft;
}

function getWindowScrollY()
{
	var ScrollTop = document.body.scrollTop;
	if (ScrollTop == 0)
	{
		if (window.pageYOffset)
			ScrollTop = window.pageYOffset;
		else
			ScrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;

	}
	return ScrollTop;
}
function eventGetAbsY(e) {
    var evt = getEvent(e);
	var y;
	if (document.all) // IE
		y = evt.clientY + document.body.scrollTop;
	else // not IE
		y = evt.pageY;
	return y;
}

function elementGetAbsX(element) {
	var off = 0;
	if(element.offsetLeft) {
		off += element.offsetLeft;
	}
	if(element.parentNode) {
		off += elementGetAbsX(element.parentNode);
	}	
	return off;
}

function elementGetAbsY(element) {
	var off = 0;
	if(element.offsetTop) {
		off += element.offsetTop;
	}
	if(element.parentNode) {
		off += elementGetAbsY(element.parentNode);
	}	
	return off;
}

function eventGetRelX(e) {
    var evt = getEvent(e);
	var x;
	if (document.all) // IE
		x = evt.offsetX;
	else // not IE
	{
		var target = eventGetTarget(e);
		x = eventGetAbsX(e) - elementGetAbsX(target);
	}
	return x;
}

function eventGetRelY(e) {
    var evt = getEvent(e);
	var y;
	if (document.all) // IE
		y = evt.offsetY;
	else // not IE
	{
		var target = eventGetTarget(e);
		y = eventGetAbsY(e) - elementGetAbsY(target);
	}
	return y;
}

function setElementText(e, v)
{
	e.innerHTML = '';
	e.appendChild(document.createTextNode(v));
}

// get color
function getColor(element)
{
    // ie
    if(element.currentStyle)
    {
        return element.currentStyle.color;
    }
    // mozilla
    if(document.defaultView)
    {
        return document.defaultView.getComputedStyle(element, '').getPropertyValue('color');
    }
    return '#ffffff';
}

function isThisIE6() {
	var isIt = false;
	try {
		if(isIE6) {
			isIt = true;
		}
	}
	catch(e) {;}
	return isIt;
}

var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return ;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{
			string: navigator.userAgent,
			subString: "Chrome",
			identity: "Chrome"
		},
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "MacIntel",
			identity: "MacIntel"
		},
		{
			string: navigator.platform,
			subString: "MacPPC",
			identity: "MacPowerPC"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();

var isIE = _isIE();
function _isIE() {
   try {
        if(!window.ActiveXObject) {
            throw 'not IE';
        }
        else {
			return true;
        }
	}
	catch (e) {
	}
	return false;
}

function isWindows()
{
    return BrowserDetect.OS == "Windows";
}

function is64BitIE8()
{
	if(isWindows() && isIE && BrowserDetect.version == 8)
	{
		if(navigator.userAgent.toLowerCase().indexOf('win64') > 0 &&
			navigator.userAgent.toLowerCase().indexOf('x64') > 0)
		{
			return true;
		}
	}
	return false;
}

function isMac() {
    return BrowserDetect.OS == "MacIntel";
}

function isMacPowerPC() {
    return BrowserDetect.OS == "MacPowerPC";
}

function isLinux() {
    return BrowserDetect.OS == "Linux";
}

function isFirefox()
{
	return BrowserDetect.browser == 'Firefox';
}

function isChrome()
{
	return BrowserDetect.browser == 'Chrome';
}

// function to parse up query string    
function qs(qsParm)
{
    var query = window.location.search.substring(1);
    var params = query.split('#');
    if(params.length > 0) {
		var parms = params[0];
		parms = parms.split('&');
		for(var i = 0; i < parms.length; i++) {
			var pos = parms[i].indexOf('=');
			if (pos > 0) {
				var key = parms[i].substring(0 , pos);
				var val = parms[i].substring(pos + 1);
				qsParm[key.toLowerCase()] = val;
			}
		}
	}
}

function createCookie(name,value,seconds) {
	if (seconds) {
		var date = new Date();
		date.setTime(date.getTime()+(seconds*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	
	document.cookie = name+"="+value+expires+"; path=/";
/*  var i = location.href.indexOf("zorap.com");
    if(i > 0) {
		// save for entire domain
    	document.cookie = name+"="+value+expires+"; path=/; domain=.zorap.com";
    }*/
}

function readCookie2(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function readCookie(name, defaultValue)
{
	var v = readCookie2(name);
	if(v == null)
	{
	    v = "";
	    if(defaultValue)
	    {
			v = defaultValue;
	    }
	}
	return v;
}

function readCookie_int(name, defaultValue)
{
	var v = readCookie(name);
	if(v)
	{
		try
		{
			v = parseInt(v, 10);
			if(typeof(v) == 'number')
			{
				return v;
			}
		}
		catch(e) {}
	}
	return defaultValue;
}

function readCookie_bool(name, defaultValue, mode)
{
	if(!mode)
	{
		mode = bool_onezero;
	}
	var v = eval("(" + mode + ")");
	
	var c = readCookie(name);
	
	if(c == v.t) return true;
	if(c == v.f) return false;
	if(typeof(defaultValue) == 'boolean')
	{
		return defaultValue;
	}
	return false;
}

function readCookieUnicode(name, defaultValue)
{
	var v = readCookie(name, defaultValue);
	return decodeURIComponent(v);
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

function saveSetting(Name, Value) {
    createCookie(Name, Value, 10*365*24*60*60);
}

var bool_truefalse = '{ "t":"true","f":"false" }';
var bool_onezero = '{ "t":"1","f":"0" }';
var bool_onoff = '{ "t":"on","f":"off" }';
var bool_outin = '{ "t":"out","f":"in" }';
function saveSetting_bool(Name, Value, mode)
{
	if(!mode)
	{
		mode = bool_onezero;
	}
	var v = eval("(" + mode + ")");
	saveSetting(Name, Value ? v.t : v.f);
}

function saveSettingUnicode(Name, Value) {
    createCookie(Name, encodeURIComponent(Value), 10*365*24*60*60);
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

function queryString(suppressRandom)
{
	this.qs = '';
	if(suppressRandom !== true)
	{
		'n=' + Math.floor(Math.random()*1000000);
	}
	this.addParam = function(name, value) {
		if(this.qs) this.qs += '&';
		this.qs += name;
		this.qs += '=';
		this.qs += encodeURIComponent(value);
	}
	this.addParam_bool = function(name, value)
	{
		this.addParam(name, value ? 'true' : 'false');
	}
	this.getQS = function()
	{
		return '?' + this.qs;
	}
}

function callServer(url, callback)
{
	var oXMLHttpRequest	= new XMLHttpRequest;
	try
	{
		oXMLHttpRequest.open("GET", url, true);
	}
	catch (e)
	{
		callback(404, null);//whatever
	}
	oXMLHttpRequest.onreadystatechange = function()
	{
		if (this.readyState == XMLHttpRequest.DONE)
		{
			callback(oXMLHttpRequest.status, oXMLHttpRequest.responseXML, oXMLHttpRequest.responseText);
		}
	}
	oXMLHttpRequest.send(null);
}

var n = Math.floor(Math.random()*1000000000);
function callJSONServer(server, whichFunction, params, callback)
{
	var proxyParams = 'serverip=' + server;
	proxyParams += '&function=' + whichFunction;
	proxyParams += '&n=' + n;
	n += 1;
	var fullParams = proxyParams;
	
	if(params.length > 0) {
		fullParams += '&';
		fullParams += params;
	}
	
	var url = 'proxyjson.aspx?' + fullParams;
//	var url = 'http://localhost:50320/Web/proxy.aspx?' + fullParams;
	var oXMLHttpRequest	= new XMLHttpRequest;
	try {
		oXMLHttpRequest.open("GET", url, true);
	}
	catch (e) {
		callback(404, null);//whatever
	}
	oXMLHttpRequest.onreadystatechange = function() {
		if (this.readyState == XMLHttpRequest.DONE) {
			callback(oXMLHttpRequest.status, oXMLHttpRequest.responseXML, oXMLHttpRequest.responseText);
		}
	}
	oXMLHttpRequest.send(null);
}

(function () {

	// Save reference to earlier defined object implementation (if any)
	var oXMLHttpRequest	= window.XMLHttpRequest;

	// Define on browser type
	var bGecko	= !!window.controllers,
		bIE		= window.document.all && !window.opera;

	// Constructor
	function cXMLHttpRequest() {
		this._object	= oXMLHttpRequest ? new oXMLHttpRequest : new window.ActiveXObject("Microsoft.XMLHTTP");
		this._listeners	= [];
	};

	// BUGFIX: Firefox with Firebug installed would break pages if not executed
	if (bGecko && oXMLHttpRequest.wrapped)
		cXMLHttpRequest.wrapped	= oXMLHttpRequest.wrapped;

	// Constants
	cXMLHttpRequest.UNSENT				= 0;
	cXMLHttpRequest.OPENED				= 1;
	cXMLHttpRequest.HEADERS_RECEIVED	= 2;
	cXMLHttpRequest.LOADING				= 3;
	cXMLHttpRequest.DONE				= 4;

	// Public Properties
	cXMLHttpRequest.prototype.readyState	= cXMLHttpRequest.UNSENT;
	cXMLHttpRequest.prototype.responseText	= "";
	cXMLHttpRequest.prototype.responseXML	= null;
	cXMLHttpRequest.prototype.status		= 0;
	cXMLHttpRequest.prototype.statusText	= "";

	// Instance-level Events Handlers
	cXMLHttpRequest.prototype.onreadystatechange	= null;

	// Class-level Events Handlers
	cXMLHttpRequest.onreadystatechange	= null;
	cXMLHttpRequest.onopen				= null;
	cXMLHttpRequest.onsend				= null;
	cXMLHttpRequest.onabort				= null;

	// Public Methods
	cXMLHttpRequest.prototype.open	= function(sMethod, sUrl, bAsync, sUser, sPassword) {

		// When bAsync parameter value is ommited, use true as default
		if (arguments.length < 3)
			bAsync	= true;

		// Save async parameter for fixing Gecko bug with missing readystatechange in synchronous requests
		this._async		= bAsync;

		// Set the onreadystatechange handler
		var oRequest	= this,
			nState		= this.readyState;

		// BUGFIX: IE - memory leak on page unload (inter-page leak)
		if (bIE) {
			var fOnUnload	= function() {
				if (oRequest._object.readyState != cXMLHttpRequest.DONE) {
					fCleanTransport(oRequest);
					// Safe to abort here since onreadystatechange handler removed
					oRequest.abort();
				}
			};
			if (bAsync)
				window.attachEvent("onunload", fOnUnload);
		}

		this._object.onreadystatechange	= function() {
			if (bGecko && !bAsync)
				return;

			// Synchronize state
			oRequest.readyState		= oRequest._object.readyState;

			//
			fSynchronizeValues(oRequest);

			// BUGFIX: Firefox fires unneccesary DONE when aborting
			if (oRequest._aborted) {
				// Reset readyState to UNSENT
				oRequest.readyState	= cXMLHttpRequest.UNSENT;

				// Return now
				return;
			}

			if (oRequest.readyState == cXMLHttpRequest.DONE) {
				//
				fCleanTransport(oRequest);
// Uncomment this block if you need a fix for IE cache
/*
				// BUGFIX: IE - cache issue
				if (!oRequest._object.getResponseHeader("Date")) {
					// Save object to cache
					oRequest._cached	= oRequest._object;

					// Instantiate a new transport object
					cXMLHttpRequest.call(oRequest);

					// Re-send request
					oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);
					oRequest._object.setRequestHeader("If-Modified-Since", oRequest._cached.getResponseHeader("Last-Modified") || new window.Date(0));
					// Copy headers set
					if (oRequest._headers)
						for (var sHeader in oRequest._headers)
							if (typeof oRequest._headers[sHeader] == "string")	// Some frameworks prototype objects with functions
								oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);

					oRequest._object.onreadystatechange	= function() {
						// Synchronize state
						oRequest.readyState		= oRequest._object.readyState;

						if (oRequest._aborted) {
							//
							oRequest.readyState	= cXMLHttpRequest.UNSENT;

							// Return
							return;
						}

						if (oRequest.readyState == cXMLHttpRequest.DONE) {
							// Clean Object
							fCleanTransport(oRequest);

							// get cached request
							if (oRequest.status == 304)
								oRequest._object	= oRequest._cached;

							//
							delete oRequest._cached;

							//
							fSynchronizeValues(oRequest);

							//
							fReadyStateChange(oRequest);

							// BUGFIX: IE - memory leak in interrupted
							if (bIE && bAsync)
								window.detachEvent("onunload", fOnUnload);
						}
					};
					oRequest._object.send(null);

					// Return now - wait untill re-sent request is finished
					return;
				};
*/
				// BUGFIX: IE - memory leak in interrupted
				if (bIE && bAsync)
					window.detachEvent("onunload", fOnUnload);
			}

			// BUGFIX: Some browsers (Internet Explorer, Gecko) fire OPEN readystate twice
			if (nState != oRequest.readyState)
				fReadyStateChange(oRequest);

			nState	= oRequest.readyState;
		};

		// Add method sniffer
		if (cXMLHttpRequest.onopen)
			cXMLHttpRequest.onopen.apply(this, arguments);

		this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);

		// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
		if (!bAsync && bGecko) {
			this.readyState	= cXMLHttpRequest.OPENED;

			fReadyStateChange(this);
		}
	};
	cXMLHttpRequest.prototype.send	= function(vData) {
		// Add method sniffer
		if (cXMLHttpRequest.onsend)
			cXMLHttpRequest.onsend.apply(this, arguments);

		// BUGFIX: Safari - fails sending documents created/modified dynamically, so an explicit serialization required
		// BUGFIX: IE - rewrites any custom mime-type to "text/xml" in case an XMLNode is sent
		// BUGFIX: Gecko - fails sending Element (this is up to the implementation either to standard)
		if (vData && vData.nodeType) {
			vData	= window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
			if (!this._headers["Content-Type"])
				this._object.setRequestHeader("Content-Type", "application/xml");
		}

		this._object.send(vData);

		// BUGFIX: Gecko - missing readystatechange calls in synchronous requests
		if (bGecko && !this._async) {
			this.readyState	= cXMLHttpRequest.OPENED;

			// Synchronize state
			fSynchronizeValues(this);

			// Simulate missing states
			while (this.readyState < cXMLHttpRequest.DONE) {
				this.readyState++;
				fReadyStateChange(this);
				// Check if we are aborted
				if (this._aborted)
					return;
			}
		}
	};
	cXMLHttpRequest.prototype.abort	= function() {
		// Add method sniffer
		if (cXMLHttpRequest.onabort)
			cXMLHttpRequest.onabort.apply(this, arguments);

		// BUGFIX: Gecko - unneccesary DONE when aborting
		if (this.readyState > cXMLHttpRequest.UNSENT)
			this._aborted	= true;

		this._object.abort();

		// BUGFIX: IE - memory leak
		fCleanTransport(this);
	};
	cXMLHttpRequest.prototype.getAllResponseHeaders	= function() {
		return this._object.getAllResponseHeaders();
	};
	cXMLHttpRequest.prototype.getResponseHeader	= function(sName) {
		return this._object.getResponseHeader(sName);
	};
	cXMLHttpRequest.prototype.setRequestHeader	= function(sName, sValue) {
		// BUGFIX: IE - cache issue
		if (!this._headers)
			this._headers	= {};
		this._headers[sName]	= sValue;

		return this._object.setRequestHeader(sName, sValue);
	};

	// EventTarget interface implementation
	cXMLHttpRequest.prototype.addEventListener	= function(sName, fHandler, bUseCapture) {
		for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
			if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
				return;
		// Add listener
		this._listeners.push([sName, fHandler, bUseCapture]);
	};

	cXMLHttpRequest.prototype.removeEventListener	= function(sName, fHandler, bUseCapture) {
		for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
			if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)
				break;
		// Remove listener
		if (oListener)
			this._listeners.splice(nIndex, 1);
	};

	cXMLHttpRequest.prototype.dispatchEvent	= function(oEvent) {
		var oEvent	= {
			'type':			oEvent.type,
			'target':		this,
			'currentTarget':this,
			'eventPhase':	2,
			'bubbles':		oEvent.bubbles,
			'cancelable':	oEvent.cancelable,
			'timeStamp':	oEvent.timeStamp,
			'stopPropagation':	function() {},	// There is no flow
			'preventDefault':	function() {},	// There is no default action
			'initEvent':		function() {}	// Original event object should be inited
		};

		// Execute onreadystatechange
		if (oEvent.type == "readystatechange" && this.onreadystatechange)
			(this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEvent]);

		// Execute listeners
		for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)
			if (oListener[0] == oEvent.type && !oListener[2])
				(oListener[1].handleEvent || oListener[1]).apply(this, [oEvent]);
	};

	//
	cXMLHttpRequest.prototype.toString	= function() {
		return '[' + "object" + ' ' + "XMLHttpRequest" + ']';
	};

	cXMLHttpRequest.toString	= function() {
		return '[' + "XMLHttpRequest" + ']';
	};

	// Helper function
	function fReadyStateChange(oRequest) {
		// Sniffing code
		if (cXMLHttpRequest.onreadystatechange)
			cXMLHttpRequest.onreadystatechange.apply(oRequest);

		// Fake event
		oRequest.dispatchEvent({
			'type':			"readystatechange",
			'bubbles':		false,
			'cancelable':	false,
			'timeStamp':	new Date + 0
		});
	};

	function fGetDocument(oRequest) {
		var oDocument	= oRequest.responseXML;
		// Try parsing responseText
		if (bIE && oDocument && !oDocument.documentElement && oRequest.getResponseHeader("Content-Type").match(/[^\/]+\/[^\+]+\+xml/)) {
			oDocument	= new window.ActiveXObject("Microsoft.XMLDOM");
			oDocument.loadXML(oRequest.responseText);
		}
		// Check if there is no error in document
		if (oDocument)
			if ((bIE && oDocument.parseError != 0) || (oDocument.documentElement && oDocument.documentElement.tagName == "parsererror"))
				return null;
		return oDocument;
	};

	function fSynchronizeValues(oRequest) {
		try {	oRequest.responseText	= oRequest._object.responseText;	} catch (e) {}
		try {	oRequest.responseXML	= fGetDocument(oRequest._object);	} catch (e) {}
		try {	oRequest.status			= oRequest._object.status;			} catch (e) {}
		try {	oRequest.statusText		= oRequest._object.statusText;		} catch (e) {}
	};

	function fCleanTransport(oRequest) {
		// BUGFIX: IE - memory leak (on-page leak)
		oRequest._object.onreadystatechange	= new window.Function;

		// Delete private properties
		delete oRequest._headers;
	};

	// Internet Explorer 5.0 (missing apply)
	if (!window.Function.prototype.apply) {
		window.Function.prototype.apply	= function(oRequest, oArguments) {
			if (!oArguments)
				oArguments	= [];
			oRequest.__func	= this;
			oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
			delete oRequest.__func;
		};
	};

	// Register new object with window
	window.XMLHttpRequest	= cXMLHttpRequest;
})();

addEventSimple(window, 'load', zorapLib_onLoad);
addEventSimple(window, 'resize', onResizeHandler);
addEventSimple(document, 'mouseup', onMouseUpHandler);
addEventSimple(document, 'keydown', zorapLib_onKeyDown);

function zorapLib_onKeyDown(e)
{
	if(isEscKey(e))
	{
		popupMenusDestroy();
	}
}

function onResizeHandler() {
	popupMenusDestroy();
}

function onMouseUpHandler(e) {
	var target = eventGetTarget(e);
	if(target.zPopupMenuItemCommand) {
		target.zPopupMenu.zPopupMenuCommand = target.zPopupMenuItemCommand;
	}
	popupMenusDestroy();
	
	if(window.parent && window != window.parent && window.parent.specialOnMouseUp)
	{
		window.parent.specialOnMouseUp()
	}
}

function specialOnMouseUp()
{
	popupMenusDestroy();
}

var popupMenus = new Array();
function popupMenusDestroy() {
	while(true) {
		var p = popupMenus.pop();
		if(p) {
			p = p.destroy();
		}
		else {
			break;
		}
	}
}

function setElementClassName(e, className)
{
	e.className = className;
	
	try
	{
		fixElementColors(e);
	}
	catch(e) {}
}

function zPopupMenu(
	id,
	className,
	itemClassName,
	itemClassNameHover,
	itemClassNameInactive,
	itemClassNameSep,
	x, y,
	urlCheck,
	urlCheckHover,
	urlUncheck,
	urlUncheckHover,
	checkWidth,
	width
	) {
	
	this.itemClassName = itemClassName;
	this.itemClassNameHover = itemClassNameHover;
	this.itemClassNameInactive = itemClassNameInactive;
	this.itemClassNameSep = itemClassNameSep;
	this.divPopup = document.createElement('div');
	this.divPopup.id = id;
	setElementClassName(this.divPopup, className);
	if(width) setWidth(this.divPopup, width);
	this.divPopup.style.left = px(x);
	this.divPopup.style.top = px(y);
	this.divPopup.zPopupMenu = this;
	document.body.appendChild(this.divPopup);
	this.divPopup.style.zIndex = 1000;
	this.addItem = function(command, text, active, sep, check) {
		var divItem = document.createElement('div');
		divItem.active = active;
		setElementClassName(divItem, this.getClassName(false, active, sep));
//		if(width) setWidth(divItem, width);
		divItem.zPopupMenuItemCommand = command;
		
		var spanItem = span();
		spanItem.zPopupMenuItemCommand = command;
		spanItem.zPopupMenu = this;
		spanItem.style.cursor = 'pointer';
		
		if(typeof(text) == "string")
		{
			setElementText(spanItem, text);
		}
		else
		{
			append(spanItem, text);
			text.zPopupMenuItemCommand = command;
			text.zPopupMenu = this;
		}
		
		if(urlCheck)
		{
			var imgCheck = img();
			imgCheck.zPopupMenuItemCommand = command;
			imgCheck.zPopupMenu = this;
			imgCheck.src = check ? urlCheck : urlUncheck;
			spanItem.style.position = 'relative';
			setLeft(spanItem, checkWidth);
			append(divItem, imgCheck);
		}
		
		append(divItem, spanItem);
		divItem.sep = sep;
		divItem.zPopupMenu = this;
		divItem.onmouseover = function () {
			setElementClassName(this, this.zPopupMenu.getClassName(true, this.active, this.sep));
			if(imgCheck)
			{
				imgCheck.src = check ? urlCheckHover : urlUncheckHover;
			}
		}
		divItem.onmouseout = function() {
			setElementClassName(this, this.zPopupMenu.getClassName(false, this.active, this.sep));
			if(imgCheck)
			{
				imgCheck.src = check ? urlCheck : urlUncheck;
			}
		}
		this.divPopup.appendChild(divItem);
	}
	this.getClassName = function(hover, active, sep) {
		var cn = itemClassName;
		if(active) {
			if(hover) {
				cn += ' ' + this.itemClassNameHover;
			}
		}
		else {
			cn += ' ' + this.itemClassNameInactive;
		}
		if(sep) {
			cn += ' ' + this.itemClassNameSep;
		}
		return cn;
	}
	this.up = function() {
		this.divPopup.style.top = px(this.divPopup.offsetTop - this.divPopup.offsetHeight);
	}
	this.destroy = function() {
		document.body.removeChild(this.divPopup);
		onMediaPopupMenuDismiss(this);
		return null;
	}
	popupMenus.push(this);
}

function zCreateElement(elementType, id, className) {
	var element = document.createElement(elementType);
	if(id) element.id = id;
	if(className) element.className = className;
	return element;
}

function div(id, className) {
	return zCreateElement('div', id, className);
}

function span(id, className) {
	return zCreateElement('span', id, className);
}

function a(id, className) {// ntrjn: delete. for some reason this doesn't always work.
	return _a(id, className);
}

function _a(id, className) {
	return zCreateElement('a', id, className);
}

function img(id, className) {
	return zCreateElement('img', id, className);
}

function ul(id, className)
{
	return zCreateElement('ul', id, className);
}

function li(id, className)
{
	return zCreateElement('li', id, className);
}

function select(id, className)
{
	return zCreateElement('select', id, className);
}

function option(id, className)
{
	return zCreateElement('option', id, className);
}

function input(type, id, className) {
	var input = zCreateElement('input', id, className);
	input.type = type;
	return input;
}

function textbox(id, className, maxLength) {
	var t = input('text', id, className);
	if(maxLength) {
		t.setAttribute('MAXLENGTH', maxLength);
		t.maxLength = maxLength;
	}
	return t;
}

function password(id, className, maxLength)
{
	var t = input('password', id, className);
	if(maxLength)
	{
		t.setAttribute('MAXLENGTH', maxLength);
		t.maxLength = maxLength;
	}
	return t;
}

function button(id, className, value) {
	var b = input('button', id, className);
	if(value) {
		b.value = value;
	}
	return b;
}

function iframe(id) {
	var iframe;
	if(isIE) {
		iframe = document.createElement('<iframe frameborder="0" scrolling="no"><iframe>');
	}
	else {
		iframe = document.createElement('iframe');
		iframe.setAttribute('frameborder', '0');
	}
	if(id) iframe.id = id;
	return iframe;
}

function radioButton(id, className, name, checked)
{
	if(document.all && !window.opera && document.createElement) {
		// MSIE 6 for windows does not support DOM-insertion of radio buttons. The following code works around that lack of support.
		var params = "<input type='radio' id='_id' className='_className' name='_name' _checked>";
		params = params.replace('_id', id);
		params = params.replace('_className', className);
		params = params.replace('_name', name);
		var chkd = checked ? 'checked' : '';
		params = params.replace('_checked', chkd);
		return document.createElement(params);
	}
	else if(document.createElement && document.createTextNode)
	{
		var radio = input('radio', id, className);
		radio.name = name;
		radio.checked = checked;
		return radio;
	}
	else {
		return null
	}
}

function space() {
	return document.createTextNode('\u00a0');
}

function br() {
	return document.createElement('br');
}

function getById(id) {
	return document.getElementById(id);
}

function append(e0, e1, e2) {
	if(e2) {
		e1.appendChild(e2);
	}
	e0.appendChild(e1);
}

function removeChildren(element) {
	while(element.hasChildNodes())
	{
		element.removeChild(element.firstChild);       
	} 
}

function removeElementById(id) {
	var e = getById(id);
	if(e) {
		e.parentNode.removeChild(e);
	}
}

function removeElement(e) {
	if(e.parentNode)
	{
		e.parentNode.removeChild(e);
	}
}

function underline(e, u) {
	if(u) {
		e.style.textDecoration = 'underline';
	}
	else {
		e.style.textDecoration = 'none';
	}
}

function getWinX() {
	return (document.all) ? window.screenLeft : window.screenX;
}
function getWinY() {
	return (document.all) ? window.screenTop : window.screenY;
}
function getWinWidth() {
	var iebody=(document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body
	return (document.all) ? iebody.clientWidth : window.innerWidth;
}
function getWinHeight()
{
	var iebody=(document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body
	return (document.all) ? iebody.clientHeight : window.innerHeight;
}

function buildWindowFeaturesString(
	x, y,
	width, height,
	menubar, toolbar,
	resizeable, scrollbars
	) {
	var windowFeatures = 'menubar=_menubar,toolbar=_toolbar,resizable=_resizable,scrollbars=_scrollbars'; 
	windowFeatures = replaceAll(windowFeatures, '_menubar', menubar ? '1':'0');
	windowFeatures = replaceAll(windowFeatures, '_toolbar', toolbar ? '1':'0');
	windowFeatures = replaceAll(windowFeatures, '_resizable', resizeable ? '1':'0');
	windowFeatures = replaceAll(windowFeatures, '_scrollbars', scrollbars ? '1':'0');
	if(x != null && y != null && width != null && height != null)
	{
		windowFeatures += ',width=_width,height=_height,screenX=_x,screenY=_y,left=_x,top=_y';
		windowFeatures = replaceAll(windowFeatures, '_height', height);
		windowFeatures = replaceAll(windowFeatures, '_width', width);
		windowFeatures = replaceAll(windowFeatures, '_x', x);
		windowFeatures = replaceAll(windowFeatures, '_y', y);
	}
	return windowFeatures;
}

addEventSimple(document, 'mouseup', onMouseStateTrackerUp);
var mouseStateTrackerArray = new Array();
function onMouseStateTrackerUp() {
	for(var which = 0; which < mouseStateTrackerArray.length; which++) {
		mouseStateTrackerArray[which].zMouseDown = false;
	}
}
function trackMouseDown(e) {
	for(var which = 0; which < mouseStateTrackerArray.length; which++) {
		if(mouseStateTrackerArray[which] == e) {
			e.zMouseDown = true;
			return;
		}
	}
	e.zMouseDown = true;
	mouseStateTrackerArray.push(e);
}
function isMouseDown(e) {
	try {
		return e.zMouseDown;
	}
	catch(e) {
	}
	return false;
}

function zMin(x, y) {
	if(x < y) return x;
	else return y;
}

function zMax(x, y) {
	if(x > y) return x;
	else return y;
}

var zScrollBarBackgroundId = 0;
var zScrollBarUpArrowId = 0;
var zScrollBarDownArrowId = 0;

zScrollBar.pageUp = function(id) {
	var el = getById(id);
	if(el) {
		if(isMouseDown(el)) {
			if(zLibMouseY <= elementGetAbsY(el.zScrollBar.zDivThumb)) {
				el.pageUp();
			}
			setTimeout('zScrollBar.pageUp("' + id + '");', 100);
		}
	}
}

zScrollBar.pageDown = function(id) {
	var el = getById(id);
	if(el) {
		if(isMouseDown(el)) {
			if(zLibMouseY >= elementGetAbsY(el.zScrollBar.zDivThumb) + el.zScrollBar.zDivThumb.offsetHeight) {
				el.pageDown();
			}
			setTimeout('zScrollBar.pageDown("' + id + '");', 100);
		}
	}
}

zScrollBar.scrollUp = function(id) {
	var el = getById(id);
	if(el) {
		if(isMouseDown(el)) {
			el.zScrollUp();
			setTimeout('zScrollBar.scrollUp("' + id + '");', 100);
		}
	}
}

zScrollBar.scrollDown = function(id) {
	var el = getById(id);
	if(el) {
		if(isMouseDown(el)) {
			el.zScrollDown();
			setTimeout('zScrollBar.scrollDown("' + id + '");', 100);
		}
	}
}

addEventSimple(document, 'mousemove', zLibOnMouseMove);
addEventSimple(document, 'mouseup', zLibOnMouseUp);
var zLibMouseX = 0;
var zLibMouseY = 0;
function zLibOnMouseMove(evt) {
    try {
        var e = getEvent(evt);
        zLibMouseX = e.clientX;
        zLibMouseY = e.clientY;
        
        if(zScrollBar.slidingScrollbar) {
			var delta = zLibMouseY - zScrollBar.slidingScrollbarAbsY;
			var moved = zScrollBar.slidingScrollbar.slide(delta);
			zScrollBar.slidingScrollbarAbsY += moved;
        }
    }
    catch(ex) {
    }
}
function zLibOnMouseUp() {
	zScrollBar.slidingScrollbar = null;
}

zScrollBar.slidingScrollbar = null;
zScrollBar.slidingScrollbarAbsY = null;
zScrollBar.slidingScrollbarRelY = null;
var clicks = 0;
function zScrollBar(
	divContent,
	parent,
	width,
	backgroundUrl,
	upArrowUrl,
	upArrowMouseDownUrl,
	downArrowUrl,
	downArrowMouseDownUrl,
	arrowHeight,
	lineHeight,
	thumbTopUrl,
	thumbTopHeight,
	thumbMiddleUrl,
	thumbMiddleHeight,
	thumbBottomUrl,
	thumbBottomHeight,
	thumbBackgroundUrl
	) {
	this.zScrollBarTarget = divContent;
	this.zParent = parent;
	
	/*
	 * background
	 */
	var divBackground = div('zScrollBarBackgroundId' + zScrollBarBackgroundId);
	divBackground.style.position = 'absolute';
	divBackground.style.right = px(0);
	divBackground.style.top = px(0);
	divBackground.style.width = px(width);
	divBackground.style.height = px(parent.offsetHeight);
	divBackground.style.backgroundImage = "url('" + backgroundUrl + "')";
	divBackground.style.fontSize = '1px';
	divBackground.style.lineHeight = '1px';
	divBackground.zScrollBar = this;
	divBackground.pageUp = function() {
		this.zScrollBar.zScrollBarTarget.scrollTop = this.zScrollBar.zScrollBarTarget.scrollTop - this.zScrollBar.zScrollBarTarget.offsetHeight;
		this.zScrollBar.setThumbPosition();
	}
	divBackground.pageDown = function() {
		this.zScrollBar.zScrollBarTarget.scrollTop = this.zScrollBar.zScrollBarTarget.scrollTop + this.zScrollBar.zScrollBarTarget.offsetHeight;
		this.zScrollBar.setThumbPosition();
	}
	divBackground.onmousedown = function(e) {
		trackMouseDown(this);
		if(eventGetRelY(e) <= this.zScrollBar.zDivThumb.offsetTop) {
			this.pageUp();
			setTimeout('zScrollBar.pageUp("' + this.id + '");', 500);	
		}
		else {
			this.pageDown();
			setTimeout('zScrollBar.pageDown("' + this.id + '");', 500);	
		}
	}
	divBackground.ondblclick = function(e) {
		if(isIE) {
			if(eventGetRelY(e) <= this.zScrollBar.zDivThumb.offsetTop) {
				this.pageUp();
			}
			else {
				this.pageDown();
			}
		}
	}	
	parent.appendChild(divBackground);
	divContent.scrollTop = 0;
 
	/*
	 * up arrow
	 */
	var divUpArrow = div('zScrollBarUpArrowId' + zScrollBarUpArrowId);
	divUpArrow.style.position = 'absolute';
	divUpArrow.style.right = px(0);
	divUpArrow.style.top = px(0);
	divUpArrow.style.width = px(width);
	divUpArrow.style.height = px(arrowHeight);
	divUpArrow.style.backgroundImage = "url('" + upArrowUrl + "')";
	divUpArrow.zImageUrl = upArrowUrl;
	divUpArrow.zImageUrlS = upArrowMouseDownUrl;
	divUpArrow.zLineHeight = lineHeight;
	divUpArrow.style.fontSize = '1px';
	divUpArrow.style.lineHeight = '1px';
	divUpArrow.zScrollBar = this;
	divUpArrow.zScrollUp = function() {
		this.zScrollBar.zScrollBarTarget.scrollTop = zMax(this.zScrollBar.zScrollBarTarget.scrollTop - this.zLineHeight, 0);
		this.zScrollBar.setThumbPosition();
	}
	divUpArrow.setBackgroundImage = function(selected) {
		if(selected) {
			this.style.backgroundImage = "url('" + this.zImageUrlS + "')";
		}
		else {
			this.style.backgroundImage = "url('" + this.zImageUrl + "')";
		}
	}
	divUpArrow.onmouseover = function() {
		this.setBackgroundImage(isMouseDown(this));
	}	
	divUpArrow.onmouseout = function() {
		this.setBackgroundImage(false);
	}	
	divUpArrow.onmouseup = function() {
		this.setBackgroundImage(false);
	}
	divUpArrow.onmousedown = function() {
		trackMouseDown(this);
		this.setBackgroundImage(true);
		this.zScrollUp();
		setTimeout('zScrollBar.scrollUp("' + this.id + '");', 500);
	}
	divUpArrow.ondblclick = function() {
		if(isIE) {
			this.setBackgroundImage(false);
			this.zScrollUp();
		}
	}	
	parent.appendChild(divUpArrow);

	/*
	 * down arrow
	 */
 	var divDownArrow = div('zScrollBarDownArrowId' + zScrollBarDownArrowId);
	divDownArrow.style.position = 'absolute';
	divDownArrow.style.right = px(0);
	divDownArrow.style.bottom = px(0);
	divDownArrow.style.width = px(width);
	divDownArrow.style.height = px(arrowHeight);
	divDownArrow.style.backgroundImage = "url('" + downArrowUrl + "')";
	divDownArrow.zImageUrl = downArrowUrl;
	divDownArrow.zImageUrlS = downArrowMouseDownUrl;
	divDownArrow.zLineHeight = lineHeight;
	divDownArrow.style.fontSize = '1px';
	divDownArrow.style.lineHeight = '1px';
	divDownArrow.zScrollBar = this;
	divDownArrow.zScrollDown = function() {
		this.zScrollBar.zScrollBarTarget.scrollTop = this.zScrollBar.zScrollBarTarget.scrollTop + this.zLineHeight;
		this.zScrollBar.setThumbPosition();
	}
	divDownArrow.setBackgroundImage = function(selected) {
		if(selected) {
			this.style.backgroundImage = "url('" + this.zImageUrlS + "')";
		}
		else {
			this.style.backgroundImage = "url('" + this.zImageUrl + "')";
		}
	}
	divDownArrow.onmouseover = function() {
		this.setBackgroundImage(isMouseDown(this));
	}	
	divDownArrow.onmouseout = function() {
		this.setBackgroundImage(false);
	}	
	divDownArrow.onmouseup = function() {
		this.setBackgroundImage(false);
	}
	divDownArrow.onmousedown = function() {
		trackMouseDown(this);
		this.setBackgroundImage(true);
		this.zScrollDown();
		setTimeout('zScrollBar.scrollDown("' + this.id + '");', 500);
	}
	divDownArrow.ondblclick = function() {
		if(isIE) {
			this.setBackgroundImage(false);
			this.zScrollDown();
		}
	}
	parent.appendChild(divDownArrow);
	
	/*
	 * thumb
	 */
	 
	this.zThumbTop = divUpArrow.offsetTop + divUpArrow.offsetHeight;
	this.zScrollSpace = divDownArrow.offsetTop - this.zThumbTop;
	this.zThumbTopHeight = thumbTopHeight;
	this.zThumbMiddleHeight = thumbMiddleHeight;
	this.zThumbBottomHeight = thumbBottomHeight;
	this.zMinThumbHeight = thumbTopHeight + thumbMiddleHeight + thumbBottomHeight;

	var divThumb = div();
	divThumb.style.position = 'absolute';
	this.zDivThumb = divThumb;
	divThumb.style.right = px(0);
	divThumb.style.width = px(width);
	parent.appendChild(divThumb);
	
	this.startThumbScroll = function(e) {
		zScrollBar.slidingScrollbar = this;
		zScrollBar.slidingScrollbarAbsY = eventGetAbsY(e);
		zScrollBar.slidingScrollbarRelY = eventGetRelY(e);
	}

	/*
	 * thumb top
	 */
	var divThumbTop = div();
	divThumbTop.style.position = 'absolute';
	divThumbTop.style.left = px(0);
	divThumbTop.style.width = px(width);
	this.zDivThumbTop = divThumbTop;
	divThumbTop.zScrollbar = this;
	divThumbTop.style.backgroundImage = "url('" + thumbTopUrl + "')";
	divThumbTop.style.fontSize = '1px';
	divThumbTop.style.lineHeight = '1px';
	divThumbTop.onmousedown = function(e) {
		return this.zScrollbar.startThumbScroll(e);
	}
	divThumb.appendChild(divThumbTop);

	/*
	 * thumb background top
	 */
	var divThumbBackgroundTop = div();
	divThumbBackgroundTop.style.position = 'absolute';
	divThumbBackgroundTop.style.left = px(0);
	divThumbBackgroundTop.style.width = px(width);
	this.zDivThumbBackgroundTop = divThumbBackgroundTop;
	divThumbBackgroundTop.zScrollbar = this;
	divThumbBackgroundTop.style.backgroundImage = "url('" + thumbBackgroundUrl + "')";
	divThumbBackgroundTop.style.fontSize = '1px';
	divThumbBackgroundTop.style.lineHeight = '1px';
	divThumbBackgroundTop.onmousedown = function(e) {
		return this.zScrollbar.startThumbScroll(e);
	}
	divThumb.appendChild(divThumbBackgroundTop);

	/*
	 * thumb background middle
	 */
	var divThumbMiddle = div();
	divThumbMiddle.style.position = 'absolute';
	divThumbMiddle.style.left = px(0);
	divThumbMiddle.style.width = px(width);
	this.zDivThumbMiddle = divThumbMiddle;
	divThumbMiddle.zScrollbar = this;
	divThumbMiddle.style.backgroundImage = "url('" + thumbMiddleUrl + "')";
	divThumbMiddle.style.fontSize = '1px';
	divThumbMiddle.style.lineHeight = '1px';
	divThumbMiddle.onmousedown = function(e) {
		return this.zScrollbar.startThumbScroll(e);
	}
	divThumb.appendChild(divThumbMiddle);

	/*
	 * thumb background bottom
	 */
	var divThumbBackgroundBottom = div();
	divThumbBackgroundBottom.style.position = 'absolute';
	divThumbBackgroundBottom.style.left = px(0);
	this.zDivThumbBackgroundBottom = divThumbBackgroundBottom;
	divThumbBackgroundBottom.zScrollbar = this;
	divThumbBackgroundBottom.style.width = px(width);
	divThumbBackgroundBottom.style.backgroundImage = "url('" + thumbBackgroundUrl + "')";
	divThumbBackgroundBottom.style.fontSize = '1px';
	divThumbBackgroundBottom.style.lineHeight = '1px';
	divThumbBackgroundBottom.onmousedown = function(e) {
		return this.zScrollbar.startThumbScroll(e);
	}
	divThumb.appendChild(divThumbBackgroundBottom);

	/*
	 * thumb bottom
	 */
	var divThumbBottom = div();
	divThumbBottom.style.position = 'absolute';
	divThumbBottom.style.left = px(0);
	this.zDivThumbBottom = divThumbBottom;
	divThumbBottom.zScrollbar = this;
	divThumbBottom.style.width = px(width);
	divThumbBottom.style.backgroundImage = "url('" + thumbBottomUrl + "')";
	divThumbBottom.style.fontSize = '1px';
	divThumbBottom.style.lineHeight = '1px';
	divThumbBottom.onmousedown = function(e) {
		return this.zScrollbar.startThumbScroll(e);
	}
	divThumb.appendChild(divThumbBottom);
	
	this.updateThumb = function() {
		if(this.zScrollBarTarget.scrollHeight <= this.zScrollBarTarget.offsetHeight) {
			this.zScrollBarTarget.scrollTop = 0;
			this.zParent.style.display = 'none';
			return;
		}
		// this.zScrollBarTarget.scrollHeight
		// this.zScrollBarTarget.offsetHeight
		// this.zScrollBarTarget.scrollTop
		if(this.zScrollBarTarget.scrollTop + this.zScrollBarTarget.offsetHeight > this.zScrollBarTarget.scrollHeight) {
			this.zScrollBarTarget.scrollTop = this.zScrollBarTarget.scrollHeight - this.zScrollBarTarget.offsetHeight;
		}
		this.zParent.style.display = 'block';
		this.setThumbHeights();
		this.setThumbPosition();
	}
	
	 this.setThumbHeights = function() {
//				this.zDivThumb.style.display = 'block';//
//				this.zDivThumbTop.style.display = 'block';//
//				this.zDivThumbBackgroundTop.style.display = 'block';//
//				this.zDivThumbMiddle.style.display = 'block';//
//				this.zDivThumbBackgroundBottom.style.display = 'block';//
//				this.zDivThumbBottom.style.display = 'block';//

		var thumbHeight = Math.round(this.zScrollSpace * this.zScrollBarTarget.offsetHeight / this.zScrollBarTarget.scrollHeight);
		thumbHeight = zMax(thumbHeight, this.zMinThumbHeight);

		var thumbBackgroundTopHeight = Math.round((thumbHeight - this.zMinThumbHeight)/2);
		var thumbBackgroundBottomHeight = thumbHeight - this.zMinThumbHeight - thumbBackgroundTopHeight;

		this.zDivThumb.style.height = px(thumbHeight);

		var thumbY = 0;
			
		this.zDivThumbTop.style.top = px(thumbY);			
		this.zDivThumbTop.style.height = px(this.zThumbTopHeight);
		thumbY += this.zThumbTopHeight;

		this.zDivThumbBackgroundTop.style.top = px(thumbY);
		this.zDivThumbBackgroundTop.style.height = px(thumbBackgroundTopHeight);
		thumbY += thumbBackgroundTopHeight;

		this.zDivThumbMiddle.style.top = px(thumbY);
		this.zDivThumbMiddle.style.height = px(this.zThumbMiddleHeight);
		thumbY += this.zThumbMiddleHeight;

		this.zDivThumbBackgroundBottom.style.top = px(thumbY);
		this.zDivThumbBackgroundBottom.style.height = px(thumbBackgroundBottomHeight);
		thumbY += thumbBackgroundBottomHeight;

		this.zDivThumbBottom.style.top = px(thumbY);
		this.zDivThumbBottom.style.height = px(thumbBottomHeight);
	 }
	
	this.setThumbPosition = function() {
		var thumbHeight = Math.round(this.zScrollSpace * this.zScrollBarTarget.offsetHeight / this.zScrollBarTarget.scrollHeight);
		thumbHeight = zMax(thumbHeight, this.zMinThumbHeight);
		
		var thumbRange = this.zScrollSpace - thumbHeight;
		
		var scrollRange = this.zScrollBarTarget.scrollHeight - this.zScrollBarTarget.offsetHeight;
		scrollRange = zMax(scrollRange, 0);
		
		var thumbTop = this.zThumbTop;
		if(scrollRange > 0) {
			thumbTop += Math.round(thumbRange * this.zScrollBarTarget.scrollTop / scrollRange);
		}
		this.zDivThumb.style.top = px(thumbTop);
	}
	this.slide = function(delta) {
		var moved = delta;
		var oldY = this.zDivThumb.offsetTop;
		var newY = oldY + delta;
		
		var thumbHeight = Math.round(this.zScrollSpace * this.zScrollBarTarget.offsetHeight / this.zScrollBarTarget.scrollHeight);
		thumbHeight = zMax(thumbHeight, this.zMinThumbHeight);
		var thumbRange = this.zScrollSpace - thumbHeight;
		
		var minY = this.zThumbTop;
		if(newY < minY) {
			newY = minY;
			moved = minY - oldY;
		}
		var maxY = minY + thumbRange;
		if(newY > maxY) {
			newY = maxY;
			moved = maxY - oldY;
		}
		this.zDivThumb.style.top = px(newY);
		
		if(moved != 0) {
			var thumbHeight = Math.round(this.zScrollSpace * this.zScrollBarTarget.offsetHeight / this.zScrollBarTarget.scrollHeight);
			thumbHeight = zMax(thumbHeight, this.zMinThumbHeight);
			var thumbRange = this.zScrollSpace - thumbHeight;
			
			var scrollRange = this.zScrollBarTarget.scrollHeight - this.zScrollBarTarget.offsetHeight;
			scrollRange = zMax(scrollRange, 0);
			this.zScrollBarTarget.scrollTop = Math.round(scrollRange * (newY - this.zThumbTop) / thumbRange);
		}		
		
		return moved;
	}
	
	this.updateThumb();

	zScrollBarBackgroundId += 1;
	zScrollBarUpArrowId += 1;
	zScrollBarDownArrowId += 1;
}

function scaleImage(theImage, maxWidth, maxHeight)
{
	var width = theImage.clientWidth;
	var height = theImage.clientHeight;

	if((width == 0) || (height == 0))
	{
		// not IE
		theImage.style.width = px(maxWidth);
		return;
	}
	// IE
	var newWidth = maxWidth;
	var newHeight = maxHeight;
	if(width != 0 && height != 0)
	{
		var scaleW = maxWidth / width;
		var scaleH = maxHeight / height;
		if (scaleH < scaleW)
		{
			newWidth = Math.round(width * scaleH);
		}
		else
		{
			newHeight = Math.round(height * scaleW);
		}

		theImage.style.width = px(newWidth);
		theImage.style.height = px(newHeight);
	}
}

function px(value)
{
	if(typeof(value) == 'string')
	{
		if(value.indexOf('px') > 0)
		{
			return value;
		}
	}
	return Math.round(value) + 'px';

}

var disrespectfulWords = ["fuck", "fucker", "cunt", "nigger"];
var pattern = new RegExp(disrespectfulWords.join("|"), "i");
function isRespectful(text)
{
	return !pattern.test(text);
}

function setLeft(e, left)
{
	if(left || left === 0 || left === '0')
	{
		e.style.left = px(left);
	}
}

function setRight(e, right)
{
	if(right || right === 0 || right === '0')
	{
		e.style.right = px(right);
	}
}

function setTop(e, top)
{
	if(top || top === 0 || top === '0')
	{
		e.style.top = px(top);
	}
}

function setBottom(e, bottom)
{
	if(bottom || bottom === 0 || bottom === '0')
	{
		e.style.bottom = px(bottom);
	}
}

function setWidth(e, width)
{
	e.style.width = px(width);
}

function setHeight(e, height)
{
	e.style.height = px(height);
}

function showElement(e, show)
{
	e.style.display = show ? 'block' : 'none';
}

function showVScrollBar(e, show)
{
	e.style.overflowY = show ? 'auto' : 'hidden';
}

function showHScrollBar(e, show)
{
	e.style.overflowX = show ? 'auto' : 'hidden';
}

function calcScrollbarDims()
{
	// This function calculates window.scrollbarWidth and window.scrollbarHeight
	var i = document.createElement('p');
	i.style.width = '100%';
	i.style.height = '200px';

	var o = document.createElement('div');
	o.style.position = 'absolute';
	o.style.top = '0px';
	o.style.left = '0px';
	o.style.visibility = 'hidden';
	o.style.width = '200px';
	o.style.height = '150px';
	o.style.overflow = 'hidden';
	o.appendChild(i);

	document.body.appendChild(o);
	var w1 = i.offsetWidth;
	var	h1 = i.offsetHeight;
	o.style.overflow = 'scroll';
	var w2 = i.offsetWidth;
	var h2 = i.offsetHeight;
	if (w1 == w2) w2 = o.clientWidth;
	if (h1 == h2) h2 = o.clientWidth;

	document.body.removeChild(o);

	window.scrollbarWidth = w1-w2;
	window.scrollbarHeight = h1-h2;
}

function zorapLib_onLoad()
{
	calcScrollbarDims();
}

function elementHasVScrollBar(e)
{
	if(e.clientHeight < e.scrollHeight)
	{
		return true;
	}
	return false;
}

function ctrlKeyDown(e)
{
	var evt = getEvent(e);
	return evt.ctrlKey === true;
}

function shiftKeyDown(e)
{
	var evt = getEvent(e);
	return evt.shiftKey === true;
}

function makeLink(url, cls, style)
{
	var link = "<a class='" + cls + "' style='padding-left:3px;" + style + "' href='_url_' target='_blank'>_urltext_</a>";
	link = link.replace('_urltext_', url);
	if(url.indexOf('http://') != 0) {
		url = 'http://' + url;
	}
	link = link.replace('_url_', url);
	return link;
}

function makeNonLink(text, cls, style)
{
	if(text.length == 0) return "";
	var nonLink = "<span class='" + cls + "' style='" + style + "'>_text_</span>";
	return nonLink.replace('_text_', text);
}

// make link-looking parts of a text message into actual links
function makeLinks(text, cls, style)
{
	var result = "";
	var c = 0;
	while(true) {
		var i = text.indexOf('http://', c);
		var j = text.indexOf('www.', c);
		if(i == -1 && j == -1) {
			result += makeNonLink(text.substring(c), cls, style);
			break;
		}
		i = i == -1 ? j : (j == -1 ? i : (i < j ? i : j));
		result += makeNonLink(text.substring(c, i), cls, style);
		var s = text.indexOf(' ', i);
		if(s == -1) {
			s = text.length;
		}
		result += makeLink(text.substring(i, s), cls, style);
		c = s;
	}
	return result;
}


function getXMLElementText(parent, elementName, defaultValue)
{
	var ret = defaultValue;
	
	try
	{		
		if(parent) {
			var elements = parent.getElementsByTagName(elementName);
			if(elements) {
				var element = elements.item(0);
				if(element) {
					ret = element.firstChild.nodeValue;
				}
			}
		}
	}
	catch(e) {};

	return ret;
}

function dom_getElements(node, ns, elt) {
    var list = node.getElementsByTagName(ns + ':' + elt);
    if(list.length)
		return list;
	return node.getElementsByTagName(elt);
}

function getXMLElementAttribute(parent, elementNamespace, elementName, attributeName, defaultValue) {
	var ret = defaultValue;
	
try
{	
	if(parent) {
		var elements = dom_getElements(parent, elementNamespace, elementName);
		if(elements) {
		    for(var whichElement = 0; whichElement < elements.length; whichElement++) {
			    var element = elements.item(whichElement);
			    if(element) {
				    var r = element.getAttribute(attributeName);
				    if(r && r != '') {
					    ret = r;
					    break;
				    }
			    }
		    }
		}
	}
}
catch(e) {};

	return ret;
}

function ZButton(
	parent,
	imageUrl,
	hoverUrl,
	pushUrl,
	text,
	textCSSClassName,
	left,
	top,
	right,
	bottom,
	width,
	height,
	onClick,
	title
	)
{
	var _enabled = true;
	var _aButton = _a();
	_aButton.style.textDecoration = 'none';
	
	if(left !== null || top !== null || right !== null || bottom !== null)
	{
		_aButton.style.position = 'absolute';
	}
	if(left !== null)
	{
		setLeft(_aButton, left);
	}
	if(top !== null)
	{
		setTop(_aButton, top);
	}
	if(right !== null)
	{
		setRight(_aButton, right + width);
	}
	if(bottom !== null)
	{
		setBottom(_aButton, bottom + height);
	}
	_aButton.href = '#';
	var _imgButton = img();
	if(left !== null || top !== null || right !== null || bottom !== null)
	{
		_imgButton.style.position = 'absolute';
	}
	_imgButton.style.border = 'none';
	_imgButton.src = imageUrl;
	var _mouseDown = false;
	
	if(title)
	{
		_imgButton.alt = title;
		_imgButton.title = title;
	}
		
	this.changeColor = function(oldColor, newColor)
	{
		_imgButton.src = _imgButton.src.replace(oldColor, newColor);
		imageUrl = imageUrl.replace(oldColor, newColor);
		hoverUrl = hoverUrl.replace(oldColor, newColor);
		pushUrl = pushUrl.replace(oldColor, newColor);
	}
	
	_aButton.onmouseover = function()
	{
		if(_enabled)
		{
			_imgButton.src = _mouseDown ? pushUrl : hoverUrl;
		}
	}
	_aButton.onmouseout = function()
	{
		_imgButton.src = imageUrl;
	}
	_aButton.onmousedown = function(e)
	{
		if(_enabled)
		{
			_aButton.href = null;
			_mouseDown = true;
			_imgButton.src = pushUrl;
		}
	}
	onMouseUp = function()
	{
		_mouseDown = false;
	}
	addEventSimple(document, 'mouseup', onMouseUp);
	_aButton.onmouseup = function()
	{
		if(_enabled)
		{
			_mouseDown = false;
			_imgButton.src = hoverUrl;
		}
	}
	_aButton.onclick = function()
	{
		if(_enabled)
		{
			if(onClick)
			{
				onClick();
			}
		}
		return false;
	}
	this.enable = function(e)
	{
		_enabled = e;
		if(e)
		{
			_aButton.href = '#';
		}
		else
		{
			_aButton.removeAttribute('href');
		}
	}
	this.show = function(s)
	{
		showElement(_aButton, s);
	}
	this.getAbsX = function()
	{
		return elementGetAbsX(_aButton);
	}
	this.getAbsY = function()
	{
		return elementGetAbsY(_aButton);
	}
	this.getHeight = function()
	{
		return height;
	}
	append(parent, _aButton, _imgButton);

	if(text)
	{
		var _spanText = span();
		_spanText.innerHTML = text;
		_spanText.className = textCSSClassName;
		_spanText.style.position = 'absolute';
		_spanText.style.cursor = 'pointer';
		append(_aButton, _spanText);
		setLeft(_spanText, Math.round(width/2 - _spanText.offsetWidth/2));
		setTop(_spanText, Math.round(height/2 - _spanText.offsetHeight/2));
	}
	this.eventTargetIsElementOrChild = function(e)
	{
		return eventTargetIsElementOrChild(_aButton, e);
	}
}

function ZButton2(
	button,
	imageUrl,
	hoverUrl,
	pushUrl
	)
{
	var _mouseDown = false;

	button.onmouseover = function()
	{
		button.style.background = makeCSSUrl(_mouseDown ? pushUrl : hoverUrl);
	}
	button.onmouseout = function()
	{
		button.style.background = makeCSSUrl(imageUrl);
	}
	button.onmousedown = function(e)
	{
		_mouseDown = true;
		button.style.background = makeCSSUrl(pushUrl);
	}
	onMouseUp = function()
	{
		_mouseDown = false;
	}
	addEventSimple(document, 'mouseup', onMouseUp);
	button.onmouseup = function()
	{
		_mouseDown = false;
		button.style.background = makeCSSUrl(hoverUrl);
	}
}

function LevelMeter(parent, left, top, clsBack, clsLevelThing, thingLeft, thingTop, meterWidth, range)
{
	var _divBack = div('', clsBack);
	_divBack.style.position = 'absolute';
	setLeft(_divBack, left);
	setTop(_divBack, top);
	append(parent, _divBack);
	
	var thingArray = new Array();
	var left = thingLeft;
	while(true)
	{
		var divLevelThing = div('', clsLevelThing);
		thingArray.push(divLevelThing);
		divLevelThing.style.position = 'absolute';
		setLeft(divLevelThing, left);
		setTop(divLevelThing, thingTop);
		append(_divBack, divLevelThing);
		
		left += divLevelThing.offsetWidth;
		if(left + divLevelThing.offsetWidth > thingLeft + meterWidth)
		{
			break;
		}
	}
	this.setLevel = function(level)
	{
		var nThings = Math.round(level * thingArray.length / range);
		for(var whichThing = 0; whichThing < thingArray.length; whichThing++)
		{
			if(whichThing < nThings)
			{
				showElement(thingArray[whichThing], true);
			}
			else
			{
				showElement(thingArray[whichThing], false);
			}
		}
	}
}

function makeCSSUrl(url)
{
	return 'url("' + url + '")';
}

function Slider(
	parent, left, top, right, bottom, 
	imageBack, imageBackDisabled,
	imageBackWidth, imageBackHeight, 
	imageSlidingThing, imageSlidingThingDisabled,
	imageSlidingThingWidth, imageSlidingThingHeight,
	imageSlidingThingXOffset, imageSlidingThingYOffset,
	imageLabel, imageLabelWidth, imageLabelHeight, imageLabelXOffset, imageLabelYOffset,
	range,
	onSlide
	)
{
	var _divBack = div();
	_divBack.style.position = 'absolute';
	if(left !== null) setLeft(_divBack, left);
	if(top !== null) setTop(_divBack, top);
	if(right !== null) setRight(_divBack, right);
	if(bottom !== null) setBottom(_divBack, bottom);
	_divBack.style.backgroundImage = makeCSSUrl(imageBack);
	setWidth(_divBack, imageBackWidth);
	setHeight(_divBack, imageBackHeight);
	append(parent, _divBack);
	
	var _divSlidingThing = div();
	_divSlidingThing.style.position = 'absolute';
	setLeft(_divSlidingThing, imageSlidingThingXOffset ? imageSlidingThingXOffset : 0);
	setTop(_divSlidingThing, imageSlidingThingYOffset ? imageSlidingThingYOffset : 0);
	_divSlidingThing.style.backgroundImage = makeCSSUrl(imageSlidingThing);
	setWidth(_divSlidingThing, imageSlidingThingWidth);
	setHeight(_divSlidingThing, imageSlidingThingHeight);
	append(_divBack, _divSlidingThing);
	var _enabled = true;
	var _sliding = false;
	var _slidingStartX = 0;
	var _slidingThingStartX = 0;
	_divSlidingThing.onmousedown = function(e)
	{
		if(_enabled)
		{
			_sliding = true;
			_slidingStartX = eventGetAbsX(e);
			_slidingThingStartX = _divSlidingThing.offsetLeft;
		}
	}
	function _mouseUp(e)
	{
		_sliding = false;
	}
	function _mouseMove(e)
	{
		if(_sliding)
		{
			var x = eventGetAbsX(e);
			var dx = x - _slidingStartX;
			
			var slidingThingNewX = _slidingThingStartX + dx;
			
			if(slidingThingNewX < 0) slidingThingNewX = 0;
			if(slidingThingNewX > getRange()) slidingThingNewX = getRange();
			
			setLeft(_divSlidingThing, slidingThingNewX);
			
			onSlide(Math.round(range * slidingThingNewX / getRange()));
		}
	}
	addEventSimple(document, 'mouseup', _mouseUp);
	addEventSimple(document, 'mousemove', _mouseMove);
	
	if(imageLabel)
	{
		var _divLabel = div();
		_divLabel.style.position = 'absolute';
		setLeft(_divLabel, imageLabelXOffset);
		setTop(_divLabel, imageLabelYOffset);
		_divLabel.style.backgroundImage = makeCSSUrl(imageLabel);
		setWidth(_divLabel, imageLabelWidth);
		setHeight(_divLabel, imageLabelHeight);
		append(_divBack, _divLabel);
	}
	this.changeColor = function(oldColor, newColor)
	{
		_divBack.style.backgroundImage = _divBack.style.backgroundImage.replace(oldColor, newColor);
		_divSlidingThing.style.backgroundImage = _divSlidingThing.style.backgroundImage.replace(oldColor, newColor);
		if(imageLabel)
		{
			_divLabel.style.backgroundImage = _divLabel.style.backgroundImage.replace(oldColor, newColor);
		}
	}
	function getRange()
	{
		return imageBackWidth - imageSlidingThingWidth;
	}
	this.setLevel = function(level)
	{
		var pixelRange = getRange();
		var x = Math.round(level * pixelRange / range);
		setLeft(_divSlidingThing, x);
	}
	this.enable = function(e)
	{
		_enabled = e;
	}
}

function DropDown2(parent, left, top, cls, cb)
{
	var _select = select('', cls);
	_select.style.position = 'absolute';
	setLeft(_select, left);
	setTop(_select, top);
	_select.onchange = function()
	{
		var sIndex = _select.selectedIndex;
		var id = _select.options[sIndex].zId;
		cb(id);
	}
	parent.appendChild(_select);
	this.append = function(item, id)
	{
		var o = option()
		o.innerHTML = item;
		o.zId = id;
		append(_select, o);
	}
	this.setSelected = function(id)
	{
		_select.selectedIndex = 0;
		
		for(var whichOption = 0; whichOption < _select.options.length; whichOption++)
		{
			var o = _select.options[whichOption];
			if(o.zId == id)
			{
				_select.selectedIndex = whichOption;
				break;
			}
		}
	}
}

function CheckBox(parent, left, top, clsBackground, clsCheck, clsLabel, label, labelOffsetX, labelOffsetY, cb)
{
	var _divBackground = div('', clsBackground);
	_divBackground.style.cursor = 'pointer';
	setLeft(_divBackground, left);
	setTop(_divBackground, top);
	var _checked = true;
	var _divCheck = div('', clsCheck);
	var _spanLabel = span('', clsLabel);
	_spanLabel.style.position = 'absolute'
	setLeft(_spanLabel, labelOffsetX);
	setTop(_spanLabel, labelOffsetY);
	_spanLabel.innerHTML = label;
	append(parent, _divBackground);
	append(_divBackground, _divCheck);
	append(_divBackground, _spanLabel);
	
	var _this = this;	
	_divBackground.onclick = function()
	{
		var newChecked =!_checked;
		_this.setChecked(newChecked);
		cb(newChecked);
	}

	this.setChecked = function(checked)
	{
		showElement(_divCheck, checked);
		_checked = checked;
	}	
}

function setAlpha(e, alpha) {
	var decAlpha = '1.0';
	if(alpha < 10) {
		decAlpha = '.0' + alpha;
	}
	else if(alpha < 100) {
		decAlpha = '.' + alpha;
	}
	e.style.filter = 'alpha(opacity=' + alpha + ')';
	e.style.opacity = decAlpha;
	e.style.MozOpacity = decAlpha;
}

function isNumeric(c)
{
	return (c >= '0' && c <= '9');
}

function fixSelect(ele)
{
    ele.onselectstart = function()//ie
	{
		var evt = getEvent();
		evt.cancelBubble = true;//undo
	}
	ele.style.MozUserSelect = 'text';
	ele.style.webkitUserSelect = 'text';
}
