var dom = (document.getElementById) ? true : false;
var ns5 = (!document.all && dom || window.opera) ? true: false;
var ie5 = ((navigator.userAgent.indexOf("MSIE")>-1) && dom) ? true : false;
var ie4 = (document.all && !dom) ? true : false;
var nodyn = (!ns5 && !ie4 && !ie5 && !dom) ? true : false;


function ValidatorUpdateIsValid() {
    if(typeof(Page_Validators)!='undefined')
        Page_IsValid = AllValidatorsValid(Page_Validators);
}

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

function popUp(url, width, height) 
{
	if (window.frames["worker_frame"]) 
	{
		document.getElementById("loaderContainer").style.display='';
		//var url = "../Utils/ModalWin.aspx?SRC="+escape(url)+"&scroll="+(scroll!=null?scroll:"no");
		document.getElementById("worker_frame").style.width = width+'px';
		document.getElementById("worker_frame").style.height = height+'px';
		window.frames["worker_frame"].location = url+"&script=window.parent.parent.location.reload();";
	} else {
		return modalWin_old(url, title, width, height, scroll);
	}
}

function popDown()
{
	window.frames["worker_frame"].location='';
	document.getElementById("loaderContainer").style.display='none';
}

function modalWin(url, title, width, height, scroll, top, left) 
{
	if (window.showModalDialog) 
	{
		//alert(url);
		var url = "../Utils/ModalWin.aspx?SRC="+escape(url)+"&title=CRMax - "+escape(title)+"&scroll="+(scroll!=null?scroll:"no");
		var att = "scroll:0;dialogWidth:"+width+"px;dialogHeight:"+height+"px;resizable:yes;status:no";
		if(top) att += ";dialogTop:"+top+"px";
		if(left) att += ";dialogLeft:"+left+"px";
		var retval = window.showModalDialog( url,window, att);
		return retval;
	} else {
	    alert('Browserul dvs. nu suporta festre modale. Pentru functionarea corecta folositi Internet Explorer 6+')
		window.open(url,name,'height='+height+',width='+width+',toolbar=no,directories=no,status=no,menubar=no,scrollbars=no,resizable=no,modal=yes');
		return null;
	}
}

function newWin(url, title, width, height, scroll) 
{
	window.open(url,'newWin','height='+height+',width='+width+',toolbar=no,directories=no,status=no,menubar=no,resizable=yes,scrollbars='+(scroll!=null?scroll:'no'));
	return null;
}

function messageBox(text) 
{
	if(text.length>0)
		return modalWin("../Utils/MessageBox.aspx?msg="+text, "", 400, 150);
	else 
		return false;
}

function addCommas(nStr)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	var rgx2 = /(,)/;
	while (rgx2.test(x1)) {
		x1=x1.replace(rgx2,'');
	}
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

function getCaretPosition(objTextBox){
/*	Purpose	:	Returns the caret position of the cursor 
*				in the text box
*
*	Effects	:	None
*
*	Inputs	:	objTextBox - a text box
*
*	Returns	:	Integer indicating the caret position 
*				in the text box
*/

	var i = objTextBox.value.length+1;
	
	if (objTextBox.createTextRange){
		objCaret = document.selection.createRange().duplicate();
		while (objCaret.parentElement()==objTextBox &&
			objCaret.move("character",1)==1) --i;
	}
	
	return i;
}

function fomatDecimalField(txtBox)
{
/* - mai tb. tratat momentul cand se fac calcule cu this.value
		var iCaretPosition = getCaretPosition(txtBox);
		var l1 = txtBox.value.length;
		txtBox.value = addCommas(txtBox.value);
		objRange = txtBox.createTextRange();
		objRange.move('character', iCaretPosition-1+(txtBox.value.length-l1))
		objRange.select();
*/
}



if (!document.layers&&!document.all&&!document.getElementById)
	event="test"
	

//

function showtip(current,e,text)
{
	if (document.all||document.getElementById)
	{
		thetitle=text.split('<br>')
		if (thetitle.length>1)
		{
			thetitles=''
			for (i=0;i<thetitle.length;i++)
				thetitles+=thetitle[i]
			current.title=thetitles
		}
		else
			current.title=text
	}
	else if (document.layers)
	{
		document.tooltip.document.write('<layer bgColor="white" style="border:1px solid black;font-size:12px;">'+text+'</layer>')
		document.tooltip.document.close()
		document.tooltip.left=e.pageX+5
		document.tooltip.top=e.pageY+5
		document.tooltip.visibility="show"
	}
}

function hidetip()
{
	if (document.layers)
		document.tooltip.visibility="hidden"
}


function framesInspector( thisw, path )
{
	var retVal ='';
	if(thisw && thisw.frames)	
		for(var i=0; i<thisw.frames.length; i++)
		{
			retVal += ' - ' + thisw.frames[i].name;
			framesInspector( thisw.frames[i].contentWindow, path+':'+thisw.frames[i].name );
		}
		
	return path +' = ( ' + retVal + ' )\n';
}


function altavaloareselected(id, pt)
{
	win = window.open("AddSetValue.aspx?id=" + pt, 'altavaloare','width=140px,height=50px');
}

var setAddedValue;
function addValueCustom(slct, xml, daSet)
{
	var newItemId = modalWin("../Utils/FormPage.aspx?xml=" + xml+"&return=id", 'Alta Valoare',400,150);
	if(newItemId!=null)
	{
		setAddedValue = newItemId;
		loadSet(slct, "name="+daSet);
	}
}

function addValueCustom2(slct, xml)
{
	var newItemId = modalWin("../Utils/FormPage.aspx?xml=" + xml+"&return=id", 'Alta Valoare',400,150);
	if(newItemId!=null)
	{
		window.location.reload(false);
	}
}


function listSetValues(slct, xml, daSet)
{
	modalWin("../Utils/ListFormPage.aspx?xml=" + xml, 'Modificare valori',400,500,'yes');
	loadSet(slct, "name="+daSet);
}

var Url = {
 
	// public method for url encoding
	encode : function (string) {
		return escape(this._utf8_encode(string));
	},
 
	// public method for url decoding
	decode : function (string) {
		return this._utf8_decode(unescape(string));
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
 
}


var req=null;
var _lastURL = null;


function loadXMLDoc(url, processor) {
	if(req != null)
	{
	    setTimeout("loadXMLDoc('"+url+"',"+processor+");", 200);
	    return;
	}
	req = false;
    // branch for native XMLHttpRequest object
    if(window.XMLHttpRequest) {
    	try {
			req = new XMLHttpRequest();
        } catch(e) {
			req = false;
        }
    // branch for IE/Windows ActiveX version
    } else if(window.ActiveXObject) {
       	try {
        	req = new ActiveXObject("Msxml2.XMLHTTP");
      	} catch(e) {
        	try {
          		req = new ActiveXObject("Microsoft.XMLHTTP");
        	} catch(e) {
          		req = false;
        	}
		}
    }
	if(req) {
		var timeval = new Date().getTime();
		if(url.indexOf("&")>0 || url.indexOf("?")>0)
			url = url + "&random_helper="+timeval ;
		else
			url = url + "?random_helper="+timeval ;
		_lastURL =url;
		
		if(typeof(processor)=='string')
		{
			_postLoadScript = processor;
			req.onreadystatechange = evalOnLoad;
		}
		else
			req.onreadystatechange = processor;
//		alert(url);
		req.open("GET", url, true);
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
		req.send("");
	}
}

function clearComboOptions(slct)
{
	for(var i=slct.options.length-1;i>=0;i--) slct.options.remove(i);
}

function processReqChange() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            alert("Am luat textul!");
        } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.responseText);
        }
    }
}


function refreshOnLoad() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            window.location.reload();
        } else {
            alert("There was a problem loading data:\n" +      req.responseText);
        }
		req=null;
    }
}

function closeOnLoad() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            window.close();
        } else {
            alert("There was a problem loading data:\n" +      req.responseText);
        }
		req=null;
    }
}

var _postLoadScript;

function evalOnLoad() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            if(typeof(_postLoadScript)=='string')
                eval(_postLoadScript);
        } else {
            alert("There was a problem loading data:\n" +      req.responseText);
        }
		req=null;
    }
}

function fillSelectFromArray(slct, arr)
{
	setAddedValue = slct.value;
	for(var i=slct.options.length-1;i>=0;i--) slct.options.remove(i);

	var selected = false;
	for(v in arr)
	{
		var op = new Option(arr[v], arr[v], false, false);
		if(setAddedValue == arr[v])
		{
			op.selected=true;
			selected=true;
			setAddedValue=null;
		}
		slct.options.add(op);
	}
	
	if(slct.options[0]!=null && !selected) 
	{
		slct.options[0].selected=true;
		slct.value = slct.options[0].value;
	}
	
	return !selected;
}

var currentSelect;

var onSetLoaded = function() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
			var slct = currentSelect;
			if(setAddedValue==null)
			    setAddedValue = slct.value;
			for(var i=slct.options.length-1;i>=0;i--) slct.options.remove(i);
			var re = /<value id="([^"]*)" display="([^"]*)"/g;
			var selected = false;
			while(arr = re.exec(req.responseText))
			{
				var op = new Option(arr[2], arr[1], false, false);
				if(setAddedValue == arr[1])
				{
					op.selected=true;
					selected=true;
					setAddedValue=null;
				}
				slct.options.add(op);
			}
			if(slct.options[0]!=null && !selected) 
			{
				slct.options[0].selected=true;
				slct.value = slct.options[0].value;
			}
			if(slct.onchange)
				slct.onchange();
        } else {
            alert("Nu s-a putut incarca setul de valori:\n" +
                req.responseText);
        }
			req=null;
    }
}

function loadSet(slct, params)
{
	currentSelect = document.getElementById(slct); 
	loadXMLDoc('../Utils/loadSet.aspx?'+params, onSetLoaded);
}

var currentTarget=null;


var onValueLoaded = function() {
    // only if req shows "loaded"
    if (req!=null && req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) 
		{
			var ct = document.getElementById(currentTarget);
			if(ct.tagName=='SPAN')
				ct.innerText = req.responseText;
			else
				ct.value = req.responseText;
				
			if(ct.onchange)
				ct.onchange();
				
        } else {
            alert("Nu s-a putut incarca valoarea:\n" +
                req.responseText);
        }
		req=null;
		currentTarget =null;
   }
}

function loadValue(target, param)
{
	if(currentTarget==null)
	{
		currentTarget = target; 
	//	alert('../Utils/loadXML.aspx?'+param);
		loadXMLDoc('../Utils/loadXML.aspx?'+param, onValueLoaded);
	}
	else
	{
		setTimeout("loadValue('"+target+"', '"+param+"');", 500);
	}
}

function loadValueFromURL(target, url)
{
	if(currentTarget==null)
	{
		currentTarget = target; 
	//	alert('../Utils/loadXML.aspx?'+param);
		loadXMLDoc(url, onValueLoaded);
	}
	else
	{
		setTimeout("loadValueFromURL('"+target+"', '"+url+"');", 200);
	}
}

var EX_afterCode;
var onExecuteXml = function() {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) 
        {
			switch (typeof EX_afterCode)
			{
				case 'string':
					setTimeout(EX_afterCode,1);
				break;
				case 'function':
					EX_afterCode();
				break;
			}			
        } else {
            alert("Nu s-a putut incarca valoarea:\n" +
                req.responseText);
        }
    }
}

function executeXml(param, afterCode)
{
	EX_afterCode = afterCode;
	loadXMLDoc('../Utils/loadXML.aspx?'+param, onExecuteXml);
}


function _lon(target) {
	try {
		if (!target)
			target = this;

		oLoader = target.document.getElementById("loader");
		oBody = target.document.getElementsByTagName("body")[0];
		if (oLoader || oBody) {
			zIndex = oLoader.style.zIndex;
			if ( zIndex == "" ) zIndex = oLoader.currentStyle.zIndex;
			zIndex = parseInt(zIndex);
			if (!isNaN(zIndex) && zIndex > 1) {
				sHiderID = oLoader.id + "SubLayer";
				oIframe = target.document.getElementById(sHiderID);
				if (!oIframe) {
					oBody.insertAdjacentHTML("afterBegin", '<iframe src="javascript:false;" id="' + sHiderID + '" scroll="no" frameborder="0" style="position:absolute;visibility:hidden;border:0;top:0;left;0;width:0;height:0;background-color:#ccc;z-index:' + (zIndex - 1) + ';"></iframe>');
					oIframe = target.document.getElementById(sHiderID);
				}
				oIframe.style.width = oLoader.offsetWidth + "px";
				oIframe.style.height = oLoader.offsetHeight + "px";
				oIframe.style.left = oLoader.offsetLeft + "px";
				oIframe.style.top = oLoader.offsetTop + "px";
				oIframe.style.visibility = "visible";
			}
		}
	} catch (e) {
		return false;
	}
	return true;
}

function _loff(target) {
	try {
		if (!target)
			target = this;
	
		target.document.getElementById("loaderSubLayer").style.display = "none";
	} catch (e) {
		return false;
	}
	return true;
}

function bitAND(v1, v2)
{
	return v1&v2;
}


function trim(str, chars) {
return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
chars = chars || "\\s";
return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function switchIt( divName, img)
{
	var dv = document.getElementById(divName);
	if(dv)
	{
		if(dv.style.display == 'none')
		{
			dv.style.display = '';
			img.src = '../Images/arr-r.gif';
			return true;
		}
		else
		{
			dv.style.display = 'none';
			img.src = '../Images/arr-d.gif';
			return false;
		}
	}
}



function readListToArray(xmldoc)
{
    var root = xmldoc.getElementsByTagName('root').item(0);
    var err = xmldoc.getElementsByTagName('error')
    if(err.length>0)
		alert(err.item(0).xml);

	var arr_header=new Array();
    
    var header = root.getElementsByTagName('header').item(0);
    if(header)
    {
		var cnt=0;
		for (x = 0; x < header.childNodes.length; x++) 
		{
			var sibl2 = header.childNodes.item(x);
			if (sibl2.childNodes.length > 0) 
			{
				sibl3 = sibl2.childNodes.item(0);
				arr_header[cnt] = sibl3.data;   
			}
			cnt++;
		}
    }
    
	var node = root.getElementsByTagName('data').item(0)
	var arr_rows = new Array();
	for( row=0; row < node.childNodes.length; row++)
	{
	    var sibl = node.childNodes.item(row);

	    var arr_fields = new Array();
	    var cnt = 0;
	    if(sibl)
	    for (x = 0; x < sibl.childNodes.length; x++) 
	    {
		    var sibl2 = sibl.childNodes.item(x);
		    var val;
		    if (sibl2.childNodes.length > 0) 
		    {
			    var sibl3 = sibl2.childNodes.item(0);
			    val = sibl3.data;   
		    }
		    else
		    {
			    val='';
		    }
		    //alert(arr_header[cnt] +"="+val);
		    arr_fields[""+arr_header[cnt]] = val;   
		    cnt++;
	    }
	    arr_rows[row] = arr_fields;
	}
	
    return arr_rows;
}
// ========================================================= START JSON  ==============================



if (!this.JSON) {

// Create a JSON object only if one does not already exist. We create the
// object in a closure to avoid creating global variables.

    JSON = function () {

        function f(n) {
            // Format integers to have at least two digits.
            return n < 10 ? '0' + n : n;
        }

        Date.prototype.toJSON = function (key) {

            return this.getUTCFullYear()   + '-' +
                 f(this.getUTCMonth() + 1) + '-' +
                 f(this.getUTCDate())      + 'T' +
                 f(this.getUTCHours())     + ':' +
                 f(this.getUTCMinutes())   + ':' +
                 f(this.getUTCSeconds())   + 'Z';
        };

        var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
            escapeable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
            gap,
            indent,
            meta = {    // table of character substitutions
                '\b': '\\b',
                '\t': '\\t',
                '\n': '\\n',
                '\f': '\\f',
                '\r': '\\r',
                '"' : '\\"',
                '\\': '\\\\'
            },
            rep;


        function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

            escapeable.lastIndex = 0;
            return escapeable.test(string) ?
                '"' + string.replace(escapeable, function (a) {
                    var c = meta[a];
                    if (typeof c === 'string') {
                        return c;
                    }
                    return '\\u' + ('0000' +
                            (+(a.charCodeAt(0))).toString(16)).slice(-4);
                }) + '"' :
                '"' + string + '"';
        }


        function str(key, holder) {

// Produce a string from holder[key].

            var i,          // The loop counter.
                k,          // The member key.
                v,          // The member value.
                length,
                mind = gap,
                partial,
                value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

            if (value && typeof value === 'object' &&
                    typeof value.toJSON === 'function') {
                value = value.toJSON(key);
            }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

            if (typeof rep === 'function') {
                value = rep.call(holder, key, value);
            }

// What happens next depends on the value's type.

            switch (typeof value) {
            case 'string':
                return quote(value);

            case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

                return isFinite(value) ? String(value) : 'null';

            case 'boolean':
            case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

                return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

            case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

                if (!value) {
                    return 'null';
                }

// Make an array to hold the partial results of stringifying this object value.

                gap += indent;
                partial = [];

// If the object has a dontEnum length property, we'll treat it as an array.

                if (typeof value.length === 'number' &&
                        !(value.propertyIsEnumerable('length'))) {

// The object is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                    length = value.length;
                    for (i = 0; i < length; i += 1) {
                        partial[i] = str(i, value) || 'null';
                    }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                    v = partial.length === 0 ? '[]' :
                        gap ? '[\n' + gap +
                                partial.join(',\n' + gap) + '\n' +
                                    mind + ']' :
                              '[' + partial.join(',') + ']';
                    gap = mind;
                    return v;
                }

// If the replacer is an array, use it to select the members to be stringified.

                if (rep && typeof rep === 'object') {
                    length = rep.length;
                    for (i = 0; i < length; i += 1) {
                        k = rep[i];
                        if (typeof k === 'string') {
                            v = str(k, value, rep);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                } else {

// Otherwise, iterate through all of the keys in the object.

                    for (k in value) {
                        if (Object.hasOwnProperty.call(value, k)) {
                            v = str(k, value, rep);
                            if (v) {
                                partial.push(quote(k) + (gap ? ': ' : ':') + v);
                            }
                        }
                    }
                }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

                v = partial.length === 0 ? '{}' :
                    gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
                            mind + '}' : '{' + partial.join(',') + '}';
                gap = mind;
                return v;
            }
        }

// Return the JSON object containing the stringify and parse methods.

        return {
            stringify: function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

                var i;
                gap = '';
                indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

                if (typeof space === 'number') {
                    for (i = 0; i < space; i += 1) {
                        indent += ' ';
                    }

// If the space parameter is a string, it will be used as the indent string.

                } else if (typeof space === 'string') {
                    indent = space;
                }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

                rep = replacer;
                if (replacer && typeof replacer !== 'function' &&
                        (typeof replacer !== 'object' ||
                         typeof replacer.length !== 'number')) {
                    throw new Error('JSON.stringify');
                }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

                return str('', {'': value});
            },


            parse: function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

                var j;

                function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                    var k, v, value = holder[key];
                    if (value && typeof value === 'object') {
                        for (k in value) {
                            if (Object.hasOwnProperty.call(value, k)) {
                                v = walk(value, k);
                                if (v !== undefined) {
                                    value[k] = v;
                                } else {
                                    delete value[k];
                                }
                            }
                        }
                    }
                    return reviver.call(holder, key, value);
                }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

                cx.lastIndex = 0;
                if (cx.test(text)) {
                    text = text.replace(cx, function (a) {
                        return '\\u' + ('0000' +
                                (+(a.charCodeAt(0))).toString(16)).slice(-4);
                    });
                }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

                if (/^[\],:{}\s]*$/.
test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                    j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                    return typeof reviver === 'function' ?
                        walk({'': j}, '') : j;
                }

// If the text is not JSON parseable, then a SyntaxError is thrown.

                throw new SyntaxError('JSON.parse');
            }
        };
    }();
}

// ========================================================= END JSON  ==============================


function sign(val)
{
    return val<0?-1:1;
}


function getLeftPos(inputObj)
{
  var returnValue = inputObj.offsetLeft;
  while((inputObj = inputObj.offsetParent) != null){
  	if(inputObj.tagName!='HTML')returnValue += inputObj.offsetLeft;
  }
  return returnValue;
}

function getTopPos(inputObj)
{
  var returnValue = inputObj.offsetTop;
  while((inputObj = inputObj.offsetParent) != null){
  	if(inputObj.tagName!='HTML')returnValue += inputObj.offsetTop;
  }
  return returnValue;
}

function ExtractNumber(value)
{
    var n = parseInt(value);
    return n == null || isNaN(n) ? 0 : n;
}

// this is simply a shortcut for the eyes and fingers
function $(id)
{
	return document.getElementById(id);
}

function checkSelectValue(cid)
{
    var c = document.getElementById(cid);
    if(c.oldValue != c.value) { setValueChanged(); c.style.backgroundColor='#fff0f0';}
}

function forceUrlReload()
{
    var timeval = new Date().getTime();
	return "&random_helper="+timeval
}

function jsRound(value, precision)
{
    if(isNaN(value)) return value;
    else return Math.round(value*Math.pow(10, precision))/Math.pow(10, precision);
}
