WL.Utils = {};
WL.Utils_ = {};

if( WL.Debug )
{
WL.Utils.assert = function( condition, message )
{
	if( condition && window.confirm( String.format( "Debug Information.\nError: {0}.\n\nGo to debugger?", message ) ) ) { debugger; }	
}

WL.attachListener( document, "keydown", function(e) 
	{
		e = WL.getEvent(e);
		if( e.keyCode == 68 && e.ctrlKey && e.altKey ) { debugger; }
	} );
} // end if( WL.Debug )
else
{
WL.Utils.assert = function(){}
} // end else if( WL.Debug )

WL.attachListener( document, "keydown", function(e) 
	{
		e = WL.getEvent(e);
		if( e.keyCode == 8 )
		{
			var target = e.target;
			if( target && target.tagName && target.tagName.match(/INPUT|TEXTAREA/i) ) return;
			return WL.returnEvent( e, false, true );
		}
	} );

WL.Utils.getXmlDoc = function( xmlstring )
{
	if( window.DOMParser )
	{
		return (new DOMParser()).parseFromString(xmlstring, "text/xml");
	}
	else
	if( window.ActiveXObject )
	{
		var xmldoc = new ActiveXObject( "Microsoft.XMLDOM" );
		xmldoc.loadXML( xmlstring );
		return xmldoc;
	}
	return null;
}

if( WL.browser.ie )
{
WL.Utils.getMouseCoords = function(e)
{
	var body = WL.Utils.getBody();
	return {x:e.clientX + body.scrollLeft - body.clientLeft, y:e.clientY + body.scrollTop  - body.clientTop };
}
} // end if WL.browser.ie
else
{
WL.Utils.getMouseCoords = function(e) { return {x:e.pageX, y:e.pageY}; }
}

WL.Utils.getEventElementOffset = function( e, element )
{
	var p = WL.Utils.getMouseCoords(e);
	var o = WL.Utils.getElementOffset(element);
	return {left:p.x-o.left,top:p.y-o.top,right:o.left+o.width-p.x-1,bottom:o.top+o.height-p.y-1};
}

WL.Utils.isVisibleElement = function( element )
{
	while( element != null )
	{
		if( WL.currentStyle( element ).display == "none" ) return false;
		if( WL.currentStyle( element ).visibility == "hidden" ) return false;
		element = element.parentNode;
	}
	return true;
}

WL.Utils.isPointInRange = function( x, y, left, top, right, bottom )
{
	return top <= y && y <= bottom && left <= x && x <= right;
}

WL.Utils.attachClickEvent = function( element, clickHandler, dblClickHandler, timeout )
{
	if( !timeout ) timeout = WL.ClickTimeout;
	
	if( clickHandler ) WL.attachListener( element, "click", WL.Utils_.attachClickEventHelper1.bind( window, clickHandler, timeout ) );	
	WL.attachListener( element, "dblclick", WL.Utils_.attachClickEventHelper3.bind( window, dblClickHandler ) );
}

WL.Utils_.attachClickEventHelper1 = function( clickHandler, timeout, e )
{
	e = WL.getEvent(e);
	var f = WL.Utils_.attachClickEventHelper2.bind( window,
													{ target: e.target,
													  x: e.x, 
													  y: e.y,
													  offsetX: e.offsetX,
													  offsetY: e.offsetY,
													  ctrlKey: e.ctrlKey }, clickHandler );
													  
	e.target.clearClick = window.setTimeout(f,timeout);											  
	return WL.returnEvent(e,false,true);
} 

WL.Utils_.attachClickEventHelper2 = function( e, clickHandler )
{
	clickHandler(e);
	e.target = null;
}

WL.Utils_.attachClickEventHelper3 = function( dblClickHandler, e )
{
	e = WL.getEvent(e);
	if( e.target.clearClick )
	{
		window.clearTimeout( e.target.clearClick );
		e.target.clearClick = null;
	}
	if( dblClickHandler ) dblClickHandler(e);
	return WL.returnEvent( e, false, true );
}

WL.Utils.serialize = function( obj, tagname )
{
	var writer = new WL.Objects.XmlWriter();
		writer.writeObject( tagname || "object", obj );
	return writer.toString();
}

WL.Utils.serialize2 = function( obj, tagname )
{
	var writer = new WL.Objects.XmlWriter();
	if( typeof(obj) == "object" ) writer.writeObject( tagname || "object", obj );
	else writer.writeElementString( tagname || "value", obj );
	return writer.toString();
}

WL.Utils.serialize_array = function( array, tagname, itemtag )
{
	var writer = new WL.Objects.XmlWriter();
		writer.writeObjectArray( tagname || "object", itemtag || "o", array );
	return writer.toString();
}

WL.Utils.deserialize = function( xml, objClass )
{
	var o = new objClass();
	o.read(new WL.Objects.XmlReader( WL.Utils.getXmlDoc(xml).firstChild ));
	return o;
}

WL.Utils.deserialize_array = function( xml, objClass, itemtag )
{
	return (new WL.Objects.XmlReader( WL.Utils.getXmlDoc(xml).firstChild )).readObjectArray( itemtag || "o", objClass );
}

WL.Utils.enter_action = function( el, action ) { WL.attachListener( el, "keypress", WL.Utils_.enter_action.bind( window, action ) ); }
WL.Utils_.enter_action = function( action, e ) { e = WL.getEvent(e); if( e.keyCode == 13 ) { if( action ) action(e); return WL.returnEvent(e,false,true); } }

if( WL.browser.ie )
{
WL.Utils.select_action = function( el, action ) { WL.attachListener( el, "selectstart", WL.Utils_.select_action.bind( window, action ) ); }
WL.Utils_.select_action = function( action, e ) { e = WL.getEvent(e); if( action ) action(); return WL.returnEvent(e,false); }
}
else
{
WL.Utils.select_action = function( el )
{
	el.__preventSelection = false;
	WL.attachListener( el, "mousemove", WL.Utils_.select_action_mousemove.bind( WL.uniqueID(el) ) );
	WL.attachListener( el, "mousedown", WL.Utils_.select_action_mousedown.bind( WL.uniqueID(el) ) );
}
WL.Utils_.select_action_mousedown = function(e) { var el = WL.$(this); if(el) el.__preventSelection = !WL.getEvent(e).target.tagName.match(/INPUT|TEXTAREA/i); } 
WL.Utils_.select_action_mousemove = function(e) { var el = WL.$(this); if(el && el.__preventSelection) WL.Utils.clear_selection(); }
}

WL.Utils.clear_container = function( c ) { while( c.firstChild ) c.removeChild( c.firstChild ); }

WL.Utils.select_content = function( el, start, length)
{
	if( start==null ) start = 0;
	if( length==null ) length = el.value.length-start;
	if( el.createTextRange ) {
		var range = el.createTextRange();
		range.moveStart( "character", start );
		range.moveEnd( "character", length - el.value.length );
		range.select();
	} else if ( el.setSelectionRange ) {
		el.setSelectionRange( start, length );
	}
}
WL.Utils.clear_selection = function()
{
	if( window.getSelection ) { window.getSelection().removeAllRanges(); }
	else if( document.selection && document.selection.clear ) document.selection.clear();
}

WL.Utils.getRadioValue = function( group )
{
	var buttons = document.forms[0][group];
	if( buttons != null )
	{
		if(typeof(buttons.length)!="undefined")
		{
			for( var i = 0; i < buttons.length; ++i )
				if( buttons[i].checked ) return buttons[i].value;
		}
		else
		{
			if( buttons.checked ) return buttons.value;
		}
	}
	return null;
}

WL.Utils.setRadioValue = function( group, value )
{
	var buttons = document.forms[0][group];
	if( buttons != null )
	{
		if(typeof(buttons.length)!="undefined")
		{
			for( var i = 0; i < buttons.length; ++i )
				buttons[i].checked = buttons[i].value == value;
		}
		else
		{
			buttons.checked = buttons.value == value;
		}
	}
}

WL.Utils.webRequest = function( returner, request, response, nullResult, hidden )
{
	if( returner === undefined )
	{
		WL.Utils.assert( true, "call sync method" );
		return response.call( this, window.xmlCallback.doWebSyncRequest( request, null ) );
	}
	
	window.xmlCallback.doWebRequest( request, this, function( reader )
	{
		if( returner ) returner( response.call( this, reader ) );
	}, WL.Utils_.requestErrorHandler.bind( this, returner, nullResult ), hidden );
}
WL.Utils_.requestErrorHandler = function( returner, nullResult, errorInfo ) 
{ 
	if( returner ) 
	{
		if( nullResult == null )
			nullResult = {};
		nullResult.error = true;
		nullResult.errorInfo = errorInfo;		
		returner.call( this, nullResult ); 
	}
	else
		WL.Utils.assert( errorInfo, errorInfo );
}

WL.Utils.setNew = function( obj, prop, value )
{
	if( obj[ prop ] != value ) obj[ prop ] = value;
}

WL.Utils.getRequestParams = function()
{
	if( !window.dialogArguments ) window.dialogArguments = {}
	if( window.location.search != "" )
	{
		var p = window.location.search.substring( 1 ).toLowerCase().split( '&' );
		for( var i = 0; i < p.length; ++i )
		{
			var param = p[i].split( '=' );
			window.dialogArguments[ param[0] ] = param[1];
		}
	}
	return window.dialogArguments;
}

WL.$idmap = function(id) { return this.idmap[id] ? WL.$(this.idmap[id]) : null; }
WL.$$idmap = function(id) { return this.idmap[id] ? WL.$$(this.idmap[id]) : null; }

WL.$table = function( rows, cols, cellCreator )
{
	var table = WL.$e("TABLE");
	var tbody = WL.$e("TBODY");
	var tr, td;
	for( var i = 0; i < rows; ++i )
	{
		tr = WL.$e("TR");
		for( var j = 0; j < cols; ++j )
		{
			td = WL.$e("TD");
			if( cellCreator ) cellCreator( i, j, td );
			tr.appendChild( td );
		}
		tbody.appendChild(tr);
	}
	table.appendChild(tbody);
	return table;
}

WL.Utils.isCss = function( element, css )
{
	return element.className.split(' ').indexOf( css ) != -1;
}
WL.Utils.addCss = function( element, css )
{
	var classes = element.className.split(' ');
	if( classes.indexOf( css ) != -1 ) return;
		classes.push( css );
	element.className = classes.join(' ');
}
WL.Utils.removeCss = function( element, css )
{
	var classes = element.className.split(' ');
	var i = classes.indexOf( css );
	if( i != -1 ) { classes.removeAt(i); element.className = classes.join(' '); }
}
WL.Utils.replaceCss = function( element, css, newCss )
{
	var classes = element.className.split(' ');
	var i = classes.indexOf( css );
	if( i != -1 ) classes.removeAt(i);
	var i = classes.indexOf( newCss );
	if( i == -1 ) classes.push( newCss );
	element.className = classes.join(' ');
}

/////////////////////////////////////////////////////
WL.inputMasks = [];
WL.mask_detach = function( el )
{
	if( el.__mask_onkeypress )
	{
		WL.detachListener( el, "keypress", el.__mask_onkeypress );
		WL.detachListener( el, "blur", el.__mask_onblur );
		WL.detachListener( el, "focus", el.__mask_onfocus );
		
		el.__mask_onkeypress = null;
		el.__mask_onblur = null;
		el.__mask_onfocus = null;
	}
}
WL.mask_attach = function( el, mask_obj, def_value )
{
	WL.mask_detach(el);
	
	if( typeof(mask_obj) == "string" ) mask_obj = WL.inputMasks.find(WL.__mask_finder.bind(mask_obj));
	WL.Utils.assert( !mask_obj, "Input mask undefined" );
	if( !mask_obj ) return;
		
	if( el.value=="" ) el.value = def_value!=null?def_value:mask_obj.getDefault();
	el.value = mask_obj.validate(el.value);
	
	el.__mask_onkeypress = WL.__mask_onkeypress.bind(mask_obj);
	WL.attachListener( el, "keypress", el.__mask_onkeypress );
	
	el.__mask_onfocus = WL.__mask_onfocus.bind(mask_obj);
	WL.attachListener( el, "focus", el.__mask_onfocus );
	
	el.__mask_onblur = WL.__mask_onblur.bind(mask_obj);
	WL.attachListener( el, "blur", el.__mask_onblur );
}
WL.__mask_finder = function(it) { return this==it.getName(); }

WL.__mask_onkeypress = function(e) 
{
	e = WL.getEvent(e);
	var el = e.target;
	
	if( e.which == 0 ) return true;
	
	var key = e.which ? e.which : e.keyCode;
	if( e.ctrlKey || e.altKey || (key < 41 && key != 32 ) ) return true;
	if( document.selection && document.selection.createRange ) {
		var rng = document.selection.createRange();
		var rng0 = rng.text.length;
		rng.moveStart( 'character', -1000000 );
		el.selectionEnd = rng.text.length;
		el.selectionStart = el.selectionEnd - rng0;
	}

	var str = el.value.substr(0,el.selectionStart) + String.fromCharCode(key) + el.value.substr(el.selectionEnd);
	if( !this.check( str ) )
		return WL.returnEvent( e, false, true );
}
WL.__mask_onfocus = function(e) { this.focus(WL.getEvent(e).target); }
WL.__mask_onblur  = function(e) { e = WL.getEvent(e); e.target.value = this.validate( e.target.value ); }

WL.InputDouble = WL.Class( Object, function()
{
	this.constructor = function( name, v, min, max )
	{
		this.name = name;
		this._v = v;
		this.min = min;
		this.max = max;
	}
	this.getName = function() { return this.name; }
	this.getDefault = function() { return Math.max(0,this.min); }
	this.focus = function(e) { if(e.value=="0") e.value=""; }
	this.check = function(v) { if(this._v.indexOf(v)!=-1) return true; var i=Number(v); if(isNaN(i))return false; return Math.middle(this.min,i,this.max)==i; }
	this.validate = function(v) { return Math.middle(this.min,parseFloat(v)||0,this.max); }
} );

WL.InputInt = WL.Class( Object, function()
{
	this.constructor = function( name, v, min, max, allowEmpty )
	{
		this.name = name;
		this.min = min;
		this.max = max;
		this._v = v;
		this.empty = allowEmpty;
	}
	this.getName = function() { return this.name; }
	this.getDefault = function() { return this.empty?"":Math.max(this.min,0); }
	this.focus = function(e) { if(!this.empty&&e.value=="0") e.value=""; }
	this.check = function(v) { if(this._v.indexOf(v)!=-1) return true; var i=parseInt(v); return i.toString()==v&&Math.middle(this.min,i,this.max)==i; }
	this.validate = function(v) { return (v==""&&this.empty)?v:Math.middle(this.min,parseInt(v)||0,this.max); }
} );

WL.InputMoney = WL.Class( Object, function()
{
	this.constructor = function( name, v, min, max )
	{
		this.name = name;
		this._v = v;
		this.min = min;
		this.max = max;
		this.fraction = null;
	}
	this.getName = function() { return this.name; }
	this.getDefault = function() { return Math.max(0,this.min).toMoney(this.fraction); }
	this.focus = function(e)
	{
		var v=Number.fromMoney(e.value);
		if(e.value!=v){
if( WL.browser.ie ) {
			var rng = document.selection.createRange();
			rng.moveStart( 'textedit', -1 );
			var caret = rng.text.length;
			var pos = rng.text.split(',').length-1;
}
			e.value=v;
if( WL.browser.ie ) {
			rng.move( 'character', caret-pos );
			rng.select();
}
		}
	}
	this.check = function(v) { if(this._v.indexOf(v)!=-1) return true; var i=Number(v.split(CultureInfo.Currency.groupSeparator).join('')); if(isNaN(i))return false; return Math.middle(this.min,i,this.max)==i; }
	this.validate = function(v) { return Math.middle(this.min,Number.fromMoney(v)||0,this.max).toMoney(this.fraction); }
} );

WL.inputMasks.push( new WL.InputDouble( "double", ["","-",CultureInfo.Number.decimalSeparator], -2147483648, 2147483647 ) );
WL.inputMasks.push( new WL.InputDouble( "+double", ["",CultureInfo.Number.decimalSeparator], 0, 2147483647 ) );
WL.inputMasks.push( new WL.InputInt( "int", ["","-"], -2147483648, 2147483647, false ) );
WL.inputMasks.push( new WL.InputInt( "+int", [""], 0, 2147483647, false ) );
WL.inputMasks.push( new WL.InputInt( "natural", [""], 1, 2147483647, false ) );
WL.inputMasks.push( new WL.InputInt( "digits", [""], 0, 2147483647, true ) );
WL.inputMasks.push( new WL.InputMoney( "money", ["",CultureInfo.Currency.decimalSeparator], 0, 2147483647 ) );
WL.inputMasks.push( new WL.InputMoney( "money0", ["",CultureInfo.Currency.decimalSeparator], 0, 2147483647 ) );
WL.inputMasks.last().fraction = 0;

WL.Utils.floatToString = function( number, fraction, showZero, showSeparator, separatorChar, dotChar )
{
	function separate( input, separator )
	{
		var output = [];
		var len = input.length;
		for( var i = 0; i < len; ++i )
		{
			if( i != 0 && (len - i) % 3 == 0 ) output.push(separator);
			output.push( input.charAt(i) );
		}
		return output.join("");		
	}

	if( fraction == null ) fraction = 0;
	if( showZero == null ) showZero = false;
	if( showSeparator == null ) showSeparator = false;
	if( separatorChar == null ) separatorChar = '\'';
	if( dotChar == null ) dotChar = '.';
	
	var nums = number.toFixed( fraction ).split( '.' );
	
	if( showSeparator ) nums[0] = separate( nums[0], separatorChar );
	if( !showZero ) nums[1].trimRight( '0' );
	
	return nums.join( dotChar );
}

WL.Utils.setBit = function( flags, bit, state ) { return state ? ( flags | bit ) : ( flags & ~bit ); }

WL.Utils.cloneObject = function( obj )
{
	if( obj == null ) return null;	
	if( typeof( obj.clone ) == "function" ) return obj.clone();	
	return WL.Utils.cloneMethod.call( obj );
}
WL.Utils.cloneMethod = function() { return WL.Utils.copyObject( this, new this.constructor() ); }
WL.Utils.copyObject = function( obj, toObj )
{
	if( obj == null ) return null;
	if( toObj == null ) toObj = new obj.constructor();	
	if( typeof( obj.copyTo ) == "function" ) obj.copyTo(toObj);
	else WL.Utils.copyMethod.call( obj, toObj );
	return toObj;
}
WL.Utils.copyMethod = function( toObj )
{	
	for( var p in this )
	{
		switch( typeof( this[p] ) )
		{
			case "object": toObj[p] = WL.Utils.cloneObject( this[p] ); break;
			case "string": case "number": case "boolean": toObj[p] = this[p]; break;
			case "function": toObj[p] = this[p]; break;
			default: WL.Utils.assert( true, "WL.Utils.cloneMethod, type: " + typeof( this[p] ) ); break;
		}
	}
}

WL.PageLayout = WL.Class( Object, function()
{
	this.constructor = function( page )
	{
		this.page = page || window.page;
		this.page.__obs = 0;
	}
	this.activate = function()
	{
		if( this.page.currentLayout != this )
		{
			if( this.page.currentLayout )
				this.page.currentLayout.deactivate();
			this.page.__obs++;
			this.onactivate();			
			this.page.currentLayout = this;
		}
	}
	
	this.deactivate = function() { this.ondeactivate(); }
	
	this.onactivate = function(){}	
	this.ondeactivate = function(){}
	
	this.checkChanges = function( e, handler ) 
	{
		if( handler ) handler.call(this);
		return false;
	}
	
	this.checkUnloadChanges = function(e){}
	
	this.getObsoleteCookie = function() { return this.page.__obs; }
	this.isObsolete = function( cookie ) { return this.page.__obs != cookie; }
	this.obsolete = function() { this.page.__obs++; }
} );
/*
WL.Utils_.resize_engine_list = [];
WL.Utils_.resize_engine = function()
{
	var list = document.getElementsByTagName("DIV");
	for( var i = 0; i < list.length; ++i )
		if( list[i].attributes["wlr"] != null )
		{
			var value = nodes[i].attributes["auctionID"].value;
			if( value == "1" || value.toLowerCase() == "true" )
			{
				var d = list[i];
				var p = d.parentNode;
				var c = WL.$e("DIV");						
				c.style.width = c.style.height = "100%";
				c.style.overflow = "hidden";
				p.replaceChild( c, d );			
				d.style.width = p.offsetWidth + "px";
				d.style.height = p.offsetHeight + "px";
				d.style.overflow = "hidden";
				c.appendChild( d );
				WL.Utils_.resize_engine_list.push(c);
			}
		}
	if( WL.Utils_.resize_engine_list.length > 0 )
		WL.attachListener( window, "resize", WL.Utils_.resize_engine_window );
}
WL.Utils_.resize_engine_window = function()
{
	for( var i = 0; i < WL.Utils_.resize_engine_list.length; ++i )
	{
		var c = WL.Utils_.resize_engine_list[i];
		WL.Utils.setNew( c.firstChild.style, "width", c.parentNode.offsetWidth + "px" );
		WL.Utils.setNew( c.firstChild.style, "height", c.parentNode.offsetHeight + "px" );
	}
}
WL.attachListener( window, "load", WL.Utils_.resize_engine );
*/
WL.Utils.testEmail = function( email )
{
	if( !email ) return false;
	WL.Utils_.testEmailRegex.lastIndex = 0;
	return WL.Utils_.testEmailRegex.exec( email ) != null;
}
WL.Utils_.testEmailRegex = /\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/ig;

WL.Utils.tryInvoke = function( method, checker, period )
{
	var func = function() {
		if( checker() ) method(); 
		else window.setTimeout( func, period || 50 );
	}
	func();
}

WL.Utils.registerServerTime = function( serverTimeValue )
{
	window.serverTimeValue = serverTimeValue+((new Date()).valueOf()-window.localTimePoint);
	window.localTimePoint = (new Date()).valueOf();
}
WL.Utils.getServerTime = function(){ return new Date(window.serverTimeValue+((new Date()).valueOf()-window.localTimePoint)); }

WL.Utils.resolve = function( template, evaluators )
{
	return template.replace(/@@(.+?)@@/ig,function($0,$1){var k=$1.toUpperCase();for(var i=0;i<evaluators.length;++i){var v=evaluators[i].evaluate(k);if(v!=null)return v;}return $0;});
}

if( WL.browser.opera )
{
WL.Utils.getBody =
WL.Utils.getScrollBody = function() { return document.body; }
}
else
if( WL.browser.safari || WL.browser.chrome )
{
WL.Utils.getBody = function() { return document.documentElement.clientHeight < document.body.clientHeight ? document.documentElement : document.body; }
WL.Utils.getScrollBody = function() { return document.body; }
}
else
{
WL.Utils.getBody = 
WL.Utils.getScrollBody = function() { return document.compatMode && document.compatMode != "BackCompat" ? document.documentElement : document.body; }
}

if( WL.browser.ie )
{
WL.Utils.getElementOffset = function( e )
{
//	var rect = e.getClientRects()[0];
//	return {top:rect.top,left:rect.left,width:rect.right-rect.left,height:rect.bottom-rect.top};
	
	var offset		= new Object();
	offset.top		= 0;
	offset.left		= 0;
	offset.width	= e.offsetWidth;
	offset.height	= e.offsetHeight;
	
    while( e.offsetParent )
    {
        offset.left += e.offsetLeft + (parseInt(e.currentStyle.borderLeftWidth)).NaN0();
        offset.top  += e.offsetTop  + (parseInt(e.currentStyle.borderTopWidth)).NaN0();        
		if( e.scrollLeft ) offset.left -= e.scrollLeft;
		if( e.scrollTop ) offset.top -= e.scrollTop;
		e = e.offsetParent;
    }

	//var docBody = document.documentElement ? document.documentElement : document.body;
//	var docBody = WL.Utils.getBody();
//	offset.left += e.offsetLeft + (parseInt(e.currentStyle.borderLeftWidth)).NaN0() + (parseInt(docBody.scrollLeft)).NaN0() - (parseInt(docBody.clientLeft)).NaN0();
//	offset.top  += e.offsetTop  + (parseInt(e.currentStyle.borderTopWidth)).NaN0()  + (parseInt(docBody.scrollTop)).NaN0()  - (parseInt(docBody.clientTop)).NaN0();
    offset.left += e.offsetLeft;
    offset.top += e.offsetTop;
    return offset;
}
}
else // if( WL.browser.ie )
if( WL.browser.opera )
{
WL.Utils.getElementOffset = function( e )
{
	var offset		= new Object();
	offset.top		= 0;
	offset.left		= 0;
	offset.width	= e.offsetWidth;
	offset.height	= e.offsetHeight;

	var el = e;
	while( el.parentNode && el.tagName != "BODY" && el.tagName != "HTML" )
    {
		if( el.tagName != "TR" )
		{
			if( el.scrollLeft ) offset.left -= el.scrollLeft;
			if( el.scrollTop ) offset.top  -= el.scrollTop;
		}
		el = el.parentNode;
    }
    
	el = e;
    while( el.offsetParent )
    {
		offset.left += el.offsetLeft;
		offset.top  += el.offsetTop; 
		el = el.offsetParent;
    }

	//var docBody = document.documentElement ? document.documentElement : document.body;
	var docBody = WL.Utils.getBody();
	offset.left += el.offsetLeft - (parseInt(docBody.clientLeft)).NaN0();
	offset.top  += el.offsetTop  - (parseInt(docBody.clientTop)).NaN0();
    return offset;
}
}
else // if( WL.browser.opera )
if( WL.browser.safari || WL.browser.chrome )
{
WL.Utils.getElementOffset = function( e )
{
	var offset		= new Object();
	offset.top		= 0;
	offset.left		= 0;
	offset.width	= e.offsetWidth;
	offset.height	= e.offsetHeight;

	var el = e;
	while( el.parentNode && el.tagName != "BODY" && el.tagName != "HTML" )
    {
		if( el.scrollLeft ) offset.left -= el.scrollLeft;
		if( el.scrollTop ) offset.top  -= el.scrollTop;
		el = el.parentNode;
    }
    
	el = e;
    while( el.offsetParent )
    {
		offset.left += el.offsetLeft;
		if( el.tagName == "TD" ) offset.top  += el.parentNode.offsetTop; 
		else offset.top  += el.offsetTop; 
		el = el.offsetParent;
    }

	//var docBody = document.documentElement ? document.documentElement : document.body;
	var docBody = WL.Utils.getBody();
	offset.left += el.offsetLeft - (parseInt(docBody.clientLeft)).NaN0();
	offset.top  += el.offsetTop  - (parseInt(docBody.clientTop)).NaN0();
    return offset;
}
}
else // if( WL.browser.safari )
{
WL.Utils.getElementOffset = function( e )
{
	var offset		= new Object();
	offset.top		= 0;
	offset.left		= 0;
	offset.width	= e.offsetWidth;
	offset.height	= e.offsetHeight;

	var el = e;
	while( el.parentNode && el.tagName != "BODY" && el.tagName != "HTML" )
    {
		if( el.tagName != "TR" )
		{
			if( el.scrollLeft ) offset.left -= el.scrollLeft;
			if( el.scrollTop ) offset.top  -= el.scrollTop;
		}
		el = el.parentNode;
    }
    
	el = e;
    while( el.offsetParent )
    {
		offset.left += el.offsetLeft + (parseInt(WL.currentStyle(el).borderLeftWidth)).NaN0();
		offset.top  += el.offsetTop + (parseInt(WL.currentStyle(el).borderTopWidth)).NaN0();      
		el = el.offsetParent;
    }

	//var docBody = document.documentElement ? document.documentElement : document.body;
	var docBody = WL.Utils.getBody();
	offset.left += el.offsetLeft - (parseInt(docBody.clientLeft)).NaN0();
	offset.top  += el.offsetTop  - (parseInt(docBody.clientTop)).NaN0();
    return offset;
}
}

WL.Utils.transformTextToHtml = function( t ) { return t.escapeHTML().replace(/\n/gm,"<br />"); }

WL.Utils.Comparers = { 
	string: function(x,y) {return x.localeCompare(y);},
	number: function(x,y) {if(isNaN(x))return -1;if(isNaN(y))return 1;return x-y;},
	absnumber: function(x,y) {x=Math.abs(x);y=Math.abs(y);if(x==y)return 0;return x>y?1:-1;},
	date: function(x,y) {if(x.valueOf()==y.valueOf())return 0; return x.valueOf()>y.valueOf()?1:-1;},
	boolean: function(x,y) {if(x==y)return 0;return x?1:-1;}
};
/*
Comparers.asc.dateonly = function(x,y)
{
	if(x.getFullYear()==y.getFullYear())
	{
		if(x.getMonth()==y.getMonth())
		{
			if(x.getDate()==y.getDate()) return 0;
			return x.getDate()>y.getDate()?1:-1;
		}
		return x.getMonth()>y.getMonth()?1:-1;
	}
	return x.getFullYear()>y.getFullYear()?1:-1;
}
Comparers.desc.dateonly = function(x,y){return -Comparers.asc.dateonly(x,y);}
*/

/*
WL.Utils.attach_tooltip = function( el, tooltipHTML )
{
	if( el == null ) return;
	WL.Utils.detach_tooltip( el );
	
	var t = WL.$e( "div" );
//	t.className = "tooltip";
	t.className = "popup-zone bordered";
	t.style.display = "none";
	t.style.width = "40%";
//	t.style.position = "absolute";
//	t.style.zIndex = 20;
//	WL.Utils.select_action( t, null );
	t.innerHTML = tooltipHTML;
	document.forms[0].insertBefore(t,document.forms[0].childNodes[0]);
	el.t_id = WL.uniqueID( t );
	el.t_func = WL.Utils_.tooltip_show.bind(WL.uniqueID(el));
	WL.attachListener( el, "mouseover", el.t_func );	
}
WL.Utils.detach_tooltip = function( el ) { if( el && el.t_func ) WL.detachListener( el, "mouseover", el.t_func );	}
WL.Utils.show_tooltip = function( el, tooltip ) { WL.Utils.attach_tooltip( el, tooltip ); el.t_func(); WL.Utils.detach_tooltip(el); }
WL.Utils_.tooltip_show = function()
{
	var t_id = WL.$(this).t_id;
	if( WL.$(t_id).style.display != "none" ) return;
		
	var func_hide = (function(e)
		{
			if( WL.$(this) != null )
			{
				var el = WL.getEvent(e).target;
				if( WL.$(this) == el ) return;
				var t = WL.$(t_id);
				while( el ) { if( el == t ) return; el = el.parentNode; }				
			//	t.style.display = "none";
				WL.popup_hide();
			}
			else
				if( WL.$(t_id) ) WL.popup_hide();// WL.$(t_id).style.display = "none";
			
			WL.detachListener( document, "mouseover", func_hide );
		}).bind(this);
		
	WL.attachListener( document, "mouseover", func_hide );
	
	var o = WL.Utils.getElementOffset(WL.$(this));
	WL.popup_show( WL.$(t_id), {x:o.left,y:o.top,opacity:0} );
//	WL.$(t_id).style.left = o.left + "px";
//	WL.$(t_id).style.top = o.top + "px";
//	WL.$(t_id).style.display = "block";
}
*/