var ie=/*@cc_on!@*/false;
/*@if(@_jscript_version>=5.7) ie=7; @end@*/

function $(id) {
	return document.getElementById(id)
};

function $$(obj) {
	if (typeof(obj) == 'string') {
		return $(obj);
	} else {
		return obj;
	}
};

function $e(obj, type, fn)
{
	obj = $$(obj);

	if (!obj || !type || !fn || !fn.call) {
		return false;
	}

	if(obj.addEventListener) {
		obj.addEventListener(type, fn, false);
	} else if (obj.attachEvent) {
		obj.attachEvent('on' + type, fn);
	} else {
		return false;
	}

	return true;
}

$e.del = function(obj, type, fn) {
	obj = $$(obj);

	if(obj.removeEventListener) {
		obj.removeEventListener(type, fn, false);
	}else if(obj.detachEvent) {
		obj.detachEvent('on' + type, fn);
	}
};

function _GET(doc, val)
{
	var ar=[], param;
	var params = doc.location.search.substr(1).split('&');
	for (var i=0; i < params.length; i++) {
		param = params[i].split('=');
		ar[param[0]] = param[1] || '';
	}

	return val ? ar[val] : ar;
}

function getWindowSize(win) {
	var myWidth = 0, myHeight = 0;

	if (win == undefined) {
		win = window;
	}
	doc = win.document;

	if (typeof(win.innerWidth) == 'number') {
		//Non-IE
		myWidth = win.innerWidth;
		myHeight = win.innerHeight;
	} else if (
		doc.documentElement &&
		(doc.documentElement.clientWidth || doc.documentElement.clientHeight)
	) {
		//IE 6+ in 'standards compliant mode'
		myWidth = doc.documentElement.clientWidth;
		myHeight = doc.documentElement.clientHeight;
	} else if (
		doc.body && (doc.body.clientWidth || doc.body.clientHeight)
	) {
		//IE 4 compatible
		myWidth = doc.body.clientWidth;
		myHeight = doc.body.clientHeight;
	}

	return {
		width: myWidth,
		height: myHeight
	};
}

function getWindowWidth() {
	return getWindowSize().width;
}

function getWindowHeight() {
	return getWindowSize().height;
}

function getWindowScrollPos() {
	var scrOfX = 0, scrOfY = 0;

	if (typeof( window.pageYOffset ) == 'number') {
		//Netscape compliant
		scrOfY = window.pageYOffset;
		scrOfX = window.pageXOffset;

	} else if (
		document.body &&
		(document.body.scrollLeft || document.body.scrollTop)
	) {
		//DOM compliant
		scrOfY = document.body.scrollTop;
		scrOfX = document.body.scrollLeft;

	} else if (
		document.documentElement && (
			document.documentElement.scrollLeft ||
			document.documentElement.scrollTop
		)
	) {
		//IE6 standards compliant mode
		scrOfY = document.documentElement.scrollTop;
		scrOfX = document.documentElement.scrollLeft;
	}

	return {left: scrOfX, top: scrOfY};
}

function getWindowScrollTop() {
	return getWindowScrollPos().top;
}

function getWindowScrollLeft() {
	return getWindowScrollPos().left;
}

function ovl2() {}

ovl2._auto_hide_timer = null;
ovl2._resize_iframe_timer = null;
ovl2._resize_iframe_width = false;
ovl2._resize_iframe_height = false;
ovl2._visible = false;
ovl2._left = null;
ovl2._top = null;

ovl2._show = function(f, auto_hide_interval, _skip_resources)
{
	if (ovl2._visible) {
		ovl2.hide()
	}

	if (_skip_resources == undefined) {
		_skip_resources = false;
	}

	var div_ovl2 = document.createElement('DIV');
	div_ovl2.id = 'divovl2';
	
    if (ie) {
		div_ovl2.style.filter = 'alpha(opacity=0)';
	}

	var div_pos = document.createElement('DIV');
	div_pos.id = 'divovl2Pos';

	div_pos.style.visibility = 'hidden';

	var div_content = document.createElement('DIV');
	div_content.id = 'divovl2Content';
	div_pos.appendChild(div_content)

	f(div_content);

	var b = document.body;
	b.appendChild(div_ovl2);
	b.appendChild(div_pos);

	ovl2._resize()

	div_pos.style.visibility = 'visible';

	if (!_skip_resources) {
		var iframes = div_pos.getElementsByTagName('IFRAME');
		for (var i=0; i<iframes.length; i++) {
			$e(iframes[i], 'load', ovl2._resize._delayed);
		}

		var images = div_pos.getElementsByTagName('IMG');
		for (var i=0; i<images.length; i++) {
			var img = new Image();
			$e(img, 'load', ovl2._resize._delayed);
			img.src = images[i].src;
		}
	}

	$e(window, 'resize', ovl2._resize._delayed);
	$e(window, 'scroll', ovl2._resize._delayed);

	$e($('divovl2'), 'click', ovl2.hide);
	if (auto_hide_interval != undefined) {
		if (ovl2._auto_hide_timer) {
			clearTimeout(ovl2._auto_hide_timer);
		}
		ovl2._auto_hide_timer = window.setTimeout(ovl2.hide, auto_hide_interval);
	}

	ovl2._visible = true;

	return false;
};

ovl2.show = function(content, left, top, auto_hide_interval, _skip_resources ) {
 	ovl2._left = left;
    ovl2._top = top;
    ovl2._show(function (div_content) {
		div_content.innerHTML = content
	}, auto_hide_interval, _skip_resources);
	return false;
}

ovl2._resize = function() {
	var div_pos = $('divovl2Pos');
	var div_ovl2 = $('divovl2');
	var div_content = $('divovl2Content');

	if (!div_pos || !div_ovl2 || !div_content) {
		return;
	}

	var b = document.body;

	var window_size = getWindowSize();
	var window_scroll_pos = getWindowScrollPos();

	// div_ovl2.style.width = Math.max(b.offsetWidth, b.scrollWidth, b.clientWidth) + 'px';
	div_ovl2.style.height = Math.max(b.offsetHeight, b.scrollHeight, b.clientHeight) + 'px';
	div_ovl2.style.width = b.offsetWidth + 'px';
	// div_ovl2.style.height = b.offsetHeight + 'px';

   if (!ovl2._left) 
    {
        var left = (window_size.width / 2) - (div_content.offsetWidth / 2);
    	if (left < 0) {
    		left = 0;
    	}
    	left = left + window_scroll_pos.left;
    }
    else {
        left = ovl2._left;
    }
    if (!ovl2._top) 
    {
    	var top = (window_size.height / 2) - (div_content.offsetHeight / 2);
    	if (top < 0) {
    		top = 0;
    	}
    	top = top + window_scroll_pos.top;
    }
    else {
        top = ovl2._top;
    }
    
	div_pos.style.left = left + 'px';
	div_pos.style.top = top + 'px';
};

ovl2._resize._delayed = function() {
	if (ovl2._resize._timer) {
		clearTimeout(ovl2._resize._timer);
	}
	ovl2._resize._timer = setTimeout(ovl2._resize, 0);
};

ovl2.hide = function() {
	if (ovl2._visible) {
		$e.del(window, 'resize', ovl2._resize._delayed)
		$e.del(window, 'scroll', ovl2._resize._delayed)
		if (ovl2._auto_hide_timer) {
			clearTimeout(ovl2._auto_hide_timer);
		}
		if (ovl2._resize_iframe_timer) {
			clearTimeout(ovl2._resize_iframe_timer);
		}

		document.body.removeChild($('divovl2Pos'));
		document.body.removeChild($('divovl2'));

		ovl2._visible = false;
	}
	return false;
};

ovl2._resizeIFrame = function() {
	var iframe = $('iframeovl2');
	if (!iframe) {
		return;
	}
	var win = iframe.contentWindow;

	if (!win) {
		if (ovl2._resize_iframe_timer) {
			clearTimeout(ovl2._resize_iframe_timer);
		}
		ovl2._resize_iframe_timer = setTimeout(ovl2._resizeIFrame, 100);
		return
	}

	var fr_size = null;
	var w_size = getWindowSize();
	var divovl2Outer = win.document.getElementById('divovl2Outer')

	if (!divovl2Outer) {
		fr_size = {
			width: win.document.body.scrollWidth,
			height: win.document.body.scrollHeight
		};
	} else {
		fr_size = {
			width: divovl2Outer.offsetWidth,
			height: divovl2Outer.offsetHeight
		};
	}

	if (ovl2._resize_iframe_width) {
		if (fr_size.width + 150 > w_size.width) {
			fr_size.width = w_size.width - 150;
			if (fr_size.width < 0) {
				fr_size.width = 150;
			}
		}
		iframe.width = fr_size.width + 'px';
	}

	if (ovl2._resize_iframe_height) {
		if (fr_size.height + 150 > w_size.height) {
			fr_size.height = w_size.height - 150;
			if (fr_size.height < 0) {
				fr_size.height = 150;
			}
		}
		iframe.height = fr_size.height + 'px';
	}

	ovl2._resize();

	$e(iframe, 'load', ovl2._resizeIFrame);
}

ovl2.showImage = function(src, auto_hide_interval) {
	return ovl2_image.show(src, auto_hide_interval);
}

ovl2.showIFrame = function(src, width, height, background, auto_hide_interval) {
	return ovl2_iframe.show(src, width, height, background, auto_hide_interval);
}

function ovl2Image(loading_src, close_src) {
	if (document.images) {
		var loading_img = new Image();
		loading_img.src = loading_src;
		var close_img = new Image();
		close_img.src = close_src;
	}
	this.loading = '<div id="divovl2Loading"><img src="' + loading_src + '" alt="..." /></div>';
	this.close_div_tag = '<div id="divovl2Close"><img onclick="ovl2.hide()" src="' + close_src + '" alt="[X]" /></div>';
}

ovl2Image.prototype.show = function(src, auto_hide_interval) {
	if (document.images) {
		ovl2.show(this.loading);
		var content_img = new Image();
		var close_div_tag = this.close_div_tag;
		var on_content_img_load = function() {
			$e.del(content_img, 'load', on_content_img_load);
			ovl2.show(close_div_tag + '<img onclick="ovl2.hide()" id="imgovl2" src="' + src + '" alt="" />', auto_hide_interval, true);
			// $('divovl2Close').style.left = (7 + $('imgovl2').offsetWidth) + 'px';
		}
		$e(content_img, 'load', on_content_img_load);
		content_img.style.visibility = 'hidden';
		content_img.src = src;
	} else {
		ovl2.show(this.close_div_tag + '<img onclick="ovl2.hide()" id="imgovl2" src="' + src + '" alt="" />', auto_hide_interval);
	}
	return false;
}

ovl2_image = new ovl2Image('/common/static/loading.gif', '/common/static/close.gif');

function ovl2IFrame(loading_src, close_src) {
	if (document.images) {
		var loading_img = new Image();
		loading_img.src = loading_src;
		var close_img = new Image();
		close_img.src = close_src;
	}
	this.loading = '<div id="divovl2Loading"><img src="' + loading_src + '" alt="..." /></div>';
	this.close_div_tag = '<div style="display:none" id="divovl2Close"><img onclick="ovl2.hide()" src="' + close_src + '" alt="[X]" /></div>';
}

ovl2IFrame.prototype.show = function(src, width, height, background, auto_hide_interval) {
	if (document.images) {
		ovl2.show(this.loading, undefined, true);
	} else {
		ovl2.show(this.loading);
	}

	var div_content = $('divovl2Content')

	var iframe_style = 'display:none';
	if (background != undefined) {
		iframe_style = iframe_style + '; background: ' + background;
	}
	var iframe_html = '<iframe src="' + src + '" style="' + iframe_style + '" id="iframeovl2" name="iframeovl2" frameBorder="0" scrolling="no"';

	var w_size = getWindowSize();

	if (width != undefined) {
		iframe_html = iframe_html + ' width="' + width + '"';
		ovl2._resize_iframe_width = false;
	} else {
		iframe_html = iframe_html + ' width="' + w_size.width + '"';
		ovl2._resize_iframe_width = true;
	}

	if (height != undefined) {
		iframe_html = iframe_html + ' height="' + height + '"';
		ovl2._resize_iframe_height = false;
	} else {
		iframe_html = iframe_html + ' height="' + w_size.height + '"';
		ovl2._resize_iframe_height = true;
	}
	iframe_html = iframe_html + '></iframe>';

	div_content.innerHTML = div_content.innerHTML + this.close_div_tag + iframe_html;
	var iframe = document.getElementById('iframeovl2');

	var on_content_iframe_load = function() {
		$e.del(iframe, 'load', on_content_iframe_load);

		var div_loading = $('divovl2Loading')
		div_loading.parentNode.removeChild(div_loading);

		$('divovl2Close').style.display = '';
		iframe.style.display = '';

		ovl2._resizeIFrame();
	}

	$e(iframe, 'load', on_content_iframe_load);
	return false;
}

ovl2_iframe = new ovl2IFrame('/common/static/loading.gif', '/common/static/close.gif');

var rexp_url = /^(http|https|ftp):\/\/[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+/i;
var rexp_url_wo_proto = /^[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+/i;
var rexp_domain = /^[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/i;
var rexp_email = /^([0-9a-zA-Z]+([_.-]?[0-9a-zA-Z]+)*@[0-9a-zA-Z]+[0-9,a-z,A-Z,.,-]*(.){1}[a-zA-Z]{2,4})+$/;
var rexp_mailto = /^mailto:\s*([0-9a-zA-Z]+([_.-]?[0-9a-zA-Z]+)*@[0-9a-zA-Z]+[0-9,a-z,A-Z,.,-]*(.){1}[a-zA-Z]{2,4})+$/i;
var rexp_time = /^([0-1][0-9]|[2][0-3])(:([0-5][0-9])){1,2}$/;
var rexp_ip = /^((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})$/;
var rexp_decimal = /^\d*[0-9](\.\d*[0-9])?$/;
var rexp_img_fname = /^[a-zA-Z0-9-_\.]+\.(jpg|jpeg|gif|png)$/;

function show_dict(d, skip)
{
	var s = '';
	var i = 1;
	if (typeof(skip) == 'undefined') skip = 0
	for (var k in d)
	{
		if (skip <= 0)
		{
			try { s = s + i + '. ' + k + '=>' + d[k] + '\n'; } catch (e) {};
		}
		skip = skip - 1;
		i = i + 1;
	}
	alert(s);
}

function html_quote(s) {
	s = s.replace(/&/g, '&amp;');
	s = s.replace(/"/g, '&quot;');
	s = s.replace(/</g, '&lt;');
	s = s.replace(/>/g, '&gt;');
	s = s.replace(/'/g, '&#39;');
	return s
}

function callFunction(func, args)
{

	func.apply(null, args);
}

function addToClassName(obj, name)
{
	var s = obj.className;
	var re = new RegExp('(?=\\b)' + name + '(?=\\b)', 'gi')
	s.replace(re, '');
	s = s + ' ' + name;
	s = s.split(/\s/).join(' ');
	obj.className = s;
}

function removeFromClassName(obj, name)
{
	var s = obj.className;
	var re = new RegExp('(?=\\b)' + name + '(?=\\b)', 'gi')
	s = s.replace(re, '');
	s = s.split(/\s/).join(' ');
	obj.className = s;
}

function hasInClassName(obj, name)
{
	var s = obj.className;
	var re = new RegExp('(\\s+|^)' + name + '(\\s+|$)', 'gi')
	return re.test(s);
}

function callMethod(obj, method_name, args)
{
	obj[method_name].apply(obj, args);
}

function args2array(args, skip)
{
	if (typeof(skip) == 'undefined')
	{
		skip = 0;
	}
	var arr = new Array();
	for (var i=skip; i<args.length; i++)
	{
		arr[i-skip] = args[i];
	}
	return arr;
}

function has_value(arr, value)
{
	for (var i=0; i<arr.length; i++)
	{
		if (arr[i] == value)
		{
			return true;
		}
	}
	return false;
}

function BoundMethod(obj, method_name)
{
	if (arguments.length > 2)
	{
		var bound_args = args2array(arguments, 2);
		return function()
		{
			if (arguments.length > 0)
			{
				var args = args2array(arguments);
				return callMethod(obj, method_name, bound_args.concat(args));
			}
			else
			{
				return callMethod(obj, method_name, bound_args);
			}
		}
	}
	else
	{
		return function()
		{
			return callMethod(obj, method_name, arguments);
		}
	}
}

function addEventListener2(obj, event_name, listener)
{
	var old_handler = obj[event_name];
	if (old_handler)
	{
		new_handler = function()
		{
			callFunction(old_handler, arguments);
			callFunction(listener, arguments);
		};
	}
	else
	{
		new_handler = listener;
	}
	obj[event_name] = new_handler;
}

function findOuterForm(element)
{
	var p = element.parentNode;
	if (!p.tagName)
	{
		return null;
	}
	if (p.tagName.toLowerCase() == 'form')
	{
		return p;
	}
	return findOuterForm(p);
}

function openDialogWindow(url, name, w, h)
{
	var sFeatures = 'directories=0,location=0,menubar=0,toolbar=0,' +
		'resizable=1,scrollbars=1,status=0,dependent=yes';
	var sFeatures = "toolbar=no,status=no,resizable=yes,dependent=yes";
	if (typeof(w) != 'undefined')
	{
		sFeatures = sFeatures + ',width=' + w.toString();
	}
	if (typeof(h) != 'undefined')
	{
		sFeatures = sFeatures + ',height=' + h.toString();
	}
	var w = window.open(url, name, sFeatures);
	w.focus();
	return w;
}

function getElementCurrentStyle(elm)
{
	if (window.getComputedStyle) {
		return window.getComputedStyle(elm, null);
	} else if (elm.currentStyle) {
		return elm.currentStyle;
	} else {
		return null;
	}
}

function getEventPos(e)
{
	var posx = 0;
	var posy = 0;
	if (!e) var e = window.event;
	if (e.pageX || e.pageY)
	{
		posx = e.pageX;
		posy = e.pageY;
	}
	else if (e.clientX || e.clientY)
	{
		posx = e.clientX + document.body.scrollLeft;
		posy = e.clientY + document.body.scrollTop;
	}
	return {x: posx, y: posy};
}

function getEventElement(e)
{
	return (e.target) ? e.target : e.srcElement;
}

function getEventKeyCode(e)
{
	var code;
	if (!e) var e = window.event;
	if (e.keyCode) code = e.keyCode;
	else if (e.which) code = e.which;
	return code;
}

function getEventChar(e)
{
	return String.fromCharCode(getEventKeyCode(e));
}

function cancelEvent(e)
{
	if (!e) var e = window.event;
	e.returnValue = false;
	if (e.preventDefault) e.preventDefault();
	return false;
}

function cancelEventBubble(e)
{
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}

function getElementPos(obj)
{
	var posx = 0;
	var posy = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			posx += obj.offsetLeft;
			posy += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
	{
		posx += obj.x;
		posy += obj.y;
	}
	return {x: posx, y: posy};
}

function Evt(e)
{
	this._e = (e) ? e : window.event;
}

Evt.prototype.getElement = function()
{
	return this._elm ? this._elm : (this._elm = getEventElement(this._e));
}

Evt.prototype.getKeyCode = function()
{
	return this._code ? this._code : (this._code = getEventKeyCode(this._e));
}

Evt.prototype.getChar = function()
{
	return this._char ? this._char : (this._char = getEventChar(this._e));
}

Evt.prototype.cancel = function()
{
	return cancelEvent(this._e);
}

Evt.prototype.cancelBubble = function()
{
	cancelEventBubble(this._e);
}

Evt.prototype.getPos = function()
{
	return (this._pos) ? this._pos : (this._pos = getEventPos(this._e));
}

Evt.prototype.getX = function()
{
	return (this._pos) ? this._pos.x : ((this._pos = getEventPos(this._e)).x);
}

Evt.prototype.getY = function()
{
	return (this._pos) ? this._pos.y : ((this._pos = getEventPos(this._e)).y);
}

function getQueryString()
{
	return location.search.substring(1);
}

function qs2dict(qs)
{
	var params = qs.split('&');
	var values = new Array();
	for (var i=0; i<params.length; i++)
	{
		if (params[i] != '')
		{
			var tmp = params[i].split('=');
			if (values[tmp[0]] == undefined)
			{
				values[tmp[0]] = unescape(tmp[1]);
			}
			else if (values[tmp[0]].length != undefined &&
				typeof(values[tmp[0]]) != 'string')
			{
				values[tmp[0]][values[tmp[0]].length] = unescape(tmp[1]);
			}
			else
			{
				values[tmp[0]] = [values[tmp[0]], unescape(tmp[1])];
			}
		}
	}
	return values;
}

function getQueryDict()
{
	return qs2dict(getQueryString());
}

function dict2qs(d)
{
	params = new Array();
	for (var k in d)
	{
		//params[params.length] = k + '=' + escape(d[k]);
		if (d[k].length != undefined && typeof(d[k]) != 'string')
		{
			for (var i=0; i<d[k].length; i++)
			{
				params[params.length] = k + '=' + d[k][i];
			}
		}
		else
		{
			params[params.length] = k + '=' + d[k];
		}
	}
	return params.join('&');
}

function setQueryString(qs, fragment)
{
	fragment = (fragment != undefined) ? ('#' + fragment) : '';
	qs = (qs != '') ? ('?' + qs) : '';
	location.replace(location.pathname + qs + fragment);
}

function setQueryDict(d, fragment)
{
	setQueryString(dict2qs(d), fragment)
}

function setQueryParam(k, v, fragment)
{
	var d = getQueryDict();
	d[k] = v;
	setQueryDict(d, fragment);
}

function setQueryParams(params, fragment)
{
	var d = getQueryDict();
	for (var k in params)
	{
		d[k] = params[k];
	}
	setQueryDict(d, fragment);
}


function resizeToElement(element, addw, addh)
{
	pos = getElementPos(element);
	w = element.offsetWidth;
	h = element.offsetHeight;
	if (typeof(addw) != "undefined")
		w = w + addw;
	if (typeof(addh) != "undefined")
		h = h + addh;
	/*availWidth = screen.availWidth - 100;
	availHeight = screen.availHeight - 100;
	if (availWidth < w) w = availWidth;
	if (availHeight < h) h = availHeight;*/
	window.resizeTo(w, h);
}

function disable_form(theform)
{
	for (i=0; i<theform.length; i++)
	{
		var tempobj = theform.elements[i];
		if (tempobj.type.toLowerCase() == "submit")
			tempobj.disabled = true;
		if (tempobj.type.toLowerCase() == "button")
			tempobj.disabled = true;
	}
}

function preload_images() {
	var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
	var i,j=d.MM_p.length,a=preload_images.arguments;
	for(i=0; i<a.length; i++) if (a[i].indexOf("#")!=0)
	{ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
}

function send_http_request(args) {
	args = args || {};

	var is_timed_out = false;
	var timer = null;

	if (args.timeout) {
		timer = setTimeout(function () {
			is_timed_out = true;
			if (args.ontimeout) {
				args.ontimeout();
			}
			if (args.onfail) {
				args.onfail();
			}
			if (args.onfinish) {
				args.onfinish();
			}
		}, args.timeout);
	}

	var xmlhttp = window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP");

	xmlhttp.onreadystatechange = function () {
		if ((!is_timed_out) && (xmlhttp.readyState == 4)) {
			clearTimeout(timer);
			timer = null;
			if (xmlhttp.status == 200) {
				if (args.ontextready) {
					args.ontextready(xmlhttp.responseText);
				}
				if (args.ondataready) {
					var data = eval('res=' + xmlhttp.responseText + ';res');
					args.ondataready(data);
				}
				if (args.onfinish) {
					args.onfinish();
				}
			} else {
				if (args.onerror) {
					args.onerror(xmlhttp.status, xmlhttp.responseText);
				}
				if (args.onfail) {
					args.onfail();
				}
				if (args.onfinish) {
					args.onfinish();
				}
			}
		}
	};

	xmlhttp.open(args.method||'GET', args.url, args.async||true, args.user, args.passwd);
	xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
	xmlhttp.send(args.data||null);
}

/*
// send_http_request usage example:

alert('Start');

send_http_request({
	url: '/ajax_answer.js',
	data: 'qwe=123&asd=432', // post data
	timeout: 2000,
	method: 'POST',
	async: false,
	ontextready: function(response_text) {
		alert('Text ready\n\n' + response_text);
	},
	ondataready: function(data) {
		alert('Data ready\n\n' + data);
	},
	onerror: function(status, response_text) {
		alert('Error: ' + status + '\n\n' + response_text);
	},
	ontimeout: function() {
		alert('Timeout');
	},
	onfail: function() {
		alert('Fail');
	},
	onfinish: function() {
		alert('Finish');
	}
});
*/

function select(selector, root) {
	/* That revolting regular expression explained
	/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
	  \---/  \---/\-------------/    \-------/
		|      |         |               |
		|      |         |           The value
		|      |    ~,|,^,$,* or =
		|   Attribute
	   Tag
	*/

	function getAllChildren(e) {
		return e.all ? e.all : e.getElementsByTagName('*');
	}

	function getAllChildrenByTagName(elm, tagName) {
		try {
			return elm.getElementsByTagName(tagName);
		}
		catch(e) {
			return [];
		}
	}

	function getChildren(e) {
		return e.childNodes;
	}

	function getChildrenByTagName(elm, tagName) {
		tagName = tagName.toUpperCase();
		var elms = elm.childNodes;
		var res = []
		for (var i=0; i<elms.length; i++) {
			if (elms[i].tagName && elms[i].tagName.toUpperCase() == tagName) {
				res[res.length] = elms[i];
			}
		}
		return res;
	}

	// Attempt to fail gracefully in lesser browsers
	if (!document.getElementsByTagName) {
		return new Array();
	}
	// Split selector in to tokens
	var tokens = selector.split(' ');
	root = $$(root);
	var currentContext = new Array(root || document);
	for (var i = 0; i < tokens.length; i++) {
		token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');
		if (token.indexOf('>') == 0) {
			token = token.replace(/^>/,'');
			get_children = getChildren;
			get_children_by_tag_name = getChildrenByTagName;
		} else {
			get_children = getAllChildren;
			get_children_by_tag_name = getAllChildrenByTagName;
		}
		if (token.indexOf('#') > -1) {
			// Token is an ID selector
			var bits = token.split('#');
			var tagName = bits[0];
			var id = bits[1];
			var element = document.getElementById(id);
			if (tagName && element.nodeName.toLowerCase() != tagName) {
				// tag with that ID not found, return false
				return new Array();
			}
			// Set currentContext to contain just this element
			currentContext = new Array(element);
			continue; // Skip to next token
		}
		if (token.indexOf('.') > -1) {
			// Token contains a class selector
			var bits = token.split('.');
			var tagName = bits[0];
			var className = bits[1];
			if (!tagName) {
				tagName = '*';
			}
			// Get elements matching tag, filter them for class selector
			var found = new Array;
			var foundCount = 0;
			for (var h = 0; h < currentContext.length; h++) {
				var elements;
				if (tagName == '*') {
						elements = get_children(currentContext[h]);
				} else {
						try {
								elements = get_children_by_tag_name(currentContext[h], tagName);
						}
						catch(e) {
								elements = [];
						}
				}
				for (var j = 0; j < elements.length; j++) {
					found[foundCount++] = elements[j];
				}
			}
			currentContext = new Array;
			var currentContextIndex = 0;
			for (var k = 0; k < found.length; k++) {
				if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
					currentContext[currentContextIndex++] = found[k];
				}
			}
			continue; // Skip to next token
		}
		// Code to deal with attribute selectors
		if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
			var tagName = RegExp.$1;
			var attrName = RegExp.$2;
			var attrOperator = RegExp.$3;
			var attrValue = RegExp.$4;
			if (!tagName) {
				tagName = '*';
			}
			// Grab all of the tagName elements within current context
			var found = new Array;
			var foundCount = 0;
			for (var h = 0; h < currentContext.length; h++) {
				var elements;
				if (tagName == '*') {
						elements = get_children(currentContext[h]);
				} else {
						elements = get_children_by_tag_name(currentContext[h], tagName);
				}
				for (var j = 0; j < elements.length; j++) {
					found[foundCount++] = elements[j];
				}
			}
			currentContext = new Array;
			var currentContextIndex = 0;
			var checkFunction; // This function will be used to filter the elements
			switch (attrOperator) {
				case '=': // Equality
					checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
					break;
				case '~': // Match one of space seperated words
					checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
					break;
				case '|': // Match start with value followed by optional hyphen
					checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
					break;
				case '^': // Match starts with value
					checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
					break;
				case '$': // Match ends with value - fails with "Warning" in Opera 7
					checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
					break;
				case '*': // Match ends with value
					checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
					break;
				default :
					// Just test for existence of attribute
					checkFunction = function(e) { return e.getAttribute(attrName); };
			}
			currentContext = new Array;
			var currentContextIndex = 0;
			for (var k = 0; k < found.length; k++) {
				if (checkFunction(found[k])) {
					currentContext[currentContextIndex++] = found[k];
				}
			}
			// alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
			continue; // Skip to next token
		}
		// If we get here, token is JUST an element (not a class or ID selector)
		tagName = token;
		var found = new Array;
		var foundCount = 0;
		for (var h = 0; h < currentContext.length; h++) {
			var elements = get_children_by_tag_name(currentContext[h], tagName);
			for (var j = 0; j < elements.length; j++) {
				found[foundCount++] = elements[j];
			}
		}
		currentContext = found;
	}
	return currentContext;
}

/*
// select usage example:

var elms = select('table#main_menu >tbody >tr >td');
*/

function menu() {}

menu._menu_registry = [];
menu._menu_item_registry = [];

menu._force_hide = function() {
	for (var i=0; i<menu._menu_registry.length; i++) {
		if (menu._menu_registry[i]._hide_timer) {
			menu._menu_registry[i]._hide();
		}
	}
}

menu.Menu = function(elm, parent, position) {
	this.elm = elm;
	this.parent = parent;
	this._hide_timer = null;
	this.position = position || 'bottom';
	this._is_visible = false;
	if (parent) {
		parent._regSubMenu(this);
		var body = document.getElementsByTagName('body')[0]
		elm.style.display = 'none';
		elm.style.zIndex = 9999;
		elm.parentNode.removeChild(elm);
		body.appendChild(elm);
		elm.style.position = 'absolute';
		addToClassName(elm, 'menu');
	}
	var obj = this;
	$e(elm, 'mouseover', function(e) { obj._onMouseOver(e) })
	$e(elm, 'mouseout', function(e) { obj._onMouseOut(e) })
	menu._menu_registry[menu._menu_registry.length] = this;
}

menu.Menu.prototype._getPosRelativeParent = function() {
	var parent = this.parent;
	var elm = this.elm;
	var position = this.position;
	var parent_elm = parent.elm

	var pp = getElementPos(parent_elm);
	var pos = null;

	if (position == 'bottom') {
		pos = {
			top: pp.y + parent_elm.offsetHeight,
			left: pp.x
		};
	} else if (position == 'right') {
		pos = {
			top: pp.y,
			left: pp.x + parent_elm.offsetWidth
		};
	} else if (position == 'top') {
		pos = {
			top: pp.y - parent_elm.offsetHeight,
			left: pp.x
		};
	} else {
		pos = position(this, parent);
	}

	var window_size = getWindowSize();

	if (pos.top > window_size.height - elm.offsetHeight) {
		pos.top = window_size.height - elm.offsetHeight;
	}

	if (pos.left > window_size.width - elm.offsetWidth) {
		pos.left = window_size.width - elm.offsetWidth;
	}

	if (pos.top < 0) {
		pos.top = 0;
	}

	if (pos.left < 0) {
		pos.left = 0;
	}

	return pos;
}

menu.Menu.prototype._over = function() {
	if (this.parent) {
		this.parent._over();
	}
	this.show();
}

menu.Menu.prototype._out = function() {
	this.hide();
	if (this.parent) {
		this.parent._out();
	}
}

menu.Menu.prototype._onMouseOver = function(e) {
	var e = new Evt(e);
	e.cancelBubble();
	this._over();
}

menu.Menu.prototype._onMouseOut = function(e) {
	var e = new Evt(e);
	e.cancelBubble();
	this._out();
}

menu.Menu.prototype._show = function() {
	if (!this._is_visible) {
		this.elm.style.display = '';
		var pos = this._getPosRelativeParent()
		this.elm.style.top = pos.top + "px";
		this.elm.style.left = pos.left + "px";
		this._is_visible = true;
		menu._force_hide();
	}
}

menu.Menu.prototype._hide = function() {
	if (this._is_visible) {
		if (this._hide_timer) {
			clearTimeout(this._hide_timer);
			this._hide_timer = null;
		}
		this.elm.style.display = 'none';
		this._is_visible = false;
		if (this.parent && this.parent._is_hover) {
			this.parent._setHover(false);
		}
	}
}

menu.Menu.prototype.show = function() {
	if (this._hide_timer) {
		clearTimeout(this._hide_timer);
		this._hide_timer = null;
	}
	this._show();
}

menu.Menu.prototype.hide = function() {
	if (this._hide_timer) {
		clearTimeout(this._hide_timer);
		this._hide_timer = null;
	}
	var obj = this;
	this._hide_timer = setTimeout(function () { obj._hide_timer = null; obj._hide(); }, 500);
}

menu.MenuItem = function(elm, parent) {
	this.elm = elm;
	this.parent = parent || null;
	this.submenu = null;
	var obj = this;
	$e(elm, 'mouseover', function(e) { obj._onMouseOver(e) })
	$e(elm, 'mouseout', function(e) { obj._onMouseOut(e) })
	menu._menu_item_registry[menu._menu_item_registry.length] = this;
	this._out_timer = null;
	this._is_hover = false;
}

menu.MenuItem.prototype._regSubMenu = function(submenu) {
	this.submenu = submenu;
}

menu.MenuItem.prototype._over = function() {
	if (this.parent) {
		this.parent._over();
	}
	this._setHover(true);
	if (this.submenu) {
		this.submenu.show();
	}
	menu._force_hide();
}

menu.MenuItem.prototype._setHover = function(v) {
	if (v) {
		addToClassName(this.elm, 'menu-item-hover');
	} else {
		removeFromClassName(this.elm, 'menu-item-hover');
	}
	this._is_hover = v;
}

menu.MenuItem.prototype._out = function() {
	if (this.submenu) {
		this.submenu.hide();
	}
	if (!this.submenu || !this.submenu._is_visible) {
		this._setHover(false);
	}
	if (this.parent) {
		this.parent._out();
	}
}

menu.MenuItem.prototype._onMouseOver = function(e) {
	var e = new Evt(e);
	e.cancelBubble();
	this._over();
}

menu.MenuItem.prototype._onMouseOut = function(e) {
	var e = new Evt(e);
	e.cancelBubble();
	this._out();
}

menu.init = function (parent_menu, root, menu_item_selector, submenu_selector, submenu_position) {
	var menu_item_elms = select(menu_item_selector, root);
	var menu_items = new Array();

	for (var menu_item_i=0; menu_item_i < menu_item_elms.length; menu_item_i++) {
		var menu_item_elm = menu_item_elms[menu_item_i];
		var menu_item = new menu.MenuItem(menu_item_elm, parent_menu);
		menu_items[menu_items.length] = menu_item;

		var submenu_elms = select(submenu_selector, menu_item_elm);
		for (var submenu_i=0; submenu_i < submenu_elms.length; submenu_i++) {
			var submenu_elm = submenu_elms[submenu_i];
			var submenu = new menu.Menu(submenu_elm, menu_item, submenu_position);
			var new_args = args2array(arguments, 5);
			if (new_args.length == 0) {
				new_args[new_args.length] = menu_item_selector;
			}
			if (new_args.length == 1) {
				new_args[new_args.length] = submenu_selector;
			}
			if (new_args.length == 2) {
				new_args[new_args.length] = submenu_position;
			}
			new_args = [submenu, submenu_elm].concat(new_args);
			menu.init.apply(null, new_args);
		}
	}

	return menu_items;
}

/*
// menu usage example:

function init() {
	menu.init(null, null, 'table#main_menu >tbody >tr >td', '>ul', 'bottom', '>li', '>ul', 'right');
}
*/