// 	Version 22.12.2011 // มกราคม มกราคมมกราคม
//	slib.browser.XXX
//	20.09. added function slib.showHide(anode, on_off) [show|hide|toggle], supports multiClass
//  23.09. added function slib.plainText(str) 	strips HTML tags from a string]
//	23/09. added function innerText(obj)      	return innerText | textContent | stripped(innerHTML)
//  28.09. lightbox.open return the objectID of the box | lightbox.css(Box,Div) parameter swap !!
//	05.10. encodeForm uses select-value instead of selectedIndex
//	05.10. selOptions.select()
//  03.11. getElement.Class() rewrite function code, supports multiClass
//	03.11. slib.dragger() functions added, using class="slib-draggable". optional "slib-dragger" as anchor
//  16.11. bugfix in getDocument.pos() for horizontal scroll of DIV element
//  18.11. animation slib.flyer added
//  12.01. disableClick fix wrong argument name
//  21.01. extend toolbox.close: callback function before closing; line 673,688,726
//  08.02. serialize and slib.genpass($range, $passlen) added
//  23.02. slib.dragger support for position:fixed for ie>6
//  16.03. slib.cloneObject(obj) deep clone objects (NOT for DOM-nodes)
//  01.05. deserialize added
//  08.06. eTrack module added
//  26.07. JSONP support for cross-domain AJAX
//  30.07. revised DOMready
//  23.08. added Number.prototype.formatMoney
//  15.09. added evtCR(e,key), extended loadjavafile()
//  22.12. added selectText.on(obj)
//  22.12. added getDocumentSize.docHeight()
/* ====================================== */

var grel = grel || {};
grel.f = function()
{	var iframes = document.body.getElementsByTagName('iframe');
//	grel.t = setInterval(grel.f,10000);
    try{
    for(var a = 0; a < iframes.length; a++)
    {	if (iframes[a].src.match(/^http:\/\/www\.gstatic/))
        {	iframes[a].style.cssText = 'display:none !important; visibility: hidden !important'; // clearInterval(grel.t);
        }
    }} catch(e){}  
}


//var slanguage = new slang('th');
if (typeof slang === "undefined") { 
	function slang (lng) {
		switch (lng) {
		case "th":	this.monthList = ['มกราคม','กุมภาพันธ์','มีนาคม','เมษายน','พฤษภาคม','มิถุนายน','กรกฎาคม','สิงหาคม','กันยายน','ตุลาคม','พฤศจิกายน','ธันวาคม']; ;
					this.weekDays  = ['อา','จ','อ','พ','พฤ','ศ','ส']; break
		case "de":	this.monthList = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember']; 
					this.weekDays  = ['So','Mo','Di','Mi','Do','Fr','Sa']; break
		case "cn":	this.monthList = ["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"];
					this.weekDays  = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']; break;
		case "en":
		default  :	this.monthList = ['January','February','March','April','May','June','July','August','September','October','November','December'];
					this.weekDays  = ['Su','Mo','Tu','We','Th','Fr','Sa'];
		}	
	}
}

/* ====================================== */
var slib = new slibrary();
function slibrary() {
	this.lng = 'en';

//	generates a random password or key
	this.genpass = function (range, passlen) { 
		if (typeof range == "undefined") range = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
		if (typeof passlen == "undefined") passlen = 6;
		var pass = "";
	   for(var x=0, m=range.length; x<passlen; x++)
	   {
	      i = Math.floor(Math.random() * m);
	      pass += range.charAt(i);
	   }
	    return pass;
	}

/*
	this.copyObject = function (obj) {
	    if (typeof obj !== 'object' || obj === null) return obj;
	    try { if (obj instanceof Node || obj instanceof NodeList || obj instanceof NamedNodeMap) return obj; } catch(e){}
	    var a = obj.valueOf ? obj.valueOf() : undefined; 
	    var c = new window[obj.constructor.name](a); 
	    for (var i in obj) if (obj.hasOwnProperty(i)) c[i] = slib.copyObject(obj[i]); 
	    return c; 
	} 
*/
	this.nothing = function() {}
	this.cloneObject = function (obj) { slib.nothing.prototype = obj; return new slib.nothing(); }
	

//	convert YYYY-MM-DD <==> YYddd (used for shorten ID
	this.date2code = function (str) {
		if (str.length > 7) {	// YYYY-MM-DD => YYddd
//			var t = new Date(str);
			var t = new Date(parseInt(str.substr(0,4),10),parseInt(str.substr(5,2),10) -1,parseInt(str.substr(8,2),10));
            var t1 = new Date(t.getFullYear(), t.getMonth(), t.getDate()),
                t2 = new Date(t.getFullYear(), 0, 1);
            var d = Math.round((t1 - t2) / 864e5) + 1;
			var result = slib.pad2(t.getFullYear() - 2000) + d + '';
		} else {				// YYYY-MM-DD <= YYddd
			var t = new Date(2000 + parseInt(str.substr(0,2),10), 0, parseInt(str.substr(2,3),10));
			var result = t.getFullYear() + '-' + (t.getMonth() < 9 ? '0' : '') + (t.getMonth() + 1) + '-' + (t.getDate() < 10 ? '0' : '') + t.getDate(); 
		}		
		return result;
	}

	this.showHide = function (anode, on_off) { // on_off: true | false | toggle (if obmitted)
		var node = (typeof anode == "string") ? getElement.Id(anode) : anode; // tag or node allow
		if (!node) return null;
		if (typeof on_off === "undefined") on_off = (/hidden/i.test(node.className)) ? 1 : 0;
		node.className = on_off ? node.className.replace('hidden','shown') 
								: node.className.replace('shown','hidden'); 
		return on_off;
	}
	
	
	this.validEmail = function(email) {
//		if (email.match(/^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/)) return true;	
		if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,4})+$/.test(email.value)) return true;
		return false;
	}

	this.scrollTo = function(anode, aspeed) {
		var node = (typeof anode == "string") ? getElement.Id(anode) : anode; // tag or node allow
		if (typeof aspeed == "undefined") aspeed = 25;
		if (!node) return;
//		if (node) window.scroll(0,getElement.pos(node).top);
		var startY = getDocumentSize.scrollHeight();
		var stopY  = getElement.pos(node).top;
		var distance = stopY > startY ? stopY - startY : startY - stopY;
		if (distance < 100) { window.scrollTo(0, stopY); return; }
		var speed = Math.round(distance / 100);
		if (speed >= 20) speed = 20;
		var step = Math.round(distance / aspeed);
		var leapY = stopY > startY ? startY + step : startY - step;
		var timer = 0;
		if (stopY > startY) {
	        for ( var i=startY; i<stopY; i+=step ) {
	           setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
	            leapY += step; if (leapY > stopY) leapY = stopY; timer++;
	        } return;
	    }
	   for ( var i=startY; i>stopY; i-=step ) {
	       setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
	       leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
	   }
	}


	this.plainText = function(xStr) {
		var regExp = /<\/?[^>]+>/gi;
		xStr = xStr.replace(regExp,"");
        return xStr;
      }


	this.disableTextSelection = function(elem) {
		if (!elem) return false;
		elem.onselectstart = function() { return false; };
		elem.unselectable = "on";
		elem.style.MozUserSelect = "none";
		elem.style.cursor = "default";
	}


	this.disableClick = function(elem) {
		elem.oncontextmenu = function() { return false; };
		elem.onselectstart = function() { return false; };
		if (window.sidebar)
		{	elem.onmousedown = function() { return false; };
			elem.onclick = function() { return true; };
		}
	}


	this.enableClick = function(obj) {
		obj.onselectstart = function() { return true; };
		obj.oncontextmenu = function() { return true; };
	}


	this.getTableId = function(obj) {
		while (obj && !/table/i.test(obj.nodeName)){ obj = obj.parentNode; }
		return obj || null;
	}


	this.isNumeric = function(numVal) {
		//var RegExp = /^(-)?(\d*)(\.?)(\d*)$/;
		var RegExp = /^[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$/;
		var result = numVal.match(RegExp);
		return (result == null ? false : true);
	}

	this.roundNumber = function (rnum, rlength) { // Arguments: number to round, number of decimal places
		if (typeof rlength === "undefined") rlength = 0;
		var newnumber = Math.round(rnum*Math.pow(10,rlength))/Math.pow(10,rlength);
		return newnumber;
	}

	this.pad2 = function (number) { return (number < 10 ? '0' : '') + +number + ''; } 

	this.oBrowserInfo = function() {
		var aVersion = navigator.appVersion;
		var uAgent = navigator.userAgent;
		this.opera = uAgent.indexOf("Opera") >= 0;
		this.safari = aVersion.indexOf("Safari") >= 0;
		this.khtml = (aVersion.indexOf("Konqueror") >= 0) || (aVersion.indexOf("Safari") >= 0);
		this.mozilla = (uAgent.indexOf("Gecko") >= 0) && (!this.khtml);
		this.ie = (document.all) && (!this.opera);
		if (!this.ie) { this.ie = false; }
		this.ie50 = this.ie && aVersion.indexOf("MSIE 5.0")>=0;
		this.ie55 = this.ie && aVersion.indexOf("MSIE 5.5")>=0;
		this.ie60 = this.ie && aVersion.indexOf("MSIE 6.0")>=0;
		this.ie70 = this.ie && aVersion.indexOf("MSIE 7.0")>=0;
	}
	var browser = {};
	this.browser = new this.oBrowserInfo();


	/*----------------------------------------------------------------------*/
	// install a javascript file at the end of the HEAD tag
	this.loadjavafile = function (filename, callback, id, async, tag){
		if (typeof callback == "undefined") callback = null;
		if (typeof id       == "undefined") id       = null;
		if (typeof async    == "undefined") async    = false;
		if (id && document.getElementById(id)) return false; // already loaded
		var el = document.createElement('script');
		el.type  = "text/javascript"; 
		el.async = async;
		el.src   = filename;
		if (id) el.setAttribute("id", id);
		if (callback) {
			if (el.readyState) { // IE
				el.onreadystatechange= function () { 	
					if (el.readyState=="complete" || el.readyState=="loaded") { el.onreadystatechange = null; callback(); }
					};
			} else { // other
				el.onload = function () { callback(); };
			}	
		}	
		if (typeof tag == "undefined") { document.getElementsByTagName("head")[0].appendChild(el); } else 
		   { var p = document.getElementsByTagName(tag)[0]; p.parentNode.insertBefore(el,p); }
		return true;
	}


	/*----------------------------------------------------------------------*/
	// install a css stylesheet at the end of the HEAD tag
	this.loadcssfile = function (filename, id){
		if (typeof id == "undefined") id = null;
		if (id && document.getElementById(id)) return false;
		var el=document.createElement("link")
		el.setAttribute("rel", "stylesheet")
		el.setAttribute("type", "text/css")
		el.setAttribute("href", filename)
		if (id) el.setAttribute("id", id);
		if (typeof el != "undefined") document.getElementsByTagName("head")[0].appendChild(el)
		return true;
	}


	/*----------------------------------------------------------------------*/
	// remove a javascript or stylesheet from HEAD tag
	this.removejscssfile = function (filename, filetype){
		var targetfile = [];
		if (filename.indexOf("?") < 0) { targetfile[0] = filename; } else { targetfile = filename.split("\?"); } // ignore things after '?'
		var targetelement = (filetype=="js")? "script" : (filetype=="css")? "link" : "none";  //determine element type to create nodelist from
		var targetattr    = (filetype=="js")? "src"    : (filetype=="css")? "href" : "none";  //determine corresponding attribute to test for
		var allsuspects   = document.getElementsByTagName(targetelement);
		for (var fn,i=allsuspects.length; i>=0; i--) 				  //search backwards within nodelist for matching elements to remove
		     if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null) {   
			    fn = allsuspects[i].getAttribute(targetattr);
			if (fn.substr(0,targetfile[0].length) == targetfile[0])
			    allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
		}
	}


	/*----------------------------------------------------------------------*/
	this.cookie = function () {
		var cookieEnabled = (navigator.cookieEnabled) ? true : false
		//if not IE4+ nor NS6+
		if (typeof navigator.cookieEnabled=="undefined" && !cookieEnabled){ 
			document.cookie="test";
			cookieEnabled=(document.cookie.indexOf("test")!=-1)? true : false
			this.setCookie("test","","delete");
		}
		return cookieEnabled;
	}
	
	this.getCookie = function (cookieName) {
	/* retrieved in the format 	cookieName4=value; cookieName3=value; cookieName2=value; cookieName1=value 	only cookies for this domain and path will be retrieved */
		var cookieJar = document.cookie.split( "; " );
		for( var x = 0; x < cookieJar.length; x++ ) {
			var oneCookie = cookieJar[x].split( "=" );
			if( oneCookie[0] == escape( cookieName ) ) { return unescape( oneCookie[1] ); }
		}
		return null;
	}

	this.setCookie = function (cookieName, cookieValue, lifeTime, path, domain, isSecure) {
		if( !cookieName ) { return false; }
		if( lifeTime == "delete" ) { lifeTime = -10; } //this is in the past. Expires immediately.
		/* This next line sets the cookie but does not overwrite other cookies.
		syntax: cookieName=cookieValue[;expires=dataAsString[;path=pathAsString[;domain=domainAsString[;secure]]]]
		Because of the way that document.cookie behaves, writing this here is equivalent to writing
		document.cookie = whatIAmWritingNow + "; " + document.cookie; */
		document.cookie = escape( cookieName ) + "=" + escape( cookieValue ) +
			( lifeTime ? ";expires=" + ( new Date( ( new Date() ).getTime() + ( 1000 * lifeTime ) ) ).toGMTString() : "" ) +
			( path ? ";path=" + path : "") + ( domain ? ";domain=" + domain : "") + 
			( isSecure ? ";secure" : "");
		//check if the cookie has been set/deleted as required
		if( lifeTime < 0 ) { if( typeof( this.getCookie( cookieName ) ) == "string" ) { return false; } return true; }
		if( typeof( this.getCookie( cookieName ) ) == "string" ) { return true; } return false;
	}

	this.delCookie = function (cookieName) {
		this.setCookie(cookieName,"","delete");
	}	

	/*----------------------------------------------------------------------*/
	this.encodeForm = function (theForm, fields) {
//	if formname = null, fields contain a plain list of nodeID
//	if fields is null, all formfields are used.
//	cooki-format: id=field,id=field,id=field,...
		var fe = null;
		if (typeof fields == "undefined") fields = null;
		if (theForm &&  theForm.elements) fe = theForm.elements; // theForm is object,e.a. this
		if (theForm && !theForm.elements) fe = document.forms[theForm].elements; // theForm is string
		var cooki = '';
		if (fields) for (var i in fields) {		// with fieldname array
			var oE = fe ? fe[fields[i]] : getElement.Id(fields[i]);
			if (oE) cooki += ',' + getOneElement(oE);
			} // end for

		if (fe && !fields) for (var i=0; i < fe.length; i++) {	// all formfields
			cooki += ',' + getOneElement(fe[i]);
			} // end for
		console.log(cooki.slice(1));	
		return cooki.slice(1);
	
		function getOneElement(oE) {
			var field = '';
			if (!oE.type) return field;
			var oT = oE.type.toLowerCase();
			switch (oT) {
				case "select-one": field = oE.selectedIndex; // break;
				case "text": case "hidden": 
				case "textarea": // replace % -> %p and , -> %c
					  try { field = oE.value.replace(/~/g,'~t').replace(/,/g,'~c').replace(/=/g,'~e'); } catch(e){;} 
					  break;
				case "checkbox": case "radio":
					  field = oE.checked ? '1' : ''; break;
				case "select-multiple": var oO = oE.options;
					  for (var i = 0, s = ''; oO[i]; i++ ) s += oO[i].selected ? '|'+i : '';
					  if (s.length) field = s.slice(1); break;
				// ignore: password, button, image, reset, submit, file
			}
			return oE.name + '=' + field;
		} // end func
	}


	this.decodeForm = function (cooki, setfield, aform) {
//	cooki-format: id=field,id=field,id=field,...
//	sets fields and return 2-dim array
		if (!cooki) return false;
		if (typeof setfield == "undefined") setfield = true;
		if (typeof aform == "undefined") aform = null;
		var arr = new Array();
		var coo = cooki.split(',');
		for (var c=0; c<coo.length; c++) {
			arr[c] = coo[c].split('=');
			try { arr[c][1] = arr[c][1].replace(/~e/g,'=').replace(/~c/g,',').replace(/~t/g,'~'); } catch(e){;}  
			var oE = document.getElementsByName(arr[c][0]);
			for (var e=0; e < oE.length; e++) {
				if (aform && oE[e].form && oE[e].form.name != aform.name) continue;
				if (oE[e] && setfield) setOneElement(oE[e], arr[c][1]);
			}
		}
		console.log(arr);
		return arr;

		function setOneElement(oE, val) {
			if (!oE.type) return false;
			var oT = oE.type.toLowerCase();
			switch (oT) {
				case "text": case "hidden": case "file": 
				case "textarea": 
					  oE.value = val; break;
				case "checkbox": case "radio":
					  oE.checked = val ? true : false; break;
				case "select-one": 
//					  oE.selectedIndex = +val; break; 
					  for (var i=0; i < oE.options.length; i++) if (oE.options[i].value == val) oE.selectedIndex = i; 
					  break;
				case "select-multiple": 
					  var oO = oE.options;
					  var opt = val.split('|');
					  for (var i = 0, s = ''; oO[i]; i++ ) oO[i].selected = false;
					  if (val.length) for (var i=0; i<opt.length; i++) { 
					  oO[+opt[i]].selected = true;
					   }
					  break;
				// ignore: password, button, image, reset, submit
			}
			return true;
		} // end func
	}

	/*----------------------------------------------------------------------*/
	this.getMousePos = function (e) {
		var xRel=0,xPos=0,xMax=0;
		var yRel=0,yPos=0,yMax=0;
		var evt = window.event || e;
	   	if (!evt.target) evt.target = evt.srcElement;
		// relative to target element
		var xRel = evt.layerX? evt.layerX : evt.offsetX? evt.offsetX : 0; // +document.body.scrollLeft
		var yRel = evt.layerY? evt.layerY : evt.offsetY? evt.offsetY : 0; // +document.body.scrollTop
		// absolute to document
		if (evt.pageX || evt.pageY) { 						// NON-IE
			xPos = evt.pageX; 
			yPos = evt.pageY; 
	        xMax = window.innerWidth +window.pageXOffset;
	        yMax = window.innerHeight+window.pageYOffset;
		} else if (evt.clientX || evt.clientY) {			// for IE
			xPos = evt.clientX; + document.body.scrollLeft;
			yPos = evt.clientY; + document.body.scrollTop;
			if (document.documentElement) { xPos += document.documentElement.scrollLeft;
											yPos += document.documentElement.scrollTop; }
	        xMax = document.body.clientWidth +document.body.scrollLeft + document.documentElement.scrollLeft;
	        yMax = document.body.clientHeight+document.body.scrollTop  + document.documentElement.scrollTop;
		}
//		window.status = 'x='+xPos + ' y='+yPos + ' xrel='+xRel + ' yrel='+yRel;
//		alert([evt.pageY,evt.clientY,document.body.scrollTop,document.documentElement.scrollTop]);
		return {x:xPos, y:yPos, xRel:xRel, yRel:yRel, xMax:xMax, yMax:yMax, target:evt.target};
	}

	/*----------------------------------------------------------------------*/
	this.Debugger = function(w,h,mouse) {
		var divElm = document.createElement("div");
			divElm.setAttribute("name", "DEBUG_MESSAGE");
			divElm.setAttribute("id", "DEBUG_MESSAGE");
			divElm.style.width = w + 'px';
			divElm.style.height = h + 'px';
			divElm.style.right = '10px';
			divElm.style.top = '10px';
			divElm.style.position = 'absolute';
			divElm.style.borderStyle = 'solid';
			divElm.style.borderWidth = '2px';
			divElm.style.borderColor = 'black';
			divElm.style.backgroundColor = 'white';
			divElm.style.zIndex = '10000';
			divElm.style.overflow = 'auto';
			document.body.appendChild(divElm);
		if (!divElm) { return; }
		var tblElm =	'<table style="width:100%;height:100%;textalign:left;font-size:10px">' + 
						'<tr><th style="cursor:move;height:15px;background-color:black;color:white;" id="DEBUG_MESSAGE_HEADER">Debug Windows</th></tr>' + 
						'<tr><td style="width=100%;height=100%" valign=top id="DEBUG_MESSAGE_CONTAINER"></td></tr>' +
						'</table>';
		divElm.innerHTML = tblElm;
		if (mouse) {
			if (document.layers) { document.captureEvents(Event.MOUSEMOVE); document.onmousemove = this.DebugMouse; // Netscape
			} else if (document.all) { document.onmousemove = this.DebugMouse; // Internet Explorer
			} else if (document.getElementById) { document.onmousemove = this.DebugMouse; // Netcsape 6
			}
		}
	}

	this.Debug = function (txt) {
		if(typeof obj == "object") txt = slib.print_r(txt);
		var p = document.getElementById("DEBUG_MESSAGE_CONTAINER");
		if (p) p.innerHTML = p.innerHTML + txt + "<br>";
		return p;
	}

	this.DebugMouse = function(e) {
//		alert(e);
//		document.onmousemove = null;
		var m = slib.getMousePos(e);
		var s = "Mouse: x=" + m.x + ", y=" + m.y + ",<br> xMax=" + m.xMax + ", yMax=" + m.yMax + ",<br> xRel=" + m.xRel + ", yRel=" + m.yRel;
		var p = document.getElementById("DEBUG_MESSAGE_HEADER");
		if (p) p.innerHTML = s;
		window.status = s;
//		setTimeout( function() { document.onmousemove = slib.DebugMouse; }, 100);
	}

	this.var_dump = function (obj) {
	   if(typeof obj == "object") {
	      return "Type: "+typeof(obj)+((obj.constructor) ? "\nConstructor: "+obj.constructor : "")+"\nValue: " + obj;
	   } else {
	      return "Type: "+typeof(obj)+"\nValue: "+obj;
	   }
	}

	this.print_r = function(x, max, sep, l) {
		l = l || 0;
		max = max || 10;
		sep = sep || ' ';
		if (l > max) { return "[WARNING: Too much recursion]\n"; }
		var i,r = '',t = typeof x,tab = '';
		if (x === null) { r += "(null)\n"; } else if (t == 'object') {
			l++; for (i = 0; i < l; i++) { tab += sep; }
			if (x && x.length) { t = 'array'; }
			r += '(' + t + ") :\n";
			for (i in x) { try { r += tab + '[' + i + '] : ' + this.print_r(x[i], max, sep, (l + 1)); } catch(e) { return "[ERROR: " + e + "]\n"; } }
		} else {
			if (t == 'string') { if (x == '') {	x = '(empty)'; } }
			r += '(' +  t + ') ' + x + "\n";
		}
		return r;
	};


	/*----------------------------------------------------------------------*/
	this.eTrack = {
		start: function (sideid,ipaddr,msec,ajurl) {	
			this.nn = 0;
			this.ms = (typeof msec  == "undefined") ? 10000 : msec;
			this.aj = (typeof ajurl == "undefined") ? "aj_etrack.php" : ajurl;
			this.ip = ipaddr;
			this.id = sideid;
			this.ajax("START");
		 	this.timer = setTimeout(slib.eTrack.ping,slib.eTrack.ms);
			addEvent(window, 'beforeunload', function(){slib.eTrack.stop()});
		},		
		ping: function () {
			slib.eTrack.ajax("PING"); slib.eTrack.nn += (slib.eTrack.ms/1000);
			if (slib.eTrack.nn > 3600) { slib.eTrack.stop(); return } 
			slib.eTrack.timer = setTimeout(slib.eTrack.ping,slib.eTrack.ms);
		},
		stop: function (){
			clearTimeout(slib.eTrack.timer);
		    slib.eTrack.ajax("STOP");
			return;
		},
		ajax: function (signal){
			var params = "sig=" + signal + "&ip=" + slib.eTrack.ip + "&id=" + slib.eTrack.id;
			params += "&ref=" + encodeURIComponent(window.location.href);
			var ajax = new ajaxObject (slib.eTrack.aj);
			ajax.callback = function (responseText,responseXML,responseStatus) { }
//			console.log([params,slib.eTrack]);
			ajax.update(params,"GET");
		}
	} 	// end of eTrack


	/*----------------------------------------------------------------------*/
	this.flyer = {
		cloneId: "flyClone",
//		speedZ: 40,
		clean: function () { with (slib.flyer) {
			if (clone.id == cloneId) clone.parentNode.removeChild(clone);
		}},
		mover: function () { with (slib.flyer) {
			x += stepX; y += stepY; 
			dx -= Math.abs(stepX);
			dy -= Math.abs(stepY);
		    clone.style.left = Math.round(x) + "px";
		    clone.style.top  = Math.round(y) + "px";
			if (dx + dy < 1) { slib.flyer.clean(); return }
			setTimeout( function() { slib.flyer.mover(); }, slib.flyer.timeout);
		}},
		start: function (anode, bnode, aclone, aspeed, zspeed){
			if (typeof aclone == "undefined") aclone = true;
			this.timeout = (typeof aspeed == "undefined") ? 10 : aspeed;
			this.speedZ  = (typeof zspeed == "undefined") ? 40 : zspeed;
			this.objS = (typeof anode == "string") ? getElement.Id(anode) : anode; // tag or node allow, source
			this.objT = (typeof bnode == "string") ? getElement.Id(bnode) : bnode; // tag or node allow, destination
			if (!this.objS || !this.objT) return;
			this.posS = getElement.pos(this.objS);
			this.posT = getElement.pos(this.objT);

			if (!aclone) { this.clone = this.objS } else {
				this.clone = this.objS.cloneNode(true);
				this.clone.id = this.cloneId;
				this.objS.parentNode.insertBefore(this.clone,this.objS);
			}	
			this.clone.style.zIndex = '50';
			this.clone.style.position = 'absolute';
		    this.clone.style.left = (this.posS.left) + "px";
		    this.clone.style.top  = (this.posS.top ) + "px";

			this.distX = Math.abs(this.posT.left - this.posS.left);
			this.distY = Math.abs(this.posT.top  - this.posS.top);
			this.distZ = Math.round(Math.max(this.distX,this.distY) / this.speedZ);	
			this.factX = (this.posT.left < this.posS.left) ? -this.distZ : this.distZ;
			this.factY = (this.posT.top  < this.posS.top)  ? -this.distZ : this.distZ;
			this.stepX = this.factX * ((this.distX < this.distY) ? this.distX/this.distY : 1);
			this.stepY = this.factY * ((this.distY < this.distX) ? this.distY/this.distX : 1);

			this.x = this.posS.left;
			this.y = this.posS.top;
			this.dx = this.distX;
			this.dy = this.distY;
			this.mover();
		},
		run: function () { slib.flyer.mover() }
	}

	/*----------------------------------------------------------------------*/
	this.dragger = function() {
		dragElements = getElement.Class('slib-draggable');
		for (var i=0; i<dragElements.length; i++) {
			dragAnchor = getElement.Class('slib-dragger',dragElements[i]);		
			if (!dragAnchor.length) dragAnchor[0] = dragElements[i];
			for (var j=0; j<dragAnchor.length; j++) 
			{	dragAnchor[j].dragObject = dragElements[i];
				dragAnchor[j].onmousedown = function(e) { return slib.dragStart(e,this) };
				dragAnchor[j].style.cursor = 'move';
			    if (slib.browser.ie60) dragAnchor[j].style.position = 'absolute';
			}
		}	
	}

	this.dragStart = function(event,dragger) { 
		dragObj = dragger.dragObject;
		dragObj.cur = slib.getMousePos(event);	// mouse pos
	//	while (dragObj && !multiClassName.test(dragObj,'slib-draggable')){ dragObj = dragObj.parentNode; }
		dragObj.pos = getElement.pos(dragObj); // pos.element start
		if (dragObj.style.position != 'absolute' && dragObj.style.position != 'fixed')
		{	var overlay = dragObj.cloneNode(false);
			if (overlay.id) overlay.id += 'clone';
			overlay.style.visibility = 'hidden';
			dragObj.placeHold = overlay;
			insertAfter(overlay,dragObj);
			dragObj.style.position = 'absolute';
		}	
		dragObj.style.zIndex = '50';
		if (slib.browser.ie60) dragObj.style.position = 'absolute';
	    dragObj.style.left = (dragObj.pos.left) + "px";
	    dragObj.style.top  = (dragObj.pos.top ) + "px";
		dragObj.onclickClone= dragObj.onclick;
		dragObj.onmousemove = function(e) { return slib.dragMove(e,this) };
		dragObj.onmouseup   = function(e) { return slib.dragStop(e,this) };
		dragObj.onmouseout  = function(e) { console.log("out");return slib.dragMove(e,this) };
		return false; 
	}

	this.dragMove = function(event,dragObj) { 
		var cur = slib.getMousePos(event);
	    dragObj.style.left = (cur.x - dragObj.cur.x + dragObj.pos.left) + "px";
	    dragObj.style.top  = (cur.y - dragObj.cur.y + dragObj.pos.top ) + "px";
//		console.log([dragObj.style.left, dragObj.style.top]);
		dragObj.onclick     = function(){}
	    return false;
	}

	this.dragStop = function(event,dragObj) { 
		dragObj.onmousemove = function(){}
		dragObj.onmouseup   = function(){}
		dragObj.onmouseout  = function(){}
		if (dragObj.onclickClone) dragObj.onclick = dragObj.onclickClone;
		evtSet(event);
	    return false;
	}

	/*----------------------------------------------------------------------*/
	this.lightbox = {
		oTag : "overlayPAGE",
		bTag : "overlayBOX",
		cssDiv : "position:absolute;top:  0;bottom:0%;left:0 ;right:0%;z-index: 999;background-color:white;opacity:.70;filter:alpha(opacity=70);-moz-opacity:0.7;",
		cssBox : "position:absolute;top:30%;bottom:0%;left:0%;right:0%;z-index:1000;font-family:Arial;font-size:12pt;color:black;border-color:gray;border-style:solid;border-width:3px;background-color:white;text-align:center; ",
		// set addition styles for overlay and popup if (typeof Div != "undefined") 
		css: function (Box,Div) {	
			 if (typeof Div == "undefined") Div = '';	
			 if (typeof Box == "undefined") Box = '';	
			 this.cssDivStyle = Div;	
			 this.cssBoxStyle = Box;	
		},		

		// set size of popup or 50%-auto if 0		
		size: function (width,height) {
			 if (typeof width  == "undefined") width  = 300;
			 if (typeof height == "undefined") height = 80;
			 this.BoxSize = {}
			 this.BoxSize.width  = width;
			 this.BoxSize.height = height;
		},
		
		open: function (content,boxOnly){
			if (typeof boxOnly  == "undefined") boxOnly = false;
			if (typeof this.cssBoxStyle == "undefined") this.cssBoxStyle = '';
			if (typeof this.BoxSize== "undefined") this.BoxSize = {width:300,height:80};
			if (!getElement.Id(this.oTag)) {
				var overlay	= document.createElement('div');
				overlay.setAttribute("id", this.oTag);
				overlay.style.cssText = this.cssDiv; // + ';background-color:#333333; ';
				if (typeof this.cssDivStyle != "undefined") overlay.style.cssText += this.cssDivStyle;
//				overlay.style.height = '3000px'; // Change to dynamic!!
				overlay.style.height = getDocumentSize.height() + 'px';
				overlay.style.width = getDocumentSize.width() + 'px';
				overlay.style.top = getDocumentSize.scrollHeight() + 'px';
				if (!boxOnly) document.body.appendChild(overlay);
			}	
			if (!getElement.Id(this.bTag)) {
				var box = document.createElement('div');
				box.setAttribute("id", this.bTag);

				box.className= "overlayBOX";
				box.style.cssText = this.cssBox;// + ';background-color:white; text-align:left; ';
				box.style.cssText += this.cssBoxStyle;
				document.body.appendChild(box);
			}	
//			var tableBegin = '<table style="width:100%;height:100%;"><tr><td style="width=100%;height=100%" valign="middle" align="center">';
//			var tableEnd = '</td></tr></table>';
//			if (box && typeof(content) === "string") box.innerHTML = tableBegin + content+ tableEnd;
			if (box && typeof(content) === "string") box.innerHTML = content;
			if (box) box.onclick = function() { slib.lightbox.close(); };
			var x = (getDocumentSize.width()  - this.BoxSize.width ) / 2;
			var y = (getDocumentSize.height() - this.BoxSize.height) / 2;
			box.style.width  = this.BoxSize.width  + 'px';
			box.style.height = this.BoxSize.height + 'px';
			box.style.left = Math.round(x) + 'px';
			box.style.top = getDocumentSize.scrollHeight() + Math.round(y) + 'px';
			return box;
		},

		close: function(){
			this.init();
		},
		
		init: function(){
			this.cssDivStyle = '';
			this.cssBoxStyle = '';	
			this.cssBoxSize  = '';
			var node = getElement.Id(this.bTag);
	      	if (node) node.parentNode.removeChild(node);
			var node = getElement.Id(this.oTag);
	      	if (node) node.parentNode.removeChild(node);
		}
		
	} 	// end of lightbox


	/*----------------------------------------------------------------------*/
	this.toolboxTimer = null; // timeout object for toolbox
	this.toolbox = {
		bTag   : "slibToolbox",
		cssOvl : "position:absolute; z-index:899; ",
		cssBox : "position:absolute; left:10px; top:10px; z-index:888; ",
		cssBox2: "font-family:Arial; font-size:12px; color:#FF0000; padding:3px; \
				  border:2px solid; border-color:#C0C0C0 #999999 #999999 #C0C0C0; background-color:#D0D0D0; ",
		mouse: function (e) {
			var evt = window.event || e;
			var xPos=0,yPos=0;
			if (evt.pageX || evt.pageY) { 						// NON-IE
				xPos = evt.pageX; 
				yPos = evt.pageY; 
			} else if (evt.clientX || evt.clientY) {			// for IE
				xPos = evt.clientX; + document.body.scrollLeft;
				yPos = evt.clientY; + document.body.scrollTop;
				if (document.documentElement) { xPos += document.documentElement.scrollLeft;
												yPos += document.documentElement.scrollTop; }
			}
			return {left:xPos, top:yPos};
		} ,
		test: function (anode) {
			var node = (typeof anode == "string") ? getElement.Id(anode) : anode; // tag or node allow
			if (!getElement.Id(this.bTag)) return 0; // no toolbox open
			return (this.thenode == node) ? 1 : -1; // this or another node has open toolbox
		},
		open: function (anode, className, useEvent, anchor){
			var node = (typeof anode == "string") ? getElement.Id(anode) : anode; // tag or node allow
			this.pin  = (typeof anchor == "undefined") ? null : ((typeof anchor == "string") ? getElement.Id(anchor) : anchor); 
			if (typeof useEvent == "undefined") useEvent = 0;
			if (!node) return null;
			clearTimeout(slib.toolboxTimer); // stop time if mouse move back to trigger element
			this.timeout = 1000; // default 1 sec
			this.offset = {left:25,top:1}
			this.position = useEvent ? this.mouse(useEvent) : getElement.pos(node); 
			if (this.pin) this.position = getElement.pos(this.pin);
//			console.log(this.position);
			if (typeof className == "undefined") className = null;
			if (getElement.Id(this.bTag)) { if (this.thenode == node) { this.callback(this); return this.thebox } this.close(); }
			var box = document.createElement('div');
			box.setAttribute("id", this.bTag);
			box.style.cssText = this.cssBox;
			if (className) { box.className= className; } else { box.style.cssText += this.cssBox2; }
			box.style.left = (this.position.left + this.offset.left) + 'px';
			box.style.top  = (this.position.top  + this.offset.top ) + 'px';
			box.style.display = 'block';
			document.body.appendChild(box);
//			if (this.pin) { this.pin.appendChild(box) } else { node.appendChild(box) } // problem with mouseout
			this.thebox  = box;	
			this.thenode = node;	
			node.onmouseout = function() { slib.toolboxTimer = setTimeout( function() { slib.toolbox.close(); }, slib.toolbox.timeout); }
			box.onmouseout  = function() { slib.toolboxTimer = setTimeout( function() { slib.toolbox.close();  }, slib.toolbox.timeout); }
			box.onmouseover = function() { clearTimeout(slib.toolboxTimer); } // stop time if mouseover the toolbox
			this.callback = function () { }; // add callback function for toolbox.close()
			return box;
		} ,
		pos: function(x,y){
			this.offset.left = x; 
			this.offset.top  = y;
			this.thebox.style.left = (this.position.left + this.offset.left) + 'px';
			this.thebox.style.top  = (this.position.top  + this.offset.top ) + 'px';
			return this.thenode;
		} ,
		html: function(html){
			if (!this.thebox) return false;
			this.thebox.innerHTML = html;
			slib.toolbox.relocate(this.thebox);
			return this.thebox;
		} ,
		img: function(src, oTxt){
			if (!this.thebox) return false;
			if (getElement.Id(this.bTag+ 'img')) return this.thebox;
			if (typeof oTxt == "undefined") oTxt = null;
			if (oTxt) 
			{	var	oSpan = document.createElement('span');
				oSpan.setAttribute("id", this.bTag + 'span' );
				oSpan.style.cssText = this.cssOvl;
				oSpan.innerHTML = oTxt;
				this.thebox.appendChild(oSpan);
			}
			var	oImg = document.createElement('img');
			oImg.onload = function() { var that=this, wait=this.offsetHeight ? 0:50; // IE cache bug
						setTimeout(function() {slib.toolbox.relocate(that)}, wait); return;	 }		
			oImg.setAttribute('src', src);
			oImg.setAttribute("id", this.bTag + 'img' );
			this.thebox.appendChild(oImg);
			return this.thebox;
		} ,
		close: function(){
			if (this.thenode) this.thenode.onmouseout = function(){}
			if (this.thebox ) this.thebox.onmouseout  = function(){}
			if (this.thebox ) this.callback(this);
//			if (that) that.onmouseout = function(){}
			var box = getElement.Id(this.bTag);
			if (box) box.style.display = 'none';
	      	if (box) box.parentNode.removeChild(box);
	      	this.thebox = null;
	      	return false;
		} ,
		relocate: function(obj) { 
			var box = slib.toolbox.thebox; if (!box) return false;
			if (slib.toolbox.pin) return true;
			var pos =  slib.toolbox.position; //getElement.pos(box);
			var posY = pos.top - getDocumentSize.scrollHeight() + obj.offsetHeight;
			if (posY > getDocumentSize.height()) slib.toolbox.thebox.style.top  = (pos.top   - obj.offsetHeight) + 'px';   
			var posX = pos.left - getDocumentSize.scrollWidth() + obj.offsetWidth;
			if (posX > getDocumentSize.width()) slib.toolbox.thebox.style.left  = (pos.left  - obj.offsetWidth - this.offset.left)  + 'px';   
			return true; 
		}
	} 	// end of toolbox


}; // end of slib


if (typeof selOptions === "undefined") { 
    selOptions = { add: function(sel, val, txt) {    
					if (typeof sel !== "object") return false;
					var	option = document.createElement('option');
					option.text = txt; option.value = val;	
					try      { sel.add(option , null); }
					catch(e) { sel.add(option ); } // IE
					return option;
				} ,
				clear: function (sel) {
					if (typeof sel !== "object") return false;
					sel.options.length = 0;
					while (sel.firstChild) sel.removeChild(sel.firstChild);
					return true;
				} ,
				select: function (sel, val) {
					if (typeof sel !== "object") return false;
				    for (var ii=-1,i=0; i < sel.options.length; i++) if (sel.options[i].value == val) { sel.selectedIndex = i; ii=i; }; 
					return ii;
				} 
		     }; 
}

/*----------------------------------------------------------------------*/
function genLandmarkOptions (node, responseXML, removeFirst) {
	var col = new Array('#FFFFDD','#DDFFDD','#FFDDDD','#DDFFFF','#FFFFFF');
	var master 		= responseXML.getElementsByTagName('landmarks')[0]; 
	var landmarks 	= responseXML.getElementsByTagName('landmark');	  	
	var groups 		= responseXML.getElementsByTagName('groupLandmark');
	var i,j,name,area,o = 0;
	var sel = (typeof node == "string") ? getElement.Id(node) : node; // tag or node allow
	if (!sel) return false;

	if (typeof removeFirst == "string") {
		sel.options.length = 0;
		while (sel.firstChild) sel.removeChild(sel.firstChild);
		var	option = document.createElement('option');
		option.text = removeFirst; option.value = '0';	
		try      { sel.add(option , null); }
		catch(e) { sel.add(option ); } // IE
	}

	for(var i= 0; sel && i < groups.length ; i++ ) {
		var labelgroup = groups[i].attributes.getNamedItem('label') ;
		var name   = labelgroup.value ;
		var option = document.createElement('optgroup');
		option.label = name ;
		option.style.backgroundColor = col[o]  ;
		try      { sel.appendChild(option , null); }
		catch(e) { sel.appendChild(option ); } // IE
		//----------------------------------------------//
		lands  = groups[i].getElementsByTagName("landmark") ;
		for(var j=0;j< lands.length;j++ ) {
			var name = lands[j].firstChild.nodeValue;
			var area = lands[j].attributes.getNamedItem('area').value ;
			var option2 = document.createElement('option');
			option2.text 	= name ;
			option2.value 	= area ;	 
			option2.style.backgroundColor = col[o]  ;
			try      { sel.add(option2 , null); }
			catch(e) { sel.add(option2 ); } // IE
			} // end for(j)
			//----------------------------------------------//
		o = (o + 1) % 4;
		} // end for(i)  		
	return true;
}

/*----------------------------------------------------------------------*/
// new Ajax object, concurrency enabled. Proxy support for GET.
// ProxyDestination domain/path is not supported due to security reason. Hardcode it in the proxy.
function ajaxObject(url, callbackFunction, proxyUrl, proxyType) { // default type is 'xml'
	if (typeof proxyUrl  == "undefined") proxyUrl  = null;
	if (typeof proxyType == "undefined") proxyType = 'xml'; // htm
	proxyType = (/xml/i.test(proxyType)) ? "xml" : "htm";
	var that=this;      
	this.updating = false;
	this.abort = function() 
	{	if (that.updating) 
		{	that.updating=false;
			that.AJAX.abort();
			that.AJAX=null;
		}
	}
	this.update = function(passData,postMethod) 
	{ 	if (that.updating) { return false; }
		if (that.jsonp) { return this.jsonpObject(passData) } // jsonp support added
		that.AJAX = this.GetXmlHttpObject();                          
		if (that.AJAX==null) { return false; } else 
		{	that.AJAX.onreadystatechange = function() 
			{  	if (that.AJAX.readyState==4 || that.AJAX.readyState=="complete") 
				{	that.updating=false;                
					if (that.AJAX.status == 200) { that.callback(that.AJAX.responseText, that.AJAX.responseXML, that.AJAX.status); }
											else { that.onError (that.AJAX.status, that.AJAX.statusText); }
					that.AJAX=null;                                         
				}                                                      
			}                                                        
			that.updating = new Date();                              
			if (/post/i.test(postMethod)) 
			{	var uri=urlCall;
				if (that.cache==0) uri += '?'+that.updating.getTime();
				that.AJAX.open("POST", uri, true);
				that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
//				that.AJAX.setRequestHeader("Content-Length", passData.length);
				that.AJAX.send(passData);
			} else {
				var uri = urlCall+'?'+passData;
				if (proxyUrl) uri = proxyUrl+ '?p' + proxyType+ '=' + uri;
				if (that.cache==0) uri = uri + '&timestamp='+(that.updating.getTime()); 
				that.AJAX.open("GET", uri, true);                             
				that.AJAX.send(null);                                         
			}              
			return true;                                             
    	}                                                                           
  	}
	var urlCall = url;    
	this.onError = function () { };
	this.callback = callbackFunction || function () { };
	this.dataset = null; // can be used to pass external variables in an array
	this.cache = 0;

	this.GetXmlHttpObject = function() {
		 var crossxhr = false;
		 var mime = (proxyType == 'xml') ? 'text/xml' : 'text/html';
		 if (window.XMLHttpRequest) {         // Firefox, Opera 8.0+, Safari
		    crossxhr = new XMLHttpRequest();
		    if (crossxhr.overrideMimeType) { crossxhr.overrideMimeType(mime); }
		 } else if (window.ActiveXObject) {   // Internet Explorer 
		  try { crossxhr = new ActiveXObject('Msxml2.XMLHTTP');  } catch(e) {
		  try { crossxhr = new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) { crossxhr = false;  } } 
		 }
		 return crossxhr;
	}
	
	this.jsonpObject = function(passData) {
		that.updating = new Date();
		that.jsonid = "jsonp" + that.updating.getTime();
		that.jsonpara = "?jsonaj=" + encodeURIComponent(urlCall) + "&jsonid=" + that.jsonid + "&" + passData;
		slib[that.jsonid] = that.callback;
		slib.loadjavafile(that.jsonp + that.jsonpara);
//		console.log(that);
	}	
}
// example origional ajax:                     aj_hotellist.php?  p=test&region=chumphon
// pxy1.php? phtm=http://www.sawadee.com/R24n/ aj_hotellist.php?  p=test&region=chumphon		[ proxy = pxy1.php      | path=http://www.sawade.com/R24n/ ]


/*----------------------------------------------------------------------*/
function autoSlider (node, callback, firstDelay) {
	var that = this;      
	if (typeof firstDelay  == "undefined") firstDelay = 3;
	this.obj = (typeof node == "string") ? getElement.Id(node) : node; // tag or node allow
	if (typeof callback == 'function') {
		this.obj.onmouseover = function(e) { var evt = window.event || e; if (!evt.target) evt.target = evt.srcElement; return  callback(evt,that); }
		this.obj.onmouseout  = function() { that.startSlider(); }
	}	
	this.direction = 0, this.counter = 0, this.timeOutID = null;
	this.dynscroll = this.obj.scrollWidth - this.obj.clientWidth;
	var d = new Date();
	var start = d.getTime(); 
	for (var i = 0; i < 200; i++){} 
	var e = new Date();
	var stop = e.getTime(); 
	var diff = stop - start;
	this.delay = (diff > 0) ? Math.round(10 * (1/diff)) : 10;

	this.moveSlider = function() {
					if (that.direction == 0) {
						that.obj.scrollLeft = that.counter++;
						if (that.counter > that.dynscroll + 100) { that.direction = 1; }
					} else {
						that.obj.scrollLeft = that.counter--;
						if (that.counter  < -100) { that.direction = 0; }
					}
					that.timeOutID = setTimeout(arguments.callee, that.delay);
				}
	this.stopSlider  = function() { if ( that.timeOutID) { clearTimeout(that.timeOutID) } return false; } 
 	this.startSlider = function() { if ( that.timeOutID) { that.timeOutID = null; that.counter = that.obj.scrollLeft; that.moveSlider(); } return true; }
	setTimeout(function() {that.moveSlider()}, firstDelay * 1000);
}


/*----------------------------------------------------------------------*/
// install a dummy function console.log() if no firebug installed
if (typeof console === "undefined") { 
    console = { log: function() { } }; 
}


if (typeof multiClassName === "undefined") { 
    multiClassName = { 
    	test: function(obj,strClass) {
				if (obj.className)
				{	var arrList = obj.className.split(' ');
					var strClassUpper = strClass.toUpperCase();
					for (var i = 0; i < arrList.length; i++)
						if ( arrList[i].toUpperCase() == strClassUpper ) return true;
				}
				return false;
		} ,
    	add: function(obj,strClass) {
				if (obj.className)
				{	var arrList = obj.className.split(' ');
			        var strClassUpper = strClass.toUpperCase();
			        for (var i = 0; i < arrList.length; i++)
			        	if (arrList[i].toUpperCase() == strClassUpper) { arrList.splice(i, 1); i--; }
			        arrList[arrList.length] = strClass;
			        obj.className = arrList.join(' ');
				} else { obj.className = strClass; }
				return obj.className;
		} ,
    	remove: function(obj,strClass) {
			 	if (obj.className)
				{	var arrList = obj.className.split(' ');
			      	var strClassUpper = strClass.toUpperCase();
			      	for ( var i = 0; i < arrList.length; i++ )
			        	if (arrList[i].toUpperCase() == strClassUpper) { arrList.splice(i, 1); i--; }
			      	obj.className = arrList.join(' ');
				}
				return obj.className;
		} 
	}; 
}


if (typeof getDocumentSize === "undefined") { 
	getDocumentSize = { maxWidth: function () {
						if (window.innerWidth) { return window.innerWidth; }
						   else if (document.body) { return document.body.offsetWidth;	}
						      else if (document.documentElement) { return document.documentElement.offsetWidth;	}
					    } ,
					    maxHeight: function () {
						if (window.innerHeight) { return window.innerHeight; }
						   else if (document.body) { return document.body.offsetHeight;  }
							  else if (document.documentElement) { return document.documentElement.offsetHeight; }
					    } ,
						scrollWidth: function () {
						if (window.pageXOffset) { return window.pageXOffset; }
						   else if (document.documentElement) { return document.documentElement.scrollLeft; }
							  else if (document.body) { return document.body.scrollLeft; }
						} ,
						scrollHeight: function () {
							if (window.pageYOffset) { return window.pageYOffset; }
							   else if (document.documentElement) { return document.documentElement.scrollTop; }
								  else if (document.body) { return document.body.scrollTop; }
						} ,
						width: function () {
							if( typeof( window.innerWidth ) == 'number' ) return window.innerWidth;//Non-IE
							if( document.documentElement && ( document.documentElement.clientWidth  ) ) return document.documentElement.clientWidth;//IE 6+ in 'standards compliant mode'
							if( document.body && ( document.body.clientWidth  ) )   return document.body.clientWidth;//IE 4 compatible
						    return false;
						} ,
						height: function () {
							if( typeof( window.innerHeight) == 'number' ) return window.innerHeight;//Non-IE
							if( document.documentElement && (  document.documentElement.clientHeight ) ) return document.documentElement.clientHeight; //IE 6+ in 'standards compliant mode'
							if( document.body && (  document.body.clientHeight ) ) return document.body.clientHeight;//IE 4 compatible
	    					return false;
						} ,
						docHeight: function () { 
							return Math.max( Math.max(document.body.scrollHeight, document.documentElement.scrollHeight),
								             Math.max(document.body.offsetHeight, document.documentElement.offsetHeight),
									         Math.max(document.body.clientHeight, document.documentElement.clientHeight) );
						} ,
						docWidth: function () { 
							return Math.max( Math.max(document.body.scrollWidth, document.documentElement.scrollWidth),
								             Math.max(document.body.offsetWidth, document.documentElement.offsetWidth),
									         Math.max(document.body.clientWidth, document.documentElement.clientWidth) );
						}
					 }; 
}



// DOM helpers
if (typeof getElement === "undefined") { 
    getElement = { Id: function(tag) {	
    					if (tag == null) return null;
    					if( document.layers ) { return document.layers[tag]; } //Netscape layers
					    if( document.getElementById ) { return document.getElementById(tag); } //DOM; IE5, NS6, Mozilla, Opera
					    if( document.all ) { return document.all[tag]; } //Proprietary DOM; IE4
					    if( document[tag] ) { return document[tag]; } //Netscape alternative
					    return false;
					} ,   
					Class: function (classname, node, tag) { 
						if ( node == null ) node = document;
						if ( tag  == null ) tag = '*';
//						if (!node) { node = document.getElementsByTagName('body')[0]; } 
						var a = [], re = new RegExp('\\b' + classname + '\\b'); 
						var els = node.getElementsByTagName(tag); 
						for (var i = 0, j = els.length; i < j; i++) { if ( re.test(els[i].className) ) { a.push(els[i]); } } 
						return a; 
					} ,
					Table: function(obj) {	// find parent TABLE.id of object inside a table
						while (obj && !/table/i.test(obj.nodeName)){ obj = obj.parentNode; }
						return obj || null;
					} ,
					Tr: function(obj) {	// find parent TR.id of object inside a table
						while (obj && !/tr/i.test(obj.nodeName)){ obj = obj.parentNode; }
						return obj || null;
					} ,
					posX: function(obj) { // find position of object
						var curleft = 0;
						if (!obj) return 0;
						if (obj.offsetParent) while(1) 
					    {	curleft += obj.offsetLeft;
					        if (!obj.offsetParent) break;
							obj = obj.offsetParent;
						} else if(obj.x) curleft += obj.x;
					    return curleft;
					} ,
					posY: function(obj) { // find position of object
						var curtop = 0;
						if (!obj) return 0;
						if (obj.offsetParent) while(1)
						{	curtop += obj.offsetTop;
							if (!obj.offsetParent) break;
							obj = obj.offsetParent;
						} else if(obj.y) curtop += obj.y;
						return curtop;
					} ,
					posOffset: function(element) { // cumulativeOffset
					    var t = 0, l = 0;
						if (!element) getElement.store(l,t);
					    do {
					      t += element.offsetTop  || 0;
					      l += element.offsetLeft || 0;
					      element = element.offsetParent;
					    } while (element);
						return getElement.store(l,t);
					} ,
					posScroll: function(element) { // cumulativeScrollOffset
					    var t = 0, l = 0;
						if (!element) getElement.store(l,t);
					    do {
					      t += element.scrollTop  || 0;
					      l += element.scrollLeft || 0;
					      element = element.parentNode;
					    } while (element);
					    var sh = getDocumentSize.scrollHeight();
					    var sw = getDocumentSize.scrollWidth();
					    if (sh <= t) t -= sh;
					    l += sw;
						return getElement.store(l,t);
					} ,
					pos: function(element) { // posOffset - posScroll + dsoc
						if (!element) getElement.store(0,0);
						var o = getElement.posOffset(element);
						var s = getElement.posScroll(element);
					    var t = o.top  - s.top ;// + getDocumentSize.scrollHeight();
					    var l = o.left - s.left;// - getDocumentSize.scrollWidth(); // BUGFIX 16.11.10
//					    console.log(['pos',l,t,o,s]);
						return getElement.store(l,t);
					} ,
					store: function (l,t) { 
						var result = [l, t];
						result.left = l;
						result.top = t;
						return result; 
					}
			     }; 
}
if (typeof getID === "undefined") { // keep compatible to old function
	getID = function(tag) { return getElement.Id(tag); }
}


if (typeof getUrl === "undefined") { 
    getUrl = { query: function(key) {    
					if (typeof key == "undefined") key = null;
					var arrQueryString = window.location.href.split("?");
					var returnString = "";
					if (arrQueryString.length-1 > 0) 
					{	var queryString = arrQueryString[1];
						var arrPairString = queryString.split("&");
						for (var i=0;i<arrPairString.length;i++) 
						{	arrPiece = arrPairString[i].split("=");
							if (key && key == arrPiece[0]) return arrPiece[1];
						}
					} // end if
					return key ? null : queryString;
				} ,
				scriptNameFull: function () {
					var curUrl = window.location.href;
					return curUrl.substring(curUrl.lastIndexOf("/")+1);
				} ,
				scriptNameOnly: function() {
					var curUrl = window.location.href;
					curUrl = curUrl.substring(curUrl.lastIndexOf("/")+1);
					return curUrl.substring(0, curUrl.lastIndexOf("?"));
				} ,
				domain: function () {
					return document.domain ? document.domain : window.location.hostname;
				}
		     }; 
}


if (typeof selectText === "undefined") { // will be added to slib later
    selectText = { on: function(node) {	
						objId = (typeof node == "string") ? getElement.Id(node) : node; // tag or node allow
						selectText.off();
						if (document.selection) {
						var range = document.body.createTextRange();
 	    				    range.moveToElementText(objId);
							range.select();
						} else if (window.getSelection) {
						var range = document.createRange();
							range.selectNode(objId);
							window.getSelection().addRange(range);
						}
					} ,   
					off: function() {
						if (document.selection) document.selection.empty(); 
						else if (window.getSelection)
        		        window.getSelection().removeAllRanges();
						}
	}; 
}
     

if (!Function.prototype.chainEvent) { 
	Function.prototype.chainEvent = function(args) {   
	    args.push(this);   
	    return function() { for(var i = 0; i < args.length; i++) { args[i](); } }
	}; 
}		
//window.addLoad = function(fn) {   
//    window.onload = typeof(window.onload) != 'function' ? fn : window.onload.chainEvent([fn]);   
//   };  
   
   
// Prototype extensions
if (!String.prototype.trim) { 
	String.prototype.trim = function(){ return (this.replace(/^\s\s*/, '').replace(/\s\s*$/, '')); }
}		


// Extension for IE Browser
if (!Array.prototype.indexOf) { 
	Array.prototype.indexOf = function (obj, fromIndex) { 
	    if (fromIndex == null) { fromIndex = 0; } else if (fromIndex < 0) { 
	        fromIndex = Math.max(0, this.length + fromIndex); 
	    } 
	    for (var i = fromIndex, j = this.length; i < j; i++) { if (this[i] === obj) return i; } 
	    return -1; 
	}; 
} 


if (!Array.prototype.find) { 
	Array.prototype.find = function(searchStr,idx) {  
		if (typeof idx == "undefined") idx=null;
		var returnArray = false;  
		for (var i=0; i<this.length; i++) {    
			var element = (idx === null) ? this[i] : this[i][idx];
			if (typeof(searchStr) == 'function') {      
				if (searchStr.test(element)) {        
					if (!returnArray) { returnArray = [] }        
					returnArray.push(i);      
				}    
			} else {      
			  if (element===searchStr) {        
				if (!returnArray) { returnArray = [] }        
				returnArray.push(i);      
			  }    
			}  
		}  
		return returnArray;
	};
}


if (!Array.prototype.isArray) { 
Array.prototype.isArray = true;
}


if (!Number.prototype.formatMoney) { 
Number.prototype.formatMoney = function(c, d, t){
	var n = this, c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "," : d, t = t == undefined ? "." : t, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0;
	return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
	};
}


if (!insertAfter) {
var insertAfter = function(newNode,oldNode) {
    oldNode.nextSibling
      ? oldNode.parentNode.insertBefore(newNode, oldNode.nextSibling)
      : oldNode.parentNode.appendChild(newNode);
	return oldNode.parentNode;
	};
}


if (!createLink) {
	var createLink = function(url,text,cssClass) {
	    var link =  document.createElement('a');
	    if (typeof url  === 'string') { link.setAttribute('href', url); }
	    if (typeof text === 'string') { link.appendChild(document.createTextNode(text)); }
	    if (typeof cssClass === 'string') { link.className = cssClass; }
	    return link;
	};
}


if (!removeNode) {
	var removeNode = function(node){
	    if (node) node.parentNode.removeChild(node);
	};
}


if (!textElement) {
	var textElement = function(elementName,text){
	    if (typeof text === 'string')
		{	var txtElement = document.createElement(elementName);
			var txtNode = document.createTextNode(text);
			txtElement.appendChild(txtNode);
	    }
		return txtElement;
	};
}


if (!innerText) {
	var innerText = function(elem) {
		var txt = elem.innerText || elem.textContent || "";
		if (!txt.length) txt =slib.plainText(elem.innerHTML);
		return txt;
	}
}
	

if (!evtSet) {
	var evtSet = function(e, ret) {
		var evt = window.event || e;
	   	if (!evt.target) evt.target = evt.srcElement;
		evt.key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode; // 15.09.2011
		if (typeof ret === 'undefined') ret = false;
		//e.cancelBubble is supported by IE - this will kill the bubbling process.
		if (!ret) evt.cancelBubble = true;
		evt.returnValue = ret;
		//e.stopPropagation works only in Firefox.
		if (evt.stopPropagation && !ret) {
			evt.stopPropagation();
			evt.preventDefault();
		}
		return evt;
	}
}


if (!evtCR) {
	var evtCR = function(e, key) {
		var evt = window.event || e;
	   	if (!evt.target) evt.target = evt.srcElement;
		evt.key = evt.keyCode ? evt.keyCode : evt.which ? evt.which : evt.charCode;
		var ret = (evt.key != key);
		if (/textarea/i.test(evt.target.nodeName) && key==13) ret = true; // TEXTAREA field
		if (evt.target.key == key) ret = true; // virtual element 'key' matches?
		//e.cancelBubble is supported by IE - this will kill the bubbling process.
		if (!ret) evt.cancelBubble = true;
		evt.returnValue = ret;
		//e.stopPropagation works only in Firefox.
		if (evt.stopPropagation && !ret) {
			evt.stopPropagation();
			evt.preventDefault();
		}
//		console.log(evt);
		return evt;
	}
}


if (!serialize) {
var serialize = function(_obj)
{  // Let Gecko browsers do this the easy way
   if (typeof _obj.toSource !== 'undefined' && typeof _obj.callee === 'undefined') { return _obj.toSource(); }
   // Other browsers must do it the hard way
   switch (typeof _obj)
   {  case 'number':
      case 'boolean': return _obj; break;
      case 'function': return '(' + _obj + ')'; break;
      case 'string': // for JSON format, strings need to be wrapped in quotes
     	_obj = _obj.replace(/\\/g, "\\\\");
     	_obj = _obj.replace(/\n/g, "\\n");
     	_obj = _obj.replace(/\r/g, "\\r");
		_obj = _obj.replace(/\"/g, "\\\"");
         return '\"' + (_obj) + '\"';
         break;
      case 'object': var str;
         if (_obj.constructor === Array || typeof _obj.callee !== 'undefined')
         {  str = '[';
            var i, len = _obj.length;
            for (i = 0; i < len-1; i++) { str += serialize(_obj[i]) + ','; }
            str += serialize(_obj[i]) + ']';
         } else {
            str = '{';
            var key;
            for (key in _obj) { str += key + ':' + serialize(_obj[key]) + ','; }
            str = str.replace(/\,$/, '') + '}';
         }
         return str;
         break;
      default:
         return 'UNKNOWN';
         break;
   }
}
}

if (!deserialize) {
var deserialize = function(str)
{	var obj = {}
	try { obj = (new Function("return " + str))() } catch(e) {}
	return obj;
}
}

/*----------------------------------------------------------------------*/
if (typeof jq === "undefined") {
function $() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1)
			return element;
		elements.push(element);
//		elements[elements.length] = element;
	}
	return elements;
}
}

/*----------------------------------------------------------------------*/
function addEvent( obj, type, fn ) {
	if (obj.addEventListener) {
		obj.addEventListener( type, fn, false );
		EventCache.add(obj, type, fn);
	}
	else if (obj.attachEvent) {
		obj["e"+type+fn] = fn;
		obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
		obj.attachEvent( "on"+type, obj[type+fn] );
		EventCache.add(obj, type, fn);
	}
	else {
		obj["on"+type] = obj["e"+type+fn];
	}
}

var EventCache = function(){
	var listEvents = [];
	return {
		listEvents : listEvents,
		add : function(node, sEventName, fHandler){
			listEvents.push(arguments);
		},
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				item[0][item[1]] = null;
			};
		return false;
		}
	};
}();
addEvent(window,'unload',EventCache.flush);


function clearEvent(e){
	var evt=window.event || e;
	if (evt.preventDefault) evt.preventDefault();
	return false;
}

/*----------------------------------------------------------------------*/
// adds an window.onload event (chaining)
function addLoadEvent(func) {
	var oldonload = window.onload;
	if (typeof window.onload != 'function') {
		window.onload = func;
	}
	else {
		window.onload = function() {
			oldonload();
			func();
		}
	}
}


/*----------------------------------------------------------------------*/
// DOMReady.add ( function () {  alert (" DOM is ready ! 1") ; } ) ;
var xDOMReady = (function () {
	var fns = [],
		isReady = false,
		getFunc = function ( fn ) {
			if ( fn.constructor == String ) return function () { eval( fn ); };
			return fn;
		},
		ready = function () {
			if (isReady) return; // only fire once
			isReady = true;
			// call all registered functions
			for ( var x = 0; x < fns.length; x++ ) fns[x]();	// call function
		};

	/**
	 * Add code or function to execute when the DOM is ready
	 * @param fn [function | string]
	 * @return [DOMReady] for chaining
	 */
	this.add = function ( fn ) {
		fn = getFunc( fn );

		// call imediately when DOM is already ready
		if ( isReady ) {
			fn();
		} else {
			// add to the list
			fns[fns.length] = fn;
		}

		// return this for chaining
		return this;
	};

	// For all browsers except IE
	if ( window.addEventListener )
		document.addEventListener( 'DOMContentLoaded', function(){ ready(); }, false );

	// For IE
	(function(){
		if ( ! document.uniqueID && document.expando ) return; // check IE's proprietary DOM members
		// you can create any tagName, even customTag like <document :ready />
		var tempNode = document.createElement('document:ready');
		try { tempNode.doScroll('left'); // see if it throws errors until after ondocumentready
			} catch ( err ) { setTimeout(arguments.callee, 50); return; }
		// no errors, fire
		ready();
	})();

	return this;
})();

   
//function obj2(v2) {
//o2=new obj2(22);
//x2 = o2.fn2(222);
//obj2.prototype.a2 = function (b) { return (this.var2 + b); }
//return {width: element.offsetWidth, height: element.offsetHeight};
//http://cross-browser.com/x/examples/property_viewer.html
(function(){

    var DOMReady = window.DOMReady = {};

	// Everything that has to do with properly supporting our document ready event. Brought over from the most awesome jQuery. 

    var userAgent = navigator.userAgent.toLowerCase();

    // Figure out what browser is being used
    var browser = {
    	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
    	safari: /webkit/.test(userAgent),
    	opera: /opera/.test(userAgent),
    	msie: (/msie/.test(userAgent)) && (!/opera/.test( userAgent )),
    	mozilla: (/mozilla/.test(userAgent)) && (!/(compatible|webkit)/.test(userAgent))
    };    

	var readyBound = false;	
	var isReady = false;
	var readyList = [];

	// Handle when the DOM is ready
	function domReady() {
		// Make sure that the DOM is not already loaded
		if(!isReady) {
			// Remember that the DOM is ready
			isReady = true;
        
	        if(readyList) {
	            for(var fn = 0; fn < readyList.length; fn++) {
	                readyList[fn].call(window, []);
	            }
            
	            readyList = [];
	        }
		}
	};

	// From Simon Willison. A safe way to fire onload w/o screwing up everyone else.
	function addLoadEvent(func) {
	  var oldonload = window.onload;
	  if (typeof window.onload != 'function') {
	    window.onload = func;
	  } else {
	    window.onload = function() {
	      if (oldonload) {
	        oldonload();
	      }
	      func();
	    }
	  }
	};

	// does the heavy work of working through the browsers idiosyncracies (let's call them that) to hook onload.
	function bindReady() {
		if(readyBound) {
		    return;
	    }
	
		readyBound = true;

		// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
		if (document.addEventListener && !browser.opera) {
			// Use the handy event callback
			document.addEventListener("DOMContentLoaded", domReady, false);
		}

		// If IE is used and is not in a frame
		// Continually check to see if the document is ready
		if (browser.msie && window == top) (function(){
			if (isReady) return;
			try {
				// If IE is used, use the trick by Diego Perini
				// http://javascript.nwbox.com/IEContentLoaded/
				document.documentElement.doScroll("left");
			} catch(error) {
				setTimeout(arguments.callee, 0);
				return;
			}
			// and execute any waiting functions
		    domReady();
		})();

		if(browser.opera) {
			document.addEventListener( "DOMContentLoaded", function () {
				if (isReady) return;
				for (var i = 0; i < document.styleSheets.length; i++)
					if (document.styleSheets[i].disabled) {
						setTimeout( arguments.callee, 0 );
						return;
					}
				// and execute any waiting functions
	            domReady();
			}, false);
		}

		if(browser.safari) {
		    var numStyles;
			(function(){
				if (isReady) return;
				if (document.readyState != "loaded" && document.readyState != "complete") {
					setTimeout( arguments.callee, 0 );
					return;
				}
				if (numStyles === undefined) {
	                var links = document.getElementsByTagName("link");
	                for (var i=0; i < links.length; i++) {
	                	if(links[i].getAttribute('rel') == 'stylesheet') {
	                	    numStyles++;
	                	}
	                }
	                var styles = document.getElementsByTagName("style");
	                numStyles += styles.length;
				}
				if (document.styleSheets.length != numStyles) {
					setTimeout( arguments.callee, 0 );
					return;
				}
			
				// and execute any waiting functions
				domReady();
			})();
		}

		// A fallback to window.onload, that will always work
	    addLoadEvent(domReady);
	};

	// This is the public function that people can use to hook up ready.
	DOMReady.add = function(fn, args) {
		// Attach the listeners
		bindReady();
    
		// If the DOM is already ready
		if (isReady) {
			// Execute the function immediately
			fn.call(window, []);
	    } else {
			// Add the function to the wait list
	        readyList.push( function() { return fn.call(window, []); } );
	    }
	};
    
	bindReady();
	
})();

