var adlib={
	version:'2.0', 
	documentElement:((window.innerWidth||(document.documentElement&&(typeof document.documentElement.clientWidth!="undefined")))?document.documentElement:document.body),	
	ElementSupported:typeof window.Element!="undefined",	
	DOMisLoaded:false,
	pageUnloading:false,
	cache:{},
	elements:{},
	patch:{},
	browser:(function(){
		var av=navigator.appVersion;
		var ua=navigator.userAgent.toLowerCase();
		var b={
			ie: (($test(window.ActiveXObject)) && (av.indexOf('MSIE')!=-1)),
			opera: (ua.indexOf('opera')!=-1),
			safari: (/WebKit/i.test(ua)&&/Safari/i.test(ua)),
			konquerer: (navigator.vendor == 'KDE'),
			webkit: (/WebKit/i.test(ua)?true:false),
			firefox:(ua.indexOf('firefox')!=-1),
			gecko:((navigator.product=='Gecko')&&(av.indexOf('KHTML')==-1)),
			win: (av.indexOf('Windows')!=-1),
			mac: (av.indexOf('Macintosh')!=-1),
			v:0,
			build:0
		};
		b.smode=(((document.compatMode)&&(document.compatMode=="CSS1Compat"))||(b.safari));
		if(b.ie){
			b.v=parseFloat(av.substring(av.indexOf('MSIE')+4));
			b.build=b.v;
		}
		else if(b.firefox){
			b.v=parseFloat(ua.substring(ua.indexOf('firefox')+8));
			b.build=ua.substring(ua.indexOf('rv:')+3,ua.indexOf(')'));
		}
		else if(b.opera){
			b.v=parseFloat(ua.substring(ua.indexOf('opera')+6));
			b.build=b.v;
		}
		else if(b.safari){
			b.v=parseFloat(ua.substring(ua.indexOf('version')+8));
			b.build=parseFloat(ua.substring(ua.indexOf('webkit')+7));
		}	
		return b;
	})(),
	defaults:{
		classes:{
			inherits:{
				overwrite:false
			},
			method:{
				overwrite:true
			}
		},
		hash:{
			toString:{
				delimiter1:',',
				delimiter2:'='
			}
		},
		number:{
			noNaN:{
				defaultReturn:0
			}
		},
		object:{
			setChild:{
				defaultType:'Object'
			}
		},
		strings:{
			more:{
				charCount:50,
				addition:'...'
			},
			template:{
				openDelimiter:'<=',
				closeDelimiter:'=>'
			},
			pad:{
				side:'b'
			}
		},
		DOM:{
			getDefaultDisplay:{
				displayType:'block'
			},
			insertions:{
				before:false
			}
		},
		styles:{
			location:{
				local:true
			}
		},
		widgets:{},
		fx:{}
	},
	utilities:{
		make:{
			//ns=[functionName,functionName...]
			globalStyleFunction:function(ns){
				$A(ns).forEach(function(v){
					window[v]=function(){
						var p=$A(arguments), n=$C($(p.shift()));
						if(!$test(n)){
							return;
						}
						var r=n[v].apply(n,p);					
						if(r!=void 0){
							return r.length>1?r:r[0];
						}
					};
				});
			},
			//n=[functionName,functionName...]
			globalSearchFunction:function(n){
				$A(n).forEach(function(v){
					window[v]=function(){
						return document[v].apply(document,$A(arguments));
					};
				});
			},	
			//ns={functionName:function,....}
			// o=overwrite (boolean)
			collectionFunction:function(ns,o){
				o=isBoolean(o)?o:false;
				$A(ns).forEach(function(v){
					Class.method(Collection.prototype,v,function(){
						var a=arguments,ret=[];
						this.forEach(function(val){
							if(isCollectable(val)){
								var q=val[v].apply(val,a);
								if(q!=void 0){
									ret.push(q);
								}
							}
						});
						if(ret.length>0){
							if(ret.every(function(n){
								return (n==null||isCollectable(n)||isCollection(n));
							})){
								var p=$C();
								ret=p.concat.apply(p,ret);
							}
						}				
						if(isCollection(ret)||ret.length>0){
							return ret;
						}
						else{
							return this;
						}
					},o);
				});
			},
			//ns={functionName:function,....}
			// o=overwrite (boolean)
			elementFunction:function(fs,o){
				o=isBoolean(o)?o:false;
				fs=$H(fs);
				fs.forEach(function(v,k){
					Class.method(adlib.elements,k,v,o);
					if(adlib.ElementSupported){
						Class.method(Element.prototype,k,v,o);
					}
				});		
				adlib.utilities.make.collectionFunction(fs.keys(),o);
				if(!adlib.ElementSupported){
					if(!adlib.DOMisLoaded){
						var e=document.getElementsByTagName('*');
						for(var x=0; x<e.length; x++){
							Class.inherits(e[x],fs,o);
						}
					}
				}		
			},
			//ns=[stylename,stylename,....]
			// g=make global (boolean)
			elementStyleShortcut:function(s,g){
				var p=$H();
				$H(s).forEach(function(v,k){
					if(isString(v)){
						p['set'+k]=function(val){
							this.setStyle(v,val);
						};
						p['get'+k]=function(d){
							return this.getStyle(v,d);
						};
					}
					else{
						p[k]=v;
					}
				});
				adlib.utilities.make.elementFunction(p);
				if(g){
					adlib.utilities.make.globalStyleFunction(p.keys());
				}
			}
		}
	},
	internal:{
		vars:{
			DOMLoadBehaviors:[],
			BodyLoadBehaviors:[],
			cleanseStack:["DOM","Events","fx","Behaviors","widgets"]
		},
		methods:{
			cleanseAll:function(){
				adlib.pageUnloading=true;
				Events.cleanUp();
				var nds=document.getElementsByTagName('*');				
				for(var x=0; x<nds.length; x++){
					if(!adlib.ElementSupported){
						for(var y=0; y<adlib.elements.length; y++){
							nds[x][adlib.elements[y]]=void 0;
						}
					}
					nds[x]._uniqueId=void 0;
				}
				for(var x=0; x<adlib.internal.vars.cleanseStack.length; x++){
					window[adlib.internal.vars.cleanseStack[x]]=void 0;
				}
				adlib=void 0;
			},
/**************** content internals *********************/
			// cl=collection
			// c=content
			// b=insert before or after (default=false/after)
			// p=insertion point (node/number/css) 
			insertIntoCollection:function(cl,c,b,p){
				if(cl.length==0){return}
				if(cl.length==1){
					adlib.internal.methods.insertIntoNode(cl[0],c,before,point); 
					return;
				}
				b=isBoolean(b)?b:adlib.defaults.DOM.insertions.before;	
				var ret=[],co,nds;
				if(p==null||p=="n"){
					co=DOM.makeCopies(c,cl.length);
					for(var x=0; x<cl.length; x++){
						cl[x].insertBefore(co[x],b?cl[x].childNodes[0]:null);
					}
				}
				else{
					nds=isNumber(p)?c.childAt(p):$(cl).$css(p);
					co=DOM.makeCopies(c,nds.length);
					for(var x=0; x<nds.length; x++){
						nds[x].$parent().insertBefore(co[x],b?nds[x]:nds[x].nextSibling);
					}
				}		
			},
			// el=element
			// c=content
			// b=insert before or after (default=false/after)
			// p=insertion point (node/number/css) 
			insertIntoNode:function(el,c,b,p){
				b=isBoolean(b)?b:adlib.defaults.DOM.insertions.before;	
				var ch,co,m=DOM.makeCopies;
				if(p==null||p=="n"){
					co=m(c,0)[0];
					return el.insertBefore(co,b?el.childNodes[0]:null);
				}
				else{
					if(isNumber(p)){
						co=m(c,0)[0];
						ch=el.childAt(p);
						el.insertBefore(co,b?ch:ch?ch.nextSibling:ch);
					}
					else{
						ch=$(el).$css(p);
						co=m(c,ch.length);
						ch.forEach(function(v,k){
							v.$parent().insertBefore(co[k],b?v:v.nextSibling);
						});
					}
				}
			}
		}
	},
	iterator:{
		each:function(f){
			this.reset();
			this.count();
			this.__iteration.f=f;
			return this.again();
		},	
		_each:function(f){
			this.reset();
			var _t=this.__iteration;
			_t.f=f;
			_t.start=this.count()-1;
			_t.step=this.count()-1;
			_t.dir=false;
			return this.again();
		},
		next:function(){
			var st=this.__iteration.step;
			this.__iteration.dir?st++:st--;
			if(st<0||st>=this.count()){
				this.clearIteration();
				return null;
			}
			this.__iteration.step=st;
			return this.again();
		},
		previous:function(){
			var st=this.__iteration.step;
			this.__iteration.dir?st--:st++;
			if(st<0||st>=this.count()){
				this.clearIteration();
				return null;
			}
			this.__iteration.step=st;
			return this.again();
		},
		again:function(){
			var k=this.__iteration.items[this.__iteration.step];
			return ($test(k)?this.__iteration.f(this[k],k,this):null);
		},
		count:function(){
			if(!this.__iteration){
				this.reset();
			}
			if(this.__iteration.items.length==0){
				this.__iteration.items=this.items();
			}
			return this.__iteration.items.length;	
		},
		reset:function(){
			this.__iteration={items:[],step:0,start:0,dir:true,f:null};
		},
		clearIteration:function(){
			this.__iteration=void 0;
			delete this.__iteration;
		},
		items:function(){
			if(!this.__iteration){
				this.reset();
			}
			var a=[];
			this.__iteration.items.clear();
			for(var x in this){
				if(!this.noEnum(x)){
					a.push(x);
				}		
			}
			this.__iteration.items=a;
			return a;
		},
		noEnum:function(x,n){
			if(!this.hasOwnProperty(x)||(this.__iteration&&this[x]==this.__iteration)||(n&&isFunction(this[x]))){
				return true;
			}
			return false;
		}
	}
};
adlib.constants={
	inlineElements:'a,b,button,cit,del,dfn,em,i,img,input,ins,label,legend,s,select,span,strike,strong,sub,sup,u'.split(','),
	blockElements:'blockquote,canvas,code,dd,div,dl,dt,embed,h1,h2,h3,h4,h5,h6,hr,iframe,li,object,ol,p,pre,textarea,ul,xmp'.split(','),
	tableElements:{
		table:adlib.browser.ie ? "block" :'table',
		tbody:adlib.browser.ie ? "block" :'table-row-group',
		td:adlib.browser.ie ? "block" : 'table-cell',
		tfoot:'table-footer-group',
		th:adlib.browser.ie ? "block" : 'table-cell',
		thead:'table-header-group',
		tr:adlib.browser.ie ? "block" : 'table-row',
		caption:adlib.browser.ie ? "block" : 'table-caption'
	}	
};




/********************* constants *****************************/
var _NL='\x0A',_BR='<br />',_Clearer='<div class="clearer"></div>';
function _Empty(){};
function _Echo(v){return v};
if(!window.Node){	
	var Node={
		ELEMENT_NODE: 1,
		ATTRIBUTE_NODE: 2,
		TEXT_NODE: 3,
		CDATA_SECTION_NODE: 4,
		ENTITY_REFERENCE_NODE: 5,
		ENTITY_NODE: 6,
		PROCESSING_INSTRUCTION_NODE: 7,
		COMMENT_NODE: 8,
		DOCUMENT_NODE: 9,
		DOCUMENT_TYPE_NODE: 10,
		DOCUMENT_FRAGMENT_NODE: 11,
		NOTATION_NODE: 12
	};
}

/*************************** type checking ************************/

(function(){
	var a=["number","boolean","string"];
	for(var x=0; x<a.length; x++){
		window["is"+(a[x].charAt(0).toUpperCase()+a[x].substring(1).toLowerCase())]=new Function('v','return typeof v=="'+a[x]+'"');
	}
})();

function isFunction(f){
	return (typeof f=="function" && !(f instanceof RegExp));
};

function isExecutable(f){
	return (typeof f=="function" && $test(f.isExecutable));
};

function isObject(f){
	return (typeof f=="object" && !(f instanceof Hash)&& !(f instanceof Array)&&!(f instanceof Collection));
};

(function(){
	var a=["Array","RegExp","Date","Hash","Collection"];
	for(var x=0; x<a.length; x++){
		window["is"+a[x]]=new Function('v','return (v!==null&&v!==undefined&&v instanceof '+a[x]+')');
	}
})();

function isElement(n){
	return (n&&n.nodeType&&n.nodeType==Node.ELEMENT_NODE)?true:false;
};

function isCollectable(n){
	return isElement(n)||n==window||n==document;
};

function $test(o){
	return ((typeof o!="undefined")&&(o!=null));
};

function isValidText(t){
	if(!$test(t)
		||!isString(t)
		||(t=="")
		||(t=="null")
		||(t=="undefined")
		||(t.toString().strip()=="")
		){
		return false;
	}
	return true;
};
adlib.internal.vars.typeChecking=["String","Number","Boolean","Collection","Array","Hash","RegExp","Date","Executable","Function","Element","Object"];
function $type(v){
	if(!$test(v)){
		return "undefined";
	}
	var r=adlib.internal.vars.typeChecking.grep(function(va){return window["is"+va](v);});
	return (r!=null)?adlib.internal.vars.typeChecking[r].toLowerCase():"other";
}; 

/********************** global containers ************************/
var Class=!$test(window.Class)?{}:window.Class;
var Events=!$test(window.Events)?{}:window.Events;
var DOM=!$test(window.DOM)?{}:window.DOM;
var Behaviors=!$test(window.Behaviors)?{}:window.Behaviors;
var widgets=!$test(window.widgets)?{}:window.widgets;
var fx=!$test(window.fx)?{}:window.fx;



/*********************** Object Utilities ************************/
// o - object
// path/property, path/property....
Object.hasProperty=function(o){
	var tmp=o, t=$A(arguments).slice(1).map(function(v){return (v.indexOf('.')!=-1)?v.split('.'):v}).flatten();	
	for(var x=0; x<t.length; x++){
		if(!(t[x] in tmp)){
			return null;
		}
		tmp=tmp[t[x]];
	}
	return tmp;
};
// o - object
// path/property, path/property....
Object.getPropertyTo=function(o){
	var tmp=o, last=false,t=$A(arguments).slice(1).map(function(v){return (v.indexOf('.')!=-1)?v.split('.'):v}).flatten();
	t.every(function(v){
		if(v in tmp){
			if(!last){
				last=[];
			}
			last.push(v);
			tmp=tmp[v];
			return true;
		}
		return false;
	});
	return last;
};
// o - object
// p - path
// v - value
// t - default type (optional)
Object.setChild=function(o,p,v,t){
	t=$if(t,"==","||","Object","Hash","Array")?t:adlib.defaults.object.setChild.defaultType;
	if(isString(p)){
		p=p.split('.');
	}
	var a=p.length-1;
	for(var x=0; x<a; x++){
		if(!$test(o[p[x]])){
			o[p[x]]=t=="Object"?{}:t=="Array"?[]:$H();
		}
		o=o[p[x]];
	}
	o[p[a]]=v;
	return o;		
};
// o - object
// p - path
Object.deleteChild=function(o,p){
	if(isString(p)){
		p=p.split('.');
	}
	var c=p.pop();
	for(var x=0; x<p.length;x++){
		if(!$test(o[p[x]])){
			return false;
		}
		o=o[p[x]];
	}
	o[c]=void 0;
	delete o[c];
	return true;
};
// o - object
// path, path, path	
Object.select=function(o){
	for(var x=1; x<arguments.length; x++){
		var p=Object.hasProperty(o,arguments[x]);
		if(p!=null){
			return p;
		}
	}
	return null;
};
// o - object
// path, path, path
Object.selectProperty=function(o){
	for(var x=1; x<arguments.length; x++){
		var p=Object.hasProperty(o,arguments[x]);
		if(p!=null){
			return arguments[x];
		}
	}
	return null;
};
/*********************** array Utilities ************************/
function array_weld(){
	var ars=$A(arguments),ln=0,ret=[];
	for(var x=0; x<ars.length; x++){
		if(ars[x].length>ln){
			ln=ars[x].length;
		}
	}
	for(var x=0; x<ln; x++){
		ret[x]=[];
		for(var y=0; y<ars.length; y++){
			ret[x].push(ars[y][x]);
		}
	}
	return ret;
};

function args2array(a){
	var r=isArray(a)?(a.callee)?[]:a:[];
	if(r.length==0&&$test(a)){
		if($test(a.length)&&!isCollectable(a)&&!isString(a)){
			for(var x=0; x<a.length; x++){
				r[x]=a[x];
			}
		}
		else if(isHash(a)){
			return a.toArray();
		}
		else{
			r.push(a);
		}	
	}
	return r;
};

var $A=args2array;

/*********************** general utilities ***************************/
function dwl(str){
	document.writeln(str);
};
// tv - test item
// o - operator
// ty - type (&&,||)
// value,value
function $if(tv,o,ty){
	var s=((ty=='&&')||(ty=='||'))?3:2, r=true, handler=new Function('i','v','return (i'+o+'v)');
	ty=((ty=='&&')||(ty=='||'))?ty:'&&';
	for(var x=s; x<arguments.length; x++){
		var b=handler(tv,arguments[x]);
		if(ty=='&&'){				
			if(!b){
				return false;
			}
			else{
				r=true;
			}
		}
		else{
			if(b){
				return true;
			}
			else{
				r=false;
			}
		}
	}
	return r;
};		

function globalEval(c){
	var s=$e('script',{type:'text/javascript'});
	s.text=c;
	$t('head')[0].appendChild(s);
};

function getRandomId(p){
	p=p||'e';
	return p+(Math.floor(Math.random()*1000000000000));
};


/********************************* Classes*********************/

Class.create=function() { 
 	var o=function(){
		if(this.init){
		    this.init.apply(this, arguments);
		}
	};
	for(var x=0; x<arguments.length; x++){
		Class.inherits(o.prototype,arguments[x]);
	} 	
	return o; 
};
// t - object
// s - inherited object
// o - overwrite
Class.inherits=function(t,s,o){
	o=isBoolean(o)?o:adlib.defaults.classes.inherits.overwrite;
	for(var x in s){
		if((o)||(!$test(t[x]))){
			t[x]=s[x];
		}
	}
};
// t - object
// n - name
// f - function
// o - overwrite
Class.method=function(t,n,f,ov){
	var ovr=isBoolean(ov)?ov:adlib.defaults.classes.method.overwrite;
	if((ovr)||(!$test(t[n]))){
		t[n]=f;
	}
};

/********************* $    ************************************/

function $(){//works
	var r=arguments[0];
	if(arguments.length>1||!isElement(r)){
		r=$C();
		var t=$A(arguments).flatten();
		for(var x=0; x<t.length; x++){
			if(isString(t[x])){
				r.push(document.getElementById(t[x]));
			}
			else if(isCollection(t[x])){
				r=r.concat.apply(r,$A(t[x]));
			}
			else{
				r.push(isCollectable(t[x])?t[x]:null);
			}
		}
	}
	DOM.extend(r);
	return (isCollection(r)&&r.length==1)?r[0]:r;
};

function $e(e,a){
	var o=document.createElement(e);
	DOM.extend(o);
	for(var x in a){
		if((a.noEnum)&&(a.noEnum(x))){continue}
		switch(x){
			case 'className': o.setClass(a[x]); break;
			case 'style':     o.applyStyle(a[x]); break;
			default:          o.setAttribute(x,a[x]); break;
		}
	}		
	return o;
};





/*****************  String ****************************************/
Class.inherits(String.prototype,{
	strip:	function(){
		var rge=/^(\s*)/;
		var rge2=/(\s*)$/;
		val=this.replace(rge,"").replace(rge2,"");
		return val;
	},
	normalizeWhitespace:function(){
		return this.replace(/\t/g,' ').strip().replace(/\t|\s{2,}/g,' ');
	},
	addParam:function(p,pv){//works
		var v=this.valueOf(),po=p;
		if($test(pv)){
			po+='='+encodeURIComponent(pv);
		}					
		return v+((v.indexOf('?')>-1)?'&'+po:'?'+po);
	},
	getParam:function(p){
		var ps=this.substring(this.indexOf('?')+1).split("&"),r=null;
		ps.some(function(v){
			if(p==v.split("=")[0]){ 
				r=decodeURIComponent(v.split("=")[1]); 
				return true;
			} 
			return false;
		});
		return r;
	},

	template:function(obj,ld,rd){			
		ld=ld||adlib.defaults.strings.template.openDelimiter;
		rd=rd||adlib.defaults.strings.template.closeDelimiter;
		var ldr="("+ld+"\\s*)", rdr="(\\s*"+rd+")", rgStr=ldr+"([\\w\\-\\.\\s,\\[\\]\\*]*)"+rdr, r=new RegExp(rgStr,'g'), loopReg=new RegExp(rgStr,'g'), ifScanReg=new RegExp(rgStr,'g'), v=this.valueOf();
		var ifReg=/IF\s*(NOT\s*)?([\w\n\.\-]+)/, loopEndReg=new RegExp(ldr+"END_LOOP"+rdr,'g'), loopCountReg=/LOOP\s+(([_a-zA-Z][\w\.\-]*),)?\s*((\d+)\s*,\s*(\d+)\s*(,\s*(\d+)\s*)?)/g;
		var loopKeysReg=/LOOP\s+(([_a-zA-Z][\w\.\-]*),)?\s*((\[(\s*([\w\.\-]+)\s*(,\s*([\w\.\-]+))+\s*)\])|\*)/g, ifEndReg=new RegExp(ldr+"END_IF"+rdr,'g'), elseReg=new RegExp(ldr+"ELSE"+rdr,'g');
		function testItems(mStr,kStr){
			var r=new RegExp(ldr+kStr+rdr);
			if(kStr=="LOOP_KEY"){
				mStr=mStr.replace(r,loopKey?loopKey:"");
			}
			else if(kStr.startsWith('LOOP_VALUE')){
				var p=Object.hasProperty(obj,loopPrepend+kStr.replace('LOOP_VALUE',loopKey));
				mStr=mStr.replace(r,p!=null?p:"");
			}
			else{
				var p=Object.hasProperty(obj,kStr);
				if(p!=null){
					mStr=mStr.replace(r,p);
				}
			}
			return mStr;
		};	
		function doLoop(mStr,kStr,i){		
			var cRes=loopCountReg.exec(kStr),kRes=loopKeysReg.exec(kStr);
			if(cRes||kRes){					
				loopEndReg.lastIndex=i;
				var tmp=cRes||kRes,out="",keys=[],loopEnd=loopEndReg.exec(mStr),il=0,str=mStr.substring(i,loopEndReg.lastIndex-loopEnd[0].length);
				loopPrepend=tmp[2]?tmp[2]+".":"";
				if(cRes){
					var k=($type(obj)=="object"?$H(obj):obj);
					if(loopPrepend!=""){
						k=Object.hasProperty(k,tmp[2]);
					}
					k=k.items();
					for(var x=tmp[4].toInt();x<=tmp[5].toInt();x+=tmp[7]?tmp[7].toInt():1){
						keys.push(loopPrepend+k[x]);
					}
				}
				else if(kRes){
					if(kRes[3]=='*'){
						var to=kRes[2]?Object.hasProperty(obj,kRes[2]):obj;
						keys=($type(to)=="object"?$H(to):to).items();						
					}
					else{
						keys=kRes[5].split(/\s*,\s*/);
					}
				}
				i-=mStr.substring(mStr.lastIndexOf(ld,i),i).length;
				for(var x=0; x<keys.length; x++){
					var ou=str.valueOf();
					loopKey=keys[x];
					while(s=loopReg.exec(ou)){	
						var tpl=doChecks(ou,s[0].replace(ld,"").replace(rd,"").strip(),loopReg.lastIndex);	
						if(tpl!=ou){
							loopReg.lastIndex=0;
							ou=tpl;
						}
					}
					if(ou!=str){
						out+=ou;
					}
				}
				if(out!=""){
					mStr=mStr.replace(mStr.substring(i,loopEndReg.lastIndex),out);
				}		
				
			}
			loopEndReg.lastIndex=0;
			loopReg.lastIndex=0;
			loopCountReg.lastIndex=0;
			loopKeysReg.lastIndex=0;
			return mStr;
		};
		function doIf(mStr,kStr,i){
			ifEndReg.lastIndex=i;
			var ifEnd=ifEndReg.exec(mStr), str=mStr.substring(mStr.substring(i-mStr.lastIndexOf(ld,i),i).length, ifEndReg.lastIndex), strTrue=mStr.substring(i,ifEndReg.lastIndex-ifEnd[0].length), strFalse="", elseLoc=elseReg.exec(strTrue);
			if(elseLoc){
				strFalse=strTrue.substring(elseReg.lastIndex,strTrue.length);
				strTrue=strTrue.substring(0,elseReg.lastIndex-elseLoc[0].length);				
			}
			var mtch=ifReg.exec(kStr), isNot=(mtch[1]!=null&&mtch[1]!="");
			mtch[2]=loopPrepend+mtch[2].replace("LOOP_VALUE",loopKey);
			var p=Object.hasProperty(obj,mtch[2]), wStr=((p!=null&&!isNot)||(p==null&&isNot))?strTrue:strFalse;
			while(tIf=ifScanReg.exec(wStr)){
				var tpIf=doChecks(wStr,tIf[0].replace(ld,"").replace(rd,"").strip(),ifScanReg.lastIndex);
				if(tpIf!=wStr){
					wStr=tpIf;
					ifScanReg.lastIndex=0;
				}					
			}
			ifScanReg.lastIndex=elseReg.lastIndex=ifEndReg.lastIndex=0;
			return mStr.replace(str,wStr);
		};
		function doChecks(mStr,kStr,i){
			return kStr.startsWith("LOOP ")?doLoop(mStr,kStr,i):kStr.startsWith("IF")?doIf(mStr,kStr,i):testItems(mStr,kStr);
		};
		while(t=r.exec(v)){			
			var loopKey="", loopPrepend="", tp=doChecks(v,t[0].replace(ld,"").replace(rd,"").strip(),r.lastIndex);
			if(tp!=v){
				v=tp;
				r.lastIndex=0;
			}
		}
		r.lastIndex=0;
		return v;
	},
	contains: function(s,e){
		return (e?(this==s||((this.indexOf(s)!=-1)&&this.match(new RegExp('(^|\\s)('+s+')(\\s|$)'))!=null)):(this.indexOf(s)!=-1));
	},
	startsWith:function(s){
		return (this.indexOf(s)===0);
	},
	endsWith:function(s){
		return (this.indexOf(s)+s.length==this.length);
	},
	camelize: function(){
		var s=this.valueOf(), rg=/([a-zA-Z]+)(-([a-zA-Z]{1})([a-zA-Z]*))/i, res;
		while(res=s.match(rg)){
			s=s.replace(rg,'$1'+res[3].toUpperCase()+'$4');
		}		
		return s;
	},
	capitalize:function(f){
		return this.charAt(0).toUpperCase()+(f?this.substring(1).toLowerCase():this.substring(1));	
	},
	more:function(c,a){
		return this.substring(0,c?c:adlib.defaults.strings.more.charCount)+(a?a:adlib.defaults.strings.more.addition);
	},
	times:function(c){
		var a="";
		for(var x=0; x<c; x++){
			a+=this;
		}
		return a;
	},	
	toHash:function(d){
		if(isString(d)){
			d=[d];
		}
		var s=this.valueOf(), r=$H(), d1=d.shift(), d2=null,t=s.split(d1);
		if(d.length>0){
			d2=d.shift();
		}
		if(t.length==1){
			if(d2==null){
				return s;
			}
			else{
				var t2=s.split(d2);
				if(t2.length==1){
					return s;
				}
				else{
				 	r[t2[0].strip()]=t2[1];
				}
			}
		}
		else if(d2){
			t.forEach(function(v,k){
				if(isValidText(v)){
					var t2=v.split(d2);
					if(t2.length==1){
						r[val.strip()]='';
					}
					else if(d.length==0){
						r[t2[0].strip()]=t2[1];
					}
					else{
						r[t2[0].strip()]=t2[1].strip().toHash(d.clone());
					}
				}
			});
		}
		else{
			r.fill(t);
		}	
		return r;
	},
	pad:function(c,s,ch){
		s=s||adlib.defaults.strings.pad.side;
		var o=(ch||' ').times(c);
		return s=="l"?o+this:s=="r"?this+o:o+this+o;
	},
	toArray:function(){
		return this.split('');
	},
	toCharCodeArray:function(){
		var a=[];
		for(var x=0; x<this.length; x++){
			a[x]=this.charCodeAt(x);
		}
		return a;
	},
	toInt:function(r){
		r=r||10;
		return parseInt(this,r);
	},
	toFloat:function(){
		return parseFloat(this);
	}
},false);



/*****************  Number ****************************************/
Class.inherits(Number.prototype,{
	toHex:function(pr){
		var p=pr||0,rt=this.toString(16);
		if(rt.length<p){
			rt=rt.pad(p-rt.length,'l','0');
		}
		return rt;
	},
	odd:function(){
		return (this.floor()%2===1);
	},
	even:function(){
		return (this.floor()%2===0);
	},
	divBy:function(n){
		return (this%n===0);
	},
	noNaN:function(v){
		return isNaN(this)?v!=null?v:adlib.defaults.number.noNaN.defaultReturn:this.valueOf();		
	},
	bound:function(n,x){
		return (this<n?n:this>x?x:this);
	},
	toInt:function(){
		return parseInt(this);
	},
	toFloat:function(){
		return parseFloat(this);
	}
},false); 

(function(){
	var a=["floor","ceil","round","abs"];
	for(var x=0; x<a.length; x++){
		Number.prototype[a[x]]=new Function('return Math.'+a[x]+'(this)');
	}
})();



/*****************  Arrays ****************************************/

Class.inherits(Array.prototype,{
	forEach:function(f,o){
		for(var k=0; k<this.length; k++){
			if(k in this){
				o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
			}
		}
	},
	every:function(f,o){
		var rt;
		for(var k=0; k<this.length; k++){
			if(k in this){
				rt=o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
				if(!rt){
					return false;
				}
			}
		}
		return true;
	},
	filter:function(f,o){
		var r=[],rt;
		for(var k=0; k<this.length;k++){	
			if(k in this){
				rt=o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
				if(rt){
					r.push(this[k]);
				}
			}
		}
		return r;
	},
	map:function(f,o){
		var r=[];
		for(var k=0; k<this.length; k++){
			if(k in this){
				r.push(o?f.apply(o,[this[k],k,this]):f(this[k],k,this));
			}
		}
		return r;
	},
	some:function(f,o){
		var r=false;
		for(var k=0; k<this.length; k++){
			if(k in this){
				r=o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
				if(r){break}
			}
		}
		return r;
	},
	indexOf:function(e,fi){
		var f=Number(fi).noNaN();
		f=f<0?Math.max(this.length+f,0):f;
		if(f<this.length){
			for(; f<this.length; f++){
				if((f in this)&&this[f]===e){
					return f;
				}
			}
		}
		return -1;
	},
	lastIndexOf:function(e,fi){
		var f=Number(fi).noNaN(this.length-1);
		f=f<0?f.ceil()+this.length:Math.min(f.floor(),this.length-1);
		if(f>0){					
			for(; f>=0;f--){
				if((f in this)&&this[f]===e){
					return f;
				}
			}
		}
		return -1;			
	},
	reduce:function(f,s){
		if(this.length==0&&arguments.length<2){throw new TypeError()}
		var i=0, pv=null;				
		if(arguments.length>=2){pv=s}
		else{
			do{
				if(i in this){
					pv=this[i];
					i++;
					break;
				}
				if(++i>=this.length){throw new TypeError()}						
				i++;
			}while(true);
		}
		for(;i<this.length;i++){
			if(i in this){
				pv=f(pv,this[i],i,this);
			}
		}
		return pv;
	},
	reduceRight:function(f,s){
		if(this.length==0&&arguments.length<2){throw new TypeError()}
		var i=this.length-1, pv=null;				
		if(arguments.length>=2){pv=s}
		else{
			do{
				if(i in this){
					pv=this[i];
					i--;
					break;
				}
				if(--i>=this.length){throw new TypeError()}						
				i--;
			}while(true);
		}
		for(;i>=0;i--){
			if(i in this){
				pv=f(pv,this[i],i,this);
			}
		}
		return pv;
	},
	filterKeys:function(f,o){
		var r=[], rt;
		for(var k=0; k<this.length;k++){	
			if(k in this){
				rt=o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
				if(rt){
					r.push(k);
				}
			}
		}
		return r;
	},
	grep:function(p){
		for(var x=0; x<this.length; x++){
			if(x in this){
				if(((isRegExp(p))&&(p.test(this[x])))||
					((isString(p))&&(this[x].contains(p)))||
					((isFunction(p))&&(p(this[x],x)))){
					return x;
				}
			}
		}
		return null;
	},
	grepAll:function(p){
		var r=[];
		for(var x=0; x<this.length; x++){
			if(x in this){
				if(((isRegExp(p))&&(p.test(this[x])))||
					((isString(p))&&(this[x].contains(p)))||
					((isFunction(p))&&(p(this[x],x)))){
					r.push(x);
				}
			}
		}
		return (r.length>0)?r:null;				
	},

	fill: function(v,c){
		var f=isFunction(v);
		for(var x=0; x<c; x++){
			this[x]=(f?v(x):v);
		}
		return this;
	},
	insert:function(l,v){	
		var st=this.splice(0,l);
		st=st.concat(v,this);
		this.clear();
		for(var x=0;x<st.length; x++){
			if(x in st){
				this.push(st[x]);
			}
		}
		return this;
	},
	normalize:function(){
		var t=[0,0];
		for(var x=0; x<this.length; x++){
			if(x in this){
				t[t.length]=this[x];
			}
		}
		this.clear();
		this.splice.apply(this,t);
		return this;
	},
	clear:function(){
		this.length=0;
		return this;
	},
	exec:function(f){
		for(var x=0; x<this.length; x++){
			if(x in this){
				this[x]=f(this[x],x);
			}			
		}
		return this;
	},
	removeDuplicates:function(){
		if(this.length>1){
			this.normalize();
			for(var x=0; x<this.length; x++){
				if(x in this){
					for(var y=x+1; y<this.length; y++){
						if((y in this) && this[x]===this[y]){
							delete this[y];
						}
					}
				}
			}
			this.normalize();
		}
		return this;
	},
	clone:function(){
		return [].concat(this);
	},
	filterSplit:function(f,o){
		var r=[[],[]],rt;
		for(var k=0; k<this.length;k++){	
			if(x in this){
				rt=o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
				r[rt?0:1].push(this[k]);
			}
		}
		return r;
	},
	flatten:function(){
		var a=[];
		return a.concat.apply(a,this);
	}
},false);
Class.inherits(Array.prototype,{
	cut:Array.prototype.splice,
	select:Array.prototype.filter,
	contains:Array.prototype.indexOf
},false);
Class.inherits(Array.prototype,adlib.iterator,false);



/*****************  Hash ****************************************/
var Hash=Class.create();
function $H(){
	var a=new Hash();
	if(arguments.length>0){
		a.fill.apply(a,$A(arguments));
	}
	return a;
};

Class.inherits(Hash.prototype,{
	forEach:function(f,o){
		for(var k in this){
			if(!this.noEnum(k)){
				o?f.apply(o,[this[k],k,this]):f(this[k],k,this);
			}
		}
	},
	map:function(f){
		var r=[];
		var vl=this.each(f);
		while(vl!=null){
			r.push(vl);			
			vl=this.next();
		}
		return r;
	},
	every:function(f){
		var r=this.each(f);
		while(r){
			r=this.next();
		}
		return (r==null?true:false);
	},
	filter:function(f){
		var r=[], rt=this.each(f);
		while(rt!=null){
			if(rt){
				r.push(this[this.__iteration.items[this.__iteration.step]]);
			}
			rt=this.next();
		}
		return r;
	},
	some:function(f){
		var r=this.each(f);
		while(r!=null){
			if(r){
				return true;
			}
			r=this.next();
		}
		return false;
	},
	indexOf:function(e){
		for(var x in this){
			if(this.noEnum(x)){continue}
			if(this[x]===e){
				return x;
			}
		}
		return null;
	},
	filterKeys:function(f){
		var r=[], rt=this.each(f);
		while(rt!=null){
			if(rt){
				r.push(this.__iteration.items[this.__iteration.step]);
			}
			rt=this.next();
		}
		return r;
	},
	cut:function(a){
		var o=new Hash(), a=isFunction(a)?this.filterKeys(a):$A(arguments).flatten();
		for(var x=0; x<a.length;x++){
			if($test(this[a[x]])){
				o[a[x]]=this[a[x]];
				delete this[a[x]];
			}
		}
		return o;
	},
	paste:function(){
		for(var y=0, a=arguments[0]; y<arguments.length; y++,a=arguments[y]){
			for(var x in a){
				if(a.noEnum&&a.noEnum(x)){continue}
				this[x]=a[x];
			}
		}
		return this;
	},
	copy:function(a){
		var o=$H(), itm=(arguments.length>0?isFunction(a)?this.filterKeys(a):$A(arguments).flatten():this.items());
		for(var x=0; x<itm.length; x++){
			switch($type(this[itm[x]])){
				case 'Array': o[itm[x]]=this[itm[x]].clone(); break;
				case 'Hash': o[itm[x]]=this[itm[x]].copy(); break;
				default: o[itm[x]]=this[itm[x]].valueOf();
			}
		}
		return o;
	},
	toArray:function(){
		return this.map(function(v){
			return v;
		});
	},
	fromString:function(s,d1,d2){
		this.clear();
		this.paste(s.toHash([d1,d2]));
		return this;
	},
	toQuery:function(r){
		var s=(r&&isString(r))?r:'';
		this.forEach(function(v,k){
			s=s.addParam(k,v);
		});
		if(r&&!isString(r)){
			s=s.substring(1);
		}
		return s;
	},
	fromQuery:function(s){
		this.clear();
		if(s.indexOf('?')!=-1){
			s=s.substring(s.indexOf('?')+1);
		}
		return this.paste(s.toHash(['&','=']));
	},
	run:function(funct){
		this.forEach(funct,this);
		return this;
	},	
	exec:function(f,o){
		for(var k in this){
			if(!this.noEnum(k)){
				o?this[k]=f.apply(o,[this[k],k,this]):this[k]=f(this[k],k,this);
			}
		}
		return this;
	},		
	grep:function(p){
		for(var x in this){
			if(this.noEnum(x)){continue ;}
			if(((isRegExp(p))&&(p.test(this[x])))||
				((isString(p))&&(this[x].contains(p)))||
				((isFunction(p))&&(p(this[x],x)))){
				return x;
			}
		}
		return null;
	},
	grepAll:function(p){
		var r=[];
		for(var x in this){
			if(this.noEnum(x)){continue}
			if(((isRegExp(p))&&(p.test(this[x])))||
				((isString(p))&&(this[x].contains(p)))||
				((isFunction(p))&&(p(this[x],x)))){
				r.push(x);
			}
		}
		return (r.length>0)?r:null;				
	},
	fill:function(va){
		if(arguments.length==1){
			if(isArray(arguments[0])){
				arguments[0].forEach(function(v){
					this[v]='';
				},this);
			}
			else{
				for(var x in arguments[0]){
					this[x]=arguments[0][x];
				}
			}
		}
		else if(arguments.length==2){
			arguments[1].forEach(function(v){
				this[v]=va;
			},this);
		}
		else{
			for(var x=1; x<arguments.length; x++){
				this[arguments[x]]=va;
			}
		}
		return this;
	},
	clear:function(){
		this.forEach(function(v,k){
			delete this[k];
		},this);
		return this;	
	},
	pasteArray:function(ks,vs){
		var _t=this;
		ks.forEach(function(v,k){
			_t[v]=vs[k];
		});
		return this;
	},
	hasKey:function(k){
		return ($test(this[k])&&!this.noEnum(k));
	},
	diff:function(o){
		return this.some(function(v,k){
			return o[k]!=v;
		});		
	}
});

Class.method(Hash.prototype,"toString",function(ds){
	var d=ds||[], tmp='', d1=adlib.defaults.hash.toString.delimiter1, d2=adlib.defaults.hash.toString.delimiter2;
	if(d.length>0){
		d1=d.shift();
		if(d.length>0){
			d2=d.shift();
		}
	}
	this.forEach(function(v,k){
		if(tmp.length>0){
			tmp+=d1;
		}
		tmp+=k+d2+(isHash(v)?v.toString(d.clone()):(isArray(v)?v.join(d1):v));
	});
	return tmp;
});


Class.inherits(Hash.prototype,adlib.iterator,false);

Class.inherits(Hash.prototype,{
	insert:Hash.prototype.paste,
	concat:Hash.prototype.paste,
	append:Hash.prototype.paste,
	clone:Hash.prototype.copy,
	findAll:Hash.prototype.filter,
	find:Hash.prototype.indexOf,
	merge:Hash.prototype.toString,
	contains:Hash.prototype.indexOf,
	keys:Hash.prototype.items,
	values:Hash.prototype.toArray,
	select:Hash.prototype.filter,
	join:Hash.prototype.toString,
	init:Hash.prototype.fill
});



/*****************  Collections ****************************************/

var Collection=Class.create();
function $C(){
	return new Collection($A(arguments[0]));
};

Class.inherits(Collection.prototype,adlib.iterator);
(function(){
	var a=["filterKeys","clear","splice","exec","push","shift","pop","unshift","flatten","forEach","some","every","map","filter","indexOf","lastIndexOf","reduce","reduceRight"];
	for(var x=0; x<a.length; x++){
		Class.method(Collection.prototype,a[x],Array.prototype[a[x]]);
	};	
})();

Class.method(Collection.prototype,"filter",function(f,o){
	return $C(Array.prototype.filter.apply(this,[f,o]));
});
Class.inherits(Collection.prototype,{
	init:function(a){
		this.push.apply(this,[]);
		this.clear();
		if(a){
			this.push.apply(this,$A(a));
		}
	},
	normalize:function(){
		var t=$C([0,0]);
		for(var x in this){
			if(this.noEnum(x)){
				continue;
			}
			t.push(this[x]);
		}
		this.clear();
		this.splice.apply(this,$A(t));
		return this;
	},
	concat:function(){
		var q=$C();
		if(this.length>0){
			q.push.apply(q,$A(this));
		}
		for(var x=0; x<arguments.length; x++){
			var a=$A(arguments[x]);
			if(a.length>0){
				q.push.apply(q,a);
			}
		}
		return q;
	},
	reverse:function(){
		return $C(Array.prototype.reverse.apply(this));
	},
	clone:function(){
		return $C().concat(this);
	},
	removeDuplicates:function(){
		if(this.length>1){
			var t=this.toHash().toArray();		
			this.clear();
			this.push.apply(this,t);
		}
		return this;
	},
	toHash:function(){
		var h=$H();
		for(var x=0; x<this.length; x++){
			if(isCollectable(this[x])){
				h[(this[x]==window)?"window":(this[x]==document)?"document":this[x]._uniqueId]=this[x];
			}
		}
		return h;
	},
	toArray:function(){
		return $A(this);
	},
	prune:function(){
		var a=this.toHash().toArray();
		this.clear();
		this.push.apply(this,a);
		return this;
	},
	filterByCSS:function(c){
		return DOM.filterByCSS(this.prune(),c);
	}
},true);


Class.method(Collection.prototype,"toString",function(){return "[Collection: length="+this.length+"]";});



/*****************  Executables ****************************************/
function $F(f,p,t){
	if(isExecutable(f)){return f}
	var __f, __p, __t; //local vars
	if(isObject(f)){
		__f=f.f;
		if(f.p){
			__p=f.p;
		}
		if(f.o){
			__t=f.o;
		}	
	}
	else{
		__f=f;
		__p=p;
		__t=t;
	}
	var fi=function(){
		var p2=(__p)?__p.clone():[];
		if(arguments.length>0){
			for(var x=arguments.length-1; x>=0; x--){
				p2.unshift(arguments[x]);
			}
		}
		var r=__f.apply((__t)?__t:this,p2);
		if(r!=void 0){
			return r;
		}
	};
	Class.inherits(fi,{
		isExecutable:true,
		getParams:function(){
			return __p.clone();
		},
		setParams:function(a){
			__p=a;
		},
		getObject:function(){
			return __t;
		},
		setObject:function(a){
			__t=a;
		},
		getFunction:function(){	
			return __f;
		},
		setFunction:function(a){
			__f=a;
		},
		runNoParams:function(){
			__f.apply((__t)?__t:this,$A(arguments));
		}
	});
	Class.method(fi,'toString',function(){return __f.toString()});
	return fi;
};




adlib.internal.vars.makeFragmentClass='makeFragmentContainer';
adlib.internal.vars.makeFragmentTypes=$H({
	tr:{
		pat:/^\s*<tr(\s+|>)/i,
		prepend:'<table><tbody class="'+adlib.internal.vars.makeFragmentClass+'">',
		postpend:'</tbody></table>'
	},
	td:{
		pat:/^\s*<td(\s+|>)/i,
		prepend:'<table><tbody><tr class="'+adlib.internal.vars.makeFragmentClass+'">',
		postpend:'</tr></tbody></table>'
	},
	tgroup:{
		pat:/^\s*<(tbody|tfoot|thead)(\s+|>)/i,
		prepend:'<table class="'+adlib.internal.vars.makeFragmentClass+'">',
		postpend:'</table>'
	},
	li:
	{
		pat:/^\s*<li(\s+|>)/i,
		prepend:'<ul class="'+adlib.internal.vars.makeFragmentClass+'">',
		postpend:'</ul>'
	},
	option:{
		pat:/^\s*<option(\s+|>)/i,
		prepend:'<select class="'+adlib.internal.vars.makeFragmentClass+'">',
		postpend:'</select>'
	}
});

Class.inherits(DOM,{
	doStyleEvent:_Empty,
	extend:function(e){
		if(!e||e._uniqueId){return}
		e=isArray(e)||isCollection(e)?e:[e];
		for(var x=0;x<e.length;x++){
			if(e[x]&&e[x]._uniqueId==undefined){		
				e[x]._uniqueId=getRandomId();		
				if(!adlib.ElementSupported&&e[x]!=window&&!e[x]._isExtended){
					DOM.doExtending(e[x]);
				}
			}		
		}
	},
	resetUniqueID:function(n){
		n._uniqueId=getRandomId();
	},
	doExtending:function(v){	
		Class.inherits(v,adlib.elements);
	},
	// child, parent
	isDescendantOf:function(c,p){
		c=$(c);
		p=$(p);
		if((p==document)||(p==window)){return true}
		var r=false;
		if((isElement(c)&&isElement(p))&&(!((c==document)||(c==window)||(c==p)))){		
			var o=c.$parent();
			while(o&&o!=p&&o!=document){
				o=o.$parent();
			}
			r=(o==p);
		}
		return r;
	},
	// node, css
	filterByCSS:function(n,c){
		return adlib.internal.methods.doFilters(n,adlib.internal.methods.parse(c,adlib.internal.vars.singleExpression)[0]);
	},
	getDefaultDisplay:function(el){
		var n=$(el)._nn();
		if(adlib.constants.tableElements[n]){
			return adlib.constants.tableElements[n];
		}
		if(adlib.constants.blockElements.indexOf(n)>-1){
			return "block";
		}
		if(adlib.constants.inlineElements.indexOf(n)>-1){
			return "inline";
		}
		return adlib.defaults.DOM.getDefaultDisplay.displayType;		
	},
/*******************insertions ***************/
	// e - element/collection
	// c - content
	// b - insert before or after (default=false/after)
	// point= element/css/number
	insertInto:function(e,c,b,p){
		return adlib.internal.methods["insertInto"+(isCollection(e)?"Collection":"Node")](e,c,b,p);
	},	
	// node, number of copies
	makeCopies:function(n,c){
		var cn, co;
		if(isString(n)){
			co=n;
			n=DOM.makeFragment(n);
		}
		else{
			var tn=$e('div');
			tn.appendChild(n);
			co=tn.getHTML();
			tn=null;
		}
		var r=[n];
		for(var x=1; x<c; x++){
			r.push(DOM.incrementIds(DOM.makeFragment(co),x));
		}		
		return r;
	},
	// number, count
	incrementIds:function(n,c){
		var nds=$C();
		if(n.nodeType==Node.ELEMENT_NODE){
			nds.push(n);
		}
		else{
			for(var x=0; x<n.childNodes.length; x++){
				if(n.childNodes[x].nodeType==Node.ELEMENT_NODE&&n.childNodes[x].getAttribute('id')!=null){
					nds.push($(n.childNodes[x]));
				}
			}
		}
		if(adlib.browser.ie){// fix for IE not allowing you to extend elements within a fragment
			var c=$C();
			for(var x=0; x<nds.length; x++){
				var t=nds[x].getElementsByTagName('*');
				for(var y=0; y<t.length; y++){
					var a=t[y].getAttribute('id');
					if(a){
						c.push(t[y]);
					}
				}
			}
			nds=nds.concat(c);
		}
		else{
			nds.push.apply(nds,$A($(nds).$a('id')));
		}
		for(var x=0; x<nds.length; x++){
			nds[x].id=nds[x].id+c;
			DOM.resetUniqueID(nds[x]);
		}
		return n;
	},
	makeFragment:function(c){
		var df=document.createDocumentFragment();
		var nd, n, p=false;
		adlib.internal.vars.makeFragmentTypes.some(function(v){
			if(c.match(v.pat)){
				c=v.prepend+c+v.postpend;
				p=true;
			}
			return p;
		});
		nd=$e('div');
		nd.innerHTML=c;
		n=p?nd.$css('.'+adlib.internal.vars.makeFragmentClass)[0]:nd;
		for(var x=0, y=n.childNodes.length; x<y; x++){
			df.appendChild(n.removeChild(n.childNodes[0]));
		}
		nd=null;
		return df;
	},
		
/******************* window ***************/
	getWindowX:function(){
		var l=window["screen"+((window.screenX&&!adlib.browser.opera)?"X":"Left")]||0;
		return l;
	},
	getWindowY:function(){
		var t=window["screen"+((window.screenY&&!adlib.browser.opera)?"Y":"Top")]||0;
		return t;
	},
	getDocumentWidth:function(){return adlib.documentElement.scrollWidth},
	getDocumentHeight:function(){return adlib.documentElement.scrollHeight}	
});
// compliant browsers	
Class.inherits(DOM,(window.innerWidth)?{
	getViewWidth:function(){return window.innerWidth},
	getViewHeight:function(){return window.innerHeight},
	getScrollX:function(){return window.pageXOffset},
	getScrollY:function(){return window.pageYOffset}
}:{
	getViewWidth:function(){return adlib.documentElement.clientWidth},
	getViewHeight:function(){return adlib.documentElement.clientHeight},
	getScrollX:function(){return adlib.documentElement.scrollLeft},
	getScrollY:function(){return adlib.documentElement.scrollTop}
});


adlib.internal.vars.DOMStore={
	nodes:$H(),
	counter:0,
	cVal:null,
	returnVal:false,
	reset:function(){
		this.counter=0;
		this.nodes=$H();
	}	
};

Class.inherits(adlib.internal.vars,(function(){
	var a={
		rxStrings:$H({
			nthOpts:"((((-?)(\\d*)?)(n)(([\\+-])\\d*)?)|(\\d+)|(odd|even))",
			nameType:"([a-zA-Z][\\w-]*)"
		}),
		rx:$H(),
		tokens:$H()
	};
	a.multiTokens=$H({
		pseudo:'\\:((only|first|last)-(child|of-type))',		
		fpos:'\\:(even|odd|first|last|only)',
		pos:'\\:(eq|nth|gt|lt)\\(\\s*(\\d+)\\s*\\)',	
		containsText:'\\:contains\\(([^\\)]+)\\)',
		nth:'\\:(nth-(last-)?(child|of-type))\\('+a.rxStrings.nthOpts+'\\)',
		classType:'\\.'+a.rxStrings.nameType,
		attribute:'\\['+a.rxStrings.nameType+'(\\s*([\\^\\$\\*~\\|\\!])?=\\s*([\"]?)([^\\]\"]+)\\4?\\s*)?\\]',
		vis:'\\:(visible|hidden)',
		xabled:'\\:(en|dis)abled',
		fSel:'\\:(checked|selected)',
		empty:'\\:empty',
		id:'\\#'+a.rxStrings.nameType,	
		tag:"(\\*|[a-zA-Z][\\w-]*)"
	});	
	a.uniqueTokens=$H({
		not:(function(){
					var ret="\\:not\\(\\s*(";
					var tmpStr="";
					a.multiTokens.forEach(function(v,k){
						tmpStr+=v+"|";
					});
					ret+=tmpStr.substring(0,tmpStr.length-1)+")\\s*\\)";
					return ret;
				})(),
		combinators:"((\\s*(>|\\+|~)\\s*)|(\\s+))"
	});			
	a.rxStrings.forEach(function(v,k){
		a.rx[k]=new RegExp("^"+v);
	});
	$H().paste(a.multiTokens,a.uniqueTokens).forEach(function(v,k){
		a.tokens[k]=new RegExp("^"+v);
	});	
	a.singleExpression=a.tokens.keys();
	a.singleExpression[a.singleExpression.length-1]=void 0;
	a.singleExpression.length=a.singleExpression.length-1;	
	return a;
})());

Class.inherits(adlib.internal.methods,{
// checks if the element has a attribute
// n=node, a=attribute name, v=value, m=modifier
	checkAttributeStatus:function(n,a,v,m){
		var at=(a=="class"?n.className:n.getAttribute(a)), r=at?true:false;
		if(at){
			at=at.strip();
		}
		if(r&&v!=null&&v!=""){
			v=v.strip();
			r=(at==v);
			if(m&&m!="="){
				if(m=='!'){
					return !r;
				}
				if(!r&&at!=""){
					// starts with value-
					if(m=='|'){
						r=at.startsWith(v+'-');
					}
					// contains exact (~)  
					else if(m=='~'){
						r=(!v.match(/\s/)&&at.contains(v,true));
					}
					// just contains (*)
					else if(m=='*'){
						r=at.contains(v);
					}
					// starts with value
					else if(m=='^'){
						r=at.startsWith(v);
					}
					// ends with value
					else if(m=='$'){
						r=at.endsWith(v);
					}
				}
			}
		}
		return r;
	},

// gets the Nth child
// n=node, f=factor (array parsed from css), l=last, t=node type
// factors:
//  0 - full match
// 	1 - nth code (eg nth-child, nth-last-child)
//  2 - "last-" or null
//  3 - "child" or "of-type"
//  4 - full options text (eg -2n+1 or odd)
//  5 - full options text if options format = (-)xn+/-y
//  6 - the n factor (x or -x) (eg if -2n+1, 6 = -2, if 2n+1, 6=2)
//  7 - negative sign on n factor
//  8 - the number on the n factor
//  9 - n (if present)
//  10 - full portion after n
//  11 - +/- after n
//  12 - number for stand-along digit as context (e.g. nth-child(3))
//  13 - odd or even
	getNth:function(n,f,l,t){
		if(t){
			t=t.toLowerCase();
		}
		var r=$C();
		var opts=isString(f)?adlib.internal.vars.rx.nthOpts.exec(f=="odd"?"2n+1":f=="even"?"2n":f):f.length>9?f.slice(3):f;		
		if(opts[9]){
			r=n.childAt(opts[9].toInt()-1,l,t);
		}
		else if(opts[5]==null&&opts[7]==null){
			r=n.childElements(t);
		}
		else{			
			var step=opts[3].toInt().noNaN(opts[4]?-1:1),aval=parseInt(opts[7]).noNaN()-1;
			if(!(step<0&&aval<0)){	
				var ch=adlib.internal.methods.getChildren(n,t);
				if(ch.length>0){
					if(l){
						ch.reverse();
					}
					while(aval<0||(aval>=ch.length&&step<0)){
						aval+=step;
					}	
					for(var x=aval; x<ch.length&&x>=0; x+=step){
						if(ch[x]){
							r.push(ch[x]);
						}
					}			
					if(l){
						r.reverse();
					}
				}				
			}
		}
		return r;
	},
// converts nth odd/even into 2n+1/2n
	nthShortToFull:function(oe,l,tpe){
		return (":nth-"+(l?l:"")+tpe+"("+"2n"+(oe=="odd"?"+1":"")+")").match(adlib.internal.vars.tokens.nth);	
	},
// parses a CSS string into a Hash (option restriction set - array)
	parse:function(cssStr,set){
		var strs=cssStr.split(/\s*[,;]\s*/), groups=[];
		adlib.internal.vars.DOMStore.reset();
		strs.removeDuplicates();
		strs.forEach(function(cssString){
			var grp=$H(), matched=true, targ=grp;
			cssString=cssString.strip();			
			var tSet=set?adlib.internal.vars.tokens.copy(set):adlib.internal.vars.tokens;
			while(matched){
				matched=tSet.some(function(val,key){
					var mtch=cssString.match(val);
					if(mtch){	
						cssString=cssString.substring(mtch[0].length);
						// if combinator, start a nested context
						if(key=="combinators"){
							targ[key]=[mtch,$H()];
							targ=targ[key][1];
						}
						else{
							if(key=='pos'||key=='fpos'){
								var q=null;
								switch(mtch[1]){
									case 'only':;
									case 'first':;
									case 'last': key='pseudo';
												 mtch[2]=mtch[1];
												 mtch[3]='child';
												 break;
									case 'eq':;
									case 'nth': q=mtch[2];
									case 'odd':	q=(q!=null?q:'2n+1');
									case 'even': q=(q!=null?q:'2n');
									case 'gt': q=(q!=null?q:'n+'+mtch[2]);
									case 'lt': q=(q!=null?q:'-n+'+mtch[2]);
												 key='nth';
												 mtch=adlib.internal.vars.tokens.nth.exec(':nth-child('+q+')');
												 break;
								}
							}
							if(key=="nth"&&(mtch[4]=="odd"||mtch[4]=="even")){
								mtch=adlib.internal.methods.nthShortToFull(mtch[4],mtch[2],mtch[3]);
							}
							if(key=="tag"){
								// lowercase tag value for quicker matching later
								mtch[1]=mtch[1].toLowerCase();
							}
							// not values are stored in a nested hash (same format as regular)
							// this allows the "not" filters to be passed directly into the doFilters function
							if(key=="not"){
								if(!targ["not"]){
									targ["not"]=$H();
								}
								var tmp=null;
								var k=adlib.internal.vars.multiTokens.grep(function(v,k){
										tmp=adlib.internal.vars.tokens[k].exec(mtch[1]);
										return (tmp?true:false);
								});
								if(k=="nth"&&(tmp[4]=="odd"||tmp[4]=="even")){
									tmp=adlib.internal.methods.nthShortToFull(tmp[4],tmp[2],tmp[3]);
								}
								if(!targ["not"][k]){
									targ["not"][k]=[tmp];
								}
								else{
									targ["not"][k].push(tmp);
								}
							}
							else{								
								if(!targ[key]){
									targ[key]=[mtch];
								}
								else{
									targ[key].push(mtch);
								}
							}												
						}						
						return true;
					}					
					return false;						
				});
			}
			if(cssString.strip().length>0){
				return null;
			}
			groups.push(grp);
		});
		return groups;
	},	
	// nodes
	// filters
	doFilters:function(nds,fs){
		return nds.filter(function(n){
			return (function(r,f){
				var NNm=n._nn();
				if(f.id){
					for(var x=0; x<f.id.length; x++){
						if(n.id!=f.id[x][1]){
							return !r;
						}
					}
				}
				if(f.tag){
					for(var x=0; x<f.tag.length; x++){
						if(NNm!=f.tag[x][1]){
							return !r;
						}
					}
				}
				if(f.empty){	
					for(var x=0; x<f.empty.length; x++){
						if(!n.isEmpty()){
							return !r;
						}
					}
				}	
				//classType
				if(f.classType){
					var c=n.className;
					for(var x=0; x<f.classType.length; x++){
						if(!c.contains(f.classType[x][1],true)){
							return !r;
						}
					}	
				}
				if(f.attribute){
					for(var x=0,j=f.attribute; x<j.length; x++){
						if(!adlib.internal.methods.checkAttributeStatus(n,j[x][1],j[x][5],j[x][3])){
							return !r;			
						}
					}
		
				}
				if(f.pseudo){
					var p=n.$parent();
					for(var x=0,j=f.pseudo; x<j.length; x++){
						var tag=(j[x][3]=="of-type")?NNm:false, o=j[x][2];
						if(	//first-child, first-of-type
							(o=="first"&&p.first(tag)!=n)||
							//last-child, last-of-type
							(o=="last"&&p.last(tag)!=n)||
							//only-child, only-of-type
							(o=="only"&&adlib.internal.methods.getChildren(p,tag).length!=1)
						){
							return !r;
						}
					}
				}
				if(f.nth){
					var p=n.$parent();
					for(var x=0,j=f.nth; x<j.length; x++){
						var e=j[x][2]?true:false, ns=adlib.internal.methods.getNthStore(p,(j[x][3]=="of-type"?NNm:null),j[x],e);
						if(!ns||ns.indexOf(n)==-1){
							return !r;
						}		
					}
				}
				if(f.fSel){
					for(var x=0; x<f.fSel.length; x++){
						if( //checked
							(f.fSel[x][1]=="checked"&&(!n.checked))||
							//selected
							(f.fSel[x][1]=="selected"&&(!n.selected))
						){
							return !r;
						}
					}				
				}
				if(f.xabled){
					var a=n.disabled;
					for(var x=0; x<f.xabled.length; x++){
						if(
							(f.xabled[x][1]=='dis'&&!a)||
							(f.xabled[x][1]=='en'&&a)
						){
							return !r;
						}
					}
				}
				if(f.vis){
					var a=(n.getStyle('display')=='none'||n.getStyle('visibility')=='hidden'||(n._nn()=='input'&&n.type=='hidden'));
					for(var x=0; x<f.vis.length; x++){
						if(
							(f.vis[x][1]=="hidden"&&!a)||
							(f.vis[x][1]=="visible"&&a)
						){
							return !r;
						}			
					}
				}
				if(f.containsText){
					for(var x=0,j=f.containsText; x<j.length; x++){
						var ret=false;
						for(var y=0; y<n.childNodes.length; y++){
							var c=n.childNodes[y];
							if((c.nodeType==Node.TEXT_NODE)&&(c.nodeValue.contains(j[x][1]))){
								ret=true;
								break;
							}
						}
						if(!ret){
							return !r;
						}
					}
				}
				if(f.not){
					return arguments.callee(false,f.not);
				}
				return r;
			})(true,fs);
		});
	},
// stores nodes for quick look up
	getNodeStore:function(i){
		var a=adlib.internal.vars.DOMStore.nodes;
		if(!a[i]){
			a[i]=$H();
		}
		return a[i];
	},
// gets the children of a node and stores them
	// n=node
	// t=node type
	getChildren:function(n,t){
		var a=adlib.internal.methods.getNodeStore(n._uniqueId), m="childElements"+(t?"_"+t:"");
		if(!a[m]){
			a[m]=n.childElements(t);
		}
		return a[m];
	},
// gets the nth children of a node and stores them
	// n=node
	// t=type
	// o=opts
	// l=last
	getNthStore:function(n,t,o,l){
		var a=adlib.internal.methods.getNodeStore(n._uniqueId), m=(l?"nthLast":"nth")+((t)?t+"_":"")+o[4].toCharCodeArray();
		if(!a[m]){
			a[m]=n.nth(o,t,l);
		}
		return a[m];
	},
// starts the CSS searching functionality
// f = a hash of the parameters to search
// w = the existing set of Nodes to search from
	doCSSGroup:function(f,w){
		adlib.internal.vars.DOMStore.counter++;
		var nl=adlib.internal.methods.doNewCSSGroup(w,f);
		if(nl.length>0&&f.combinators){
			nl=adlib.internal.methods.doSubGroup(nl,f.combinators);
		}		
		return nl;					
	},
// does an initial node selection for a new CSS group (new or after " " combinator)
// 	gl=existing nodes
//	f = filters
// 
	doNewCSSGroup:function(gl,f){
		var wl=$C();
		if(f['id']){		
			for(var x=0; x<gl.length; x++){
				var tmp=gl[x].$(f["id"][0][1]);
				if(tmp){					
					wl=$C(tmp);
					break;
				}							
			}
			delete f['id'];	
			f.reset();	
		}
		else{
			var t="*";
			if(f["tag"]){
				t=f["tag"][0][1];
				delete f['tag'];	
				f.reset();
			}
			if(adlib.internal.vars.DOMStore.counter==1){
				wl=gl.$t(t);	
			}
			else{
				var a=$H(), nd=[];
				for(var x=0; x<gl.length; x++){
					if(a[gl[x]._uniqueId]){continue}
					var tmp=gl[x].$t(t);
					for(var y=0; y<tmp.length; y++){
						if(a[tmp[y]._uniqueId]){continue}
						a[tmp[y]._uniqueId]=true;
						nd[nd.length]=tmp[y];
					}
				}
				wl=wl.concat(nd);
			}
		}
		if(wl.length>0&&((f.count()==1&&!f.combinators)||(f.count()>1))){
			wl=adlib.internal.methods.doFilters(wl,f);
		}
		return wl;
	},
// processes a subset of nodes for combinator selectors (~,>,+)
// 	wl=existing nodes
//	f = filters
//
	doSubGroup:function(wl,f){
		var c=f[0][1].strip(), g=$C(), t=f[1]["tag"]?f[1]["tag"][0][1]:false;
		if(c==""){
			g=adlib.internal.methods.doCSSGroup(f[1],wl);
		}
		else{
			delete f[1]["tag"];
			if(c=='>'){
				g=g.concat.apply(g,wl.map(function(v){
					return v.childElements(t);
				}));						
			}
			else if(c=="+"){
				wl.forEach(function(v){
					var q=v.$next();
					if(q&&(!t||q._nn()==t)){						
						g.push(q);
					}
				});
			}
			else if(c=="~"){
				var w=$H();
				g=g.concat.apply(g,wl.map(function(v){	
					return (!w[v._uniqueId])?v.$next(t,true).filter(function(i){
						if(!w[i._uniqueId]){
							w[i._uniqueId]=true;
							return true;
						}
						return false;
					}):$C();
				}));
			}
			if(g.length>0&&((f[1].count()>1)||(f[1].count()==1&&!f[1].combinators))){
				g=adlib.internal.methods.doFilters(g,f[1]);
			}
			if(f[1].combinators){
				g=adlib.internal.methods.doSubGroup(g,f[1].combinators);
			}
		}
		return g;		
	},
	// e=element
	// d=direction (next or previous)
	// t=node type
	_getSibling:function(e,d,t){
		while(e=e[d+"Sibling"]){
			if(e.nodeType==Node.ELEMENT_NODE){
				if(!t||($(e)._nn()==t)){
					break;
				}
			}
		}
		return e;
	},
	// e=element
	// s=index number or node
	// b=boolean (true=previous, false=next)
	// t=nodetype (optional)
	_childrenAround:function(e,s,b,t){
		if(isNumber(s)){
			var c=e.childElements(t);
			return b?c.slice(0,start):c.slice(start+1);
		}	
		else{
			var ret=[], tp=b?"previous":"next", r=$(s);
			if(t){t=t.toLowerCase()}
			while(r=r[tp+"Sibling"]){
				if(r.nodeType==Node.ELEMENT_NODE){
					if(!t||(t==$(r)._nn())){					
						ret.push(r);
					}
				}
			}
			return $C(b?ret:ret.reverse());
		}
	},
	// e=element
	// t=node type
	// l=last
	_getSingleChild:function(e,t,l){		
		var r=e[(l?"last":"first")+"Child"];
		if(t){t=t.toLowerCase()}
		while(r&&(r.nodeType!=Node.ELEMENT_NODE||(t&&(t!=$(r)._nn())))){	
			r=r[(l?"previous":"next")+"Sibling"];
		}
		return $(r);
	},
/**************** style internals *********************/
	// el - element
	// wh - "w" (width) or "h" (height)
	// fDim - full dimension (false = content dimensions)
	getDim:function(el,wh,fDim){
		var dim=((wh=="w")?"Width":"Height"),rd=false;
		if(el==document||el==document.documentElement||el==document.body){
			return DOM["getDocument"+dim]();
		}
		if(el.getStyle('display')=='none'){
			el.toggleOn();
			rd=true;
		}
		var r=el["offset"+dim];
		if(!fDim){
			var dirs=((wh=="w")?["Left","Right"]:["Top","Bottom"]);
			r=r-el.getStyle("border"+dirs[0]+"Width").toInt().noNaN()-el.getStyle("border"+dirs[1]+"Width").toInt().noNaN()-el.getStyle("padding"+dirs[0]).toInt().noNaN()-el.getStyle("padding"+dirs[1]).toInt().noNaN();
		}		
		if(rd){
			el.toggleOff();
		}	
		return r;
	},
	// el - element
	// xy - "x" (Left) or "y" (top)
	// cont - remove padding/borders (boolean)
	// local - local (boolean) false=cumulative, or Node
	getLoc:function(el,xy,cont,local){
		var loc=isBoolean(local)?local:(isString(local)||isElement(local))?$(local):adlib.defaults.styles.location.local, cord=((xy=="x")?"Left":"Top"), par=el, ofp=0;
		if(isElement(loc)){
			var ps=loc.getStyle('position');
			if($if(loc,'!=','&&',document,window,document.body,document.documentElement)&&((!DOM.isDescendantOf(el,loc))||(ps!='relative'&&ps!='absolute'))){				
				return null;
			}
			do{
				ofp+=par["offset"+cord]||0;
				par=par.offsetParent;
			}while(par&&par!=loc);
		}
		else if(loc){
			ofp+=par["offset"+cord]||0;
		}
		else{
			do{
				ofp+=par["offset"+cord]||0;
				par=par.offsetParent;
			}while(par);
		}
		if(cont){
			ofp+=el.getStyle("padding"+cord).toInt().noNaN()+el.getStyle("border"+cord+"Width").toInt().noNaN();
		}
		return ofp;
	}	
});








/****************** extend Collections with special content functions *****************/
Class.inherits(Collection.prototype,{
	setHTML:function(c){
		var cs=[];
		if(isElement(c)){
			cs=DOM.makeCopies(c,this.length);
		}
		else{
			cs.fill(c,this.length);
		}
		this.forEach(function(v,k){
			v.setHTML(cs[k]);
		});
		return this;
	}
});
adlib.utilities.make.elementFunction({
	_isExtended:true,
/************************* content ***************************/
	setHTML:function(c){
		this.cleanUp();
		if(!isElement(c)){
			this.innerHTML = c;
			this.$t('*');
		}
		else{
			this.innerHTML="";
			this.appendChild(c);
		}			
		DOM.doStyleEvent('content',this);
		return this;
	},	
	appendContent:function(c){
		DOM.insertInto(this,c,false);
		DOM.doStyleEvent('content',this);
		return this;	
	},
	prependContent:function(c){
		DOM.insertInto(this,c,true);
		DOM.doStyleEvent('content',this);
		return this;	
	},
	// c - content
	// b - before (boolean) optional
	// p - point (node/number/css) optional
	insertContent:function(c,b,p){
		DOM.insertInto(this,c,b,p);
		DOM.doStyleEvent('content',this);
		return this;
	},
	getHTML:function(){
		return this.innerHTML.replace(/_isExtended\="true"/g,'');
	},
	// p - number/css
	deleteElements:function(p){			
		if(isNumber(p)){
			return this.removeChild(this.childAt(p));
		}
		else{
			return $C(this.childElements().filterByCSS(p).map(function(v){
				return this.removeChild(v);
			},this));
		}
		DOM.doStyleEvent('content',this);
	},
/*********************** searching ************************/
	$:function(){		
		var a=window.$($A(arguments)), r=null;
		if(a){
			if(isCollection(a)){	
				r=a.map(function(v){
					return (v&&DOM.isDescendantOf(v,this))?v:null;
				},this);
				return (r.length>1?r:r[0]);
			}
			r=DOM.isDescendantOf(a,this)?a:null;
		}
		return r;
	},
	// element type, ....
	$t:function(a){
		var z;		
		if(arguments.length>1){
			a=$A(arguments);
			z=$C(this.getElementsByTagName('*'));
			if(z.length>0&&z[0].nodeType!=Node.ELEMENT_NODE){
				z.shift();
			}
			z=z.filter(function(val){
				var n=$(val)._nn();
				for(var x=0; x<a.length; x++){
					if(n==a[x].toLowerCase()){
						return true;
					}
				}
				return false;
			});			
		}
		else{
			z=$C(this.getElementsByTagName(a));
			if(a=='*'&&z.length>0&&z[0].nodeType!=Node.ELEMENT_NODE){
				z.shift();
			}
		}		
		DOM.extend(z);
		return z;
	},
	// c - classname
	// element type, ....
	$c:function(c){//works
		return (arguments.length>1?this.$t.apply(this,$A(arguments).slice(1)):this.$t('*')).filter(function(v){
			return v.className.contains(c,true);
		});			
	},
	// a - attribute
	// v - value (optional)
	// element type, ....
	$a:function(a,val){
		return (arguments.length>2?this.$t.apply(this,$A(arguments).slice(2)):this.$t('*')).filter(function(n){
			var d,v=val;
			if(isValidText(val)){
				d='=';
				if(val.match(/^[~\|\^\$\*\!]/)){
					v=val.substring(1);
					d=val.charAt(0);						
				}
			}
			return adlib.internal.methods.checkAttributeStatus(n,a,v,d);
		});		
	},
	// number
	// or
	//
	// css
	// count (optional
	$anc:function(){
		var obj=null;
		if(isNumber(arguments[0])){
			obj=this;
			for(var x=0; x<arguments[0]; x++){
				obj=obj.$parent();
				if(obj==document){
					break;
				}
			}
		}
		else if(isString(arguments[0])){
			var nds=this.$ancestors().filterByCSS(arguments[0]);
			var cnt=(isNumber(arguments[1]))?arguments[1]:1;
			obj=nds[cnt-1]?nds[cnt-1]:null;
		}		
		return obj;
	},
	$ancestors:function(){
		var r=$C(),p=this.$parent();
		while(p&&p!=document){
			r.push(p);
			p=p.$parent();
		}
		return r;
	},
		
	$css:function(cssStr){		
		var _t=this.nodeType==Node.ELEMENT_NODE?this:document, n=$C([_t]), gs=adlib.internal.methods.parse(cssStr), d=0,t=$C();
		// loop through each CSS strings 
		var an=gs.map(function(g){			
			if(g.count()==1){
				if(g.tag){
					return _t.$t(g.tag[0][1]);
				}
				else if(g.id){					
					var i=_t.$(g.id[0][1]);
					return i?$C(i):$C();
				}
			}
			r=adlib.internal.methods.doCSSGroup(g,n);
			if(r.length>0){d++}
			return r;
		});		
		t=t.concat.apply(t,an);
		if(d>1){
			t.removeDuplicates();
		}
		return t;
	},
	// t - type (optional)
	first:function(t){
		return adlib.internal.methods._getSingleChild(this,t,false);
	},
	// t - type (optional)
	last:function(t){
		return adlib.internal.methods._getSingleChild(this,t,true);
	},
	// f - factor
	// t - type (optional)
	// last - boolean
	nth:function(f,t,l){	
		return	adlib.internal.methods.getNth(this,f,isBoolean(l)?l:false,t);
	},
	$parent:function(){
		return $(this.parentNode);
	},
	// t - type (optional)
	// a - all (boolean)
	$next:function(t,a){
		return (a?this.$parent().childrenAfter(this,t):adlib.internal.methods._getSibling(this,'next',t));
	},	
	// t - type (optional)
	// a - all (boolean)
	$previous:function(t,a){
		return (a?this.$parent().childrenBefore(this,t):adlib.internal.methods._getSibling(this,'previous',t));
	},
	// o - of-type (boolean)
	onlyChild:function(o){
		return this==document?true:(this.$parent().childElements((o?this._nn():null)).length==1);
	},
	isEmpty:function(){
		if(this.childNodes.length!=0){
			for(var x=0,c=this.childNodes; x<c.length; x++){
				var t=c[x].nodeType;
				if(t==Node.ELEMENT_NODE||(t>=Node.TEXT_NODE&&t<=Node.ENTITY_NODE&&c[x].nodeValue.length>0)){
					return false;
				}
			}
		}
		return true;
		
	},
	// t - type (optional)
	childElements:function(t){
		var r=$C(),c=this.childNodes;
		if(t){t=t.toLowerCase()}
		for(var x=0; x<c.length; x++){
			if(c[x].nodeType==Node.ELEMENT_NODE){
				if(!t||t==$(c[x])._nn()){
					r.push($(c[x]));
				}
			}
		}
		return r;	
	},
	// e - element/number
	// t - type (optional)
	childrenBefore:function(e,t){
		return adlib.internal.methods._childrenAround(this,e,true,t);
	},
	// e - element/number
	// t - type (optional)
	childrenAfter:function(s,t){
		return adlib.internal.methods._childrenAround(this,s,false,t);
	},
	// p - point (number)
	// l - last (boolean) optional
	// t - type (optional)
	childAt:function(p,l,t){
		var r=this.childElements(t);
		if(l){
			r.reverse();
		}
		return r[p]?$(r[p]):null;
	},
	_nn:function(){
		return this.nodeName.toLowerCase();
	},
/************************ events and behaviors *********************/
	// e=event Type
	// cp= capture
	// cn=cancel
	// s=stop
	attach:function(e,cp,cn,s){
		Events.attach(this,e,cp,cn,s);
		return this;
	},

	// i=event ID (number) or event type (string)
	detach:function(i){
		if(isNumber(i)){
			Events.detach(i);
		}
		else{
			Events.detach(this,i);
		}
		return this;
	},
	cleanUp:function(){
		Events.cleanUp(this);
		return this;
	},

	// a=behavior or array of behaviors
	runBehavior:function(a){
		Behaviors.run(a,this);
		return this;
	},

	// e=event type
	// p=properties
	// c=cancelable
	// b=bubbles
	send:function(e,p,c,b){
		Events.send(e,this,p,c,b);
		return this;
	},
/************************** styles: setting******************/
	setStyle:function(s,v){
		if(s=="opacity"){
			this.setOpacity(v);
		}
		else{
			s=s.camelize();
			this.style[s]=($if(s,'==','||',"width","height","top","left")&&isNumber(v))?v+'px':(s.contains('Image')&&!v.startsWith('url('))?'url('+v+')':v;
			DOM.doStyleEvent('css',this,s);			
		}
		return this;
	},
	// string/hash/object
	applyStyle:function(sText){
		(isHash(sText)?sText:isString(sText)?sText.toHash([';',':']):$H(sText)).forEach(function(val,key){
			this.setStyle(key,isNumber(val)?val:val.toString());
		},this);
		return this;
	},
	setOpacity:function(v){	
		v=v.toFloat(),o="opacity";
		// handle IE
		if($test(this.filters)){
			if(v<=1){
				v*=100;
			}
			var t="DXImageTransform.Microsoft.Alpha";
			if(this.filters[t]!=null){
				this.filters.item(t)[o]=v;
			}	
			else{
				this.style.filter+="progid:"+t+"("+o+"="+v+")";
			}
		}else{	
			if(v>1){
				v/=100;
			}
			this.style[o]=v;
		}	
		DOM.doStyleEvent('css',this,o);
		return this;
	},
	setWidth:function(v){
		return this.setStyle('width',v);
	},
	setHeight:function(v){
		return this.setStyle('height',v);
	},
/************************** styles: getting******************/	
	// stylename, default value
	getStyle:function(s,de){
		s=s.camelize();
		var tmp=de||null,t=this;
		if($if(s,'==','||','opacity','width','height')){
			tmp=t['get'+s.capitalize()]();
		}
		else{
			var d=document.defaultView;
			if(d){
				var a=d.getComputedStyle(t,null);
				if(a&&a[s]){
					tmp=a[s];	
				}
			}
			else{
				tmp=(t.currentStyle&&t.currentStyle[s])?t.currentStyle[s]:(t.style[s])?t.style[s]:tmp;
			}
		}		
		return tmp;
	},
	getOpacity:function(){
		if($test(this.filters)){
			var a=this.filters["DXImageTransform.Microsoft.Alpha"];
			if(a!=null){
				return a.opacity;
			}
			return 100;
		}
		else{
			var v=100, s=Object.selectProperty(this.style,"opacity","MozOpacity","KhtmlOpacity")||'opacity', t=this.style[s].toFloat();
			if(isNumber(t)){
				v=t*100;
			}
			return v;
		}
		return null;
	},
	getWidth:function(){
		return adlib.internal.methods.getDim(this,'w',false);
	},
	getHeight:function(){
		return adlib.internal.methods.getDim(this,'h',false);
	},

	getFullWidth:function(){
		return adlib.internal.methods.getDim(this,'w',true);
	},

	getFullHeight:function(){
		return adlib.internal.methods.getDim(this,'h',true);
	},
/************************** styles: classes******************/		
	setClass:function(c){
		this.className=c;
		DOM.doStyleEvent('class',this);	
		return this;
	},
	getClassName:function(){
		return this.className;
	},
	addClass:function(c){
		if(!this.hasClass(c)){
			this.className+=' '+c;
			DOM.doStyleEvent('class',this);	
		}
		return this;
	},
	removeClass:function(c){	
		var cls=this.className.strip();
		if(cls.contains(c,true)){
			if(cls==c){
				cls="";
			}
			else{			
				var h=cls.toHash(' ');	
				delete h[c];
				cls=h.keys().join(' ');
			}
			this.className=cls;
			DOM.doStyleEvent('class',this);	
		}
		return this;	
	},
	// remove, add
	replaceClass:function(r,a){
		var cls=this.className.strip(), h=cls.toHash(' '), f=false;
		if(isString(h)){
			if(h==r){
				cls=a;
				f=true;
			}
		}
		else if(h.hasKey(r)){
			delete h[r];
			var k=h.keys();
			k.push(a);
			cls=k.join(' ');
			f=true;
		}
		if(f){
			this.className=cls;	
			DOM.doStyleEvent('class',this);	
		}
		return this;
	},
	// remove, add
	rAddClass:function(r,a){
		var c=this.className.strip(), h=c.toHash(' ');
		if(isString(h)){
			c=((h==r)?a:h+' '+a);
		}
		else{
			if(h.hasKey(r)){	
				delete h[r];
			}
			var k=h.keys();
			k.push(a);
			c=k.join(' ');
		}
		this.className=c;
		DOM.doStyleEvent('class',this);	
		return this;	
	},
	toggleClass:function(c){
		this.className.contains(c,true)?this.removeClass(c):this.addClass(c);
		return this;		
	},
	hasClass:function(c){
		return this.className.contains(c,true);
	},

/************************** styles: display******************/	
	toggle:function(){
		var d=this.getStyle("display");
		if(d=="none"){
			this.style.display=(this._oldDisplay != null)?this._oldDisplay:DOM.getDefaultDisplay(this);
			this._oldDisplay = null;
		}
		else{
			this._oldDisplay=d;
			this.style.display="none";
		}
		DOM.doStyleEvent('css',this,'display');
		return this;
	},	
	toggleOn:function (){
		if(this.getStyle("display")=="none"){
			this.style.display=(this._oldDisplay != null)?this._oldDisplay:DOM.getDefaultDisplay(this);
			this._oldDisplay = null;
		}
		DOM.doStyleEvent('css',this,'display');
		return this;
	},	
	toggleOff:function(){
		var d=this.getStyle("display");
		if(d!='none'){		
			this._oldDisplay=d;
			this.style.display="none";
		}
		DOM.doStyleEvent('css',this,'display');
		return this;
	},
	show:function(){
		return this.setStyle('visibility','visible');
	},
	hide:function(){
		return this.setStyle('visibility','hidden');
	},
	toggleVis:function(){
		return this.setStyle('visibility',this.getStyle('visibility')=='hidden'?'visible':'hidden');
	},
	
/************************** styles: position******************/
	setTop:function(v){
		return this.setStyle('top',v);
	},
	setLeft:function(v){
		return this.setStyle('left',v);
	},
	moveTo:function(x,y){
		return this.setStyle('left',x).setStyle('top',y);
	},
	moveBy:function(x,y){
		return this.setStyle('left',this.getLeft(true)+x).setStyle('top',this.getTop(true)+y);
	},
	// l - local (boolean/element) optional
	getTop:function(l){
		return adlib.internal.methods.getLoc(this,'y',false,l);
	},
	// l - local (boolean/element) optional
	getLeft:function(l){
		return adlib.internal.methods.getLoc(this,'x',false,l);
	},
	// l - local (boolean/element) optional
	getContentTop:function(l){
		return adlib.internal.methods.getLoc(this,'y',true,l);
	},
	// l - local (boolean/element) optional
	getContentLeft:function(l){
		return adlib.internal.methods.getLoc(this,'x',true,l);
	},
/************************** styles: centering******************/
	getCenterX:function(s){
		s=isBoolean(s)?s:true;
		var o=(this==window||this==document||this==document.body)?adlib.documentElement:this;
		return (((o==adlib.documentElement)?DOM.getViewWidth():o.getFullWidth())/2).floor()+(s?o.scrollLeft.toInt():0);
	},
	getCenterY:function(s){
		s=isBoolean(s)?s:true;
		var o=(this==window||this==document||this==document.body)?adlib.documentElement:this;
		return (((o==adlib.documentElement)?DOM.getViewHeight():o.getFullHeight())/2).floor()+(s?o.scrollTop.toInt():0);
	},
	// gets the center point of an element
	getCenter:function(s){
		return [this.getCenterX(s),this.getCenterY(s)];
	},
	// centers the element horizontally in relation to its offsetParent
	centerX:function(t){
		var xt=t?$(t).getLeft(this.offsetParent):null;
		return this.setLeft((xt?xt+$(t).getCenterX(t?DOM.isDescendantOf(this,t):false):this.offsetParent.getCenterX())-this.getFullWidth()/2);
	},
	// centers the element vertically in relation to its offsetParent
	centerY:function(t){
		var xt=t?$(t).getTop(this.offsetParent):null;
		return this.setTop((xt?xt+$(t).getCenterY(t?DOM.isDescendantOf(this,t):false):this.offsetParent.getCenterY())-this.getFullHeight()/2);
	},
	center:function(t){
		return this.centerX(t).centerY(t);
	},

/******************************* element caching **********************/
	store:function(property,value){
		if(isString(property)){
			property=this._uniqueId+'.'+property;
		}
		else{
			property.unshift(this._uniqueId);
		}
		Object.setChild(adlib.cache,property,value);
		return this;
	},
	getStore:function(property){
		if(isString(property)){
			property=this._uniqueId+'.'+property;
		}
		else{
			property.unshift(this._uniqueId);
		}
		return Object.hasProperty(adlib.cache,property);
	},
	deleteStore:function(property){
		if(isString(property)){
			property=this._uniqueId+'.'+property;
		}
		else{
			property.unshift(this._uniqueId);
		}
		Object.deleteChild(adlib.cache,property);
		return this;
	}
},false);




adlib.internal.vars.Events={
 	items:$H(),
	assignedEvents:$H(),
	customIE:$H()
}; 
 
/*******************  Events **************************************/

Class.inherits(Events,{	
	customIE:$H(),
	// i = event id
	// en = event type
	// function, ....function
	add:function(i,en){
		adlib.internal.vars.Events.items[i]=new Events.Event(en);
		for(var x=2; x<arguments.length; x++){
			this.inQ(i,arguments[x]);
		}
	},
	// i = event id
	remove:function(i){
		var _t=this;
		adlib.internal.vars.Events.assignedEvents.forEach(function(v,k){
			if(v._id==i){
				_t.detach(k);
			}
		});
		delete adlib.internal.vars.Events.items[i];			
	},
	// i = event id
	// function,...function
	inQ:function(i){
		for(var x=1; x<arguments.length;x++){
			adlib.internal.vars.Events.items[i].queue.push($F(arguments[x]));
		}
	},
	// i = event id
	// f = function
	// a = all (default=true)
	deQ:function(i,f,a){
		a=isBoolean(a)?a:true;
		for(var x=0; x<adlib.internal.vars.Events.items[i].queue.length; x++){
			var fn=adlib.internal.vars.Events.items[i].queue[x].getFunction();
			if(fn==f||String(fn)==String(f)){
				delete adlib.internal.vars.Events.items[i].queue[x];
				if(!a){		
					break;
				}
			}
		}		
		adlib.internal.vars.Events.items[i].queue.normalize();
	},
	// nn = new id
	// on = old id
	// ne = type (optional)
	clone:function(nn,on,ne){
		this.add(nn,(ne||adlib.internal.vars.Events.items[on].eventType));
		adlib.internal.vars.Events.items[nn].queue=adlib.internal.vars.Events.items[on].queue.clone();
	},
	//	e=element
	//	i=id of the event Queue	
	//  cap=capture (boolean)
	//  can= cancel (boolean)
	//  s=stop (boolean)
	makeAssignedEventObject:function(e,i,cap,can,s){	
		var t=getRandomId();
		adlib.internal.vars.Events.assignedEvents[t]={
				_el:$(e), 
				_id:i,
				_capture:isBoolean(cap)?cap:false,
				_cancel:isBoolean(can)?can:false,
				_stop:isBoolean(s)?s:false,
				_run:$F(function(e,i,t){adlib.internal.vars.Events.items[i].run(e,adlib.internal.vars.Events.assignedEvents[t])},[i,t])			
			};
		return t;
	},
	// e - element
	// i - event id
	// cap - capture
	// can - cancel
	// s - stop
	attach:function(e,i,cap,can,s){
		e=$C($(e)).prune();
		var tr=[];
		var evs=adlib.internal.vars.Events.assignedEvents.filterKeys(function(v){
			return (v._id==i);
		});
		e.forEach(function(n,k){
			if(!evs.some(function(ek){
				return (adlib.internal.vars.Events.assignedEvents[ek]._el==n);
			})){
				tr[k]=Events.makeAssignedEventObject(n,i,cap,can,s);
				var ev=adlib.internal.vars.Events.assignedEvents[tr[k]];
				if(document.addEventListener){// if w3c
					n.addEventListener(adlib.internal.vars.Events.items[i].eventType,ev._run,ev._capture);
				}
				else{// assume IE
					if(ev._capture){
						n.setCapture();
					}
					n.attachEvent("on"+adlib.internal.vars.Events.items[i].eventType,ev._run);
					if(n["on"+adlib.internal.vars.Events.items[i].eventType]===undefined){
						var cie=n.getStore('Events.'+adlib.internal.vars.Events.items[i].eventType);
						if(!cie){
							n.store('Events.customIE.'+adlib.internal.vars.Events.items[i].eventType+'.'+tr[k],true);
						}
						else{
							cie.push(tr[k]);
						}
					}
				}
			}
		});
		return (tr.length==1)?tr[0]:tr;
	},
	// e - event id
	// or
	// el - element
	// et - event type
	detach:function(){
		var i=[], ar=$A(arguments), nds=$(ar[0]), el=null;
		if(isElement(nds)||nds==document||nds==window){
			el=$C(nds);
		}
		else if(isCollection(nds)){
			el=nds.prune();
			if(el.length==0){
				el=null;
			}
		}
		if(el){
			ar.shift();
		}
		i=ar.flatten();		
		if(!/e\d{7,}/.test(i[0])){// if first item does not match an ID, assume eventTypes
			var a=(i.indexOf('*')!=-1);
			i=adlib.internal.vars.Events.assignedEvents.filterKeys(function(v){
				return ((el.indexOf(v._el)!=-1)&&(a||(i.indexOf(adlib.internal.vars.Events.items[v._id].eventType)!=-1)||(i.indexOf(v._id)!=-1)));
			});
		}	
		if(document.removeEventListener){//if w3c
			i.forEach(function(v){
				adlib.internal.vars.Events.assignedEvents[v]._el.removeEventListener(adlib.internal.vars.Events.items[adlib.internal.vars.Events.assignedEvents[v]._id].eventType,adlib.internal.vars.Events.assignedEvents[v]._run,adlib.internal.vars.Events.assignedEvents[v]._capture);	
				adlib.internal.vars.Events.assignedEvents[v]=void 0;
				delete adlib.internal.vars.Events.assignedEvents[v];
			},this);
		}
		else{// assume IE		
			i.forEach(function(v){			
				try{
					if(adlib.internal.vars.Events.assignedEvents[v]._capture){
						adlib.internal.vars.Events.assignedEvents[v]._el.releaseCapture();
					}
					adlib.internal.vars.Events.assignedEvents[v]._el.detachEvent("on"+adlib.internal.vars.Events.items[adlib.internal.vars.Events.assignedEvents[v]._id].eventType,adlib.internal.vars.Events.assignedEvents[v]._run);	
				}
				catch(err){	
					try{
						var cie=adlib.internal.vars.Events.assignedEvents[v]._el.getStore('Events.customIE.'+adlib.internal.vars.Events.items[adlib.internal.vars.Events.assignedEvents[v]._id].eventType+'.'+v);
						if(cie){						
							adlib.internal.vars.Events.assignedEvents[v]._el.deleteStore('Events.customIE.'+adlib.internal.vars.Events.items[adlib.internal.vars.Events.assignedEvents[v]._id].eventType+'.'+v);
						}
					}
					catch(e){
						if(!adlib.pageUnloading){
							throw e;
						}
					};
				}
				adlib.internal.vars.Events.assignedEvents[v]=void 0;
				delete adlib.internal.vars.Events.assignedEvents[v];
			},this);
		}	
		
	},	
	// nd- node (option)
	cleanUp:function(nd){
		nd=$C($(nd||document)).prune();
		var _t=this;
		nd.forEach(function(n){			
			adlib.internal.vars.Events.assignedEvents.forEach(function(v,k){
				if(n==document||(v._el&&DOM.isDescendantOf(v._el,n))){
					_t.detach(k);
				}
			});
		});
	},
	// e - event
	stop:function(e){//stopBubble
		if(e.stopPropagation){
			e.stopPropagation();
		}
		else{
			e.cancelBubble=true;
		}
	},
	// e - event
	cancel:function(e){//preventDefault
		if(e.preventDefault){
			e.preventDefault();
		}
		else{
			e.returnValue=false;
		}
	},
	// e - event
	kill:function(e){
		Events.stop(e); 
		Events.cancel(e);
	},
	// et - event type
	// el - element
	// p - properties (optional)
	// c - cancellable (optional)
	// b - bubbles (optional)
	send:function(et,el,p,c,b){
		el=$C($(el)).prune();
		var e=null, c=isBoolean(c)?c:true, b=isBoolean(b)?b:true;		
		el.forEach(function(o){
			if(document.createEvent){
				var e=null;				
				if(et=="click"||et=="mousedown"||et=="mouseup"||et=="mouseover"||et=="mouseout"||et=="mouseup"||et=="mousemove"){
					e=document.createEvent("MouseEvents");
					e.initEvent(et,b,c);
				}
				else{
					try{
						e=document.createEvent("Events");
						e.initEvent(et,b,c);
					}
					catch(err){
						e=document.createEvent("UIEvents");
						e.initUIEvent(et,b,c,window,1);
					}
				}
				if(p){
					Class.inherits(e,p);
				}
				o.dispatchEvent(e);
			}
			else{
				e=document.createEventObject();
				if(p){
					Class.inherits(e,p);
				}
				try{
//				if(o["on"+et]!==undefined){
					o.fireEvent("on"+et,e);
				}
//				else{					
				catch(err){
					var i;	
					e.type=et;
					var p=o.getStore('Events.customIE.'+et);
					if(p){
						for(var x in p){
							adlib.internal.vars.Events.assignedEvents[x]._run(e);
						}
						o=o.$parent();
						if(b&&o&&o!=document&&o!=window&&(e.returnValue!=false||!c)){
							this.send(et,o,p,c,b);
						}
					}
				}
			}		
		},this);
	}	
	
});


Events.Event=Class.create({
	// e=event type
	init:function(e){
		this.eventType=e;
		this.queue=[];
	},
	// e=event object
	// ae=assigned event object
	run:function(e,ae){
		//fix for safari botching custom events
		if(e.type!=this.eventType||ae==null){return}
		if(ae._stop){
			Events.stop(e);
		}
		if(ae._cancel){
			Events.cancel(e);
		}
		// Normalize event properties in IE
		if(adlib.browser.ie){
			e.target=e.srcElement;
			e.relatedTarget=(e.fromElement)?e.fromElement:e.toElement;		
			if(e.clientX){
				e.pageX=e.clientX+DOM.getScrollX();
				e.pageY=e.clientY+DOM.getScrollY();
			}
		}		
		if(!e.stopExecution){		
			this.queue.forEach(function(v){
					v(e,ae._el);
			});
		}
	}
});



Events.Button={
	left:(adlib.browser.ie)?1:0,
	none:(adlib.browser.ie)?0:null,
	right:2,
	middle:(adlib.browser.ie)?4:1
};


/************************	Behaviors	******************************/
var Behavior=Class.create({
	init:function(o){
		this.css=o.css;
		this.events=$H(o.events);
		this.runnow=o.exec?$A(o.exec):[];
	},
	exec:function(t){
		var _t=this;
		t=t||document;		
		(isCollection(this.css)?this.css:$(t).$css(this.css)).forEach(function(n){
			_t.runnow.forEach(function(f){
				f(n);
			});
			_t.events.forEach(function(v,k){
				var a=[n,k];
				if(isArray(v)){
					a.push.apply(a,v);
				}
				Events.attach.apply(Events,a);
			});			
		});	
	},
	setCss:function(css){		
		this.css=css;
	}
});

Class.inherits(Behaviors,{
	run:function(a,t){
		var x=$A(arguments[arguments.length>2?2:0]).flatten(), y=((arguments.length>2)?((arguments[3])?arguments[3]:document):((t)?t:document));	
		x.forEach(function(v){
			v.exec(y);
		});
	},	
	runAtLoad:function(){
		Behaviors.run(arguments[2]=="DOM"?adlib.internal.vars.DOMLoadBehaviors:adlib.internal.vars.BodyLoadBehaviors);
	},
	addToDOMLoad:function(){
		adlib.internal.vars.DOMLoadBehaviors.push.apply(adlib.internal.vars.DOMLoadBehaviors,$A(arguments).flatten());
	},
	addToBodyLoad:function(){
		adlib.internal.vars.BodyLoadBehaviors.push.apply(adlib.internal.vars.BodyLoadBehaviors,$A(arguments).flatten());
	}
});


Events.add('DOMLoad','DOMContentLoaded');
Events.add('BodyLoad','load',{f:Behaviors.runAtLoad,p:["Body"]});
Events.add('BodyUnLoad','unload');
Events.add('clickAutoStop','click',function(ev){Events.cancel(ev)});
Events.clone('submitAutoStop','clickAutoStop','submit');






// fix DOMLoad for opera (<9) and safari (<3)
if((adlib.browser.safari&&adlib.browser.v<3)||(adlib.browser.opera&&adlib.browser.v<9)){
	(function(){
		if(/loaded|complete/.test(document.readyState)){
			Events.send('DOMContentLoaded',document);
			return;
		}
		else{
			setTimeout(arguments.callee,1);
		}
	})();
}
// fix DOMLoad for IE
if(adlib.browser.ie){
	adlib.internal.vars.startSize=0;
	adlib.testDOMLoad=function(force){
		if(!adlib.DOMisLoaded){
			if(((adlib.internal.vars.startSize!=0)&&(document.body.innerHTML.length==adlib.internal.vars.startSize))||(force)){
				Events.send('DOMContentLoaded',document);
				delete adlib.internal.vars.startSize;
			}
			else{
				adlib.internal.vars.startSize=document.body.innerHTML.length;
				setTimeout(adlib.testDOMLoad,25);
			}
		}
	};		
	dwl('<scr'+'ipt defer id="testing123" src="//:" onreadystatechange="(function(el){if(el.readyState === \'complete\'){adlib.testDOMLoad(); el.parentNode.removeChild(el);}})(this)"></sc'+'ript>');
	Events.inQ('BodyLoad',function(){adlib.testDOMLoad(true)});
}



/**** init DOM shortcuts *****/
adlib.utilities.make.globalSearchFunction(['$css','$t','$c','$a']);

/*** init Element inheritance ****/
if(adlib.ElementSupported){
	DOM.doExtending(Element.prototype);
}
DOM.doExtending(document);

/**** init events ******/
Events.attach(document,'DOMLoad');
Events.attach(window,'BodyLoad');
Events.attach(window,'BodyUnLoad');	
Events.inQ('DOMLoad',function(){
	adlib.DOMisLoaded=true; 
	$t('*');
	document.body.addClass('DOMLoaded');
	Events.inQ('BodyUnLoad',function(){Events.inQ('BodyUnLoad',adlib.internal.methods.cleanseAll)});
},{f:Behaviors.runAtLoad,p:["DOM"]});	
Events.inQ('BodyLoad',function(){
	document.body.addClass('BodyLoaded');
});
(function(){
	var f=arguments.callee;
	if(document.body){
		$(document.body).addClass('adlib');
	}
	else{
		setTimeout(f,20);
	}
})();




if(adlib.browser.ie){
	Events.add('adlibCheckJsLoad','readystatechange',function(ev,el){if(el.readyState.match(/loaded|complete/i)){Load.loadedJS[el.id]();}});
}
else{
	Events.add('adlibCheckJsLoad','load',function(ev,el){Load.loadedJS[el.id]()});
}
var Load=!$test(window.Load)?{}:window.Load;
Class.inherits(Load,{
	loadedJS:$H(),
	js:function(src,callback){
		var id="ScriptURL_"+src.toCharCodeArray();
		if(!Load.loadedJS[id]){
			var h=$t('head')[0];
			callback=callback||_Empty;
			Load.loadedJS[id]=callback;
			var s=$e('script',{type:'text/javascript',src:src,id:id});
			if(adlib.browser.opera||(adlib.browser.safari&&adlib.browser.v<=2)){
				h.appendChild(s);
				(function(id){
					var a=arguments.callee;
					if(document.readyState.match(/loaded|complete/i)){
						Load.loadedJS[id]();
					}
					else{
						setTimeout(10,function(){a(id)});
					}
						
				})(id);
			}
			else{
				s.attach('adlibCheckJsLoad');
				h.appendChild(s);
			}
		}
		else{
			Load.loadedJS[id]();
		}
		return id;
	},
	css:function(src,id){
		var s=$t('head')[0].appendChild($e('link',{href:src,type:"text/css",rel:"stylesheet"}));
		if(id){
			s.setAttribute('id',id);
		}
	},	
	images:function(o,callback,status){
		var cb=callback||_Empty,st=status||_Empty,id=getRandomId('ImageLoader');
		o=isString(o)?[o]:o;
		var obj={
			callback:cb,
			images:[],
			status:st,			
			loaded:0,
			doStatus:function(ev,el){
				this.loaded++;
				this.status(this.loaded,this.images.length,el,el.order);
				if(this.loaded==this.images.length){
					this.callback(this.images);							
					Events.remove(id);		
				}
			}
		};
		Events.add(id,'load',$F({f:obj.doStatus,o:obj}));
		o.forEach(function(v,k){
			var i=new Image();
			i.order=k;
			Events.attach(i,id);
			i.src=v;
			obj.images.push(i);
		});
	}	
},true);

var XHR=!$test(window.XHR)?{}:window.XHR;
Class.inherits(XHR,{
	init:function(){
		this.addRequestType('form','application/x-www-form-urlencoded',this.buildQuery);
		this.addRequestType('xml','text/xml');
		this.addRequestType('text','text/plain');
		this.addRequestType('json','text/plain');
		this.addRequestType('html','text/html');
		this.globalHandler=this.pasteImport;
		if(window.Logs&&window.Logs.addLog){
			Logs.addLogType('XHR-requests',false,['Id','Action','Data','Lock']);
			Logs.addLogType('XHR-errors',false,['ID','Message','Ready State','Status Code','Headers','Response Text']);
			Logs.addLogType('XHR-events',false,['ID','Message']);
			this.log=function(type,params){Logs.addLog("XHR-"+type,params);}
		}
		else{
			this.log=_Empty;
		}
		if(window.XMLHttpRequest) {
			this.openHttpConn=function(){			
				return new XMLHttpRequest();
			};
		}
		else if (window.ActiveXObject){
			this.openHttpConn=function(){
				try {
		 			return new ActiveXObject("Msxml2.XMLHTTP");
					
		 		} catch (e) {
		  			try {
		   				return new ActiveXObject("Microsoft.XMLHTTP");
					} catch (e) {}
				}
			};
		}
		else{
			this.openHttpConn=function(){return false;};
		}
	},
	locked:false,
	lockedId:null,
	requests:$H(),
	pendingRequests:[],
	activeRequests:$H(),
	activeRequestCount:0,
	globalParams:$H(),
	globalHeaders:$H(),
	rTypes:$H(),
	// id, url, options
	addRequest: function(i,u,o){
		this.requests[i]=new XHR.httpRequest(u,o);
		this.log('events',[i,'Add Request']);
		return this.requests[i];
	},
	// name, value
	addGlobalParam: function(n,v){
		this.globalParams[n]=v;
		this.log('events',['Global','Add Global Param: '+n]);
	},
	// name, value
	addGlobalHeader: function(n,v){
		this.globalHeaders[n]=v;
		this.log('events',['Global','Add Global Header: '+n]);
	},
	// a "send object"
	queueRequest: function(o){
		this.pendingRequests.push(o);
		this.log('events',[o.id,'Queue Request']);
	},
	// id
	send: function(i){
		this.makeHttpCall(this.requests[i]);
	},
	// a request object	
	quickSend: function(o){
		var o1=$H(o).cut('method','requestType','timeout','target','handler','data');
		this.addRequest(o.id,o.url,o1);				
		var o2={
			id:o.id,
			lock:($test(o.lock)?o.lock:false),
			asynch:($test(o.asynch)?o.asynch:true),
			username:o.username||null,
			password:o.password||null
		};
		this.makeHttpCall(o2);
	},
// 
// makeHttpCall
// (*internal*) builds the XHMHttpRequest call and sends it to the server 
// 
// parameters:
// (Object) obj - a "send object"
	 makeHttpCall: function(o){
	 	if(this.locked){
			this.queueRequest(o);
			return ;
		}
		var asynch=o.asynch||true;
		var lock=o.lock||false;
		var _this=this;
		var mr=this.openHttpConn();
		if(!mr){
			throw new Error("XHR not supported");
		}
		else{
			this.activeRequests[o.id]=mr;	
			var req=this.requests[o.id], ar=this.activeRequests[o.id], rt=this.rTypes[req.requestType];
			ar.onreadystatechange=function(){
				_this.handleReturn.call(_this,o.id);
			};
			var q='';
			if(req.data){					
				q=req.data;
			}
			else if(rt.typeProcessor!=null){					
				q=rt.typeProcessor.call(this,o.id);
			}			
			var url=req.url;
			req.sentVal=q;
			if((isValidText(q))&&(req.method=="GET")){
				url=url.addParam(q);
				q="";
			}					
			ar.open(req.method,url,asynch,o.username,o.password);
			if(rt!=null){
				ar.setRequestHeader('Content-type',rt.typeEncoding);
			}
			this.globalHeaders.forEach(function(val,key){
				ar.setRequestHeader(key,val);
			});				
			req.headers.forEach(function(val,key){
				ar.setRequestHeader(key,val);
			});				
			this.activeRequestCount++;	
			if(o.lock){
				this.lockRequests(o.id);
			}
			this.startTimer(o.id);
			ar.send(q);
			this.log('requests',[o.id,'start','<xmp>'+req.sentVal+'</xmp>',o.lock]);
		}
	},

	// id, abort code
	closeRequest: function(i,c){
		var a=this.activeRequests[i];
		if(a){
			a.abort();
			this.log('events',[i,'Closing Request: '+c]);
		}
	},
	// id
	deleteRequest: function(i){
		this.requests[i]=void 0;
		delete this.requests[i];
		this.log('events',[i,'Delete request']);
	},	
// 
// startTimer
// (*internal*) starts a timer that will abort the active request when it expires (if the request is not completed)
// 
// parameters:
//  (String) id - the id of the request object to track
	startTimer: function(i){
		var r=this.requests[i];
		var t=(r.timeout!=null)?r.timeout:null;
		if(t){
			r.intervalCode=setTimeout(function(){XHR.requestTimeOutFail(i);},t);
		}
	},
// requestTimeOutFail
// (*internal*) closes an active request if it times out	
// 
	requestTimeOutFail: function(i){
		this.closeRequest(i,"timeout");
		this.requests[i].intervalCode=null;
	},		
// function: lockRequests
// Locks requests with a request ID.  When that ID returns it will unlock.
// 
// parameters:
// 	(String) id - the id of the request object requesting locking status (fails if already locked)
// 
	lockRequests: function(i){
		if(!this.locked){
			this.locked=true;
			this.lockedId=i;
			this.log('events',[i,'Lock']);
		}
	},			
// 
// function: unlockRequests
// Unlocks requests
// 
// parameters:
// (String) id - the id of the request object that is requesting to unlock (fails if it is not the locking id)
// (Boolean) send - whether to send pending/queued requests (true if auto-locked)	
	unlockRequests: function(i,s){
		if((i==this.lockedId)||(!this.activeRequests[i])){
			this.locked=false;
			this.lockedId=null;
			this.log('events',[i,'Unlock']);
			if(s){
				this.sendPendingRequest();
			}						
		}
	},	
// sendPendingRequest
// (*internal*) pulls the next object from the pending requests and sends it.
	sendPendingRequest: function(){
		var p=this.pendingRequests;
		if(p.length>0){
			var pa=p.shift();	
			this.log('events',[pa.id,'DeQueue Pending Request']);				
			this.makeHttpCall(pa);
		}
	},					
// buildQuery
// (*internal*) builds a query string (without the ?) from the local and global parameters of the request object
// 
// returns:
// (String) a query string
// 
	buildQuery: function(i){
		return this.requests[i].params.toQuery(this.globalParams.toQuery(true));
	},
		
	// typename, typeEncoding, processor
	addRequestType: function(tn,te,tp){
		this.rTypes[tn]={
			typeEncoding:te,
			typeProcessor:tp
		}
	},
	getRequest:function(id){
		return this.requests[id];
	},
// handleReturn
// (*internal*) Monitors the state of the request and if readyState=4 and status=0,200-299 passes the request object to the handler function. 
	handleReturn: function(i){	
		var ar=this.activeRequests[i], req=this.requests[i];
		if(ar.readyState==4){
			req.response=ar;
			var st=req.response.status;				
			delete this.activeRequests[i];
			this.log('requests',[i,'finish',req.response.getAllResponseHeaders().split(/\n/g).join(_BR)+'<xmp>'+req.response.responseText+'</xmp>']);
			var resp=req.response, sh=resp.getResponseHeader('XHR-handler'), st=resp.getResponseHeader('XHR-target'), t=isValidText(st)?st:req.target;
			var g=(st==0||st>=200&&st<300);			
			(isValidText(sh)?sh:((req.handler!=null)?req.handler:this.globalHandler))(resp,t,i,g);
			this.unlockRequests(i,true);	
		}			
	},
// pasteImport
// (*internal*) default global handler, just pastes the responseText into the target 
	pasteImport: function(c,t){
		if(c){
			t=$(t);
			if(t!=null){
				t.setHTML(c.responseText);					
			}			
		}
	}
},true);


XHR.httpRequest=Class.create();

Class.inherits(XHR.httpRequest.prototype,{
	// url, options
	init:function(u,o){
		this.url=u;
		this.params=$H();
		this.method='GET';	
		this.requestType='form';
		this.target=null;
		this.handler=null;
		this.headers=[];
		this.timeout=null;
		this.data=null;
		this.sentVal=null;
		this.intervalCode=null;
		this.connection=null;
		this.response=null;
		if(o){
			Class.inherits(this,o,true);
		}
	},
	// name, value
	addHeader: function(l,v){
		this.headers[l]=v;
	},
	// name, value
	addParam: function(p,v){
		this.params[p]=v;
	}
});
(function(){
	var a=["url","method","requestType","target","handler","requestTimeout","data"];
	for(var x=0; x<a.length; x++){
		Class.method(XHR.httpRequest.prototype,"set"+a[x].capitalize(),function(v){this[a[x]]=v},true);
	}
})();

XHR.init();
adlib.internal.vars.cleanseStack.push("XHR");



var Color=Class.create({
	init:function(){
		this.value=Color.parse.apply(this,$A(arguments));
	},
	getRed:function(){
		return this.value[0];
	},	
	getGreen:function(){
		return this.value[1];
	},
	getBlue:function(){
		return this.value[2];
	},
	setRed:function(r){
		this.value[0]=r.bound(0,255);
	},	
	setGreen:function(g){
		this.value[1]=g.bound(0,255);
	},	
	setBlue:function(b){
		this.value[2]=b.bound(0,255);
	},
	normalize:function(){
		this.value.exec(function(v){return v.bound(0,255)});
	},
	toRgb:function(){
		return 'rgb('+this.value[0]+','+this.value[1]+','+this.value[2]+')';
	},
	add:function(){
		var vs=isArray(arguments[0])?arguments[0]:isNumber(arguments[0])?[arguments[0],arguments[0],arguments[0]]:isColor(arguments[0])?arguments[0].toArray():arguments;
		this.values.exec(function(v,k){return v+=vs[k]});
		this.normalize();
		return this.toString();				
	},
	subtract:function(){
		var vs=isArray(arguments[0])?arguments[0]:isNumber(arguments[0])?[arguments[0],arguments[0],arguments[0]]:isColor(arguments[0])?arguments[0].toArray():arguments;
		this.values.exec(function(v,k){return v-=vs[k]});
		this.normalize();
		return this.toString();	
	},
	toHex:function(){
		return "#"+this.value[0].toHex(2)+this.value[1].toHex(2)+this.value[2].toHex(2);
	},
	toArray:function(){
		return this.value;
	}
});
Class.method(Color.prototype,"toString",Color.prototype.toHex,true);

Color.parse=function(){
	var a=$A(arguments),vals;
	if(isColor(a[0])){
		return a[0].toArray();
	}
	if(a.length==1&&!isArray(a[0])){	
		if(a[0]=="transparent"){
			a[0]=adlib.defaults.color.transparentColor;
		}	
		function matchRGB(n){
			var t=n.replace(/\s/g,'').match(/^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/);
			if(t){
				t.shift();
				return t.map(function(v){
					return v.toInt().noNaN();
				});
			}
			return false;
		};
		function matchHex(n){		
			var t=n.strip().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/);
			if(t){
				if(t[1].length==3){
					
					return t[1].split('').map(function(v){return (v+v).toInt(16)});
				}
				var r=/([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})/.exec(t[1]);
				if(r){
					r.shift();
					return r.map(function(v){return v.toInt(16)});
				}
			}
			return false;
		};
		if(isNumber(a[0])){		
			vals=[a[0],a[0],a[0]];	
		}
		else{			
			a[0]=a[0].toLowerCase();	
			if(Color.NamedColors[a[0]]){
				a[0]=Color.NamedColors[a[0]];
			}
			vals=matchHex(a[0]);
			if(!vals){
				vals=matchRGB(a[0]);
				if(!vals){
					vals=a[0].toInt(16).noNaN();
					vals=[vals,vals,vals];
				}
			}
		}
	}
	else{
		vals=(a.length==1?a[0]:a).map(function(v){return v.toInt(16)});
	}
	return vals.map(function(v){return v.bound(0,255)});
};

Color.partToNum=function(n){
	return n.toInt(16);
};

adlib.internal.vars.typeChecking.unshift('Color');
function isColor(c){
	return c instanceof Color;
};

adlib.defaults.color={
	transparentColor:'#fff'
};

Color.NamedColors=$H({
	black:'#000',
	blue:'#00f',
	silver:'#c0c0c0',
	grey:'#808080',
	white:'#fff',
	maroon:'#800000',
	red:'#f00',
	purple:'#800080',
	fuschia:'#f0f',
	green:'#008000',
	lime:'#0f0',
	olive:'#808000',
	yellow:'#ff0',
	navy:'#000080',
	teal:'#008080',
	aqua:'#0ff'	
});









adlib.defaults.fx={
	steps:20,
	interval:50,
	autoDelete:true
};
adlib.internal.vars.fx={
	storedTweens:$H(),
	FLOAT_UNITS:['pt','em']
};
adlib.internal.methods.fx={
	getStartValue:function(el,style,v){
		var s=null;
		if(!$test(v)){
			s=el.getStyle(style);
		}
		else if(isFunction(v)){
			s=v(el,style);
		}
		else{
			s=v;
		}
		var r=[s,""];
		if(!isNumber(s)&&!isColor(s)){
			if(style.match(/color/i)){
				r[0]=new Color(s);
			}
			else{
				r[0]=s.toFloat();
				r[1]=s.substring((""+r[0]).length);
			}
		}
		return r;			
	},
	getEndValue:function(el,style,eVal,sVal){
		var e=(isFunction(eVal))?eVal(sVal,style,el):eVal;
		if(style.match(/color/i)){
			e=new Color(e);
		}		
		return e;
	},
	getSteps:function(el,stylename,start,end,steps,tween){		
		var s=adlib.internal.methods.fx.getStartValue(el,stylename,start);
		end=adlib.internal.methods.fx.getEndValue(el,stylename,end,s[0]);
		var res={
			start:s[0],
			end:end,
			unit:s[1],
			steps:(stylename.match(/color/i)?fx.tweenColor(s[0],end,steps,tween):fx.tween(s[0],end,steps,(adlib.internal.vars.fx.FLOAT_UNITS.indexOf(s[1])==-1),tween))
		};
		return res;
	}
};

Math.linear=function (b,c,s) {
	return b+(c*s);
};
fx.tween=function(s,e,n,r,t,st){
	s=s.toInt(),e=e.toInt(),t=t||'linear',r=isBoolean(r)?r:true, d=(e-s)/n, st=isBoolean(st)?st:true, tmp=[];
	a="Tween"+("start"+s+"end"+e+"steps"+n+"round"+r+"tween"+t).toCharCodeArray();
	if(!adlib.internal.vars.fx.storedTweens[a]){
		for(var x=1; x<=n; x++){
			tmp[x-1]=(r?Math.round:_Echo)(Math[t](s,d,x,n));
		}
		if(st){
			adlib.internal.vars.fx.storedTweens[a]=tmp;
		}
	}
	else{
		tmp=adlib.internal.vars.fx.storedTweens[a];
	}
	return tmp.clone();
};

fx.tweenColor=function(ti,ta,s,ty){
	var a="Color"+("start"+ti+"end"+ta+"steps"+s+"tween"+(ty?ty:'linear')).toCharCodeArray();
	ti=new Color(ti);
	ta=new Color(ta);
	if(!adlib.internal.vars.fx.storedTweens[a]){
		adlib.internal.vars.fx.storedTweens[a]=array_weld.apply(this,ti.value.map(function(v,k){
			return fx.tween(v,ta.value[k],s,true,ty,false);
		})).map(function(v){return new Color(v)});
	}
	return adlib.internal.vars.fx.storedTweens[a].clone();
};




	


Class.inherits(adlib.internal.methods.fx,{
	animate:function(el,items){
		var t=$type(items);
		// if new animation
		if(t=="object"||t=="hash"){			
			items=$H(items);	
			var res={
				callback:_Empty,
				interval:adlib.defaults.fx.interval,
				direction:true
			};
			var steps=adlib.defaults.fx.steps;
			var tween='linear';
			if(items.tween){
				tween=items.tween;
				delete items.tween;
			}
			if(items.interval){
				res.interval=items.interval;
				delete items.interval;
			}
			if(items.steps){
				steps=items.steps;
				delete items.steps;
			}
			if(items.callback){
				res.callback=items.callback;
				delete items.callback;
			}
			var tmp=$H();	
			var keys=items.keys();
			var startVals=$H();
			var sets=items.map(function(v,k){
				var start=null;
				var end=v;
				if(isArray(v)){
					start=v[0];
					end=v[1];
				}
				var vals=adlib.internal.methods.fx.getSteps(el,k,start,end,steps,tween);
				vals.steps.unshift(vals.start);
				if(vals.unit!=""){
					vals.steps.exec(function(v){
						return v+vals.unit;
					});
				}
				return vals;
			});
			var vals=sets.map(function(v){return v.steps});
			res.f=array_weld.apply(this,vals).map(function(v){
				return $H().pasteArray(keys,v);
			});
			el.store('fx.animation',res);
			adlib.internal.methods.fx.runAnimation(el,res,0);
		}
		else{ // reverse the last animation
			var o=el.getStore('fx.animation');
			if(o){
				o.direction=(t=="boolean"?t:(!o.direction));
				adlib.internal.methods.fx.runAnimation(el,o,o.direction?0:o.f.length-1);
			}
		}
	},
	runAnimation:function(el,o,step){
		el.applyStyle(o.f[step]);
		step+=(o.direction?1:-1);
		if((o.direction&&step<o.f.length)||(!o.direction&&step>=0)){
			setTimeout(function(){adlib.internal.methods.fx.runAnimation(el,o,step)},o.interval);
		}
		else{
			o.callback(el);
		}
		
	}
});
adlib.utilities.make.elementFunction({
	animate:function(items){
		adlib.internal.methods.fx.animate(this,items);		
		return this;
	}
});


adlib.defaults.widgets.tabs={
	runOnLoad:true,
	classes:{
		tabOn:'tab-on',
		tabOff:'tab-off',
		contentOn:'tab-content-on',
		contentOff:'tab-content-off'
	},	
	group:{
		css:{
			tabContainer:'ul.tabs',
			tab:'li.tab',
			next:'li.tab-next',
			previous:'li.tab-previous'
		},

		loadingMessage:'<p class="tab-loading-message">Loading...</p>',
		//on,off,loading,options
		switchTab:function(n,f,l,o){
			if(l){
				o.setLoadingMessage(n,o);
			}	
			o.setTabOn(n,o);
			if(f){
				o.setTabOff(f,o);						
			}
		},

		// element, options object
		setTabOff:function(el,o){
			var c=adlib.defaults.widgets.tabs.classes;
			el.$t('img').forEach(function(v){
				v.setAttribute('src',v.getAttribute('src').replace(/_on/i,"_off"));
			});
			$(o.getContentId(el.id)).rAddClass(c.contentOn,c.contentOff);
			el.rAddClass(c.tabOn,c.tabOff).send('taboff');
		},

		// element, options object
		setTabOn:function(el,o){
			var c=adlib.defaults.widgets.tabs.classes;
			el.$t('img').forEach(function(v){
				v.setAttribute('src',v.getAttribute('src').replace(/_off/i,"_on"));
			});
			$(o.getContentId(el.id)).rAddClass(c.contentOff,c.contentOn);
			el.rAddClass(c.tabOff,c.tabOn).send('tabon');
		},
		// element, XHR response
		setTabContent:function(el,c){
			$(el).setHTML(c.responseText);
		},
		// tabs collection
		getDefaultTab:function(t){
			var c=t[0],f=false;
			for(var x=0; x<t.length; x++){
				var a=t[x].getAttribute('taboptions');
				if(a){
					globalEval('widgets.tabs.items["'+t[x].id+'"]='+a);
					widgets.tabs.items[t[x].id].loadCount=0;
				}
				if(Object.hasProperty(widgets.tabs.items,t[x].id,'defaultTab')||(!f&&t[x].hasClass(adlib.defaults.widgets.tabs.classes.tabOn))){
					c=t[x];
					f=true;
				}
			}
			return c;
		},
		// tab id
		getContentId:function(i){
			return i.replace(/-/,'-content-');
		},
		// element, options object
		setLoadingMessage:function(el,o){
			$(o.getContentId(el.id)).setHTML(o.loadingMessage);
		}		
	}

};


widgets.tabs={
	groups:$H(),	
	loadHandlers:$H(),
	items:$H(),
	//options, node
	load:function(o,n){
		if(o!=adlib.defaults.widgets.tabs.group){
			Class.inherits(o,adlib.defaults.widgets.tabs.group,false);
		}
		n=n||document;
		n.$css(o.css.tabContainer).forEach(function(v){
			var i=v._uniqueId, t=v.$css(o.css.tab), c=o.getDefaultTab(t);
			Events.add(i+'Click','click',function(ev,el){widgets.tabs.tabClick(ev,el,i)});
			Events.add(i+'NextClick','click',function(ev,el){widgets.tabs.tabStep(i,true)});
			Events.add(i+'PreviousClick','click',function(ev,el){widgets.tabs.tabStep(i,false)});
			// handle "next" tabs
			v.$css(o.css.next).attach(i+'NextClick',false,true,true);
			// handle "previous" tabs
			v.$css(o.css.previous).attach(i+'PreviousClick',false,true,true);
			// handle regular tabs
			t.attach(i+'Click',false,true,true);
			for(var x=0; x<t.length; x++){
				var it=Object.hasProperty(widgets.tabs.items,t[x].id),l=false;
				if(t[x]==c){	
					if(it&&it.url&&$test(window.XHR)){
						if(it.load==-1||it.loadCount>o.load){
							it.loadCount++;
							widgets.tabs.loadTabContent(t[x],it.url,it.loadCount,o);
							l=true;
						}
					}	
					o.switchTab(t[x],null,l,o);
				}
				else{
					o.setTabOff(t[x],o);
				}
			}
			this.groups[i]={tabContainer:v,currentTab:c,options:o,tabs:t};
		},this);
	},

	// {
	// tabId:{
		// url:'http://www.example.com',
		// load:1,
		// default:true
	// }
// }
	addOptions:function(o){
		for(var x in o){
			if(o.noEnum&&o.noEnum(x)){continue}
			if(o[x].url){
				if(!$test(o[x].load)){
					o[x].load=-1;
				}
				o[x].loadCount=0;
			}
		}
		widgets.tabs.items.paste(o);			
	},
	// event, element, options object
	tabClick:function(ev,el,gr){
		var g=widgets.tabs.groups[gr], p=g.options;
		if(el!=g.currentTab){
			var i=el.id, o=Object.hasProperty(widgets.tabs.items,i), l=false;
			if(o&&o.url&&$test(window.XHR)){			
				if(o.load==-1||o.loadCount<o.load){
					o.loadCount++;								
					l=true;
				}	
			}
			p.switchTab(el,g.currentTab,l,p);
			g.currentTab=el;
			if(l){
				widgets.tabs.loadTabContent(el,o.url,o.loadCount,p);	
			}			
		}
	},
	// tab group ID, direction (true=next, false=previous)
	tabStep:function(gr,dir){
		var g=widgets.tabs.groups[gr], c=g.currentTab, t=-1;
		for(var x=0; x<g.tabs.length; x++){
			if(g.tabs[x]==c){
				t=x+(dir?1:-1);
				t=(t<0)?g.tabs.length-1:t==g.tabs.length?0:t;
				break;
			}
		}
		g.tabs[t].send('click');
	},
	// element, url, count, options object
	loadTabContent:function(el,u,c,g){
		var i='tab_'+el.id, o={id:i,handler:widgets.tabs.receiveTabContent,target:g.getContentId(el.id)};
		if(isFunction(u)||isExecutable(u)){
			o=u(o,el,c);
		}
		else{
			o.url=u;
		}
		widgets.tabs.loadHandlers[i]=g.setTabContent;
		XHR.quickSend(o);
	},
	// xhr response, target, xhr id
	receiveTabContent:function(c,t,i){
		var l=widgets.tabs.loadHandlers;
		l[i]($(t),c);
		delete l[i];
	}
};

Events.inQ('DOMLoad',function(){if(adlib.defaults.widgets.tabs.runOnLoad){widgets.tabs.load(adlib.defaults.widgets.tabs.group)}});

