function encode_base64( what )
{
	var base64_encodetable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	var result = "";
	var len = what.length;
	var x, y;
	var ptr = 0;

	while( len-- > 0 )
	{
		x = what.charCodeAt( ptr++ );
		result += base64_encodetable.charAt( ( x >> 2 ) & 63 );

		if( len-- <= 0 )
		{
			result += base64_encodetable.charAt( ( x << 4 ) & 63 );
			result += "==";
			break;
		}

		y = what.charCodeAt( ptr++ );
		result += base64_encodetable.charAt( ( ( x << 4 ) | ( ( y >> 4 ) & 15 ) ) & 63 );

		if ( len-- <= 0 )
		{
			result += base64_encodetable.charAt( ( y << 2 ) & 63 );
			result += "=";
			break;
		}

		x = what.charCodeAt( ptr++ );
		result += base64_encodetable.charAt( ( ( y << 2 ) | ( ( x >> 6 ) & 3 ) ) & 63 );
		result += base64_encodetable.charAt( x & 63 );

	}

	return result;
}

function cancelAction(event)
{
	if (event.stopPropagation)
		event.stopPropagation();
	else //if (event.cancelBubble)
		event.cancelBubble = true;

	if (event.preventDefault)
		event.preventDefault();
	else //if (event.returnValue)
		event.returnValue = false;
}

function findParentByTagName(elem, tagname)
{
	while (elem)
	{
		if (String(elem.nodeName).toLowerCase() == String(tagname).toLowerCase())
			return elem;
		elem = elem.parentNode;
	}
	return null;
}

function findParentByClassName(elem, classname)
{
	var re = new RegExp("\\b" + classname + "\\b");
	while (elem)
	{
		if (String(elem.className).match(re))
			return elem;
		elem = elem.parentNode;
	}
	return null;
}

function findChild(elem, tagname, classname)
{
	var re = new RegExp("\\b" + classname + "\\b");
	var children = elem.getElementsByTagName(tagname);
	for (var i = 0; i < children.length; i++)
	{
		var child = children[i];
		if (String(child.className).match(re))
			return child;
	}
	return null;
}

function findChildren(elem, tagname, classname, name)
{
	var reClass = classname ? new RegExp("\\b" + classname + "\\b") : null;
	var reName = name ? new RegExp("\\b" + name + "\\b") : null;
	var children = elem.getElementsByTagName(tagname);
	var found = new Array();
	for (var i = 0; i < children.length; i++)
	{
		var child = children[i];
		if (reClass && !String(child.className).match(reClass))
			continue;
		if (reName && !String(child.name).match(reName))
			continue;
		found[found.length] = child;
	}
	return found;
}

function classAdd(elem, classname)
{
	if (!elem)
		return;

	var re = new RegExp("\\b" + classname + "\\b");
	if (String(elem.className).match(re))
		return;

	elem.className += (String(elem.className) == "" ? "" : " ") + classname;
}

function classRemove(elem, classname)
{
	if (!elem)
		return;

	var re = new RegExp("\\b" + classname + "\\b");
	if (!String(elem.className).match(re))
		return;

	elem.className = String(elem.className).replace(re, "");
	elem.className = String(elem.className).replace(/^\s+|\s+$/, "");
	elem.className = String(elem.className).replace(/\s\s+$/, " ");
}
