﻿/* ====================================================================================*\
|* =============================== JScript Library ====================================*|
|* ================================== by VNVN41 =======================================*|
\* ====================================================================================*/

var loadQueue = [];
window.onload = function()
{
	window.__isLoaded = true;
	for (var i = 0; i < loadQueue.length; i++)
		loadQueue[i].wait(10);
	loadQueue = null;
}

var Browser			= {};
Browser.userAgent	= navigator.userAgent.toLowerCase();
Browser.Opera		= ((Browser.userAgent.indexOf('opera') != -1) || (typeof(window.opera) != 'undefined'));
Browser.Safari		= ((Browser.userAgent.indexOf('applewebkit') != -1) || (navigator.vendor == 'Apple Computer, Inc.'));
Browser.Webtv		= (Browser.userAgent.indexOf('webtv') != -1);
Browser.IE			= ((Browser.userAgent.indexOf('msie') != -1) && (!Browser.Opera) && (!Browser.Safari) && (!Browser.Webtv));
Browser.IE4			= ((Browser.IE) && (Browser.userAgent.indexOf('msie 4.') != -1));
Browser.IE6			= ((Browser.userAgent.indexOf('msie 6.') != -1) && Browser.IE);
Browser.IE7			= ((Browser.userAgent.indexOf('msie 7.') != -1) && Browser.IE);
Browser.Mozila		= ((navigator.product == 'Gecko') && (!Browser.Safari));
Browser.Kon			= (Browser.userAgent.indexOf('konqueror') != -1);
Browser.Nes			= ((Browser.userAgent.indexOf('compatible') == -1) && (Browser.userAgent.indexOf('mozilla') != -1) && (!Browser.Opera) && (!Browser.Webtv) && (!Browser.Safari));
Browser.Nes4		= ((Browser.Nes) && (parseInt(navigator.appVersion) == 4));
Browser.Mac			= (Browser.userAgent.indexOf('mac') != -1);

/* ================= Element ================= */
var Element =
{
	get: function(id)
	{
		if (id == null || id == "")
			return null;
		if (id && id.tagName)
			return id;
		return document.getElementById(id);
	},

	create: function(tagName, parentNode)
	{
		if (typeof (tagName) == "string")
			return document.createElement(tagName);
		else
			return Element._create(tagName, get(parentNode), {});
	},

	_create: function(childs, parent, rootParent)
	{
		var obj = null;
		var count = childs.length;
		for (var i = 0; i < count; i++)
		{
			var child = childs[i];
			var tag = child[0]; //.toUpperCase();
			var atts = child[1];
			var _childs = child[2];
			switch (tag)
			{
				case "TR":
					obj = Element._createTR(parent);
					break;
				case "TD":
					obj = Element._createTD(parent);
					break;
				case "OPTION":
					obj = document.createElement(tag);
					parent.options.add(obj);
					break;
				case "UC":
					eval("obj = new " + atts + "()");
					atts = _childs;
					_childs = null;
					break;
				case "IFRAME":
					obj = document.createElement(tag);
					obj.frameBorder = 0;
					obj.src = "about:blank";
					if (obj && parent) parent.appendChild(obj);
					break;

				case "INPUT":
					if (Browser.IE)
					{
						obj = document.createElement("<INPUT type='" + atts["type"] + "' name='" + atts["name"] + "'></INPUT>");
						atts["type"] = null;
						atts["name"] = null;
						delete atts["type"];
						delete atts["name"];
						if (obj && parent) parent.appendChild(obj);
						break;
					}

				default:
					obj = document.createElement(tag);
					if (obj && parent) parent.appendChild(obj);
					break;
			}
			if (obj)
			{
				for (var att in atts)
				{
					switch (att)
					{
						case "style":
							var styles = atts[att];
							for (var s in styles)
							{
								switch (s)
								{
									case "opacity":
										Element.makeOpacity(obj, styles[s]);
										break;
									case "position":
										if (styles[s] == "fixed" && Browser.IE6)
											styles[s] = "absolute";
									default:
										obj.style[s] = styles[s] || "";
										break;
								}
							}
							break;

						case "UNSELECTABLE":
							Element.setAttribute(obj, "UNSELECTABLE", atts[att]);
							break;

						case "innerHTML":
						case "frameBorder":
							if (Browser.IE)
							{
								var parent = obj.parentNode;
								if (parent)
								{
									parent.removeChild(obj);
									obj[att] = atts[att];
									parent.appendChild(obj);
								}
							}
							else
								obj[att] = atts[att];
							break;

						case "text":
							if (Browser.IE)
								obj.innerText = atts[att];
							else
								obj.textContent = atts[att];
							break;

						case "ID":
							rootParent[atts[att]] = obj;
							break;

						default:
							obj[att] = atts[att];
							break;
					}
				}
				if (tag == "UC")
					obj.create(parent);
				if (_childs != null && _childs.length > 0)
					Element._create(_childs, obj, rootParent);
			}
		}
		return rootParent;
	},

	_createTR: function(table)
	{
		if (Browser.IE)
			return table.insertRow();
		else
		{
			var tr = document.createElement("TR");
			table.appendChild(tr);
			return tr;
		}
	},

	_createTD: function(tr)
	{
		if (Browser.IE)
			return tr.insertCell();
		else
		{
			var td = document.createElement("TD");
			tr.appendChild(td);
			return td;
		}
	},

	getSize: function(element)
	{
		element = get(element);
		return [element.offsetWidth, element.offsetHeight];
	},

	setSize: function(element, w, h)
	{
		element = get(element);
		if (element != null)
		{
			if (w != null && w >= 0) element.style.width = w + "px";
			if (h != null && h >= 0) element.style.height = h + "px";
		}
	},

	setPosition: function(element, x, y)
	{
		element = get(element);
		if (x != null && x >= 0) element.style.left = x + "px";
		if (y != null && y >= 0) element.style.top = y + "px";
	},

	setAttribute: function(element, name, value)
	{
		if (!element.attributes)
			return;
		if (element.attributes.getNamedItem(name) == null)
		{
			var att = document.createAttribute(name);
			att.value = value;
			element.attributes.setNamedItem(att);
		}
		else
			element.attributes.getNamedItem(name).value = value;
	},

	getAttribute: function(element, name)
	{
		element = get(element);
		if (element)
		{
			var att = element.attributes.getNamedItem(name);
			if (att == null) return null;
			return att.value;
		}
		return null;
	},

	getPosition: function(element)
	{
		return [parseInt(element.style.left), parseInt(element.style.top)];
	},

	getOffsetPosition: function(element)
	{
		element = get(element);
		return [element.offsetLeft, element.offsetTop];
	},

	getRealOffsetPosition: function(element)
	{
		var valueT = 0, valueL = 0;
		do
		{
			valueT += element.offsetTop || 0;
			valueL += element.offsetLeft || 0;
			element = element.offsetParent;
			if (element)
			{
				//if ()
				//	break;
				//var p = element.style.position;
				//if (p == 'relative' || p == 'absolute')
				//	break;
			}
		} while (element && element.tagName != 'BODY');
		return [valueL, valueT];
	},

	show: function(element)
	{
		get(element).style.display = '';
	},

	hide: function(element)
	{
		get(element).style.display = 'none';
	},

	visible: function(element)
	{
		get(element).style.visibility = 'visible';
	},

	invisible: function(element)
	{
		get(element).style.visibility = 'hidden';
	},

	text: function(element)
	{
		element = get(element);
		return element.innerText || element.textContent;
	},

	setText: function(element, value)
	{
		element = get(element);
		if (Browser.IE)
			element.innerText = value;
		else
			element.textContent = value;
	},

	makeOpacity: function(element, opacity)
	{
		element = get(element);
		if (Browser.IE)
		{
			var filter = element.style['filter'],
				style = element.style;
			if (opacity == 1 || opacity === '')
			{
				style.filter = filter.replace(/alpha\([^\)]*\)/gi, '');
			}
			else
			{
				if (opacity < 0.00001) value = 0;
				style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + (opacity * 100) + ')';
			}
		}
		else
			element.style.opacity = opacity;
	},

	refreshNode: function(element)
	{
		element = get(element);
		var p = element.parentNode;
		if (p)
		{
			p.removeChild(element);
			p.appendChild(element);
		}
	}
}

function get(id)
{
	return Element.get(id);
}

function gets(name)
{
	return document.getElementsByTagName(name);
}

function exec(script)
{
	if (Browser.IE)
		window.execScript(script);
	else
		window.eval(script);
}

function create(tag, parentNode)
{
	return Element.create(tag, parentNode);
}

function inherit(obj, base)
{
	for (var o in base)
		obj[o] = base[o];
}

function isFunction(func)
{
	return (func != null && typeof(func) == typeof(Function));
}

var Event =
{
	cancel: function(e)
	{
		if (!e) return;
		if (Browser.IE)
		{
			e.returnValue = false;
			e.cancelBubble = true;
			return e;
		}
		else
		{
			e.stopPropagation();
			e.preventDefault();
			return e;
		}
	},

	stop: function(e)
	{
		if (!e) return;
		if (Browser.IE)
		{
			e.cancelBubble = true;
			return e;
		}
		else
		{
			e.stopPropagation();
			return e;
		}
	},

	element: function(e)
	{
		return (e.target || e.srcElement);
	},

	raise: function(name, element)
	{
		name = name.toLowerCase();
		if (document.createEvent)
		{
			if (name.startsWith("on"))
				name = eventName.substr(2);

			var e = null;
			if ((name.substr(0, 5) == 'mouse') || (name == 'click'))
			{
				e = document.createEvent("MouseEvents");
				e.initMouseEvent(name, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
			}
			else
			{
				e = document.createEvent('HTMLEvents');
				e.initEvent(name, false, false);
			}

			get(element).dispatchEvent(e);
		}
		else if (document.createEventObject)
		{
			get(element).fireEvent("onclick");
		}
	}
};


/* ================= String ================= */

String.format = function(template, object)
{
	return Template.evaluate(template, object, /(^|.|\r|\n)(\{(.*?)\})/);
}

String.prototype.endsWith = function(pattern)
{
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
}

String.prototype.trim = function()
{
	var str = this;
	if (str == null || str == "")
		return str;
			
	while (str.substring(0, 1) == ' ')
		str = str.substring(1, str.length);
	while (str.substring(str.length - 1, str.length) == ' ')
		str = str.substring(0, str.length - 1);
	return str;
}

/* ================= Array ================= */

Array.prototype.select = function(func)
{
	var arr = [];
	for (var i = 0 ; i < this.length ; i++)
	{
		var item = func(this[i], i);
		if (item)
			arr.push(item);
	}
	return arr;
}

Array.prototype.each = function(fn, bind)
{
	for(var i = 0; i < this.length ; i++) fn.call(bind, this[i], i);
};

/* ================= Template ================= */

var Template = 
{
	Pattern : /(^|.|\r|\n)(#\{(.*?)\})/	,			// #{ name }
	//		  /(^|.|\r|\n)(\<%=\s*(\w+)\s*%\>)/		// <%= %>
	
	evaluate: function(template, object, pattern)
	{
		template	= template.toString();
		pattern		= pattern || Template.Pattern;
		
		var result = '', source = template, match;

		while (source.length > 0) 
		{
			if (match = source.match(pattern)) 
			{
				result += source.slice(0, match.index);
				{
					var before = match[1];
					if (before == '\\') return match[2];
					result += before + ((o = object[match[3]]) ? o : '');
				};
				source  = source.slice(match.index + match[0].length);
			}
			else
				result += source, source = '';
		}
		return result;
	}
}

/* ================= Function ================= */

var $A = function(iterable) 
{
	if (!iterable) return [];
	if (iterable.toArray) 
	{
		return iterable.toArray();
	}
	else 
	{
		var results = [];
		for (var i = 0, length = iterable.length; i < length; i++)
			results.push(iterable[i]);
		return results;
	}
}

Function.prototype.handle = function() 
{
	var __method = this, args = $A(arguments), object = args.shift();
	return function() 
	{
		return __method.apply(object, args.concat($A(arguments)));
	}
}
	
Function.prototype.eventHandle = function(object) 
{
	var __method = this, args = $A(arguments), object = args.shift();
	return function(event)
	{
		return __method.apply(object, [event || window.event].concat(args));
	}
}

Function.prototype.wait = function(m_second)
{
	return window.setTimeout(this, m_second);
}

Function.prototype.loop = function(m_second)
{
	return window.setInterval(this, m_second);
}

/* ================= Color ================= */
var Color =
{
	rgbToHex: function(str, isArray)
	{
		var rgb = str.match(new RegExp('([\\d]{1,3})', 'g'));
		if (rgb[3] == 0) 
			return 'transparent';
		var hex = [];
		for (var i = 0; i < 3; i++)
		{
			var bit = (rgb[i] - 0).toString(16);
			hex.push(bit.length == 1 ? '0' + bit : bit);
		}
		var hexText = '#' + hex.join('');
		if (isArray) 
			return hex;
		else
			return hexText;
	},

	hexToRgb: function(str, isArray)
	{
		var hex = str.match(new RegExp('^[#]{0,1}([\\w]{1,2})([\\w]{1,2})([\\w]{1,2})$'));
		var rgb = [];
		for (var i = 1; i < hex.length; i++)
		{
			if (hex[i].length == 1) 
				hex[i] += hex[i];
			rgb.push(parseInt(hex[i], 16));
		}
		var rgbText = 'rgb(' + rgb.join(',') + ')';
		if (isArray) 
			return rgb;
		else 
			return rgbText;
	},
	
	hexToDec : function(value)
	{
		return parseInt(value, 16);
	},
	
	decToHex : function(value)
	{
		var hex_string = "";
		for (var hexpair = 0; hexpair < 3; hexpair++) 
		{
			var myByte = value & 0xFF;          
			value >>= 8;                        
			var nybble2 = myByte & 0x0F;        
			var nybble1 = (myByte >> 4) & 0x0F; 
			hex_string += nybble1.toString(16); 
			hex_string += nybble2.toString(16); 
		}
		return hex_string.toUpperCase();
	}
}

/* ================= XML ================= */
var Xml = 
{
	load : function(file, func)
	{
		var doc = null;
		if (window.ActiveXObject)
		{
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async = false;
			doc.load(file);
			func(doc);
		}
		else
		{
			doc = document.implementation.createDocument("", "", null);
			doc.load(file);
			doc.onload = func.handle(null, doc);
		}
	},
	
	parse : function(xml)
	{
		var doc = null;
		if (window.ActiveXObject)
		{
			doc = new ActiveXObject("Microsoft.XMLDOM");
			doc.async = "false";
			doc.loadXML(xml);
		}
		else
		{
			var parser = new DOMParser();
			doc = parser.parseFromString(xml, "text/xml");
		}
		return doc;
	},
	
	safeStringForXml : function(str)
	{
		if (!str || str == "")
			return "";
		return str.replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
	}
}

/* ================= Function ================= */
var Class = function(args)
{
	var _class = function(args)
	{
		for (var i in args)
			this[i] = args[i];
		if (this.init)
		{
			if (window.__isLoaded)
				this.init();
			else
				loadQueue.push(this.init.handle(this));
		}
	}
	return _class;
}

/* ================= PopMenu ================= */

var PopupMenu = new Class();
PopupMenu.prototype = 
{
	menu		: null,
	moved		: null,
	moveObj		: null,
	useMask		: null,
	resetPos	: null,
	autoClose	: null,
	opacity		: null,
	centerScreen: null,
	onopen		: null,
	onclose		: null,
	usingForm	: null,
	isOpen		: null,
	background	: "#fff",
	
	init : function()
	{
		if (!this.opacity) this.opacity = 0.5;
		if (this.menu)
		{
			if (this.moved)
			{
				var _p = this.usingForm ? document.forms[0] : document.body;
				var tmp = create
				(
					[
						["DIV", {ID : "DocZone", style : {width : "100%", height : "100%", background : this.background,
								 zIndex : 997, position : "fixed", top : "0px", left : "0px", display : "none",
								 opacity : this.opacity
								}}],
						["DIV", {ID : "Zone", style : {width : "100%", height : "100%",
								 zIndex : 998, position : "fixed", top : "0px", left : "0px", display : "none"
								}},[
							["DIV", {ID : "Mask", style : {width : "1px", height : "1px", background : "#888",
								 zIndex : 999, position : "absolute", top : "0px", left : "0px", display : "none",
								 opacity : 0.5, cursor : "default", border : "1px solid #000"}}]
						]]
					],
					_p
				);
				this.DocZone	= tmp.DocZone;
				this.Zone		= tmp.Zone;
				this.Mask		= tmp.Mask;
				this.menu.style.zIndex	 = 998;
			}
			
			this.menu = get(this.menu);
			this.menu.style.position = "absolute";
			Element.invisible(this.menu);
			if (this.moved)
			{
				if (this.x == null && this.y == null)
				{
					var pos = Element.getRealOffsetPosition(this.menu);
					this.x	= pos[0];
					this.y	= pos[1];
				}
				var p = this.menu.parentNode;
				p.removeChild(this.menu);
				this.Zone.appendChild(this.menu);
				Element.setPosition(this.menu, this.x, this.y);
			}
		}
	},
	
	show : function(x, y)
	{
		if (!this.isOpen)
		{
			this.saveDocMouseDown	= document.onmousedown;
			this.saveMenuMouseDown	= this.menu.onmousedown;
			document.onmousedown	= this._docMouseDown.handle(this);
			this.menu.onmousedown	= this._menuMouseDown.eventHandle(this);
		}
		
		if (Browser.IE6)
		{
			document.getElementsByTagName("HTML")[0].style.overflow = "hidden";
			Element.setPosition(this.DocZone, (document.documentElement.scrollLeft || document.body.scrollLeft), (document.documentElement.scrollTop || document.body.scrollTop));
			Element.setPosition(this.Zone, (document.documentElement.scrollLeft || document.body.scrollLeft), (document.documentElement.scrollTop || document.body.scrollTop));
		}

		if (this.moved)
		{
			if (!this.isOpen)
			{
				if (!this.moveObj) this.moveObj = this.menu;
				
				this.saveDocMouseUp			= document.onmouseup;
				this.saveDocMouseMove		= document.onmousemove;
				this.saveMoveObjMouseDown	= this.moveObj.onmousedown;
				if (Browser.IE)
				{
					this.saveSelectStart	= document.onselectstart;
					document.onselectstart	= this._onSelectStart.handle(this);
				}
				
				document.onmouseup			= this._docMouseUp.handle(this);
				document.onmousemove		= this._docMouseMove.handle(this);
				this.moveObj.onmousedown	= this._moveObjMouseDown.eventHandle(this);
				if (this.resetPos)
					this.savePos = Element.getPosition(this.menu);
			}
			
			Element.show(this.DocZone);
			Element.show(this.Zone);
			var s1 = Element.getSize(this.Zone);
			var s2 = Element.getSize(this.menu);
			if (this.centerScreen)
			{
				x = (s1[0] - s2[0]) / 2;
				y = (s1[1] - s2[1]) / 2;
			}
			else
			{
				if (x == null) x = this.x;
				if (y == null) y = this.y;
				
				if (x < 0) x = 0;
				if (x + s2[0] >= s1[0]) x = s1[0] - s2[0];
				if (y < 0) y = 0;
				if (y + s2[1] >= s1[1]) y = s1[1] - s2[1];
			}
			
			Element.setPosition(this.menu, x, y);
		}
		else
		{
			if (x != null && y != null)
				Element.setPosition(this.menu, x, y);
		}
		Element.visible(this.menu);
		if (!this.isOpen && this.onopen) this.onopen();
		this.isOpen = true;
	},
	
	hide : function()
	{
		if (Browser.IE6)
		{
			document.getElementsByTagName("HTML")[0].style.overflow = "auto";
		}
	
		if (this.moved)
		{
			document.onmouseup			= this.saveDocMouseUp;
			document.onmousemove		= this.saveDocMouseMove;
			this.moveObj.onmousedown	= this.saveMoveObjMouseDown;
			this.saveDocMouseUp	= this.saveDocMouseMove = this.saveMoveObjMouseDown = null;
			if (Browser.IE)
			{
				document.onselectstart	= this.saveSelectStart;
				this.saveSelectStart	= null;
			}
			Element.hide(this.DocZone);
			Element.hide(this.Zone);
			
			if (this.resetPos)
			{
				Element.setPosition(this.menu, this.savePos[0], this.savePos[1]);
				this.x = this.y = null;
			}
		}
		document.onmousedown	= this.saveDocMouseDown;
		this.menu.onmousedown	= this.saveMenuMouseDown;
		this.saveDocMouseDown	= this.saveMenuMouseDown = null;
		Element.invisible(this.menu);
		if (this.onclose) this.onclose();
		this.isOpen = false;
	},
	
	_menuMouseDown : function(e)
	{
		Event.stop(e);
		if (this.saveMenuMouseDown) this.saveMenuMouseDown(e);
	},
	
	_moveObjMouseDown : function(e)
	{
		if (!e) e = window.event;
		if ((Browser.IE && e.button == 1) || (!Browser.IE && e.button == 0))
		{
			if (Event.element(e) == this.moveObj)
			{
				this._moving = true;
				this.lastX	= e.clientX;
				this.lastY	= e.clientY;
				this.width	= this.menu.offsetWidth;
				this.height	= this.menu.offsetHeight;
				this.x		= parseInt(this.menu.style.left);
				this.y		= parseInt(this.menu.style.top);
				if (this.useMask)
				{
					Element.setSize(this.Mask, this.width, this.height);
					Element.setPosition(this.Mask, this.x, this.y);
					Element.show(this.Mask);
				}
				document.body.style.MozUserSelect		= "none";
				document.body.style.WebkitUserSelect	= "none";
				this.Zone.style.MozUserSelect			= "none";
				this.Zone.style.WebkitUserSelect		= "none";
			}
		}
		if (this.saveMoveObjMouseDown) this.saveMoveObjMouseDown(e);
		Event.cancel(e);
	},
	
	_endMove : function()
	{
		this._moving = false;
		if (this.useMask)
			Element.hide(this.Mask);
		document.body.style.MozUserSelect		= "text";
		document.body.style.WebkitUserSelect	= "text";
		this.Zone.style.MozUserSelect			= "text";
		this.Zone.style.WebkitUserSelect		= "text";
	},
	
	_docMouseDown : function(e)
	{
		if (this.autoClose)
			this.hide();
		if (this.saveDocMouseDown) this.saveDocMouseDown(e);
	},
	
	_docMouseUp : function(e)
	{
		if (this._moving)
		{
			this._endMove();
			if (this.useMask)
				Element.setPosition(this.menu, this.x, this.y);
		}
	},
	
	_docMouseMove : function(e)
	{
		if (!e) e = window.event;
		if (this._moving && ((Browser.IE && e.button != 1) || (!Browser.IE && e.button != 0)))
		{
			this._endMove();
			return;
		}
		if (this._moving)
		{
			var curX	= e.clientX,
				curY	= e.clientY,
				x		= this.x + curX - this.lastX,
				y		= this.y + curY - this.lastY,
				w		= this.Zone.offsetWidth,
				h		= this.Zone.offsetHeight;
			if (x < 0) x = 0;
			if (x + this.width >= w) x = w - this.width;
			if (y < 0) y = 0;
			if (y + this.height >= h) y = h - this.height;
			this.lastX	= curX;
			this.lastY	= curY;
			this.x		= x;
			this.y		= y;
			if (this.useMask)
				Element.setPosition(this.Mask, x, y);
			else
				Element.setPosition(this.menu, x, y);
		}
		if (this.saveDocMouseMove) this.saveDocMouseMove(e);
	},
	
	_onSelectStart : function(e)
	{
		if (this._moving)
		{
			if (!e) e = window.event;
			Event.cancel(e);
		}
	}
}

/* ================= Effect ================= */
var Effect = new Class();
/*
Author: Robert Penner, <http://www.robertpenner.com/easing/>, modified to be used with mootools.
License: Easing Equations v1.5, (c) 2003 Robert Penner, all rights reserved. Open Source BSD License.
*/
Effect.Transitions = 
{
	linear : function(t, b, c, d)
	{
		return c * t / d + b;
	},

	quadIn: function(t, b, c, d){
		return c*(t/=d)*t + b;
	},

	quadOut: function(t, b, c, d){
		return -c *(t/=d)*(t-2) + b;
	},

	quadInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},

	cubicIn: function(t, b, c, d){
		return c*(t/=d)*t*t + b;
	},

	cubicOut: function(t, b, c, d){
		return c*((t=t/d-1)*t*t + 1) + b;
	},

	cubicInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},

	quartIn: function(t, b, c, d){
		return c*(t/=d)*t*t*t + b;
	},

	quartOut: function(t, b, c, d){
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},

	quartInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},

	quintIn: function(t, b, c, d){
		return c*(t/=d)*t*t*t*t + b;
	},

	quintOut: function(t, b, c, d){
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},

	quintInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},

	sineIn: function(t, b, c, d){
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},

	sineOut: function(t, b, c, d){
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},

	sineInOut: function(t, b, c, d){
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},

	expoIn: function(t, b, c, d){
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},

	expoOut: function(t, b, c, d){
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},

	expoInOut: function(t, b, c, d){
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},

	circIn: function(t, b, c, d){
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},

	circOut: function(t, b, c, d){
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},

	circInOut: function(t, b, c, d){
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},

	elasticIn: function(t, b, c, d, a, p){
		if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (!a) a = 1;
		if (a < Math.abs(c)){ a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin(c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},

	elasticOut: function(t, b, c, d, a, p){
		if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; if (!a) a = 1;
		if (a < Math.abs(c)){ a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin(c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},

	elasticInOut: function(t, b, c, d, a, p){
		if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5); if (!a) a = 1;
		if (a < Math.abs(c)){ a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin(c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},

	backIn: function(t, b, c, d, s){
		if (!s) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},

	backOut: function(t, b, c, d, s){
		if (!s) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},

	backInOut: function(t, b, c, d, s){
		if (!s) s = 1.70158;
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},

	bounceIn: function(t, b, c, d){
		return c - Effect.Transitions.bounceOut (d-t, 0, c, d) + b;
	},

	bounceOut: function(t, b, c, d){
		if ((t/=d) < (1/2.75)){
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)){
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)){
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},

	bounceInOut: function(t, b, c, d){
		if (t < d/2) return Effect.Transitions.bounceIn(t*2, 0, c, d) * .5 + b;
		return Effect.Transitions.bounceOut(t*2-d, 0, c, d) * .5 + c*.5 + b;
	}

};

Effect.prototype =
{
	fps: 50,
	duration: 500,
	transition: Effect.Transitions.linear,
	unit: "px",
	style: "",
	element: null,
	from: null,
	to: null,
	onstart: null,
	onend: null,

	start: function()
	{
		if (this.run) this.abort();
		if (this.onstart) this.onstart();
		this.element = get(this.element);
		this.run = true;
		this.timer = null,
		this.time = 0;
		this._loop = this.duration / this.fps;
		switch (this.style)
		{
			case "backgroundColor":
			case "borderColor":
			case "borderBottomColor":
			case "borderLeftColor":
			case "borderTopColor":
			case "borderBottomColor":
			case "color":
				this.from = Color.hexToRgb(this.from, true);
				this.to = Color.hexToRgb(this.to, true);
				this.now = [];
				this._isColor = true;
				break;
		}
		this._set();
	},

	abort: function()
	{
		this.run = false;
		if (this.timer) window.clearTimeout(this.timer);
	},

	_set: function()
	{
		if (this.time > this.duration)
		{
			this.run = false;
			this.now = this.to;
			this._setStyle();
			if (this.onend) this.onend();
		}
		else
		{
			if (this._isColor)
				this.from.each(function(value, index)
				{
					this.now[index] = Math.round(this.transition(this.time, value, this.to[index] - value, this.duration));
				}, this);
			else
				this.now = this.transition(this.time, this.from, this.to - this.from, this.duration);
			this._setStyle();
			this.time += this._loop;
			this.timer = window.setTimeout(this._set.handle(this), this._loop);
		}
	},

	_setStyle: function()
	{
		switch (this.style)
		{
			case "backgroundColor":
			case "borderColor":
			case "borderBottomColor":
			case "borderLeftColor":
			case "borderTopColor":
			case "borderBottomColor":
			case "color":
				this.element.style[this.style] = "rgb(" + this.now.join(",") + ")";
				break;
			case "opacity":
				Element.makeOpacity(this.element, this.now);
				break;
			case "scrollLeft":
				this.element.scrollLeft = this.now;
				break;
			default:
				this.element.style[this.style] = this.now + "px";
				break;
		}
	}
}

Effect.FX =
{
	Height : function(element, onstart, onend)
	{
		element = get(element);
		if (!element.fx)
		{
			element.style.width = element.offsetWidth + "px";
			element.style.overflow	= 'hidden';
			if (element.style.visibility == 'hidden')
			{
				element.fx = new Effect
				({
					element		: element,
					transition	: Effect.Transitions.bounceOut,
					style		: "height",
					from		: 0,
					to			: element.saveHeight || element.scrollHeight,
					duration	: 500,
					onstart		: function()
					{
						element.style.visibility = 'visible';
						if (onstart) onstart();
					},
					onend		: function()
					{
						element.fx = null;
						element.style.overflow	= '';
						element.style.width		= 'auto';
						if (onend) onend(true);
					}
				});
				element.fx.start();
			}
			else
			{
				element.saveHeight	= element.offsetHeight;
				element.fx = new Effect
				({
					element		: element,
					transition	: Effect.Transitions.bounceOut,
					style		: "height",
					from		: element.saveHeight,
					to			: 0,
					duration	: 500,
					onstart		: function()
					{
						if (onstart) onstart();
					},
					onend		: function()
					{
						element.style.visibility	= 'hidden';
						element.style.overflow		= '';
						element.fx = null;
						if (onend) onend(false);
					}
				});
				element.fx.start();
			}
		}
	}
}

var True	= true;
var False	= false;
