var DOMAIN      = "http://energizeyourworkforce.com";
var SITE_URL    = "";
var LEGATO   	= "/js/legato";


// Developed by Robert Nyman/DOMAssistant team
// Code/licensing: http://domassistant.googlecode.com/
// Documentation: http://www.domassistant.com/documentation
// Version 2.8
var Legato = {};
Legato.DOMLoad = function () {
	var DOMLoaded = false,
	DOMLoadTimer = null,
	functionsToCall = [],
	addedStrings = {},
	errorHandling = null,
	execFunctions = function () {
		for (var i=0, il=functionsToCall.length; i<il; i++) {
			try {
				functionsToCall[i]();
			}
			catch (e) {
				if (errorHandling && typeof errorHandling === "function") {
					errorHandling(e);
				}
			}
		}
		functionsToCall = [];
	},
	DOMHasLoaded = function () {
		if (DOMLoaded) {
			return;
		}
		DOMLoaded = true;
		execFunctions();
	};
	/* Internet Explorer */
	/*@cc_on
	@if (@_win32 || @_win64)
		document.write("<script id=\"ieScriptLoad\" defer src=\"//:\"><\/script>");
		document.getElementById("ieScriptLoad").onreadystatechange = function() {
			if (this.readyState === "complete") {
				DOMHasLoaded();
			}
		};
	@end @*/
	/* Mozilla, Chrome, Opera */
	if (document.addEventListener) {
		document.addEventListener("DOMContentLoaded", DOMHasLoaded, false);
	}
	/* Safari, iCab, Konqueror */
	if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
		DOMLoadTimer = setInterval(function () {
			if (/loaded|complete/i.test(document.readyState)) {
				DOMHasLoaded();
				clearInterval(DOMLoadTimer);
			}
		}, 10);
	}
	/* Other web browsers */
	window.onload = DOMHasLoaded;

	return {
		DOMReady : function () {
			for (var i=0, il=arguments.length, funcRef; i<il; i++) {
				funcRef = arguments[i];
				if (!funcRef.DOMReady && !addedStrings[funcRef]) {
					if (typeof funcRef === "string") {
						addedStrings[funcRef] = true;
						funcRef = new Function(funcRef);
					}
					funcRef.DOMReady = true;
					functionsToCall.push(funcRef);
				}
			}
			if (DOMLoaded) {
				execFunctions();
			}
		},

		setErrorHandling : function (funcRef) {
			errorHandling = funcRef;
		}
	};
}();
Legato.DOMReady = Legato.DOMLoad.DOMReady;

/*
 * jQuery 1.2.3 - New Wave Javascript
 *
 * Copyright (c) 2008 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
 * $Rev: 4663 $
 */
(function(){if(window.jQuery)var _jQuery=window.jQuery;var jQuery=window.jQuery=function(selector,context){return new jQuery.prototype.init(selector,context);};if(window.$)var _$=window.$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;var isSimple=/^.[^:#\[\.]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem)if(elem.id!=match[3])return jQuery().find(selector);else{this[0]=elem;this.length=1;return this;}else
selector=[];}}else
return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.3",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;this.each(function(i){if(this==elem)ret=i;});return ret;},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],name)||undefined;else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else
return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else
selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return!selector?this:this.pushStack(jQuery.merge(this.get(),selector.constructor==String?jQuery(selector).get():selector.length!=undefined&&(!selector.nodeName||jQuery.nodeName(selector,"form"))?selector:[selector]));},is:function(selector){return selector?jQuery.multiFilter(selector,this).length>0:false;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i<max;i++){var option=options[i];if(option.selected){value=jQuery.browser.msie&&!option.attributes.value.specified?option.text:option.value;if(one)return value;values.push(value);}}return values;}else
return(this[0].value||"").replace(/\r/g,"");}return undefined;}return this.each(function(){if(this.nodeType!=1)return;if(value.constructor==Array&&/radio|checkbox/.test(this.type))this.checked=(jQuery.inArray(this.value,value)>=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=value.constructor==Array?value:[value];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else
this.value=value;});},html:function(value){return value==undefined?(this.length?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value==null){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data==undefined&&this.length)data=jQuery.data(this[0],key);return data==null&&parts[1]?this.data(parts[0]):data;}else
return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);}else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.prototype.init.prototype=jQuery.prototype;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else
jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==1){target=this;i=0;}for(;i<length;i++)if((options=arguments[i])!=null)for(var name in options){if(target===options[name])continue;if(deep&&options[name]&&typeof options[name]=="object"&&target[name]&&!options[name].nodeType)target[name]=jQuery.extend(target[name],options[name]);else if(options[name]!=undefined)target[name]=options[name];}return target;};var expando="jQuery"+(new Date()).getTime(),uuid=0,windowData={};var exclude=/z-?index|font-?weight|opacity|zoom|line-?height/i;jQuery.extend({noConflict:function(deep){window.$=_$;if(deep)window.jQuery=_jQuery;return jQuery;},isFunction:function(fn){return!!fn&&typeof fn!="string"&&!fn.nodeName&&fn.constructor!=Array&&/function/i.test(fn+"");},isXMLDoc:function(elem){return elem.documentElement&&!elem.body||elem.tagName&&elem.ownerDocument&&!elem.ownerDocument.body;},globalEval:function(data){data=jQuery.trim(data);if(data){var head=document.getElementsByTagName("head")[0]||document.documentElement,script=document.createElement("script");script.type="text/javascript";if(jQuery.browser.msie)script.text=data;else
script.appendChild(document.createTextNode(data));head.appendChild(script);head.removeChild(script);}},nodeName:function(elem,name){return elem.nodeName&&elem.nodeName.toUpperCase()==name.toUpperCase();},cache:{},data:function(elem,name,data){elem=elem==window?windowData:elem;var id=elem[expando];if(!id)id=elem[expando]=++uuid;if(name&&!jQuery.cache[id])jQuery.cache[id]={};if(data!=undefined)jQuery.cache[id][name]=data;return name?jQuery.cache[id][name]:id;},removeData:function(elem,name){elem=elem==window?windowData:elem;var id=elem[expando];if(name){if(jQuery.cache[id]){delete jQuery.cache[id][name];name="";for(name in jQuery.cache[id])break;if(!name)jQuery.removeData(elem);}}else{try{delete elem[expando];}catch(e){if(elem.removeAttribute)elem.removeAttribute(expando);}delete jQuery.cache[id];}},each:function(object,callback,args){if(args){if(object.length==undefined){for(var name in object)if(callback.apply(object[name],args)===false)break;}else
for(var i=0,length=object.length;i<length;i++)if(callback.apply(object[i],args)===false)break;}else{if(object.length==undefined){for(var name in object)if(callback.call(object[name],name,object[name])===false)break;}else
for(var i=0,length=object.length,value=object[0];i<length&&callback.call(value,i,value)!==false;value=object[++i]){}}return object;},prop:function(elem,value,type,i,name){if(jQuery.isFunction(value))value=value.call(elem,i);return value&&value.constructor==Number&&type=="curCSS"&&!exclude.test(name)?value+"px":value;},className:{add:function(elem,classNames){jQuery.each((classNames||"").split(/\s+/),function(i,className){if(elem.nodeType==1&&!jQuery.className.has(elem.className,className))elem.className+=(elem.className?" ":"")+className;});},remove:function(elem,classNames){if(elem.nodeType==1)elem.className=classNames!=undefined?jQuery.grep(elem.className.split(/\s+/),function(className){return!jQuery.className.has(classNames,className);}).join(" "):"";},has:function(elem,className){return jQuery.inArray(className,(elem.className||elem).toString().split(/\s+/))>-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else
jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret;function color(elem){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=elem.style.outline;elem.style.outline="0 solid black";elem.style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&elem.style&&elem.style[name])ret=elem.style[name];else if(document.defaultView&&document.defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var getComputedStyle=document.defaultView.getComputedStyle(elem,null);if(getComputedStyle&&!color(elem))ret=getComputedStyle.getPropertyValue(name);else{var swap=[],stack=[];for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(var i=0;i<stack.length;i++)if(color(stack[i])){swap[i]=stack[i].style.display;stack[i].style.display="block";}ret=name=="display"&&swap[stack.length-1]!=null?"none":(getComputedStyle&&getComputedStyle.getPropertyValue(name))||"";for(var i=0;i<swap.length;i++)if(swap[i]!=null)stack[i].style.display=swap[i];}if(name=="opacity"&&ret=="")ret="1";}else if(elem.currentStyle){var camelCase=name.replace(/\-(\w)/g,function(all,letter){return letter.toUpperCase();});ret=elem.currentStyle[name]||elem.currentStyle[camelCase];if(!/^\d+(px)?$/i.test(ret)&&/^\d/.test(ret)){var style=elem.style.left,runtimeStyle=elem.runtimeStyle.left;elem.runtimeStyle.left=elem.currentStyle.left;elem.style.left=ret||0;ret=elem.style.pixelLeft+"px";elem.style.left=style;elem.runtimeStyle.left=runtimeStyle;}}return ret;},clean:function(elems,context){var ret=[];context=context||document;if(typeof context.createElement=='undefined')context=context.ownerDocument||context[0]&&context[0].ownerDocument||document;jQuery.each(elems,function(i,elem){if(!elem)return;if(elem.constructor==Number)elem=elem.toString();if(typeof elem=="string"){elem=elem.replace(/(<(\w+)[^>]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+"></"+tag+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("<opt")&&[1,"<select multiple='multiple'>","</select>"]||!tags.indexOf("<leg")&&[1,"<fieldset>","</fieldset>"]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"<table>","</table>"]||!tags.indexOf("<tr")&&[2,"<table><tbody>","</tbody></table>"]||(!tags.indexOf("<td")||!tags.indexOf("<th"))&&[3,"<table><tbody><tr>","</tr></tbody></table>"]||!tags.indexOf("<col")&&[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"]||jQuery.browser.msie&&[1,"div<div>","</div>"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf("<table")&&tags.indexOf("<tbody")<0?div.firstChild&&div.firstChild.childNodes:wrap[1]=="<table>"&&tags.indexOf("<tbody")<0?div.childNodes:[];for(var j=tbody.length-1;j>=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else
ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,""+value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(typeof array!="array")for(var i=0,length=array.length;i<length;i++)ret.push(array[i]);else
ret=array.slice(0);return ret;},inArray:function(elem,array){for(var i=0,length=array.length;i<length;i++)if(array[i]==elem)return i;return-1;},merge:function(first,second){if(jQuery.browser.msie){for(var i=0;second[i];i++)if(second[i].nodeType!=8)first.push(second[i]);}else
for(var i=0;second[i];i++)first.push(second[i]);return first;},unique:function(array){var ret=[],done={};try{for(var i=0,length=array.length;i<length;i++){var id=jQuery.data(array[i]);if(!done[id]){done[id]=true;ret.push(array[i]);}}}catch(e){ret=array;}return ret;},grep:function(elems,callback,inv){var ret=[];for(var i=0,length=elems.length;i<length;i++)if(!inv&&callback(elems[i],i)||inv&&!callback(elems[i],i))ret.push(elems[i]);return ret;},map:function(elems,callback){var ret=[];for(var i=0,length=elems.length;i<length;i++){var value=callback(elems[i],i);if(value!==null&&value!=undefined){if(value.constructor!=Array)value=[value];ret=ret.concat(value);}}return ret;}});var userAgent=navigator.userAgent.toLowerCase();jQuery.browser={version:(userAgent.match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1],safari:/webkit/.test(userAgent),opera:/opera/.test(userAgent),msie:/msie/.test(userAgent)&&!/opera/.test(userAgent),mozilla:/mozilla/.test(userAgent)&&!/(compatible|webkit)/.test(userAgent)};var styleFloat=jQuery.browser.msie?"styleFloat":"cssFloat";jQuery.extend({boxModel:!jQuery.browser.msie||document.compatMode=="CSS1Compat",props:{"for":"htmlFor","class":"className","float":styleFloat,cssFloat:styleFloat,styleFloat:styleFloat,innerHTML:"innerHTML",className:"className",value:"value",disabled:"disabled",checked:"checked",readonly:"readOnly",selected:"selected",maxlength:"maxLength",selectedIndex:"selectedIndex",defaultValue:"defaultValue",tagName:"tagName",nodeName:"nodeName"}});jQuery.each({parent:function(elem){return elem.parentNode;},parents:function(elem){return jQuery.dir(elem,"parentNode");},next:function(elem){return jQuery.nth(elem,2,"nextSibling");},prev:function(elem){return jQuery.nth(elem,2,"previousSibling");},nextAll:function(elem){return jQuery.dir(elem,"nextSibling");},prevAll:function(elem){return jQuery.dir(elem,"previousSibling");},siblings:function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},children:function(elem){return jQuery.sibling(elem.firstChild);},contents:function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}},function(name,fn){jQuery.fn[name]=function(selector){var ret=jQuery.map(this,fn);if(selector&&typeof selector=="string")ret=jQuery.multiFilter(selector,ret);return this.pushStack(jQuery.unique(ret));};});jQuery.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(name,original){jQuery.fn[name]=function(){var args=arguments;return this.each(function(){for(var i=0,length=args.length;i<length;i++)jQuery(args[i])[original](this);});};});jQuery.each({removeAttr:function(name){jQuery.attr(this,name,"");if(this.nodeType==1)this.removeAttribute(name);},addClass:function(classNames){jQuery.className.add(this,classNames);},removeClass:function(classNames){jQuery.className.remove(this,classNames);},toggleClass:function(classNames){jQuery.className[jQuery.className.has(this,classNames)?"remove":"add"](this,classNames);},remove:function(selector){if(!selector||jQuery.filter(selector,[this]).r.length){jQuery("*",this).add(this).each(function(){jQuery.event.remove(this);jQuery.removeData(this);});if(this.parentNode)this.parentNode.removeChild(this);}},empty:function(){jQuery(">*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return i<m[3]-0;},gt:function(a,i,m){return i>m[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j<rl;j++){var n=m=="~"||m=="+"?ret[j].nextSibling:ret[j].firstChild;for(;n;n=n.nextSibling)if(n.nodeType==1){var id=jQuery.data(n);if(m=="~"&&merge[id])break;if(!nodeName||n.nodeName.toUpperCase()==nodeName){if(m=="~")merge[id]=true;r.push(n);}if(m=="+")break;}}ret=r;t=jQuery.trim(t.replace(re,""));foundToken=true;}}if(t&&!foundToken){if(!t.indexOf(",")){if(context==ret[0])ret.shift();done=jQuery.merge(done,ret);r=ret=[context];t=" "+t.substr(1,t.length);}else{var re2=quickID;var m=re2.exec(t);if(m){m=[0,m[2],m[3],m[1]];}else{re2=quickClass;m=re2.exec(t);}m[2]=m[2].replace(/\\/g,"");var elem=ret[ret.length-1];if(m[1]=="#"&&elem&&elem.getElementById&&!jQuery.isXMLDoc(elem)){var oid=elem.getElementById(m[2]);if((jQuery.browser.msie||jQuery.browser.opera)&&oid&&typeof oid.id=="string"&&oid.id!=m[2])oid=jQuery('[@id="'+m[2]+'"]',elem)[0];ret=r=oid&&(!m[3]||jQuery.nodeName(oid,m[3]))?[oid]:[];}else{for(var i=0;ret[i];i++){var tag=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];if(tag=="*"&&ret[i].nodeName.toLowerCase()=="object")tag="param";r=jQuery.merge(r,ret[i].getElementsByTagName(tag));}if(m[1]==".")r=jQuery.classFilter(r,m[2]);if(m[1]=="#"){var tmp=[];for(var i=0;r[i];i++)if(r[i].getAttribute("id")==m[2]){tmp=[r[i]];break;}r=tmp;}ret=r;}t=t.replace(re2,"");}}if(t){var val=jQuery.filter(t,r);ret=r=val.r;t=jQuery.trim(val.t);}}if(t)ret=[];if(ret&&context==ret[0])ret.shift();done=jQuery.merge(done,ret);return done;},classFilter:function(r,m,not){m=" "+m+" ";var tmp=[];for(var i=0;r[i];i++){var pass=(" "+r[i].className+" ").indexOf(m)>=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i<rl;i++){var a=r[i],z=a[jQuery.props[m[2]]||m[2]];if(z==null||/href|src|selected/.test(m[2]))z=jQuery.attr(a,m[2])||'';if((type==""&&!!z||type=="="&&z==m[5]||type=="!="&&z!=m[5]||type=="^="&&z&&!z.indexOf(m[5])||type=="$="&&z.substr(z.length-m[5].length)==m[5]||(type=="*="||type=="~=")&&z.indexOf(m[5])>=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i<rl;i++){var node=r[i],parentNode=node.parentNode,id=jQuery.data(parentNode);if(!merge[id]){var c=1;for(var n=parentNode.firstChild;n;n=n.nextSibling)if(n.nodeType==1)n.nodeIndex=c++;merge[id]=true;}var add=false;if(first==0){if(node.nodeIndex==last)add=true;}else if((node.nodeIndex-last)%first==0&&(node.nodeIndex-last)/first>=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval!=undefined)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(arguments.callee.elem,arguments);return val;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else
for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data||[]);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event)data.unshift(this.fix({type:type,target:elem}));data[0].type=type;if(exclusive)data[0].exclusive=true;if(jQuery.isFunction(jQuery.data(elem,"handle")))val=jQuery.data(elem,"handle").apply(elem,data);if(!fn&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var handlers=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in handlers){var handler=handlers[j];args[0].handler=handler;args[0].data=handler.data;if(!parts[1]&&!event.exclusive||handler.type==parts[1]){var ret=handler.apply(this,args);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);return undefined;},toggle:function(){var args=arguments;return this.click(function(event){this.lastToggle=0==this.lastToggle?1:0;event.preventDefault();return args[this.lastToggle].apply(this,arguments)||false;});},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else
jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i<document.styleSheets.length;i++)if(document.styleSheets[i].disabled){setTimeout(arguments.callee,0);return;}jQuery.ready();},false);if(jQuery.browser.safari){var numStyles;(function(){if(jQuery.isReady)return;if(document.readyState!="loaded"&&document.readyState!="complete"){setTimeout(arguments.callee,0);return;}if(numStyles===undefined)numStyles=jQuery("style, link[rel=stylesheet]").length;if(document.styleSheets.length!=numStyles){setTimeout(arguments.callee,0);return;}jQuery.ready();})();}jQuery.event.add(window,"load",jQuery.ready);}jQuery.each(("blur,focus,load,resize,scroll,unload,click,dblclick,"+"mousedown,mouseup,mousemove,mouseover,mouseout,change,select,"+"submit,keydown,keypress,keyup,error").split(","),function(i,name){jQuery.fn[name]=function(fn){return fn?this.bind(name,fn):this.trigger(name);};});var withinElement=function(event,elem){var parent=event.relatedTarget;while(parent&&parent!=elem)try{parent=parent.parentNode;}catch(error){parent=elem;}return parent==elem;};jQuery(window).bind("unload",function(){jQuery("*").add(document).unbind();});jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("load",url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("<div/>").append(res.responseText.replace(/<script(.|\s)*?\/script>/g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){var jsonp,jsre=/=\?(&|$)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get"){var ts=(new Date()).getTime();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if((!s.url.indexOf("http")||!s.url.indexOf("//"))&&s.dataType=="script"&&s.type.toLowerCase()=="get"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async,s.username,s.password);try{if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");xml.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else
jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else
for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else
s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else
e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;i<timers.length;i++)if(!timers[i]())timers.splice(i--,1);if(!timers.length){clearInterval(jQuery.timerId);jQuery.timerId=null;}},13);}},show:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.show=true;this.custom(0,this.cur());if(this.prop=="width"||this.prop=="height")this.elem.style[this.prop]="1px";jQuery(this.elem).show();},hide:function(){this.options.orig[this.prop]=jQuery.attr(this.elem.style,this.prop);this.options.hide=true;this.custom(this.cur(),0);},step:function(gotoEnd){var t=(new Date()).getTime();if(gotoEnd||t>this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})();

//------------------------------------------------------------------------
// Package: Structures
// The various structures used by the system.
// 
// Topic: Dependencies
// - <DOM Library>
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Class: Legato_Structure_Color
// Handles a single color.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Structure_Color()
// Class constructor.
//
// Parameters:
//     RGB - A six character string of Red, Green and Blue values, eg: "FF2345".
//     
//     OR
//
//     R - Red value, 0 - 255.
//     G - Green value, 0 - 255.
//     B - Blue value, 0 - 255.
//------------------------------------------------------------------------
function Legato_Structure_Color()
{

	// What type of argument was passed in?
	if ( arguments.length == 1 && (typeof arguments[0] == "string" || arguments[0] instanceof String) )
	{

		this.R = parseInt( arguments[0].substring( 0, 2 ), 16 );
		this.G = parseInt( arguments[0].substring( 2, 4 ), 16 );
		this.B = parseInt( arguments[0].substring( 4, 6 ), 16 );

	}  // End if hex string.
	else if ( arguments.length == 3 )
	{

		this.R = arguments[0];
		this.G = arguments[1];
		this.B = arguments[2];

	}  // End if numbers passed in.
	else
	{

		this.R = null;
		this.G = null;
		this.B = null;

	}  // End if null passed in.

}


//------------------------------------------------------------------------
// Public Member Functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Function: toHexString()
// Returns the color as a string of hexidecimal values.
//------------------------------------------------------------------------
Legato_Structure_Color.prototype.toHexString = function()
{

	var R = (this.R < 16) ? "0" + this.R.toString( 16 ) : this.R.toString( 16 );
	var G = (this.G < 16) ? "0" + this.G.toString( 16 ) : this.G.toString( 16 );
	var B = (this.B < 16) ? "0" + this.B.toString( 16 ) : this.B.toString( 16 );

	return R + G + B;

}


//------------------------------------------------------------------------
// Class: Legato_Structure_Dimensions
// Handles a single set of dimensions.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Structure_Dimensions()
// Class constructor.
//
// Parameters:
//     width - The width to store.
//     height - The height to store.
//
//     OR
//
//     element - A DOM element, in which case it will store the dimensions
//               of that element at the time this structure was created.
//------------------------------------------------------------------------
function Legato_Structure_Dimensions()
{
	
	// What type of arguments passed in?
	if ( arguments.length == 2 )
	{

		// Store the passed in parameters.
		this.width   = arguments[0];
		this.height  = arguments[1];
		
	}  // End if a width and height.
	else if ( arguments.length == 1 )
	{
		
		var element = $( arguments[0] );

		// Get the element's dimensions.
		var dimensions = element.dimensions();
		this.width = dimensions[0];
		this.height = dimensions[1];
		
	}  // End if element passed in.

}


//------------------------------------------------------------------------
// Class: Legato_Structure_Position
// Handles a single position. For positioning objects relative to its
// containing element.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Structure_Position()
// Class constructor.
//
// Parameters:
//     top - The value from the top of the containing element.
//     right - The value from the right of the containing element.
//     bottom - The value from the bottom of the containing element.
//     left - The value from the left of the containing element.
//------------------------------------------------------------------------
function Legato_Structure_Position( top, right, bottom, left )
{

	// Store the passed in parameters.
	this.top     = top;
	this.right   = right;
	this.bottom  = bottom;
	this.left    = left;

}


//------------------------------------------------------------------------
// Class: Legato_Structure_Point
// Handles a single point.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Structure_Point()
// Class constructor.
//
// Parameters:
//     X - The X value of the point.
//     Y - The Y value of the point.
//------------------------------------------------------------------------
function Legato_Structure_Point( X, Y )
{

	// Store the passed in parameters.
	this.X = X;
	this.Y = Y;

}


//------------------------------------------------------------------------
// Class: Legato_Structure_Region
// Handles a single region.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Structure_Region()
// Class constructor.
//
// Parameters:
//     min_point - The <Legato_Structure_Point> of the top left corner.
//     max_point - The <Legato_Structure_Point> of the bottom right corner.
//
//     OR
//
//     element - A DOM element, in which case the region will be the
//               containing region of the element.
//------------------------------------------------------------------------
function Legato_Structure_Region()
{

	// What was passed in?
	if ( arguments.length == 2 )
	{

		// Store the passed in parameters.
	  this.min_point  = arguments[0];
	  this.max_point  = arguments[1];

	}  // End if points passed in.
	else if ( arguments.length == 1 )
	{

		var element = $( arguments[0] );

		// Get the element's position for the region's min point.
		this.min_point = this.element.position();
		this.min_point = new Legato_Structure_Point( this.min_point[0], this.min_point[1] );

		// Get the max point for the region.
		var dimensions = element.dimensions();
		this.max_point = new Legato_Structure_Point( (this.min_point.X + dimensions[0]), (this.min_point.Y + dimensions[1]) );

	}  // End if HTML element passed in.

}


//------------------------------------------------------------------------
// Public Member Functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Function: intersectRegion()
// Used to test if two <Legato_Structure_Region> objects are intersecting
// each other.
//
// Parameters:
//     region - The <Legato_Structure_Region> that you'd like to test for
//              intersection against this object.
//     in_test - (Optional) If this is set to true, the region passed in
//               must be fully contained by this object.
//     epsilon - (Optional) This is the allowable mistake that can happen
//               between the tests, eg: if this is 1, then if the region
//               is 1 pixel away from intersecting, this function will
//               still return true.
//------------------------------------------------------------------------
Legato_Structure_Region.prototype.intersectRegion = function( region, in_test, epsilon )
{

	// Get the epsilon.
	epsilon = (epsilon) ? epsilon : 0;

	// Only do this if we are testing if it's completely contained.
	if ( in_test )
	{

	  var contained = true;

		// Is the region completely contained in this region?
		if ( region.min_point.X < (this.min_point.X + epsilon) || region.min_point.X > (this.max_point.X + epsilon) ) contained = false;
		else if ( region.min_point.Y < (this.min_point.Y + epsilon) || region.min_point.Y > (this.max_point.Y + epsilon) ) contained = false;
		else if ( region.max_point.X < (this.min_point.X + epsilon) || region.max_point.X > (this.max_point.X + epsilon) ) contained = false;
		else if ( region.max_point.Y < (this.min_point.Y + epsilon) || region.max_point.Y > (this.max_point.Y + epsilon) ) contained = false;

		// Return.
		return contained;

	}  // End if completely contained test.
	else
	{

		// Perform the intersection test.
		return ((this.min_point.X + epsilon) <= region.max_point.X) &&
						((this.min_point.Y + epsilon) <= region.max_point.Y) &&
						((this.max_point.X + epsilon) >= region.min_point.X) &&
						((this.max_point.Y + epsilon) >= region.min_point.Y);

	}  // End normal touching test.

}


//------------------------------------------------------------------------
// Function: containsPoint()
// Used to test if there is an <Legato_Structure_Point> object within the
// bounds of this region.
//
// Parameters:
//     point - The <Legato_Structure_Point> object.
//------------------------------------------------------------------------
Legato_Structure_Region.prototype.containsPoint = function( point )
{

	var contained = true;

	// Is the point completely contained in this region?
	if ( this.min_point.X > point.X || this.max_point.X < point.X ) contained = false;
	if ( this.min_point.Y > point.Y || this.max_point.Y < point.Y ) contained = false;

	// Return.
	return contained;

}



// Developed by Robert Nyman/DOMAssistant team
// Code/licensing: http://domassistant.googlecode.com/
// Documentation: http://www.domassistant.com/documentation
// Version 2.8
var DOMAssistant = function () {
	var HTMLArray = function () {
		// Constructor
	},
	w = window, _$ = w.$, _$$ = w.$$,
	isIE = /*@cc_on!@*/false,
	isIE5 = isIE && parseFloat(navigator.appVersion) < 6,
	sort, tagCache = {}, lastCache = {}, useCache = true,
	slice = Array.prototype.slice,
	camel = {
		"accesskey": "accessKey",
		"class": "className",
		"colspan": "colSpan",
		"for": "htmlFor",
		"maxlength": "maxLength",
		"readonly": "readOnly",
		"rowspan": "rowSpan",
		"tabindex": "tabIndex",
		"valign": "vAlign",
		"cellspacing": "cellSpacing",
		"cellpadding": "cellPadding"
	},
	regex = {
		rules: /\s*,\s*/g,
		selector: /^(\w+|\*)?(#[\w\u00C0-\uFFFF\-=$]+)?((\.[\w\u00C0-\uFFFF\-]+)*)?((\[\w+\s*([~^$*|])?(=\s*([-\w\u00C0-\uFFFF\s.]+|"[^"]*"|'[^']*'))?\]+)*)?((:\w[-\w]*(\((odd|even|\-?\d*n?([-+]\d+)?|[:#]?[-\w\u00C0-\uFFFF.]+|"[^"]*"|'[^']*'|((\w*\.[-\w\u00C0-\uFFFF]+)*)?|(\[#?\w+([~^$*|])?=?[-\w\u00C0-\uFFFF\s.'"]+\]+)|(:\w[-\w]*\(.+\)))\))?)*)?([+>~])?/,
		selectorSplit: /(?:\[.*\]|\(.*\)|[^\s+>~[(])+|[+>~]/g,
		id: /^#([-\w\u00C0-\uFFFF=$]+)$/,
		tag: /^\w+/,
		relation: /^[+>~]$/,
		pseudo: /^:(\w[-\w]*)(\((.+)\))?$/,
		pseudos: /:(\w[-\w]*)(\((([^(]+)|([^(]+\([^(]+)\))\))?/g,
		attribs: /\[(\w+)\s*([~^$*|])?(=)?\s*([^\[\]]*|"[^"]*"|'[^']*')?\](?=$|\[|:|\s)/g,
		classes: /\.([-\w\u00C0-\uFFFF]+)/g,
		quoted: /^["'](.*)["']$/,
		nth: /^((odd|even)|([1-9]\d*)|((([1-9]\d*)?)n([-+]\d+)?)|(-(([1-9]\d*)?)n\+(\d+)))$/,
		special: /(:check|:enabl|\bselect)ed\b/
	},
	navigate = function (node, direction, checkTagName) {
		var oldName = node.tagName;
		while ((node = node[direction + "Sibling"]) && (node.nodeType !== 1 || (checkTagName? node.tagName !== oldName : node.tagName === "!"))) {}
		return node;
	},
	def = function (obj) {
		return typeof obj !== "undefined";
	},
	sortDocumentOrder = function (elmArray) {
		return (sortDocumentOrder = elmArray[0].compareDocumentPosition? function (elmArray) { return elmArray.sort( function (a, b) { return 3 - (a.compareDocumentPosition(b) & 6); } ); } :
			isIE? function (elmArray) { return elmArray.sort( function (a, b) { return a.sourceIndex - b.sourceIndex; } ); } :
			function (elmArray) { return elmArray.sort( function (a, b) {
				var range1 = document.createRange(), range2 = document.createRange();
				range1.setStart(a, 0);
				range1.setEnd(a, 0);
				range2.setStart(b, 0);
				range2.setEnd(b, 0);
				return range1.compareBoundaryPoints(Range.START_TO_END, range2);
			} ); })(elmArray);
	};
	var pushAll = function (set1, set2) {
		set1.push.apply(set1, slice.apply(set2));
		return set1;
	};
	if (isIE) {
		pushAll = function (set1, set2) {
			if (set2.slice) {
				return set1.concat(set2);
			}
			var i=0, item;
			while ((item = set2[i++])) {
				set1[set1.length] = item;
			}
			return set1;
		};
	}
	return {
		isIE : isIE,
		camel : camel,
		def : def,
		allMethods : [],
		publicMethods : [
			"prev",
			"next",
			"hasChild",
			"cssSelect",
			"elmsByClass",
			"elmsByAttribute",
			"elmsByTag"
		],

		harmonize : function () {
			w.$ = _$;
			w.$$ = _$$;
			return this;
		},

		initCore : function () {
			this.applyMethod.call(w, "$", this.$);
			this.applyMethod.call(w, "$$", this.$$);
			w.DOMAssistant = this;
			if (isIE) {
				HTMLArray = Array;
			}
			HTMLArray.prototype = [];
			(function (H) {
				H.each = function (fn, context) {
					for (var i=0, il=this.length; i<il; i++) {
						if (fn.call(context || this[i], this[i], i, this) === false) {
							break;
						}
					}
					return this;
				};
				H.first = function () {
					return def(this[0])? DOMAssistant.addMethodsToElm(this[0]) : null;
				};
				H.end = function () {
					return this.previousSet;
				};
				H.indexOf = H.indexOf || function (elm) {
					for (var i=0, il=this.length; i<il; i++) {
						if (i in this && this[i] === elm) {
							return i;
						}
					}
					return -1;
				};
				H.map = function (fn, context) {
					var res = [];
					for (var i=0, il=this.length; i<il; i++) {
						if (i in this) {
							res[i] = fn.call(context || this[i], this[i], i, this);
						}
					}
					return res;
				};
				H.filter = function (fn, context) {
					var res = new HTMLArray();
					res.previousSet = this;
					for (var i=0, il=this.length; i<il; i++) {
						if (i in this && fn.call(context || this[i], this[i], i, this)) {
							res.push(this[i]);
						}
					}
					return res;
				};
				H.every = function (fn, context) {
					for (var i=0, il=this.length; i<il; i++) {
						if (i in this && !fn.call(context || this[i], this[i], i, this)) {
							return false;
						}
					}
					return true;
				};
				H.some = function (fn, context) {
					for (var i=0, il=this.length; i<il; i++) {
						if (i in this && fn.call(context || this[i], this[i], i, this)) {
							return true;
						}
					}
					return false;
				};
			})(HTMLArray.prototype);
			this.attach(this);
		},

		addMethods : function (name, method) {
			if (!def(this.allMethods[name])) {
				this.allMethods[name] = method;
				this.addHTMLArrayPrototype(name, method);
			}
		},

		addMethodsToElm : function (elm) {
			for (var method in this.allMethods) {
				if (def(this.allMethods[method])) {
					this.applyMethod.call(elm, method, this.allMethods[method]);
				}
			}
			return elm;
		},

		applyMethod : function (method, func) {
			if (typeof this[method] !== "function") {
				this[method] = func;
			}
		},

		attach : function (plugin) {
			var publicMethods = plugin.publicMethods;
			if (!def(publicMethods)) {
				for (var method in plugin) {
					if (method !== "init" && def(plugin[method])) {
						this.addMethods(method, plugin[method]);
					}
				}
			}
			else if (publicMethods.constructor === Array) {
				for (var i=0, current; (current=publicMethods[i]); i++) {
					this.addMethods(current, plugin[current]);
				}
			}
			if (typeof plugin.init === "function") {
				plugin.init();
			}
		},

		addHTMLArrayPrototype : function (name, method) {
			HTMLArray.prototype[name] = function () {
				var elmsToReturn = new HTMLArray();
				elmsToReturn.previousSet = this;
				for (var i=0, il=this.length; i<il; i++) {
					elmsToReturn.push(method.apply(DOMAssistant.$$(this[i]), arguments));
				}
				return elmsToReturn;
			};
		},

		cleanUp : function (elm) {
			var children = elm.all || elm.getElementsByTagName("*");
			for (var i=0, child; (child=children[i++]);) {
				if (child.hasData && child.hasData()) {
					if (child.removeEvent) { child.removeEvent(); }
					child.unstore();
				}
			}
			elm.innerHTML = "";
		},

		setCache : function (cache) {
			useCache = cache;
		},

		$ : function () {
			var obj = arguments[0];
			if (arguments.length === 1 && (typeof obj === "object" || (typeof obj === "function" && !!obj.nodeName))) {
				return DOMAssistant.$$(obj);
			}
			var elm = !!obj? new HTMLArray() : null;
			for (var i=0, arg, idMatch; (arg=arguments[i]); i++) {
				if (typeof arg === "string") {
					arg = arg.replace(/^[^#\(]*(#)/, "$1");
					if (regex.id.test(arg)) {
						if ((idMatch = DOMAssistant.$$(arg.substr(1), false))) {
							elm.push(idMatch);
						}
					}
					else {
						var doc = (document.all || document.getElementsByTagName("*")).length;
						elm = (!document.querySelectorAll && useCache && lastCache.rule && lastCache.rule === arg && lastCache.doc === doc)? lastCache.elms : pushAll(elm, DOMAssistant.cssSelection.call(document, arg));
						lastCache = { rule: arg, elms: elm, doc: doc };
					}
				}
			}
			return elm;
		},

		$$ : function (id, addMethods) {
			var elm = (typeof id === "object" || typeof id === "function" && !!id.nodeName)? id : document.getElementById(id),
				applyMethods = def(addMethods)? addMethods : true,
				getId = function(el) { var eid = el.id; return typeof eid !== "object"? eid : el.attributes.id.nodeValue; };
			if (typeof id === "string" && elm && getId(elm) !== id) {
				elm = null;
				for (var i=0, item; (item=document.all[i]); i++) {
					if (getId(item) === id) {
						elm = item;
						break;
					}
				}
			}
			if (elm && applyMethods && !elm.next) {
				DOMAssistant.addMethodsToElm(elm);
			}
			return elm;
		},

		prev : function () {
			return DOMAssistant.$$(navigate(this, "previous"));
		},

		next : function () {
			return DOMAssistant.$$(navigate(this, "next"));
		},

		hasChild: function (elm) {
			return this === document || this !== elm && (this.contains? this.contains(elm) : !!(this.compareDocumentPosition(elm) & 16));
		},

		getSequence : function (expression) {
			var start, add = 2, max = -1, modVal = -1,
				pseudoVal = regex.nth.exec(expression.replace(/^0n\+/, "").replace(/^2n$/, "even").replace(/^2n+1$/, "odd"));
			if (!pseudoVal) {
				return null;
			}
			if (pseudoVal[2]) {	// odd or even
				start = (pseudoVal[2] === "odd")? 1 : 2;
				modVal = (start === 1)? 1 : 0;
			}
			else if (pseudoVal[3]) {	// single digit
				start = max = parseInt(pseudoVal[3], 10);
				add = 0;
			}
			else if (pseudoVal[4]) {	// an+b
				add = pseudoVal[6]? parseInt(pseudoVal[6], 10) : 1;
				start = pseudoVal[7]? parseInt(pseudoVal[7], 10) : 0;
				while (start < 1) {
					start += add;
				}
				modVal = (start >= add)? (start - add) % add : start;
			}
			else if (pseudoVal[8]) {	// -an+b
				add = pseudoVal[10]? parseInt(pseudoVal[10], 10) : 1;
				start = max = parseInt(pseudoVal[11], 10);
				while (start > add) {
					start -= add;
				}
				modVal = (max >= add)? (max - add) % add : max;
			}
			return { start: start, add: add, max: max, modVal: modVal };
		},

		cssByDOM : function (cssRule) {
			var prevParents, currentRule, cssSelectors, childOrSiblingRef, nextTag, nextRegExp, current, previous, prevParent, notElm, addElm, iteratorNext, childElm, sequence, anyTag,
				elm = new HTMLArray(), index = elm.indexOf, prevElm = [], matchingElms = [], cssRules = cssRule.replace(regex.rules, ",").split(","), splitRule = {};
			function clearAdded (elm) {
				elm = elm || prevElm;
				for (var n=elm.length; n--;) {
					elm[n].added = null;
					elm[n].removeAttribute("added");
				}
			}
			function clearChildElms () {
				for (var n=prevParents.length; n--;) {
					prevParents[n].childElms = null;
				}
			}
			function subtractArray (arr1, arr2) {
				for (var i=0, src1; (src1=arr1[i]); i++) {
					var found = false;
					for (var j=0, src2; (src2=arr2[j]); j++) {
						if (src2 === src1) {
							found = true;
							arr2.splice(j, 1);
							break;
						}
					}
					if (found) {
						arr1.splice(i--, 1);
					}
				}
				return arr1;
			}
			function getAttr (elm, attr) {
				return (isIE || regex.special.test(attr))? elm[camel[attr.toLowerCase()] || attr] : elm.getAttribute(attr, 2);
			}
			function attrToRegExp (attrVal, substrOperator) {
				attrVal = attrVal? attrVal.replace(regex.quoted, "$1").replace(/(\.|\[|\])/g, "\\$1") : null;
				return {
					"^": "^" + attrVal,
					"$": attrVal + "$",
					"*": attrVal,
					"|": "^" + attrVal + "(\\-\\w+)*$",
					"~": "\\b" + attrVal + "\\b"
				}[substrOperator] || (attrVal !== null? "^" + attrVal + "$" : attrVal);
			}
			function notComment(el) {
				return (el || this).tagName !== "!";
			}
			function getTags (tag, context) {
				return isIE5? (tag === "*"? context.all : context.all.tags(tag)) : context.getElementsByTagName(tag);
			}
			function getElementsByTagName (tag, parent) {
				tag = tag || "*";
				parent = parent || document;
				return (parent === document || parent.lastModified)? tagCache[tag] || (tagCache[tag] = getTags(tag, document)) : getTags(tag, parent);
			}
			function getElementsByPseudo (previousMatch, pseudoClass, pseudoValue) {
				prevParents = [];
				var pseudo = pseudoClass.split("-"), matchingElms = [], idx = 0, checkNodeName = /\-of\-type$/.test(pseudoClass), recur,
				match = {
					first: function(el) { return !navigate(el, "previous", checkNodeName); },
					last: function(el) { return !navigate(el, "next", checkNodeName); },
					empty: function(el) { return !el.firstChild; },
					enabled: function(el) { return !el.disabled && el.type !== "hidden"; },
					disabled: function(el) { return el.disabled; },
					checked: function(el) { return el.checked; },
					contains: function(el) { return (el.innerText || el.textContent || "").indexOf(pseudoValue.replace(regex.quoted, "$1")) > -1; },
					other: function(el) { return getAttr(el, pseudoClass) === pseudoValue; }
				};
				function basicMatch(key) {
					while ((previous=previousMatch[idx++])) {
						if (notComment(previous) && match[key](previous)) {
							matchingElms[matchingElms.length] = previous;
						}
					}
					return matchingElms;
				}
				var word = pseudo[0] || null;
				if (word && match[word]) {
					return basicMatch(word);
				}
				switch (word) {
					case "only":
						var kParent, kTag;
						while ((previous=previousMatch[idx++])) {
							prevParent = previous.parentNode;
							var q = previous.nodeName;
							if (prevParent !== kParent || q !== kTag) {
								if (match.first(previous) && match.last(previous)) {
									matchingElms[matchingElms.length] = previous;
								}
								kParent = prevParent;
								kTag = q;
							}
						}
						break;
					case "nth":
						if (pseudoValue === "n") {
							matchingElms = previousMatch;
						}
						else {
							var direction = (pseudo[1] === "last")? ["lastChild", "previousSibling"] : ["firstChild", "nextSibling"];
							sequence = DOMAssistant.getSequence(pseudoValue);
							if (sequence) {
								while ((previous=previousMatch[idx++])) {
									prevParent = previous.parentNode;
									prevParent.childElms = prevParent.childElms || {};
									var p = previous.nodeName;
									if (!prevParent.childElms[p]) {
										var childCount = 0;
										iteratorNext = sequence.start;
										childElm = prevParent[direction[0]];
										while (childElm && (sequence.max < 0 || iteratorNext <= sequence.max)) {
											var c = childElm.nodeName;
											if ((checkNodeName && c === p) || (!checkNodeName && childElm.nodeType === 1 && c !== "!")) {
												if (++childCount === iteratorNext) {
													if (c === p) { matchingElms[matchingElms.length] = childElm; }
													iteratorNext += sequence.add;
												}
											}
											childElm = childElm[direction[1]];
										}
										if (anyTag) { sort++; }
										prevParent.childElms[p] = true;
										prevParents[prevParents.length] = prevParent;
									}
								}
								clearChildElms();
							}
						}
						break;
					case "target":
						var hash = document.location.hash.slice(1);
						if (hash) {
							while ((previous=previousMatch[idx++])) {
								if (getAttr(previous, "name") === hash || getAttr(previous, "id") === hash) {
									matchingElms[matchingElms.length] = previous;
									break;
								}
							}
						}
						break;
					case "not":
						if ((recur = regex.pseudo.exec(pseudoValue))) {
							matchingElms = subtractArray(previousMatch, getElementsByPseudo(previousMatch, recur[1]? recur[1].toLowerCase() : null, recur[3] || null));
						}
						else {
							for (var re in regex) {
								if (regex[re].lastIndex) {
									regex[re].lastIndex = 0;
								}
							}
							pseudoValue = pseudoValue.replace(regex.id, "[id=$1]");
							var notTag = regex.tag.exec(pseudoValue);
							var notClass = regex.classes.exec(pseudoValue);
							var notAttr = regex.attribs.exec(pseudoValue);
							var notRegExp = new RegExp(notAttr? attrToRegExp(notAttr[4], notAttr[2]) : "(^|\\s)" + (notTag? notTag[0] : notClass? notClass[1] : "") + "(\\s|$)", "i");
							while ((notElm=previousMatch[idx++])) {
								addElm = null;
								if (notTag && !notRegExp.test(notElm.nodeName) || notClass && !notRegExp.test(notElm.className)) {
									addElm = notElm;
								}
								else if (notAttr) {
									var att = getAttr(notElm, notAttr[1]);
									if (!def(att) || att === false || typeof att === "string" && !notRegExp.test(att)) {
										addElm = notElm;
									}
								}
								if (addElm && !addElm.added) {
									addElm.added = true;
									matchingElms[matchingElms.length] = addElm;
								}
							}
						}
						break;
					default: return basicMatch("other");
				}
				return matchingElms;
			}
			function pushUnique(set1, set2) {
				var i=0, s=set1, item;
				while ((item = set2[i++])) {
					if (!s.length || s.indexOf(item) < 0) {
						set1.push(item);
					}
				}
				return set1;
			}
			sort = -1;
			for (var a=0, tagBin=[]; (currentRule=cssRules[a]); a++) {
				if (!(cssSelectors = currentRule.match(regex.selectorSplit)) || a && index.call(cssRules.slice(0, a), currentRule) > -1) { continue; }
				prevElm = [this];
				for (var i=0, rule; (rule=cssSelectors[i]); i++) {
					matchingElms = [];
					if ((childOrSiblingRef = regex.relation.exec(rule))) {
						var idElm = null, nextWord = cssSelectors[i+1];
						if ((nextTag = regex.tag.exec(nextWord))) {
							nextTag = nextTag[0];
							nextRegExp = new RegExp("(^|\\s)" + nextTag + "(\\s|$)", "i");
						}
						else if (regex.id.test(nextWord)) {
							idElm = DOMAssistant.$(nextWord) || null;
						}
						for (var j=0, prevRef; (prevRef=prevElm[j]); j++) {
							switch (childOrSiblingRef[0]) {
								case ">":
									var children = idElm || getElementsByTagName(nextTag, prevRef);
									for (var k=0, child; (child=children[k]); k++) {
										if (child.parentNode === prevRef) {
											matchingElms[matchingElms.length] = child;
										}
									}
									break;
								case "+":
									if ((prevRef = navigate(prevRef, "next"))) {
										if ((idElm && idElm[0] === prevRef) || (!idElm && (!nextTag || nextRegExp.test(prevRef.nodeName)))) {
											matchingElms[matchingElms.length] = prevRef;
										}
									}
									break;
								case "~":
									while ((prevRef = prevRef.nextSibling) && !prevRef.added) {
										if ((idElm && idElm[0] === prevRef) || (!idElm && (!nextTag || nextRegExp.test(prevRef.nodeName)))) {
											prevRef.added = true;
											matchingElms[matchingElms.length] = prevRef;
										}
									}
									break;
							}
						}
						prevElm = matchingElms;
						clearAdded();
						rule = cssSelectors[++i];
						if (/^\w+$/.test(rule) || regex.id.test(rule)) {
							continue;
						}
						prevElm.skipTag = true;
					}
					var cssSelector = regex.selector.exec(rule);
					splitRule = {
						tag : cssSelector[1]? cssSelector[1] : "*",
						id : cssSelector[2],
						allClasses : cssSelector[3],
						allAttr : cssSelector[5],
						allPseudos : cssSelector[10]
					};
					anyTag = (splitRule.tag === "*");
					if (splitRule.id) {
						var u = 0, DOMElm = document.getElementById(splitRule.id.slice(1));
						if (DOMElm) {
							while (prevElm[u] && !DOMAssistant.hasChild.call(prevElm[u], DOMElm)) { u++; }
							matchingElms = (u < prevElm.length && (anyTag || splitRule.tag === DOMElm.tagName.toLowerCase()))? [DOMElm] : [];
						}
						prevElm = matchingElms;
					}
					else if (splitRule.tag && !prevElm.skipTag) {
						if (i===0 && !matchingElms.length && prevElm.length === 1) {
							prevElm = matchingElms = pushAll([], getElementsByTagName(splitRule.tag, prevElm[0]));
						}
						else {
							for (var l=0, ll=prevElm.length, tagCollectionMatches, tagMatch; l<ll; l++) {
								tagCollectionMatches = getElementsByTagName(splitRule.tag, prevElm[l]);
								for (var m=0; (tagMatch=tagCollectionMatches[m]); m++) {
									if (!tagMatch.added) {
										tagMatch.added = true;
										matchingElms[matchingElms.length] = tagMatch;
									}
								}
							}
							prevElm = matchingElms;
							clearAdded();
						}
					}
					if (!matchingElms.length) {
						break;
					}
					prevElm.skipTag = false;
					if (splitRule.allClasses) {
						var n = 0, matchingClassElms = [], allClasses = splitRule.allClasses.split(".").slice(1);
						while ((current = prevElm[n++])) {
							var matchCls = true, elmClass = current.className;
							if (elmClass && elmClass.length) {
								elmClass = elmClass.split(" ");
								for (var o=allClasses.length; o--;) {
									if (elmClass.indexOf(allClasses[o]) < 0) {
										matchCls = false;
										break;
									}
								}
								if (matchCls) {
									matchingClassElms[matchingClassElms.length] = current;
								}
							}
						}
						prevElm = matchingElms = matchingClassElms;
					}
					if (splitRule.allAttr) {
						var matchAttr, r = 0, regExpAttributes = [], matchingAttributeElms = [], allAttr = splitRule.allAttr.match(regex.attribs);
						for (var specialStrip = /^\[(selected|readonly)(\s*=.+)?\]$/, q=0, ql=allAttr.length, attributeMatch, attrVal; q<ql; q++) {
							regex.attribs.lastIndex = 0;
							attributeMatch = regex.attribs.exec(allAttr[q].replace(specialStrip, "[$1]"));
							attrVal = attrToRegExp(attributeMatch[4], attributeMatch[2] || null);
							regExpAttributes[q] = [(attrVal? new RegExp(attrVal) : null), attributeMatch[1]];
						}
						while ((current = matchingElms[r++])) {
							for (var s=0, sl=regExpAttributes.length; s<sl; s++) {
								var attributeRegExp = regExpAttributes[s][0], currentAttr = getAttr(current, regExpAttributes[s][1]);
								matchAttr = true;
								if (!attributeRegExp && currentAttr === true) { continue; }
								if ((!attributeRegExp && (!currentAttr || typeof currentAttr !== "string" || !currentAttr.length)) || (!!attributeRegExp && !attributeRegExp.test(currentAttr))) {
									matchAttr = false;
									break;
								}
							}
							if (matchAttr) {
								matchingAttributeElms[matchingAttributeElms.length] = current;
							}
						}
						prevElm = matchingElms = matchingAttributeElms;
					}
					if (splitRule.allPseudos) {
						var allPseudos = splitRule.allPseudos.match(regex.pseudos);
						for (var t=0, tl=allPseudos.length; t<tl; t++) {
							regex.pseudos.lastIndex = 0;
							var pseudo = regex.pseudos.exec(allPseudos[t]);
							var pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null;
							var pseudoValue = pseudo[3] || null;
							matchingElms = getElementsByPseudo(matchingElms, pseudoClass, pseudoValue);
							clearAdded(matchingElms);
						}
						prevElm = matchingElms;
					}
				}
				elm = ((tagBin.length && (anyTag || index.call(tagBin, splitRule.tag) >= 0 || index.call(tagBin, "*") >= 0))? pushUnique : pushAll)(elm, prevElm);
				tagBin.push(splitRule.tag);
				if (isIE && anyTag) { elm = elm.filter(notComment); }
			}
			return ((elm.length > 1 && cssRules.length > 1) || sort > 0)? sortDocumentOrder(elm) : elm;
		},

		cssByXpath : function (cssRule) {
			var ns = { xhtml: "http://www.w3.org/1999/xhtml" },
				prefix = (document.documentElement.namespaceURI === ns.xhtml)? "xhtml:" : "",
				nsResolver = function lookupNamespaceURI (prefix) {
					return ns[prefix] || null;
				};
			DOMAssistant.cssByXpath = function (cssRule) {
				var currentRule, cssSelectors, xPathExpression, cssSelector, splitRule, sequence,
					elm = new HTMLArray(), cssRules = cssRule.replace(regex.rules, ",").split(",");
				function attrToXPath (wrap) {
					var pre = wrap? "[" : "", post = wrap? "]" : "";
					return function (match, p1, p2, p3, p4) {
						p4 = (p4 || "").replace(regex.quoted, "$1");
						if (p1 === p4 && p1 === "readonly") { p3 = null; }
						return pre + ({
							"^": "starts-with(@" + p1 + ", \"" + p4 + "\")",
							"$": "substring(@" + p1 + ", (string-length(@" + p1 + ") - " + (p4.length - 1) + "), " + p4.length + ") = \"" + p4 + "\"",
							"*": "contains(concat(\" \", @" + p1 + ", \" \"), \"" + p4 + "\")",
							"|": "@" + p1 + "=\"" + p4 + "\" or starts-with(@" + p1 + ", \"" + p4 + "-\")",
							"~": "contains(concat(\" \", @" + p1 + ", \" \"), \" " + p4 + " \")"
						}[p2] || ("@" + p1 + (p3? "=\"" + p4 + "\"" : ""))) + post;
					};
				}
				function pseudoToXPath (tag, pseudoClass, pseudoValue) {
					tag = /\-child$/.test(pseudoClass)? "*" : tag;
					var pseudo = pseudoClass.split("-"), position = ((pseudo[1] === "last")? "(count(following-sibling::" : "(count(preceding-sibling::") + tag + ") + 1)", recur, hash;
					switch (pseudo[0]) {
						case "nth": return (pseudoValue !== "n" && (sequence = DOMAssistant.getSequence(pseudoValue)))? ((sequence.start === sequence.max)? position + " = " + sequence.start : position + " mod " + sequence.add + " = " + sequence.modVal + ((sequence.start > 1)? " and " + position + " >= " + sequence.start : "") + ((sequence.max > 0)? " and " + position + " <= " + sequence.max: "")) : "";
						case "not": return "not(" + ((recur = regex.pseudo.exec(pseudoValue))? pseudoToXPath(tag, recur[1]? recur[1].toLowerCase() : null, recur[3] || null) : pseudoValue.replace(regex.id, "[id=$1]").replace(regex.tag, "self::$0").replace(regex.classes, "contains(concat(\" \", @class, \" \"), \" $1 \")").replace(regex.attribs, attrToXPath())) + ")";
						case "first": return "not(preceding-sibling::" + tag + ")";
						case "last": return "not(following-sibling::" + tag + ")";
						case "only": return "not(preceding-sibling::" + tag + " or following-sibling::" + tag + ")";
						case "empty": return "not(child::*) and not(text())";
						case "contains": return "contains(., \"" + pseudoValue.replace(regex.quoted, "$1") + "\")";
						case "enabled": return "not(@disabled) and not(@type=\"hidden\")";
						case "disabled": return "@disabled";
						case "target": return "@name=\"" + (hash = document.location.hash.slice(1)) + "\" or @id=\"" + hash + "\"";
						default: return "@" + pseudoClass + "=\"" + pseudoValue + "\"";
					}
				}
				for (var i=0; (currentRule=cssRules[i]); i++) {
					if (!(cssSelectors = currentRule.match(regex.selectorSplit)) || i && elm.indexOf.call(cssRules.slice(0, i), currentRule) > -1) { continue; }
					xPathExpression = xPathExpression? xPathExpression + " | ." : ".";
					for (var j=0, jl=cssSelectors.length; j<jl; j++) {
						cssSelector = regex.selector.exec(cssSelectors[j]);
						splitRule = {
							tag: prefix + (cssSelector[1]? cssSelector[1] : "*"),
							id: cssSelector[2],
							allClasses: cssSelector[3],
							allAttr: cssSelector[5],
							allPseudos: cssSelector[10],
							tagRelation: cssSelector[20]
						};
						xPathExpression +=
							(splitRule.tagRelation? ({ ">": "/", "+": "/following-sibling::*[1]/self::", "~": "/following-sibling::" }[splitRule.tagRelation] || "") : ((j > 0 && regex.relation.test(cssSelectors[j-1]))? splitRule.tag : ("//" + splitRule.tag))) +
							(splitRule.id || "").replace(regex.id, "[@id = \"$1\"]") +
							(splitRule.allClasses || "").replace(regex.classes, "[contains(concat(\" \", @class, \" \"), \" $1 \")]") +
							(splitRule.allAttr || "").replace(regex.attribs, attrToXPath(true));
						if (splitRule.allPseudos) {
							var allPseudos = splitRule.allPseudos.match(regex.pseudos);
							for (var k=0, kl=allPseudos.length; k<kl; k++) {
								regex.pseudos.lastIndex = 0;
								var pseudo = regex.pseudos.exec(allPseudos[k]),
									pseudoClass = pseudo[1]? pseudo[1].toLowerCase() : null,
									pseudoValue = pseudo[3] || null,
									xpath = pseudoToXPath(splitRule.tag, pseudoClass, pseudoValue);
								if (xpath.length) {
									xPathExpression += "[" + xpath + "]";
								}
							}
						}
					}
				}
				try {
					var xPathNodes = document.evaluate(xPathExpression, this, nsResolver, 7, null), node, p=0;
					while ((node = xPathNodes.snapshotItem(p++))) { elm.push(node); }
				} catch (e) {}
				return elm;
			};
			return DOMAssistant.cssByXpath.call(this, cssRule);
		},

		cssSelection : function (cssRule) {
			if (!cssRule) { return null; }
			var special = regex.special.test(cssRule);
			try {
				if (document.querySelectorAll && !special) {
					return pushAll(new HTMLArray(), this.querySelectorAll(cssRule));
				}
			} catch (e) {}
			return ((document.evaluate && !special && !/-of-type/.test(cssRule))? DOMAssistant.cssByXpath : DOMAssistant.cssByDOM).call(this, cssRule);
		},

		cssSelect : function (cssRule) {
			return DOMAssistant.cssSelection.call(this, cssRule);
		},

		elmsByClass : function (className, tag) {
			var cssRule = (tag || "") + "." + className;
			return DOMAssistant.cssSelection.call(this, cssRule);
		},

		elmsByAttribute : function (attr, attrVal, tag, substrMatchSelector) {
			var cssRule = (tag || "") + "[" + attr + ((attrVal && attrVal !== "*")? ((substrMatchSelector || "") + "=" + attrVal + "]") : "]");
			return DOMAssistant.cssSelection.call(this, cssRule);
		},

		elmsByTag : function (tag) {
			return DOMAssistant.cssSelection.call(this, tag);
		}
	};
}();
DOMAssistant.initCore();
DOMAssistant.Storage = function () {
	var uniqueId = 1, data = [], expando = "_da" + +new Date();
	return {
		hasData : function () {
			var uid = this[expando];
			return !!uid && !!data[uid];
		},
		retrieve : function (key) {
			if (!DOMAssistant.def(key)) {
				return this[expando] || (this[expando] = uniqueId++);
			}
			if (!this[expando] || !data[this[expando]]) { return; }
			return data[this[expando]][key];
		},

		store : function (key, val) {
			var uid = this[expando] || (this[expando] = uniqueId++);
			data[uid] = data[uid] || {};
			if (typeof key === "object") {
				for (var i in key) {
					if (typeof i === "string") {
						data[uid][i] = key[i];
					}
				}
			}
			else {
				data[uid][key] = val;
			}
			return this;
		},

		unstore : function (key) {
			var uid = this[expando] || (this[expando] = uniqueId++);
			if (data[uid]) {
				if (DOMAssistant.def(key)) {
					delete data[uid][key];
				}
				else {
					data[uid] = null;
				}
			}
			return this;
		}
	};
}();
DOMAssistant.attach(DOMAssistant.Storage);
DOMAssistant.CSS = function () {
	var def = DOMAssistant.def,
		direct = { display: true };
	return {
		addClass : function (className) {
			if (!this.hasClass(className)) {
				var currentClass = this.className;
				this.className = currentClass + (currentClass.length? " " : "") + className;
			}
			return this;
		},

		removeClass : function (className) {
			return this.replaceClass(className);
		},

		replaceClass : function (className, newClass) {
			var classToRemove = new RegExp(("(^|\\s)" + className + "(\\s|$)"), "i");
			this.className = this.className.replace(classToRemove, function (match, p1, p2) {
				return newClass? (p1 + newClass + p2) : " ";
			}).replace(/^\s+|\s+$/g, "");
			return this;
		},

		hasClass : function (className) {
			return (" " + this.className + " ").indexOf(" " + className + " ") > -1;
		},

		setStyle : function (style, value) {
			var css = this.style;
			if ("filters" in this && (typeof style === "string"? /opacity/i.test(style) : def(style.opacity))) {
				css.zoom = 1;
				css.filter = (css.filter || "").replace(/alpha\([^)]*\)/, "") + "alpha(opacity=" + (def(style.opacity)? style.opacity : value) * 100 + ")";
			}
			if (def(css.cssText)) {
				var styleToSet = css.cssText;
				if (typeof style === "object") {
					for (var i in style) {
						if (typeof i === "string") {
							if (direct[i]) { css[i] = style[i]; }
							styleToSet += ";" + i + ":" + style[i];
						}
					}
				}
				else {
					if (direct[style]) { css[style] = value; }
					styleToSet += ";" + style + ":" + value;
				}
				css.cssText = styleToSet;
			}
			return this;
		},

		getStyle : function (cssRule) {
			var val = "", f;
			cssRule = cssRule.toLowerCase();
			if (document.defaultView && document.defaultView.getComputedStyle) {
				val = document.defaultView.getComputedStyle(this, "").getPropertyValue(cssRule);
			}
			else if (this.currentStyle) {
				if ("filters" in this && cssRule === "opacity") {
					val = (f = this.style.filter || this.currentStyle.filter) && f.indexOf("opacity=") >= 0? parseFloat(f.match(/opacity=([^)]*)/)[1]) / 100 : 1;
				}
				else {
					cssRule = cssRule.replace(/^float$/, "styleFloat").replace(/\-(\w)/g, function (match, p1) {
						return p1.toUpperCase();
					});
					val = this.currentStyle[cssRule];
				}
				if (val === "auto" && /^(width|height)$/.test(cssRule) && this.currentStyle.display !== "none") {
					val = this["offset" + cssRule.charAt(0).toUpperCase() + cssRule.substr(1)] + "px";
				}
			}
			return val;
		}
	};
}();
DOMAssistant.attach(DOMAssistant.CSS);
DOMAssistant.Content = function () {
	var D$ = DOMAssistant.$$;
	return {
		init : function () {
			DOMAssistant.setCache(false);
		},

		create : function (name, attr, append, content) {
			var elm = D$(document.createElement(name));
			if (attr) {
				elm = elm.setAttributes(attr);
			}
			if (DOMAssistant.def(content)) {
				elm.addContent(content);
			}
			if (append) {
				this.appendChild(elm);
			}
			return elm;
		},

		setAttributes : function (attr) {
			if (DOMAssistant.isIE) {
				var setAttr = function (elm, att, val) {
					var attLower = att.toLowerCase();
					switch (attLower) {
						case "name":
						case "type":
						case "multiple":
							return D$(document.createElement(elm.outerHTML.replace(new RegExp(attLower + "(=[a-zA-Z]+)?"), " ").replace(">", " " + attLower + "=" + val + ">")));
						case "style":
							elm.style.cssText = val;
							return elm;
						default:
							elm[DOMAssistant.camel[attLower] || att] = val;
							return elm;
					}
				};
				DOMAssistant.Content.setAttributes = function (attr) {
					var elem = this;
					var parent = this.parentNode;
					for (var i in attr) {
						if (typeof attr[i] === "string" || typeof attr[i] === "number") {
							var newElem = setAttr(elem, i, attr[i]);
							if (parent && /(name|type)/i.test(i)) {
								if (elem.innerHTML) {
									newElem.innerHTML = elem.innerHTML;
								}
								parent.replaceChild(newElem, elem);
							}
							elem = newElem;
						}
					}
					return elem;
				};
			}
			else {
				DOMAssistant.Content.setAttributes = function (attr) {
					for (var i in attr) {
						if (/class/i.test(i)) {
							this.className = attr[i];
						}
						else {
							this.setAttribute(i, attr[i]);
						}
					}
					return this;
				};
			}
			return DOMAssistant.Content.setAttributes.call(this, attr);
		},

		addContent : function (content) {
			var type = typeof content;
			if (type === "string" || type === "number") {
				if (!this.firstChild) {
					this.innerHTML = content;
				}
				else {
					var tmp = document.createElement("div");
					tmp.innerHTML = content;
					for (var i=tmp.childNodes.length-1, last=null; i>=0; i--) {
						last = this.insertBefore(tmp.childNodes[i], last);
					}
				}
			}
			else if (type === "object" || (type === "function" && !!content.nodeName)) {
				this.appendChild(content);
			}
			return this;
		},

		replaceContent : function (content) {
			DOMAssistant.cleanUp(this);
			return this.addContent(content);
		},

		replace : function (content, returnNew) {
			var type = typeof content;
			if (type === "string" || type === "number") {
				var parent = this.parentNode;
				var tmp = DOMAssistant.Content.create.call(parent, "div", null, false, content);
				for (var i=tmp.childNodes.length; i--;) {
					parent.insertBefore(tmp.childNodes[i], this.nextSibling);
				}
				content = this.nextSibling;
				parent.removeChild(this);
			}
			else if (type === "object" || (type === "function" && !!content.nodeName)) {
				this.parentNode.replaceChild(content, this);
			}
			return returnNew? content : this;
		},

		remove : function () {
			DOMAssistant.cleanUp(this);
			if (this.hasData()) {
				if (this.removeEvent) { this.removeEvent(); }
				this.unstore();
			}
			this.parentNode.removeChild(this);
			return null;
		}
	};
}();
DOMAssistant.attach(DOMAssistant.Content);


/*
	Class: Legato_DOM_Library
	Provides a plugin to DOMAssistant to allow extra features for working with the DOM.
*/
Legato_DOM_Library = {};

Legato_DOM_Library.DOMAssistantPlugIn = function ()
{

	return {

		/*
			Function: dimensions()
			Sets/gets the dimension's of the element.
			If no dimensions passed in, will return the element's dimensions.

			Syntax:
				*Getting Dimensions*

				array dimensions()

				*Setting Dimensions*

				object dimensions( int width, int height )

			Parameters:
				*Setting Dimensions*

				int width - The new width you'd like the element to have. Pass in null if you would like the width to stay the same.
				int height - The new height you'd like the element to have. Pass in null if you would like the height to stay the same.

			Returns:
				*Getting Dimensions*

				Returns an array of the dimensions, with the first item being the width and the second item being the height.

				*Setting Dimensions*

				Returns the element the dimensions were set on.

			Examples:
			(begin code)
				var dimensions = $$( 'container' ).dimensions();
				alert( dimensions[0] )  // Show the width of the container.
			(end)

			(begin code)
				// Set the height of the container to 300 pixels.
				$$( 'container' ).dimensions( null, 300 );
			(end)
		*/
		dimensions: function()
		{

			if ( this.window == window )
			{

				var width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
		        var height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);

		        return [ width, height ];

			}
			else if ( arguments.length == 0 )
			{

				return [ this.offsetWidth, this.offsetHeight ];

			}
			else
			{

				if ( arguments[0] !== null ) this.setStyle( 'width', arguments[0] + 'px' );
				if ( arguments[1] !== null ) this.setStyle( 'height', arguments[1] + 'px' );
				return this;

			}

		},


		/*
			Function: position()
			Sets/gets the position of an element.
			If no position passed in, will return the current position of the element.

			Syntax:
				*Getting Position*

				array position()

				*Setting Position*

				object position( int X, int Y )

			Parameters:
				*Setting Position*

				int X - The new X value that you'd like the element to have. Pass in null if you would like the X position to stay the same.
				int Y - The new Y value that you'd like the element to have. Pass in null if you would like the Y position to stay the same.

			Returns:
				*Getting Position*

				Returns an array of the position, with the first item being the X value and the second item being the Y value.

				*Setting Position*

				Returns the element the position was set on.

			Notes:
				This function works off of the page grid and not the containing element. So, setting an X value of 50 would put the element
				50 pixels from the top of the page.

			Examples:
			(begin code)
				// Show the position of the container element.
				var pos = $$( 'container' ).position();
				alert( pos[0] + ' | ' + pos[1] );

				// Set the Y position to 50 pixels.
				$$( 'container' ).position( null, 50 );
			(end)
		*/
		position: function()
		{

			if ( arguments.length == 0 )
			{

				var offsetLeft = offsetTop = 0;
				var elem = this;

				while ( elem !== null )
				{
					offsetLeft += elem.offsetLeft;
					offsetTop += elem.offsetTop;
					elem = elem.offsetParent;
				}

				return [ offsetLeft, offsetTop ];

			}
			else
			{

				// Get the positioning of this element.
				var positioning = this.getStyle( 'position' );

				// If it's statically positioned, we change it to relative positioning.
				// If it's absolute, we leave it.
                if ( positioning == 'static' )
				{
					positioning = 'relative';
                    this.setStyle( 'position', 'relative' );
                }

                // Try to get the offset value.
                var offset =
				[
                    parseInt( this.getStyle( 'left' ), 10 ),
                    parseInt( this.getStyle( 'top' ), 10 )
                ];

            	// If auto was returned, retrieve the correct offset.
                if ( isNaN( offset[0] ) )
                    offset[0] = (positioning == 'relative') ? 0 : this.offsetLeft;

                // If auto was returned, retrieve the correct offset.`
                if ( isNaN( offset[1] ) )
                    offset[1] = (positioning == 'relative') ? 0 : this.offsetTop;

                // Get the page XY position of the element.
                var posXY = this.position();

                // If a new X or Y value was passed in, set it.
                if ( arguments[0] !== null ) this.setStyle( 'left', arguments[0] - posXY[0] + offset[0] + 'px' );
                if ( arguments[1] !== null ) this.setStyle( 'top', arguments[1] - posXY[1] + offset[1] + 'px' );

				// One some browsers (Opera) top/left offsets get calculated relative to
				// the offset parent and not the actual relative positioning. We do this
				// so that if there is any error in the positioning, it will correct it.
				// This only needs to be done once.
				if ( arguments[0] && !this.retrieve( 'legato_delta_x' ) || arguments[1] && !this.retrieve( 'legato_delta_y' ) )
				{

					if ( arguments[0] ) this.store( 'legato_delta_x', true );
					if ( arguments[1] ) this.store( 'legato_delta_y', true );

	                var curPos = this.position();

	                // If this element didn't get set to the position we'd like it to be, set it again.
	                if ( (arguments[0] && curPos[0] != arguments[0]) || (arguments[1] && curPos[1] != arguments[1]) )
	                {

						offset[0] -= curPos[0] - arguments[0];
						offset[1] -= curPos[1] - arguments[1];

						// Set the position again. This time with updated deltas.
						if ( arguments[0] !== null ) this.setStyle( 'left', arguments[0] - posXY[0] + offset[0] + 'px' );
	                	if ( arguments[1] !== null ) this.setStyle( 'top', arguments[1] - posXY[1] + offset[1] + 'px' );

	                }

 				}

                return this;

			}

		},


		/*
			Function: scrollOffset()
			Sets/gets the scroll offset of an element.
			If no offset passed in, will return the current offset of the element.

			Syntax:
				*Getting Offset*

				array scrollOffset()

				*Setting Offset*


				object scrollOffset( int X, int Y )

			Parameters:
				*Setting Offset*

				int X - The new X value that you'd like the element's scroll offset to be. Pass in null if you would like the X offset to stay the same.
				int Y - The new Y value that you'd like the element's scroll offset to be. Pass in null if you would like the Y offset to stay the same.

			Returns:
				*Getting Offset*

				Returns an array of the scroll offset, with the first item being the X offset and the second item being the Y offset.

				*Setting Offset*

				Returns the element the scroll offset was set on.

			Examples:
			(begin code)
				// Show the Y offset of the container element.
				alert( $$( 'container' ).position() );

				// Set the X offset to 75 pixels.
				$$( 'container' ).scrollOffset( 75, null );
			(end)
		*/
		scrollOffset: function()
		{

			if ( this.window == window || this == document.body )
			{

				var X = Y = 0;

				if( typeof( window.pageXOffset ) == 'number' )
				{
					X = window.pageXOffset;
					Y = window.pageYOffset;
				}  // Netscape.
				else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) )
				{
					X = document.body.scrollLeft;
					Y = document.body.scrollTop;
				}  // Standards compliant.
				else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
				{
					X = document.documentElement.scrollLeft;
					Y = document.documentElement.scrollTop;
				}  // IE 6 standards mode.

				return [ X, Y ];

			}
			else if ( arguments.length == 0 )
			{

				return [ this.scrollLeft, this.scrollTop ];

			}
			else
			{

				if ( arguments[0] !== null ) this.scrollLeft = arguments[0];
				if ( arguments[1] !== null ) this.scrollTop = arguments[1];
				return this;

			}

		}

	};

}();

DOMAssistant.attach( Legato_DOM_Library.DOMAssistantPlugIn );

// Developed by Robert Nyman/DOMAssistant team
// Code/licensing: http://domassistant.googlecode.com/
// Documentation: http://www.domassistant.com/documentation
// Version 2.8
DOMAssistant.Events = function () {
	var handler,
		key = "_events",
		w3cMode = !!document.addEventListener,
		useCapture = { focus: true, blur: true },
		translate = DOMAssistant.isIE? { focus: "activate", blur: "deactivate", mouseenter: "mouseover", mouseleave: "mouseout" } : { mouseenter: "mouseover", mouseleave: "mouseout" },
		regex = {
			special: /^submit|reset|change|select$/i,
			mouseenterleave: /^mouse(enter|leave)$/i,
			dom: /^DOM/,
			on: /^on/i
		},
		special = function (e) {
			return DOMAssistant.isIE && regex.special.test(e);
		},
		fix = function (e) {
			return translate[e] || e;
		},
		createEvent = function (e, type, target) {
			e = e || window.event || {};
			if (e.event) { return e; }
			var event = {
				event: e,
				type: type || e.type,
				bubbles: e.bubbles || true,
				cancelable: e.cancelable || false,
				target: target || e.target || e.srcElement,
				clientX: e.clientX || 0,
				clientY: e.clientY || 0,
				altKey: e.altKey || false,
				ctrlKey: e.ctrlKey || false,
				shiftKey: e.shiftKey || false,
				button: e.button || null,
				timeStamp: +new Date(),
				preventDefault: function() {
					if (e.preventDefault) { e.preventDefault(); }
					this.returnValue = e.returnValue = false;
				},
				stopPropagation: function() {
					if (e.stopPropagation) { e.stopPropagation(); }
					this.cancelBubble = e.cancelBubble = true;
				}
			};
			if (event.target && 3 === event.target.nodeType) { // Safari textnode bug
				event.target = event.target.parentNode;
			}
			event.currentTarget = event.target;
			event.relatedTarget = e.relatedTarget || (e.fromElement === event.target? e.toElement : e.fromElement) || null;
			var de = document.documentElement, b = document.body;
			event.pageX = DOMAssistant.def(e.pageX)? e.pageX : (event.clientX + (de.scrollLeft || b.scrollLeft) - (de.clientLeft || 0));
			event.pageY = DOMAssistant.def(e.pageY)? e.pageY : (event.clientY + (de.scrollTop || b.scrollTop) - (de.clientTop || 0));
			if ("number" === typeof e.which) {
				event.keyCode = e.keyCode;
				event.charCode = event.which = e.which;
			}
			else if (e.keyCode) {
				event.keyCode = event.charCode = e.keyCode;
			}
			return event;
		};

	return {
		publicMethods : [
			"triggerEvent",
			"addEvent",
			"removeEvent",
			"relayEvent",
			"unrelayEvent",
			"preventDefault",
			"cancelBubble"
		],

		init : function () {
			DOMAssistant.preventDefault = this.preventDefault;
			DOMAssistant.cancelBubble = this.cancelBubble;
			handler = this.handleEvent;
		},

		triggerEvent : function (evt, target, e) {
			var fevt = fix(evt),
				events = this.retrieve(key),
				event = e || createEvent(e, fevt, target || this);
			event.currentTarget = this;
			if (events && events[fevt]) {
				for (var i=0, iL=events[fevt].length; i<iL; i++) {
					if (events[fevt][i].call(this, event) === false) { event.stopPropagation(); }
				}
			}
			else if (typeof this["on" + fevt] === "function") {
				this["on" + fevt].call(this, event);
			}
			var p = DOMAssistant.$$(this.parentNode);
			if (!event.cancelBubble && p && p.nodeType === 1) {
				p.triggerEvent(fevt, target, event);
			}
			return this;
		},

		addEvent : function (evt, func, relay, proxy, selector) {
			var existingEvent,
				fevt = fix(evt),
				uid = fevt + this.retrieve(),
				onevt = "on" + fevt;
			if (!(func.attachedElements && func.attachedElements[uid])) {
				var events = this.retrieve(key) || {};
				if (!events[fevt]) {
					events[fevt] = [];
					existingEvent = this[onevt];
					this[onevt] = null;
				}
				if (typeof this.window === "object") { this.window[onevt] = handler; }
				else if (!events[fevt].length) {
					if (w3cMode) { this.addEventListener(fevt, handler, useCapture[fevt]); }
					else { this[onevt] = handler; }
				}
				if (existingEvent) {
					events[fevt].push(existingEvent);
				}
				if (fevt !== evt) { func.evt = evt; }
				func.relay = relay;
				func.proxy = proxy;
				func.selector = selector;
				func.attachedElements = func.attachedElements || {};
				func.attachedElements[uid] = true;
				events[fevt].push(func);
				this.store(key, events);
			}
			return this;
		},

		handleEvent : function (evt) {
			var currentEvt = (evt && regex.dom.test(evt.type) && w3cMode)? evt : createEvent(evt),
				type = fix(currentEvt.type),
				targ = currentEvt.target,
				relatedTarg = currentEvt.relatedTarget,
				eventColl = this.retrieve(key)[type].slice(0), eventCollLength, eventReturn, oevt;
			if ((eventCollLength = eventColl.length)) {
				for (var i=0; i<eventCollLength; i++) {
					if (typeof eventColl[i] === "function") {
						if ((oevt = eventColl[i].evt) && oevt !== type) {
							currentEvt.type = oevt;
							if (relatedTarg && regex.mouseenterleave.test(oevt)) {
								if (eventColl[i].relay) {
									var elms = eventColl[i].elms || (eventColl[i].elms = this.cssSelect(eventColl[i].selector));
									if (elms.indexOf(targ) < 0 || !DOMAssistant.hasChild.call(relatedTarg, targ)) { continue; }
								}
								else if (this === relatedTarg || this.hasChild(relatedTarg)) { continue; }
							}
						}
						eventReturn = eventColl[i].call(this, currentEvt);
					}
				}
				if (eventReturn === false) { currentEvt.stopPropagation(); }
				return eventReturn;
			}
		},

		removeEvent : function (evt, func, relay, proxy) {
			var uid = (evt = fix(evt)) + this.retrieve(),
				events = this.retrieve(key),
				onevt = "on" + evt;
			if (events && !evt) {
				for (var ev in events) {
					if (events[ev].length) { this.removeEvent(ev); }
				}
				var attr = this.attributes;
				for (var att, j=attr.length; j--;) {
					att = attr[j].nodeName.toLowerCase();
					if (regex.on.test(att) && typeof this[att] === "function") {
						this[att] = null;
					}
				}
			}
			else if (events && events[evt]) {
				var eventColl = events[evt];
				for (var fn, i=eventColl.length; i--;) {
					fn = func || eventColl[i];
					if (eventColl[i] === fn && relay === fn.relay && proxy === fn.proxy) {
						eventColl.splice(i, 1);
						if (!!proxy && fn.selector) {
							this.cssSelect(fn.selector).removeEvent(proxy);
						}
						if (fn.attachedElements) {
							fn.attachedElements[uid] = null;
						}
					}
				}
				if (!events[evt].length) {
					if (w3cMode) { this.removeEventListener(evt, handler, useCapture[evt]); }
					else { this[onevt] = null; }
				}
			}
			else if (this[onevt] && !func && !relay) {
				this[onevt] = null;
			}
			return this;
		},

		relayEvent: function (evt, selector, fn, proxy) {
			if (special(evt)) {
				this.relayEvent("focus", selector, function() {
					DOMAssistant.$$(this).removeEvent(evt).addEvent(evt, function(e) {
						return fn.call(this, createEvent(e));
					});
				}, evt).relayEvent("blur", selector, function() {
					DOMAssistant.$$(this).removeEvent(evt);
				}, evt);
				return this;
			}
			return this.addEvent(evt, function(e) {
				e = createEvent(e);
				var target = e.target, args = arguments, i = 0, elm, elms = this.cssSelect(selector);
				while ((elm = elms[i++])) {
					if ((elm === target || DOMAssistant.hasChild.call(elm, target)) && !elm.disabled) {
						e.currentTarget = elm;
						var retVal = fn.apply(elm, args);
						if (!retVal) { e.preventDefault(); }
						return retVal;
					}
				}
			}, true, proxy, selector);
		},

		unrelayEvent: function (evt) {
			if (special(evt)) {
				return this.removeEvent("focus", null, true, evt).removeEvent("blur", null, true, evt);
			}
			return this.removeEvent(evt, null, true);
		},

		preventDefault : function (evt) {
			if (evt.preventDefault) { evt.preventDefault(); }
			evt.returnValue = false;
		},

		cancelBubble : function (evt) {
			if (evt.stopPropagation) { evt.stopPropagation(); }
			evt.cancelBubble = true;
		}
	};
}();
DOMAssistant.attach(DOMAssistant.Events);

//------------------------------------------------------------------------
// Name: Legato_Form
// Desc: A helper class to help with the PHP Form class.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Public Member Functions
//------------------------------------------------------------------------
//------------------------------------------------------------------------
// Name: Legato_Form
// Desc: Class constructor.
//------------------------------------------------------------------------
function Legato_Form( form, options_object )
{

	this.form                  = $$( form );
	this.input_elements        = [];
	this.groups                = [];

	// Store the parameters.
	this.submit_buttons         = options_object.submit_buttons;
	this.submit_form           = (options_object.submit_form == null) ? false : true;
	this.redirect_url          = options_object.redirect_url;
	this.request_url           = options_object.request_url;
	this.modified_request_url  = '';
	this.errors                = [];

	this.processing            = false;

	// Add on onsubmit event for the form.
	var form = this;
	$( this.form ).addEvent( 'submit', function(){ return form.validateForm(); } );

	// Add onclick events for all the submit buttons.
	for ( var i = 0; i < this.submit_buttons.length; ++i )
		if ( this.submit_buttons[i] != null )
			$( this.submit_buttons[i] ).addEvent( 'click', function(){ form.submitOnClick( this ); } );

}


//----------------------------------------------------------------------
// Name: validateForm()
// Desc: Start the validation.
//----------------------------------------------------------------------
Legato_Form.prototype.validateForm = function()
{

	var errors = false;

	// Are we processing?
	if ( this.processing == true )
		return false;
	else
		this.processing = true;

	// Disable the submit button.
	for ( var i = 0; i < this.submit_buttons.length; ++i )
		if ( this.submit_buttons[i] != null )
			this.submit_buttons[i].disabled = true;

	// First make sure the form is clean.
	this.cleanupForm();

	// If there is a request URL, send the request.
	if ( this.request_url != null )
	{

		var query_string = this.getQueryString();

		// Send the request.
		var form = this;
		Legato_RequestManager.makeRequest( this.modified_request_url, function( response ){ form.processResponse( response ); }, query_string );

		// Return. We will continue processing in the processResponse() function.
		return false;

	}

	// Finish the validation.
	this.finishValidation();

};


//----------------------------------------------------------------------
// Name: processResponse()
// Desc: Processes the response from the XHR request.
//----------------------------------------------------------------------
Legato_Form.prototype.processResponse = function( response )
{

	var any_errors = false;

	// JSON or XML?
	if ( !response.responseXML || response.responseXML.getElementsByTagName( 'errors' ).length == 0 )
	{

		var errors = eval( '(' + response.responseText + ')' );

		// Any errors?
		if ( errors.length != 0 )
		{

			// Set errors on.
			any_errors = true;

			// Loop through each error.
			for ( var id in errors )
			{

				// Get the message.
				var message = errors[id];

				// Post the error.
				this.postError( id, message );

			}  // Next error.

		}

	}
	else
	{

		response = response.responseXML;

		// Get the errors.
		var errors = response.getElementsByTagName( 'error' );

		// Is there any errors?
		if ( errors.length != 0 )
		{

			// Set errors on.
			any_errors = true;

			// Loop through each error.
			for ( var i = 0; i < errors.length; i++ )
			{

				// Get the error details.
				var id = errors[i].getElementsByTagName( "id" );

				if ( id.length == 0 )
					id = null;
				else
					id = id[0].firstChild.data;

				// Get the message.
				var message = errors[i].getElementsByTagName( "message" )[0].firstChild.data;

				// Post the error.
				this.postError( id, message );

			}  // Next error.

		}

	}

	// Any errors?
	if ( !any_errors )
	{

		// Finish validation.
		this.finishValidation();

		// Return.
		return;

	}

	// Show the generic error message.
	this.postError( null, 'There were errors while processing the form. Please fix them and try submitting the form again.' );

	// Set processing to false.
	this.processing = false;

	// Enable the submit button.
	for ( var i = 0; i < this.submit_buttons.length; ++i )
		if ( this.submit_buttons[i] != null )
			this.submit_buttons[i].disabled = false;

};


//----------------------------------------------------------------------
// Name: finishValidation()
// Desc: Finishes the validation.
//----------------------------------------------------------------------
Legato_Form.prototype.finishValidation = function()
{

	// Check for a redirect URL and if there is one redirect them.
	if ( this.redirect_url != null )
	{
		window.location = this.redirect_url;
		return true;
	}

	// If the submit form flag is set, submit the form.
	if ( this.submit_form )
		return true;

	// Set processing to false.
	this.processing = false;

	// Enable the submit button.
	for ( var i = 0; i < this.submit_buttons.length; ++i )
		if ( this.submit_buttons[i] != null )
			this.submit_buttons[i].disabled = false;

	// Don't submit form.
	return false;

};


//----------------------------------------------------------------------
// Name: submitOnClick()
// Desc: Gets called when a submit button is clicked for this form.
//----------------------------------------------------------------------
Legato_Form.prototype.submitOnClick = function( elem )
{

	// Since we disable the submit buttons during submission, we have to
	// add a hidden form element with the same name/value as the element
	// being clicked, so that we know which submit button was clicked
	// during processing.
	this.form.addContent( '<input type="hidden" name="' + elem.name + '" value="' + elem.value + '">' );

};


//----------------------------------------------------------------------
// Name: postError()
// Desc: Posts an error to the form with information about what went
//       wrong and why it went wrong.
// Note: If null is passed in for element_id, the error will be placed
//       at the end of the form.
//----------------------------------------------------------------------
Legato_Form.prototype.postError = function( element_id, error )
{

	// Create the error node.
	var error_node = $( document.body ).create( 'p', { className: 'error' }, false, error );

	// What type of placement?
	if ( element_id == null )
	{

		// Do we have a submit button?
		if ( this.submit_buttons[0] != null )
		{

			// A group or not?
			if ( $( this.submit_buttons[0].parentNode.parentNode ).hasClass( 'group_elements' ) )
				this.submit_buttons[0].parentNode.parentNode.parentNode.insertBefore( error_node, this.submit_buttons[0].parentNode.parentNode.parentNode.firstChild );
			else
				this.submit_buttons[0].parentNode.insertBefore( error_node, this.submit_buttons[0].parentNode.firstChild );
		}
		else
			this.form.addContent( error_node );

	}  // End if general error message.
	else
	{

		var html_element = this.form.cssSelect( '#' + element_id )[0];

		// Group or normal?
		if ( $( html_element.parentNode.parentNode ).hasClass( 'group' ) )
			html_element.parentNode.parentNode.insertBefore( error_node, html_element.parentNode.parentNode.firstChild );
		else
			html_element.parentNode.insertBefore( error_node, html_element.parentNode.firstChild );

	}  // End if normal/group error message.

};


//----------------------------------------------------------------------
// Name: cleanupForm()
// Desc: Cleans up the form to make it ready for form validation.
//----------------------------------------------------------------------
Legato_Form.prototype.cleanupForm = function()
{

	// Get all the forms error's.
	var errors = this.form.cssSelect( 'p.error' );

	// Loop through each error.
	// We get the length before hand, because we take elements away from the
	// array in the loop.
	for ( var i = 0; i < errors.length; i++ )
	{

		// Get the element. We retrieve the 0th element because we remove
		// the child below, and the next one will fall in this place.
		var error_element = errors[i];

		// Is this an error element?
		error_element.remove();  // Remove the element.


	}  // Next error node.

};


//----------------------------------------------------------------------
// Name: getQueryString()
// Desc: Concatenates all the managed input elements in to a query
//       string suitable for appending to a URL.
//----------------------------------------------------------------------
Legato_Form.prototype.getQueryString = function()
{

	var values = Array();

	// Loop through each input element in the form.
	for ( var i = 0; i < this.form.elements.length; i++ )
	{

		var element = this.form.elements[i];

		// What type of element?
		switch ( element.type )
		{

		// Simple elements.
		case 'text':
		case 'password':
		case 'file':
		case 'textarea':
		case 'hidden':
		case 'select-one':

			values.push( (element.name + "=" + encodeURIComponent( element.value )) );
			break;

		// Checkboxes and radio buttons.
		case 'checkbox':
		case 'radio':

			// Only add if checked.
			if ( element.checked )
				values.push( (element.name + "=" + encodeURIComponent( element.value )) );

			break;

		// Select multiples.
		case 'select-multiple':

			// Loop through each option.
			for ( var n = 0; n < element.options.length; n++ )
			{

				// Only add if option is selected.
				if ( element.options[n].selected )
					values.push( (element.name + "=" + encodeURIComponent( element.options[n].value )) );

			}  // Next option.

			break;

		}  // End what type of elements.

	}  // Next input element.

	// Put the values together into a string.
	var query_string = values.join( "&" );

	// Get the pieces of the request URL.
	var pieces = this.request_url.match( /(\S*)\?(\S*)/ );

	// If the request_url does not have a ? in it, get rid of the query values from
	// the request URL, and add it to the query string.
	if ( pieces != null )
	{

		this.modified_request_url = pieces[1];
		query_string              = pieces[2] + "&" + query_string;

	}
	else
	{

		this.modified_request_url = this.request_url;

	}

	// Return the query string.
	return query_string;

};



//------------------------------------------------------------------------
// Package: Animation
// For animating elements in the DOM in various ways.
//
// Topic: Dependencies
// - <Events Handler>
// - <Structures>
// - <DOM Library>
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Class: Legato_Animation_Controller
// Stores the animations parameters.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Animation_Controller()
// Class constructor. You don't need to instantiate this as it is used by
// the system.
//------------------------------------------------------------------------
function Legato_Animation_Controller()
{

	// Store the default values.
	this.move              = { to:    new Legato_Structure_Point(),
	                           by:    new Legato_Structure_Point(),
							   ease:  Legato_Animation.EASE_NONE };

	this.width             = { to:    null,
	                           by:    null,
							   ease:  Legato_Animation.EASE_NONE };

	this.height            = { to:    null,
	                           by:    null,
							   ease:  Legato_Animation.EASE_NONE };

	this.opacity           = { to:    null,
	                           by:    null,
							   ease:  Legato_Animation.EASE_NONE };

	this.background_color  = { to:    new Legato_Structure_Color(),
	                           by:    new Legato_Structure_Color() };

	this.border_color      = { to:    new Legato_Structure_Color(),
	                           by:    new Legato_Structure_Color() };

	this.text_color        = { to:    new Legato_Structure_Color(),
	                           by:    new Legato_Structure_Color() };

	this.delay             = 0;

}


//------------------------------------------------------------------------
// Class: Legato_Animation
// Holds a single animation for an element and the necessary methods to
// handle it.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Class Constants
//------------------------------------------------------------------------
Legato_Animation.EASE_NONE          = 0;
Legato_Animation.EASE_IN            = 1;
Legato_Animation.EASE_OUT           = 2;
Legato_Animation.EASE_BOTH          = 3;
Legato_Animation.STRONG_EASE_IN     = 4;
Legato_Animation.STRONG_EASE_OUT    = 5;
Legato_Animation.STRONG_EASE_BOTH   = 6;
Legato_Animation.BACK_EASE_IN       = 7;
Legato_Animation.BACK_EASE_OUT      = 8;
Legato_Animation.BACK_EASE_BOTH     = 9;
Legato_Animation.BOUNCE_EASE_IN     = 10;
Legato_Animation.BOUNCE_EASE_OUT    = 11;
Legato_Animation.BOUNCE_EASE_BOTH   = 12;
Legato_Animation.ELASTIC_EASE_IN    = 13;
Legato_Animation.ELASTIC_EASE_OUT   = 14;
Legato_Animation.ELASTIC_EASE_BOTH  = 15;


//------------------------------------------------------------------------
// Public Member Functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Animation()
// Class constructor.
//
// Parameters:
//     element - The DOM element that you'd like to animate.
//     run_time - The length that you'd like the animation to run.
//------------------------------------------------------------------------
function Legato_Animation( element, run_time )
{

	// Store the values.
	this.element               = $( element );
	this.element_properties    = Object();
	this.run_time              = run_time;
	this.controller            = new Legato_Animation_Controller();

	this.onStart               = null;
	this.onInterval            = null;
	this.onAdvance             = null;
	this.onEventFrame          = null;
	this.onStop                = null;
	this.onFinish              = null;

	// These values are used by the Legato_Animation system internally.
	this.status                = false;
	this.event_frames          = new Array();

	this.start_time            = null;
	this.current_time          = null;

	this.begin_width           = null;
	this.begin_height          = null;
	this.begin_pos             = null;
	this.begin_back_color      = null;
	this.begin_border_color    = null;
	this.begin_text_color      = null;
	this.begin_opacity         = null;

	this.offset_width          = null;
	this.offset_height         = null;
	this.offset_pos            = new Legato_Structure_Point();
	this.offset_back_color     = new Legato_Structure_Color();
	this.offset_border_color   = new Legato_Structure_Color();
	this.offset_text_color     = new Legato_Structure_Color();
	this.offset_opacity        = null;

	this.desired_width         = null;
	this.desired_height        = null;
	this.desired_pos           = new Legato_Structure_Point();
	this.desired_back_color    = null;
	this.desired_border_color  = null;
	this.desired_text_color    = null;
	this.desired_opacity       = null;

}


//------------------------------------------------------------------------
// Function: addEventFrame()
// Adds an event frame to the animation.
//
// Parameters:
//      time_offset - The offset from the beginning of the animation that
//                    you'd like this event to be fired.
//      event_func - The function that you'd like to execute.
//------------------------------------------------------------------------
Legato_Animation.prototype.addEventFrame = function( time_offset, event_func )
{

  // Add the new event frame to the animation.
	this.event_frames.push( { time_offset: time_offset, event_func: event_func, triggered: false } );

}


//------------------------------------------------------------------------
// Function: start()
// Sets the animation to start playing.
//------------------------------------------------------------------------
Legato_Animation.prototype.start = function()
{

	// Don't start if in the middle of playing.
	if ( this.status ) return;

	// Set the necessary values.
	this.status      = true;
	this.start_time  = new Date();

	// Width.
	if ( this.controller.width.to != null || this.controller.width.by != null )
	{

		// Get the element's width.
		this.begin_width = this.element.dimensions()[0];

		// Get the desired width and offset width.
		this.desired_width  = (this.controller.width.to != null) ? (this.controller.width.to) : (this.begin_width + this.controller.width.by);
		this.offset_width   = this.desired_width - this.begin_width;

	}

	// Height.
	if ( this.controller.height.to != null || this.controller.height.by != null )
	{

		// Get the element's height.
		this.begin_height = this.element.dimensions()[1];

		// Get the desired height and offset height.
		this.desired_height  = (this.controller.height.to != null) ? (this.controller.height.to) : (this.begin_height + this.controller.height.by);
		this.offset_height   = this.desired_height - this.begin_height;

	}

	// Position.
	if ( this.controller.move.to.X != null || this.controller.move.to.Y != null || this.controller.move.by.X != null || this.controller.move.by.Y != null )
	{

		// Get the element's position.
		this.begin_pos = this.element.position();
		this.begin_pos = new Legato_Structure_Point( this.begin_pos[0], this.begin_pos[1] );

		// Get the desired X position and X offset position.
		if ( this.controller.move.to.X != null || this.controller.move.by.X != null )
		{

			this.desired_pos.X  = (this.controller.move.to.X != null) ? (this.controller.move.to.X) : (this.begin_pos.X + this.controller.move.by.X);
			this.offset_pos.X   = this.desired_pos.X - this.begin_pos.X;

		}

		// Get the desired Y position and Y offset position.
		if ( this.controller.move.to.Y != null || this.controller.move.by.Y != null )
		{

			this.desired_pos.Y  = (this.controller.move.to.Y != null) ? (this.controller.move.to.Y) : (this.begin_pos.Y + this.controller.move.by.Y);
			this.offset_pos.Y   = this.desired_pos.Y - this.begin_pos.Y;

		}

	}

	// Opacity.
	if ( this.controller.opacity.to != null || this.controller.opacity.by != null )
	{
		
		// Get the element's opacity.
		this.begin_opacity = this.element.getStyle( 'opacity' );
		
		// Get the desired opacity and offset opacity.
		this.desired_opacity  = (this.controller.opacity.to != null) ? (this.controller.opacity.to) : (this.begin_opacity + this.controller.opacity.by);
		this.offset_opacity   = this.desired_opacity - this.begin_opacity;
		
	}

	// Background Color.
	if ( this.controller.background_color.to.R != null || 
	     this.controller.background_color.to.G != null || 
		 this.controller.background_color.to.B != null || 
	     this.controller.background_color.by.R != null ||
		 this.controller.background_color.by.G != null ||
		 this.controller.background_color.by.B != null )
	{
		
		// Get the element's background color.
		this.begin_back_color   = new Legato_Structure_Color( this.element.getStyle( 'background-color' ).substring( 1 ) );
		this.desired_back_color = new Legato_Structure_Color( this.begin_back_color.toHexString() );

		// Get the desired red value and offset value.
		if ( this.controller.background_color.to.R != null || this.controller.background_color.by.R != null )
		{

			this.desired_back_color.R  = (this.controller.background_color.to.R != null) ? (this.controller.background_color.to.R) : (this.begin_back_color.R + this.controller.background_color.by.R);
			this.offset_back_color.R   = this.desired_back_color.R - this.begin_back_color.R;

		}

		// Get the desired green value and offset value.
		if ( this.controller.background_color.to.G != null || this.controller.background_color.by.G != null )
		{

			this.desired_back_color.G  = (this.controller.background_color.to.G != null) ? (this.controller.background_color.to.G) : (this.begin_back_color.G + this.controller.background_color.by.G);
			this.offset_back_color.G   = this.desired_back_color.G - this.begin_back_color.G;

		}

		// Get the desired blue value and offset value.
		if ( this.controller.background_color.to.B != null || this.controller.background_color.by.B != null )
		{

			this.desired_back_color.B  = (this.controller.background_color.to.B != null) ? (this.controller.background_color.to.B) : (this.begin_back_color.B + this.controller.background_color.by.B);
			this.offset_back_color.B   = this.desired_back_color.B - this.begin_back_color.B;

		}

	}

	// Border Color.
	if ( this.controller.border_color.to.R != null || 
	     this.controller.border_color.to.G != null || 
		 this.controller.border_color.to.B != null || 
	     this.controller.border_color.by.R != null ||
		 this.controller.border_color.by.G != null ||
		 this.controller.border_color.by.B != null )
	{
		
		// Get the element's border color.
		this.begin_border_color   = new Legato_Structure_Color( this.element.getStyle( 'border-color' ).substring( 1 ) );
		this.desired_border_color = new Legato_Structure_Color( this.begin_border_color.toHexString() );

		// Get the desired red value and offset value.
		if ( this.controller.border_color.to.R != null || this.controller.border_color.by.R != null )
		{

			this.desired_border_color.R  = (this.controller.border_color.to.R != null) ? (this.controller.border_color.to.R) : (this.begin_border_color.R + this.controller.border_color.by.R);
			this.offset_border_color.R   = this.desired_border_color.R - this.begin_border_color.R;

		}

		// Get the desired green value and offset value.
		if ( this.controller.border_color.to.G != null || this.controller.border_color.by.G != null )
		{

			this.desired_border_color.G  = (this.controller.border_color.to.G != null) ? (this.controller.border_color.to.G) : (this.begin_border_color.G + this.controller.border_color.by.G);
			this.offset_border_color.G   = this.desired_border_color.G - this.begin_border_color.G;

		}

		// Get the desired blue value and offset value.
		if ( this.controller.border_color.to.B != null || this.controller.border_color.by.B != null )
		{

			this.desired_border_color.B  = (this.controller.border_color.to.B != null) ? (this.controller.border_color.to.B) : (this.begin_border_color.B + this.controller.border_color.by.B);
			this.offset_border_color.B   = this.desired_border_color.B - this.begin_border_color.B;

		}

	}

	// Text Color.
	if ( this.controller.text_color.to.R != null || 
	     this.controller.text_color.to.G != null || 
		 this.controller.text_color.to.B != null || 
	     this.controller.text_color.by.R != null ||
		 this.controller.text_color.by.G != null ||
		 this.controller.text_color.by.B != null )
	{

		// Get the element's text color.
		this.begin_text_color   = new Legato_Structure_Color( this.element.getStyle( 'color' ).substring( 1 ) );
		this.desired_text_color = new Legato_Structure_Color( this.begin_text_color.toHexString() );
		
		// Get the desired red value and offset value.
		if ( this.controller.text_color.to.R != null || this.controller.text_color.by.R != null )
		{

			this.desired_text_color.R  = (this.controller.text_color.to.R != null) ? (this.controller.text_color.to.R) : (this.begin_text_color.R + this.controller.text_color.by.R);
			this.offset_text_color.R   = this.desired_text_color.R - this.begin_text_color.R;

		}

		// Get the desired green value and offset value.
		if ( this.controller.text_color.to.G != null || this.controller.text_color.by.G != null )
		{

			this.desired_text_color.G  = (this.controller.text_color.to.G != null) ? (this.controller.text_color.to.G) : (this.begin_text_color.G + this.controller.text_color.by.G);
			this.offset_text_color.G   = this.desired_text_color.G - this.begin_text_color.G;

		}

		// Get the desired blue value and offset value.
		if ( this.controller.text_color.to.B != null || this.controller.text_color.by.B != null )
		{

			this.desired_text_color.B  = (this.controller.text_color.to.B != null) ? (this.controller.text_color.to.B) : (this.begin_text_color.B + this.controller.text_color.by.B);
			this.offset_text_color.B   = this.desired_text_color.B - this.begin_text_color.B;

		}

	}

	// Call the onStart function if there is any.
	if ( this.onStart != null )
	  this.onStart( this );

	// Call the incrementAnimation function. It will start the animation.
	Legato_Animation_Manager.addAnimation( this );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceWidth()
// Advances the width.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceWidth = function()
{

	// Get the new width.
	var new_width = Legato_Animation.tweenValue( this.controller.width.ease, (this.current_time - this.controller.delay), this.run_time, this.begin_width, this.offset_width );

	// Bounds.
	new_width = Math.max( new_width, 0 );

	// Set the new width on the element.
	this.element.dimensions( Math.ceil( new_width ), null );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceHeight()
// Advances the height.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceHeight = function()
{

	// Get the new height.
	var new_height = Legato_Animation.tweenValue( this.controller.height.ease, (this.current_time - this.controller.delay), this.run_time, this.begin_height, this.offset_height );
	
	// Bounds.
	new_height = Math.max( new_height, 0 );
	
	// Set the new height on the element.
	this.element.dimensions( null, Math.ceil( new_height ) );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advancePosition()
// Advances the position.
//------------------------------------------------------------------------
Legato_Animation.prototype.advancePosition = function()
{

	// Updating X position?
	if ( this.offset_pos.X != null )
	{

		// Get the new X position.
		var new_X_pos = Legato_Animation.tweenValue( this.controller.move.ease, (this.current_time - this.controller.delay), this.run_time, this.begin_pos.X, this.offset_pos.X );
		
		// Bounds.
		new_X_pos = Math.max( new_X_pos, 0 );

		// Set the new X position on the element.
		this.element.position( Math.ceil( new_X_pos ), null );

	}  // End if updating X position.

	// Updating Y position?
	if ( this.offset_pos.Y != null )
	{

		// Get the new Y position.
		var new_Y_pos = Legato_Animation.tweenValue( this.controller.move.ease, (this.current_time - this.controller.delay), this.run_time, this.begin_pos.Y, this.offset_pos.Y );
		
		// Bounds.
		new_Y_pos = Math.max( new_Y_pos, 0 );

		// Set the new Y position on the element.
		this.element.position( null, Math.ceil( new_Y_pos ) );

	}  // End if updating Y position.

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceOpacity()
// Advances the opacity.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceOpacity = function()
{

	// Get the new opacity.
	var new_opacity = (Legato_Animation.tweenValue( this.controller.opacity.ease, (this.current_time - this.controller.delay), this.run_time, (this.begin_opacity * 100), (this.offset_opacity * 100) ) / 100);
	
	// Bounds.
	new_opacity = Math.min( Math.max( new_opacity, 0 ), 1 );
	
	// Set the new opacity on the element.
	this.element.setStyle( 'opacity', new_opacity );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceBackgroundColor()
// Advances the background color.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceBackgroundColor = function()
{

	// Set the new back color as the beginning color.
	var new_back_color = new Legato_Structure_Color( this.begin_back_color.toHexString() );

	// Updating red value?
	if ( this.offset_back_color.R != null )
	{

		// Get the new background color.
		new_back_color.R = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_back_color.R, this.offset_back_color.R ) );
	
	}  // End if updating red value.

	// Updating green value?
	if ( this.offset_back_color.G != null )
	{

		// Get the new background color.
		new_back_color.G = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_back_color.G, this.offset_back_color.G ) );

	}  // End if updating red value.

	// Updating blue value?
	if ( this.offset_back_color.B != null )
	{

		// Get the new background color.
		new_back_color.B = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_back_color.B, this.offset_back_color.B ) );

	}  // End if updating red value.
	
	// Bounds.
	new_back_color.R = Math.min( Math.max( new_back_color.R, 0 ), 255 );
	new_back_color.G = Math.min( Math.max( new_back_color.G, 0 ), 255 );
	new_back_color.B = Math.min( Math.max( new_back_color.B, 0 ), 255 );
	
	// Set the new background color on the element.
	this.element.setStyle( 'background-color', '#' + new_back_color.toHexString() );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceBorderColor()
// Advances the border color.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceBorderColor = function()
{

	// Set the new border color as the beginning color.
	var new_border_color = new Legato_Structure_Color( this.begin_border_color.toHexString() );

	// Updating red value?
	if ( this.offset_border_color.R != null )
	{

		// Get the new border color.
		new_border_color.R = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_border_color.R, this.offset_border_color.R ) );

	}  // End if updating red value.

	// Updating green value?
	if ( this.offset_back_color.G != null )
	{

		// Get the new border color.
		new_border_color.G = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_border_color.G, this.offset_border_color.G ) );

	}  // End if updating red value.

	// Updating blue value?
	if ( this.offset_border_color.B != null )
	{

		// Get the new border color.
		new_border_color.B = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_border_color.B, this.offset_border_color.B ) );

	}  // End if updating red value.
	
	// Bounds.
	new_border_color.R = Math.min( Math.max( new_border_color.R, 0 ), 255 );
	new_border_color.G = Math.min( Math.max( new_border_color.G, 0 ), 255 );
	new_border_color.B = Math.min( Math.max( new_border_color.B, 0 ), 255 );

	// Set the new border color on the element.
	this.element.setStyle( 'border-color', '#' + new_border_color.toHexString() );
	
}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceTextColor()
// Advances the text color.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceTextColor = function()
{
	
	// Set the new text color as the beginning color.
	var new_text_color = new Legato_Structure_Color( this.begin_text_color.toHexString() );

	// Updating red value?
	if ( this.offset_text_color.R != null )
	{
		
		// Get the new text color.
		new_text_color.R = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_text_color.R, this.offset_text_color.R ) );

	}  // End if updating red value.

	// Updating green value?
	if ( this.offset_text_color.G != null )
	{

		// Get the new text color.
		new_text_color.G = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_text_color.G, this.offset_text_color.G ) );

	}  // End if updating red value.

	// Updating blue value?
	if ( this.offset_text_color.B != null )
	{

		// Get the new text color.
		new_text_color.B = Math.ceil( Legato_Animation.tweenValue( Legato_Animation.EASE_NONE, (this.current_time - this.controller.delay), this.run_time, this.begin_text_color.B, this.offset_text_color.B ) );

	}  // End if updating red value.
	
	// Bounds.
	new_text_color.R = Math.min( Math.max( new_text_color.R, 0 ), 255 );
	new_text_color.G = Math.min( Math.max( new_text_color.G, 0 ), 255 );
	new_text_color.B = Math.min( Math.max( new_text_color.B, 0 ), 255 );

	// Set the new text color on the element.
	this.element.setStyle( 'color', '#' + new_text_color.toHexString() );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: advanceFrame()
// Carries out the next frame of the animation.
//------------------------------------------------------------------------
Legato_Animation.prototype.advanceFrame = function()
{

	// If the animation is stopped, return false.
	if ( !this.status )
	  return false;

	// Update the current time.
	this.current_time = new Date() - this.start_time;

	// Only start incrementing if we have passed the delay time.
	if ( this.current_time > this.controller.delay )
	{
		
		// Animating width?
		if ( this.desired_width != null )
			this.advanceWidth();

		// Animating height?
		if ( this.desired_height != null )
			this.advanceHeight();

		// Animating position?
		if ( this.desired_pos.X != null || this.desired_pos.Y != null )
			this.advancePosition();

		// Animating opacity?
		if ( this.desired_opacity != null )
			this.advanceOpacity();

		// Animating background color?
		if ( this.desired_back_color != null )
			this.advanceBackgroundColor();

		// Animating border color?
		if ( this.desired_border_color != null )
			this.advanceBorderColor();

		// Animating text color?
		if ( this.desired_text_color != null )
			this.advanceTextColor();
			
		// Loop through each event frame.
		var event_triggered = false;
		for ( var i = 0; i < this.event_frames.length; i++ )
		{

			// If it is time (or passed time) to trigger the event, do so.
			if ( !this.event_frames[i].triggered && this.current_time >= this.controller.delay + this.event_frames[i].time_offset )
			{

			  this.event_frames[i].event_func( this );
				this.event_frames[i].triggered = true;
				event_triggered = true;

			}

		}  // Next event frame.

		// If an event was triggered and there's an onEventFrame function, call it.
		if ( event_triggered && this.onEventFrame )
		  this.onEventFrame( this );

		// Call the onAdvance function if there is any.
		if ( this.onAdvance )
			this.onAdvance( this );

	}  // End if delay is over.

	// Call the onAdvance function if there is any.
	if ( this.onInterval )
		this.onInterval( this );

	// Should we continue processing?
	if ( this.current_time < this.run_time + this.controller.delay )
		return true;
	else
		return false;

}


//------------------------------------------------------------------------
// Function: stop()
// Stops the animation where it currently is. Does not finish it.
//------------------------------------------------------------------------
Legato_Animation.prototype.stop = function()
{

	// Set the animation's status to not playing.
	this.status = false;

	// Call the onStop function if there is any.
	if ( this.onStop )
	  this.onStop( this );

}


//------------------------------------------------------------------------
// (Exclude)
// Function: finish()
// Does the required clean up of the animation.
//------------------------------------------------------------------------
Legato_Animation.prototype.finish = function()
{

	// Set the animation's status to not playing.
	this.status = false;
	
	// Get rid of any animation errors. Set the desired values on the elements.
	if ( this.desired_width        ) this.element.dimensions( this.desired_width, null );
	if ( this.desired_height       ) this.element.dimensions( null, this.desired_height );

	if ( this.desired_pos.X        ) this.element.position( this.desired_pos.X, null );
	if ( this.desired_pos.Y        ) this.element.position( null, this.desired_pos.Y );

	if ( this.desired_opacity      ) this.element.setStyle( 'opacity', this.desired_opacity );

	if ( this.desired_back_color   ) this.element.setStyle( 'background-color', '#' + this.desired_back_color.toHexString() );

	if ( this.desired_border_color ) this.element.setStyle( 'border-color', '#' + this.desired_border_color.toHexString() );

	if ( this.desired_text_color   ) this.element.setStyle( 'color', '#' + this.desired_text_color.toHexString() );

	// Call the onFinish function if there is any.
	if ( this.onFinish )
	  this.onFinish( this );

}


//------------------------------------------------------------------------
// Public Static Member Functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// (Exclude)
// Function: tweenValue()
// Tweens the value.
//------------------------------------------------------------------------
Legato_Animation.tweenValue = function( ease_type, current_time, duration, begin_val, change_val )
{
	
	// What easing equation?
	switch( ease_type )
	{
		
	// EASE NONE
	case Legato_Animation.EASE_NONE:	
		return change_val * (current_time / duration) + begin_val;
		
	// EASE IN
	case Legato_Animation.EASE_IN:
		return change_val * (current_time /= duration) * current_time + begin_val;
		
	// EASE OUT
	case Legato_Animation.EASE_OUT:
		return -change_val * (current_time /= duration) * (current_time - 2) + begin_val;
		
	// EASE BOTH
	case Legato_Animation.EASE_BOTH:
		
		if ( (current_time /= duration / 2) < 1 ) 
			return change_val / 2 * current_time * current_time + begin_val;

		return -change_val / 2 * ((--current_time) * (current_time - 2) - 1) + begin_val;
		
	// STRONG EASE IN
	case Legato_Animation.STRONG_EASE_IN:
		return change_val * (current_time /= duration) * current_time * current_time * current_time + begin_val;
	
	// STRONG EASE OUT	
	case Legato_Animation.STRONG_EASE_OUT:
		return -change_val * ((current_time = current_time / duration - 1) * current_time * current_time * current_time - 1) + begin_val;
		
	// STRONG EASE BOTH
	case Legato_Animation.STRONG_EASE_BOTH:
	
		if ( (current_time /= duration / 2) < 1 ) 
			return change_val / 2 * current_time * current_time * current_time * current_time + begin_val;

		return -change_val / 2 * ((current_time -= 2) * current_time * current_time * current_time - 2) + begin_val;
		
	// BACK EASE IN
	case Legato_Animation.BACK_EASE_IN:
		return change_val * (current_time /= duration) * current_time * (2.70158 * current_time - 1.70158) + begin_val;
		
	// BACK EASE OUT
	case Legato_Animation.BACK_EASE_OUT:
		return change_val * ((current_time = current_time / duration - 1) * current_time * (2.70158 * current_time + 1.70158) + 1) + begin_val;
		
	// BACK EASE BOTH
	case Legato_Animation.BACK_EASE_BOTH:
		
		if ( (current_time /= duration / 2) < 1 ) 
			return change_val / 2 * (current_time * current_time * (3.5949095 * current_time - 2.5949095)) + begin_val;

		return change_val / 2 * ((current_time -= 2) * current_time * (3.5949095 * current_time + 2.5949095) + 2) + begin_val;
		
	// BOUNCE EASE IN
	case Legato_Animation.BOUNCE_EASE_IN:
		
		current_time = duration - current_time;

		if ( (current_time /= duration) < (1 / 2.75) )
			return change_val - (change_val * (7.5625 * current_time * current_time)) + begin_val;
		else if ( current_time < (2 / 2.75 ) )
			return change_val - (change_val * (7.5625 * (current_time -= (1.5 / 2.75)) * current_time + 0.75)) + begin_val;
		else if ( current_time < (2.5 / 2.75) )
			return change_val - (change_val * (7.5625 * (current_time -= (2.25 / 2.75)) * current_time + 0.9375)) + begin_val;
		else
			return change_val - (change_val * (7.5625 * (current_time -= (2.625 / 2.75)) * current_time + 0.984375)) + begin_val;
		
	// BOUNCE EASE OUT	
	case Legato_Animation.BOUNCE_EASE_OUT:
	
		if ( (current_time /= duration) < (1 / 2.75) )
		  return change_val * (7.5625 * current_time * current_time) + begin_val;
		else if ( current_time < (2 / 2.75 ) )
		  return change_val * (7.5625 * (current_time -= (1.5 / 2.75)) * current_time + 0.75) + begin_val;
		else if ( current_time < (2.5 / 2.75) )
		  return change_val * (7.5625 * (current_time -= (2.25 / 2.75)) * current_time + 0.9375) + begin_val;
		else
		  return change_val * (7.5625 * (current_time -= (2.625 / 2.75)) * current_time + 0.984375) + begin_val;
		  
	// BOUNCE EASE BOTH
	case Legato_Animation.BOUNCE_EASE_BOTH:
	
		if ( current_time < duration / 2 )
		{

			current_time = duration - (current_time * 2);

			if ( (current_time /= duration) < (1 / 2.75) )
				return (change_val - (change_val * (7.5625 * current_time * current_time))) * 0.5 + begin_val;
			else if ( current_time < (2 / 2.75 ) )
				return (change_val - (change_val * (7.5625 * (current_time -= (1.5 / 2.75)) * current_time + 0.75))) * 0.5 + begin_val;
			else if ( current_time < (2.5 / 2.75) )
				return (change_val - (change_val * (7.5625 * (current_time -= (2.25 / 2.75)) * current_time + 0.9375))) * 0.5 + begin_val;
			else
				return (change_val - (change_val * (7.5625 * (current_time -= (2.625 / 2.75)) * current_time + 0.984375))) * 0.5 + begin_val;

		}

		current_time = current_time * 2 - duration;

		if ( (current_time /= duration) < (1 / 2.75) )
		  return change_val * (7.5625 * current_time * current_time) * 0.5 + change_val * 0.5 + begin_val;
		else if ( current_time < (2 / 2.75 ) )
		  return change_val * (7.5625 * (current_time -= (1.5 / 2.75)) * current_time + 0.75) * 0.5 + change_val * 0.5 + begin_val;
		else if ( current_time < (2.5 / 2.75) )
		  return change_val * (7.5625 * (current_time -= (2.25 / 2.75)) * current_time + 0.9375) * 0.5 + change_val * 0.5 + begin_val;
		else
		  return change_val * (7.5625 * (current_time -= (2.625 / 2.75)) * current_time + 0.984375) * 0.5 + change_val * 0.5 + begin_val;
		  
	// ELASTIC EASE IN
	case Legato_Animation.ELASTIC_EASE_IN:
	
		if ( current_time == 0 ) 
			return begin_val;
			
		if ( (current_time /= duration) == 1 ) 
			return begin_val + change_val;

		var p = duration * 0.3;
		var a = change_val;
		var s = p / 4;

		return -(a * Math.pow( 2, 10 * (current_time -= 1) ) * Math.sin( (current_time * duration - s) * (2 * Math.PI) / p )) + begin_val;
		
	// ELASTIC EASE OUT
	case Legato_Animation.ELASTIC_EASE_OUT:
		
		if ( current_time == 0 ) 
			return begin_val;
			
		if ( (current_time /= duration) == 1 ) 
			return begin_val + change_val;

		var p = duration * 0.3;
		var a = change_val;
		var s = p / 4;

		return a * Math.pow( 2, -10 * current_time ) * Math.sin( (current_time * duration - s) * (2 * Math.PI) / p ) + change_val + begin_val;
		
	// ELASTIC EASE BOTH
	case Legato_Animation.ELASTIC_EASE_BOTH:
	
		if ( current_time == 0 ) 
			return begin_val;
			
		if ( (current_time /= duration / 2) == 2 ) 
			return begin_val + change_val;

		var p = duration * (0.3 * 1.5);
		var a = change_val;
		var s = p / 4;

		if ( current_time < 1 ) return -0.5 * (a * Math.pow( 2, 10 * (current_time -= 1) ) * Math.sin( (current_time * duration - s) * (2 * Math.PI) / p )) + begin_val;

		return a * Math.pow( 2, -10 * (current_time -= 1) ) * Math.sin( (current_time * duration - s) * (2 * Math.PI) / p ) * 0.5 + change_val + begin_val;
		
	}

}


//------------------------------------------------------------------------
// Class: Legato_Animation_Sequence
// Stores a sequence of <Legato_Animation> objects.
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Static Variables
//------------------------------------------------------------------------
Legato_Animation_Sequence.sequences = new Array();


//------------------------------------------------------------------------
// Public Member Functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// Constructor: Legato_Animation_Sequence()
// Class constructor.
//
// Parameters:
//     options - An optional object of options for the Animation Sequence.
//------------------------------------------------------------------------
function Legato_Animation_Sequence( options )
{

	// Store the default values.
	this.animations               = new Array();
	this.current_animation_index  = 0;
	this.sequence_index           = Legato_Animation_Sequence.sequences.length;
	this.status                   = false;
	this.options                  = options;
	
	// Callbacks.
	this.onStart               = null;
	this.onAdvance             = null;
	this.onLoop                = null;
	this.onFinish              = null;

	// Store this animation sequence in the global sequences array.
	Legato_Animation_Sequence.sequences[this.sequence_index] = this;

}


//------------------------------------------------------------------------
// Function: addAnimation()
// Adds an <Legato_Animation> object to the animation sequence.
//
// Parameters:
//     animation - An <Legato_Animation> object that you would like to set up
//                 to play in the animation. Will add it at the end of the
//                 sequence.
//------------------------------------------------------------------------
Legato_Animation_Sequence.prototype.addAnimation = function( animation )
{

	// Store the animation in the sequence.
	this.animations.push( animation );

	// Add the onFinish and onStop functions.
	Legato_Events_Handler.addEvent( animation, "onFinish", Legato_Animation_Sequence.nextAnimation );
	Legato_Events_Handler.addEvent( animation, "onStop", Legato_Animation_Sequence.nextAnimation );

	// Store the sequence index in the animation.
	animation.sequence_index = this.sequence_index;

}


//------------------------------------------------------------------------
// Function: start()
// Sets the Animation Sequence to start playing.
//------------------------------------------------------------------------
Legato_Animation_Sequence.prototype.start = function()
{

	// Only start if there is at least one animation in the sequence
	// and we are not already playing.
	if ( this.animations.length == 0 || this.status ) return;

	// Set as playing.
	this.status = true;
	
	// On start callback.
	if ( this.onStart != null && this.onStart( this ) == false )
		return;

	// Start the first animation in the sequence.
	this.animations[0].start();

}


//------------------------------------------------------------------------
// (Exclude)
// Function: reset()
// Cleans up the animation sequence.
//------------------------------------------------------------------------
Legato_Animation_Sequence.prototype.reset = function()
{

	// Reset the values.
	this.status                   = false;
	this.current_animation_index  = 0;

}


//------------------------------------------------------------------------
// Public Static Member Functions
//------------------------------------------------------------------------

//------------------------------------------------------------------------
// (Exclude)
// Function: nextAnimation()
// Plays the next animation in the sequence. This is set as the previous
// animation's onFinish function so that a chain forms.
//------------------------------------------------------------------------
Legato_Animation_Sequence.nextAnimation = function( animation )
{

	// Get the animation sequence.
	var animation_sequence = Legato_Animation_Sequence.sequences[animation.sequence_index];

	// If the animation sequence is stopped, return false.
	if ( !animation_sequence.status )
	  return false;

	// Increment the current animation index.
	animation_sequence.current_animation_index++;

	// Play the next animation if there is one.
	if ( animation_sequence.animations[animation_sequence.current_animation_index] != null )
	{
		
		// On advance callback.
		if ( animation_sequence.onAdvance != null && animation_sequence.onAdvance( animation_sequence ) == false )
			return;

		// Start the next animation.
		animation_sequence.animations[animation_sequence.current_animation_index].start();

	}  // End if next animation.
	else
	{
		
		// Should we loop?
		if ( animation_sequence.options && animation_sequence.options.loop == true )
		{
			
			// On loop callback.
			if ( animation_sequence.onLoop != null && animation_sequence.onLoop( animation_sequence ) == false )
				return;
				
			// Loop.
			animation_sequence.reset();
			animation_sequence.start();
			
		}  // End if looping.
		else
		{

			// Finish the animation sequence.
			animation_sequence.reset();
			
			// On finish callback.
			if ( animation_sequence.onFinish != null )
				animation_sequence.onFinish( animation_sequence );
			
		}

	}  // End if no more animations.

}


//------------------------------------------------------------------------
// (Exclude)
// Class: Legato_Animation_Manager
// Manages each animation. All the animations are incremented through the
// manager.
//------------------------------------------------------------------------
Legato_Animation_Manager =
{

	//----------------------------------------------------------------------
	// Public Variables
	//----------------------------------------------------------------------
	increment_speed:     20,           // The speed at which the animation manager will increment each animation.
	playing_animations:  new Array(),  // An array of all the currently playing animations.
	interval_handle:     null,         // The handle that the setInterval() function returns.


	//----------------------------------------------------------------------
	// Public Member Functions
	//----------------------------------------------------------------------
	//----------------------------------------------------------------------
	// (Exclude)
	// Function: addAnimation()
	// This function is used to add an animation to the animation manager
	// for playing.
	//----------------------------------------------------------------------
	addAnimation: function( animation )
	{

		// Loop through each animation being played.
		for ( var i = 0; i < this.playing_animations.length; i++ )
		{

			// Get the animation.
			var playing_animation = this.playing_animations[i];

			// Is the animation we're adding animate the
			// same element than this animation's element?
			if ( animation.element == playing_animation.element )
			{

				// Remove the animation from the playing animations array.
				this.playing_animations.splice( i, 1 );

				// Stop the currently playing animation so that we can play this one.
				playing_animation.stop();

			}  // End if managing the same element.

		}  // Next playing animation.

		// Add the animation to the playing animations array.
		this.playing_animations.push( animation );

		// If we don't have any animations playing,
		// we have to set up the timeout.
		if ( this.interval_handle == null )
		{

			// Set to advanced all animations.
			this.interval_handle = setInterval( Legato_Animation_Manager.advanceAnimations, this.increment_speed, null );

		}  // End if no animations currently playing.

	},


	//------------------------------------------------------------------------
	// (Exclude)
	// Function: advanceAnimations()
	// Advances each animation being played.
	//------------------------------------------------------------------------
	advanceAnimations: function()
	{

		// Loop through each animation being played.
		for ( var i = 0; i < Legato_Animation_Manager.playing_animations.length; i++ )
		{

			// Get the animation from the array.
			var animation = Legato_Animation_Manager.playing_animations[i];

			// Advance the animation.
			var continue_playing = animation.advanceFrame();

			// Is the animation done playing?
			if ( !continue_playing )
			{
				
				// Remove the animation from the playing animations array.
				Legato_Animation_Manager.playing_animations.splice( i, 1 );
				
				// Finish up the animation.
				animation.finish();
				
				// If we don't have any more animations to play, stop
				// JavaScript from calling this function again.
				if ( Legato_Animation_Manager.playing_animations.length == 0 )
				{
					clearInterval( Legato_Animation_Manager.interval_handle );
					Legato_Animation_Manager.interval_handle = null;
				}

			}  // End if stop playing this animation.

		}  // Next playing animation.

	}

}




// Developed by Robert Nyman/DOMAssistant team
// Code/licensing: http://domassistant.googlecode.com/
// Documentation: http://www.domassistant.com/documentation
// Version 2.8
DOMAssistant.AJAX = function () {
	var globalXMLHttp = null,
	readyState = 0,
	status = -1,
	statusText = "",
	requestPool = [],
	createAjaxObj = function (url, method, callback, addToContent) {
		var params = null;
		if (/POST/i.test(method)) {
			url = url.split("?");
			params = url[1];
			url = url[0];
		}
		return {
			url : url,
			method : method,
			callback : callback,
			params : params,
			headers : {},
			responseType : "text",
			addToContent : addToContent || false
		};
	};
	return {
		publicMethods : [
			"ajax",
			"get",
			"post",
			"load"
		],

		initRequest : function () {
			var XMLHttp = null;
			if (!!window.XMLHttpRequest && !DOMAssistant.isIE) {
				XMLHttp = new XMLHttpRequest();
				DOMAssistant.AJAX.initRequest = function () {
					return requestPool.length? requestPool.pop() : new XMLHttpRequest();
				};
			}
			else if (!!window.ActiveXObject) {
				var XMLHttpMS = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP", "Microsoft.XMLHTTP"];
				for (var i=0; i<XMLHttpMS.length; i++) {
					try {
						XMLHttp = new window.ActiveXObject(XMLHttpMS[i]);
						DOMAssistant.AJAX.initRequest = function () {
							return requestPool.length? requestPool.pop() : new window.ActiveXObject(XMLHttpMS[i]);
						};
						break;
					}
					catch (e) {
						XMLHttp = null;
					}
				}
			}
			return XMLHttp;
		},

		ajax : function (ajaxObj) {
			if (!ajaxObj.noParse && ajaxObj.url && /\?/.test(ajaxObj.url) && ajaxObj.method && /POST/i.test(ajaxObj.method)) {
				var url = ajaxObj.url.split("?");
				ajaxObj.url = url[0];
				ajaxObj.params = url[1] + ((url[1].length > 0 && ajaxObj.params)? ("&" + ajaxObj.params) : "");
			}
			return DOMAssistant.AJAX.makeCall.call(this, ajaxObj);
		},

		get : function (url, callback, addToContent) {
			return DOMAssistant.AJAX.makeCall.call(this, createAjaxObj(url, "GET", callback, addToContent));
		},

		post : function (url, callback) {
			return DOMAssistant.AJAX.makeCall.call(this, createAjaxObj(url, "POST", callback));
		},

		load : function (url, addToContent) {
			this.get(url, DOMAssistant.AJAX.replaceWithAJAXContent, addToContent);
		},

		makeCall : function (ajaxObj) {
			var XMLHttp = DOMAssistant.AJAX.initRequest();
			if (XMLHttp) {
				globalXMLHttp = XMLHttp;
				(function (elm) {
					var url = ajaxObj.url,
						method = ajaxObj.method || "GET",
						callback = ajaxObj.callback,
						params = ajaxObj.params,
						headers = ajaxObj.headers,
						responseType = ajaxObj.responseType || "text",
						addToContent = ajaxObj.addToContent,
						timeout = ajaxObj.timeout || null,
						ex = ajaxObj.exception,
						timeoutId = null,
						done = false;
					XMLHttp.open(method, url, true);
					XMLHttp.setRequestHeader("AJAX", "true");
					XMLHttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
					if (method === "POST") {
						XMLHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
						XMLHttp.setRequestHeader("Content-length", params? params.length : 0);
						if (XMLHttp.overrideMimeType) {
							XMLHttp.setRequestHeader("Connection", "close");
						}
					}
					if (responseType === "json") {
						XMLHttp.setRequestHeader("Accept", "application/json, text/javascript, */*");
					}
					for (var i in headers) {
						if (typeof i === "string") {
							XMLHttp.setRequestHeader(i, headers[i]);
						}
					}
					if (typeof callback === "function") {
						XMLHttp.onreadystatechange = function () {
							try {
								if (XMLHttp.readyState === 4 && !done) {
									window.clearTimeout(timeoutId);
									done = true;
									status = XMLHttp.status;
									statusText = XMLHttp.statusText;
									readyState = 4;
									if ((status || location.protocol !== "file:") && (status < 200 || status >= 300)) {
										throw new Error(statusText);
									}
									var response = /xml/i.test(responseType)? XMLHttp.responseXML : XMLHttp.responseText;
									if (/json/i.test(responseType) && !!response) {
										response = (typeof JSON === "object" && typeof JSON.parse === "function")? JSON.parse(response) : eval("(" + response + ")");
									}
									globalXMLHttp = null;
									XMLHttp.onreadystatechange = function () {};
									requestPool.push(XMLHttp);
									callback.call(elm, response, addToContent);
								}
							}
							catch (e) {
								globalXMLHttp = XMLHttp = null;
								if (typeof ex === "function") {
									ex.call(elm, e);
									ex = null;
								}
							}
						};
					}
					XMLHttp.send(params);
					if (timeout) {
						timeoutId = window.setTimeout( function () {
							if (!done) {
								XMLHttp.abort();
								done = true;
								if (typeof ex === "function") {
									readyState = 0;
									status = 408;
									statusText = "Request timeout";
									globalXMLHttp = XMLHttp = null;
									ex.call(elm, new Error(statusText));
									ex = null;
								}
							}
						}, timeout);
					}
				})(this);
			}
			return this;
		},

		replaceWithAJAXContent : function (content, add) {
			if (add) {
				this.innerHTML += content;
			}
			else {
				DOMAssistant.cleanUp(this);
				this.innerHTML = content;
			}
		},

		getReadyState : function () {
			return (globalXMLHttp && DOMAssistant.def(globalXMLHttp.readyState))? globalXMLHttp.readyState : readyState;
		},

		getStatus : function () {
			return status;
		},

		getStatusText : function () {
			return statusText;
		}
	};
}();
DOMAssistant.attach(DOMAssistant.AJAX);

var Opacitize = function()
{

	var _background_width = 2000;

	return {

		initialize: function()
		{

			$( $$( 'content' ).cssSelect( 'h1 span' )[0] ).addClass( 'blur' );

			var window_width = $( window ).dimensions()[0];
			var offset_width = (_background_width - window_width) * 0.5;

			$( '.blur' ).each( function()
			{

				var blurred = $$( 'container' ).create( 'div', { className: 'blurred' }, true );
				$( blurred ).store( 'linked-elem', this );

				// Set up the blurred elem.
				Opacitize.drawBlurred( offset_width, blurred );

			} );

			// We draw all the elements above, however after the page has loaded
			// the fonts may resize, causing the blurred elems to not be the correct
			// size/position. We do this so that it redraws it all after the body has
			// completely finished loading.
			$( window ).addEvent( 'load', Opacitize.redrawBlurred );

			// We also have to redraw after they resize the browser window.
			$( window ).addEvent( 'resize', Opacitize.redrawBlurred );

		},

		redrawBlurred: function()
		{

			var window_width = $( window ).dimensions()[0];
			var offset_width = (_background_width - window_width) * 0.5;

			$( '.blurred' ).each( function()
			{

				Opacitize.drawBlurred( offset_width, this );

			} );

		},

		drawBlurred: function( offset_width, blurred )
		{

			elem = $( blurred ).retrieve( 'linked-elem' );

			var elem_position = $( elem ).position();
			var elem_dimensions = $( elem ).dimensions();
			var left_offset = offset_width + elem_position[0];
			var top_offset = elem_position[1];

			// If this is the menu, make the blurred div stretch the whole main container.
			if ( elem.id == 'menu' )
				elem_dimensions[1] = $$( 'main' ).dimensions()[1];

			$( blurred ).setStyle
			( {
				left: elem_position[0] + 'px',
				top: elem_position[1] + 'px',
				width: elem_dimensions[0] + 'px',
				height: elem_dimensions[1] + 'px',
				'background-position': '-' + left_offset + 'px -' + top_offset + 'px'
			} );

		}

	};

}();

Legato.DOMReady( Opacitize.initialize );
