/* * jQuery 1.2.3 - New Wave Javascript * * Copyright (c) 2008 John Resig (jquery.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $ * $Rev: 4663 $ */ (function(){if(window.jQuery)var _jQuery=window.jQuery;var jQuery=window.jQuery=function(selector,context){return new jQuery.prototype.init(selector,context);};if(window.$)var _$=window.$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;var isSimple=/^.[^:#\[\.]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem)if(elem.id!=match[3])return jQuery().find(selector);else{this[0]=elem;this.length=1;return this;}else selector=[];}}else return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.3",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;this.each(function(i){if(this==elem)ret=i;});return ret;},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],name)||undefined;else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return!selector?this:this.pushStack(jQuery.merge(this.get(),selector.constructor==String?jQuery(selector).get():selector.length!=undefined&&(!selector.nodeName||jQuery.nodeName(selector,"form"))?selector:[selector]));},is:function(selector){return selector?jQuery.multiFilter(selector,this).length>0:false;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=value.constructor==Array?value:[value];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else this.value=value;});},html:function(value){return value==undefined?(this.length?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value==null){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data==undefined&&this.length)data=jQuery.data(this[0],key);return data==null&&parts[1]?this.data(parts[0]):data;}else return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);}else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.prototype.init.prototype=jQuery.prototype;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==1){target=this;i=0;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret;function color(elem){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=elem.style.outline;elem.style.outline="0 solid black";elem.style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&elem.style&&elem.style[name])ret=elem.style[name];else if(document.defaultView&&document.defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var getComputedStyle=document.defaultView.getComputedStyle(elem,null);if(getComputedStyle&&!color(elem))ret=getComputedStyle.getPropertyValue(name);else{var swap=[],stack=[];for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(var i=0;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,""+value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(typeof array!="array")for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval!=undefined)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(arguments.callee.elem,arguments);return val;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data||[]);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event)data.unshift(this.fix({type:type,target:elem}));data[0].type=type;if(exclusive)data[0].exclusive=true;if(jQuery.isFunction(jQuery.data(elem,"handle")))val=jQuery.data(elem,"handle").apply(elem,data);if(!fn&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var handlers=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in handlers){var handler=handlers[j];args[0].handler=handler;args[0].data=handler.data;if(!parts[1]&&!event.exclusive||handler.type==parts[1]){var ret=handler.apply(this,args);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);return undefined;},toggle:function(){var args=arguments;return this.click(function(event){this.lastToggle=0==this.lastToggle?1:0;event.preventDefault();return args[this.lastToggle].apply(this,arguments)||false;});},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){var jsonp,jsre=/=\?(&|$)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get"){var ts=(new Date()).getTime();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if((!s.url.indexOf("http")||!s.url.indexOf("//"))&&s.dataType=="script"&&s.type.toLowerCase()=="get"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async,s.username,s.password);try{if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");xml.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})();/** * jQuery.ScrollTo - Easy element scrolling using jQuery. * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * Date: 2/19/2008 * @author Ariel Flesler * @version 1.3.3 */ ;(function($){var o=$.scrollTo=function(a,b,c){o.window().scrollTo(a,b,c)};o.defaults={axis:'y',duration:1};o.window=function(){return $($.browser.safari?'body':'html')};$.fn.scrollTo=function(l,m,n){if(typeof m=='object'){n=m;m=0}n=$.extend({},o.defaults,n);m=m||n.speed||n.duration;n.queue=n.queue&&n.axis.length>1;if(n.queue)m/=2;n.offset=j(n.offset);n.over=j(n.over);return this.each(function(){var a=this,b=$(a),t=l,c,d={},w=b.is('html,body');switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t=j(t);break}t=$(t,this);case'object':if(t.is||t.style)c=(t=$(t)).offset()}$.each(n.axis.split(''),function(i,f){var P=f=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,e=a[k],D=f=='x'?'Width':'Height';if(c){d[k]=c[p]+(w?0:e-b.offset()[p]);if(n.margin){d[k]-=parseInt(t.css('margin'+P))||0;d[k]-=parseInt(t.css('border'+P+'Width'))||0}d[k]+=n.offset[p]||0;if(n.over[p])d[k]+=t[D.toLowerCase()]()*n.over[p]}else d[k]=t[p];if(/^\d+$/.test(d[k]))d[k]=d[k]<=0?0:Math.min(d[k],h(D));if(!i&&n.queue){if(e!=d[k])g(n.onAfterFirst);delete d[k]}});g(n.onAfter);function g(a){b.animate(d,m,n.easing,a&&function(){a.call(this,l)})};function h(D){var b=w?$.browser.opera?document.body:document.documentElement:a;return b['scroll'+D]-b['client'+D]}})};function j(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);/** * jQuery.LocalScroll - Animated scrolling navigation, using anchors. * Copyright (c) 2007-2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com * Dual licensed under MIT and GPL. * Date: 3/10/2008 * @author Ariel Flesler * @version 1.2.5 **/ ;(function($){var g=location.href.replace(/#.*/,''),h=$.localScroll=function(a){$('body').localScroll(a)};h.defaults={duration:1e3,axis:'y',event:'click',stop:1};h.hash=function(a){a=$.extend({},h.defaults,a);a.hash=0;if(location.hash)setTimeout(function(){i(0,location,a)},0)};$.fn.localScroll=function(b){b=$.extend({},h.defaults,b);return(b.persistent||b.lazy)?this.bind(b.event,function(e){var a=$([e.target,e.target.parentNode]).filter(c)[0];a&&i(e,a,b)}):this.find('a').filter(c).bind(b.event,function(e){i(e,this,b)}).end().end();function c(){var a=this;return!!a.href&&!!a.hash&&a.href.replace(a.hash,'')==g&&(!b.filter||$(a).is(b.filter))}};function i(e,a,b){var c=a.hash.slice(1),d=document.getElementById(c)||document.getElementsByName(c)[0],f;if(d){e&&e.preventDefault();f=$(b.target||$.scrollTo.window());if(b.lock&&f.is(':animated')||b.onBefore&&b.onBefore.call(a,e,d,f)===!1)return;if(b.stop)f.queue('fx',[]).stop();f.scrollTo(d,b).trigger('notify.serialScroll',[d]);if(b.hash)f.queue(function(){location=a.hash})}}})(jQuery);/** * An adapter for the Shadowbox media viewer and the jQuery JavaScript library. * * This file is part of Shadowbox. * * Shadowbox is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * Shadowbox is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for * more details. * * You should have received a copy of the GNU Lesser General Public License * along with Shadowbox. If not, see . * * @author Michael J. I. Jackson * @copyright 2007 Michael J. I. Jackson * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LGPL 3.0 * @version SVN: $Id: shadowbox-jquery.js 75 2008-02-21 16:51:29Z mjijackson $ */ if(typeof jQuery == 'undefined'){ throw 'Unable to load Shadowbox, jQuery library not found.'; } // create the Shadowbox object first var Shadowbox = {}; Shadowbox.lib = { /** * Gets the value of the style on the given element. * * @param {HTMLElement} el The DOM element * @param {String} style The name of the style (e.g. margin-top) * @return {mixed} The value of the given style * @public */ getStyle: function(el, style){ return jQuery(el).css(style); }, /** * Sets the style on the given element to the given value. May be an * object to specify multiple values. * * @param {HTMLElement} el The DOM element * @param {String/Object} style The name of the style to set if a * string, or an object of name => * value pairs * @param {String} value The value to set the given style to * @return void * @public */ setStyle: function(el, style, value){ if(typeof style != 'object'){ var temp = {}; temp[style] = value; style = temp; } jQuery(el).css(style); }, /** * Gets a reference to the given element. * * @param {String/HTMLElement} el The element to fetch * @return {HTMLElement} A reference to the element * @public */ get: function(el){ return (typeof el == 'string') ? document.getElementById(el) : el; }, /** * Removes an element from the DOM. * * @param {HTMLElement} el The element to remove * @return void * @public */ remove: function(el){ jQuery(el).remove(); }, /** * Gets the target of the given event. The event object passed will be * the same object that is passed to listeners registered with * addEvent(). * * @param {mixed} e The event object * @return {HTMLElement} The event's target element * @public */ getTarget: function(e){ return e.target; }, /** * Prevents the event's default behavior. The event object passed will * be the same object that is passed to listeners registered with * addEvent(). * * @param {mixed} e The event object * @return void * @public */ preventDefault: function(e){ e = e.browserEvent || e; if(e.preventDefault){ e.preventDefault(); }else{ e.returnValue = false; } }, /** * Adds an event listener to the given element. It is expected that this * function will be passed the event as its first argument. * * @param {HTMLElement} el The DOM element to listen to * @param {String} name The name of the event to register * (i.e. 'click', 'scroll', etc.) * @param {Function} handler The event handler function * @return void * @public */ addEvent: function(el, name, handler){ jQuery(el).bind(name, handler); }, /** * Removes an event listener from the given element. * * @param {HTMLElement} el The DOM element to stop listening to * @param {String} name The name of the event to stop * listening for (i.e. 'click') * @param {Function} handler The event handler function * @return void * @public */ removeEvent: function(el, name, handler){ jQuery(el).unbind(name, handler); }, /** * Animates numerous styles of the given element. The second parameter * of this function will be an object of the type that is expected by * YAHOO.util.Anim. See http://developer.yahoo.com/yui/docs/YAHOO.util.Anim.html * for more information. * * @param {HTMLElement} el The DOM element to animate * @param {Object} obj The animation attributes/parameters * @param {Number} duration The duration of the animation * (in seconds) * @param {Function} callback A callback function to call when * the animation completes * @return void * @public */ animate: function(el, obj, duration, callback){ duration = Math.round(duration * 1000); // convert to milliseconds var o = {}; for(var p in obj){ for(var p in obj){ o[p] = String(obj[p].to); if(p != 'opacity') o[p] += 'px'; } } jQuery(el).animate(o, duration, null, callback); } }; /** * Passes the selected elements to the Shadowbox.setup() function. Supports * embedded height and width attributes within the class attribute. * * @param {Object} options The options to pass to setup() for all * selected elements * @public * @author Mike Alsup * @author Roger Barrett */ (function($){ $.fn.shadowbox = function(options){ return this.each(function(){ var $this = $(this); // support jQuery metadata plugin var opts = $.extend({}, options || {}, $.metadata ? $this.metadata() : $.meta ? $this.data() : {}); // support embedded opts (for w/h) within the class attr var cls = this.className || ''; opts.width = parseInt((cls.match(/w:(\d+)/)||[])[1]) || opts.width; opts.height = parseInt((cls.match(/h:(\d+)/)||[])[1]) || opts.height; Shadowbox.setup($this, opts); }); }; })(jQuery); /** * A media-viewer script for web pages that allows content to be viewed without * navigating away from the original linking page. * * This file is part of Shadowbox. * * Shadowbox is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) * any later version. * * Shadowbox is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for * more details. * * You should have received a copy of the GNU Lesser General Public License * along with Shadowbox. If not, see . * * @author Michael J. I. Jackson * @copyright 2007 Michael J. I. Jackson * @license http://www.gnu.org/licenses/lgpl-3.0.txt GNU LGPL 3.0 * @version SVN: $Id: shadowbox.js 75 2008-02-21 16:51:29Z mjijackson $ */ if(typeof Shadowbox == 'undefined'){ throw 'Unable to load Shadowbox, no base library adapter found.'; } /** * The Shadowbox class. Used to display different media on a web page using a * Lightbox-like effect. * * Useful resources: * - http://www.alistapart.com/articles/byebyeembed * - http://www.w3.org/TR/html401/struct/objects.html * - http://www.dyn-web.com/dhtml/iframes/ * - http://support.microsoft.com/kb/316992 * - http://www.apple.com/quicktime/player/specs.html * - http://www.howtocreate.co.uk/wrongWithIE/?chapter=navigator.plugins * * @class Shadowbox * @author Michael J. I. Jackson * @singleton */ (function(){ /** * The current version of Shadowbox. * * @property {String} version * @private */ var version = '1.0'; /** * Contains the default options for Shadowbox. This object is almost * entirely customizable. * * @property {Object} options * @private */ var options = { /** * A base URL that will be prepended to the loadingImage, flvPlayer, and * overlayBgImage options to save on typing. * * @var {String} assetURL */ assetURL: '', /** * The path to the image to display while loading. * * @var {String} loadingImage */ loadingImage: 'img/sbox/loading.gif', /** * Enable animations. * * @var {Boolean} animate */ animate: true, /** * Specifies the sequence of the height and width animations. May be * 'wh' (width then height), 'hw' (height then width), or 'sync' (both * at the same time). Of course this will only work if animate is true. * * @var {String} animSequence */ animSequence: 'wh', /** * The path to flvplayer.swf. * * @var {String} flvPlayer */ flvPlayer: 'flvplayer.swf', /** * The background color and opacity of the overlay. Note: When viewing * movie files on FF Mac, the default background image will be used * because that browser has problems displaying movies above layers * that aren't 100% opaque. * * @var {String} overlayColor */ overlayColor: '#000', /** * The background opacity to use for the overlay. * * @var {Number} overlayOpacity */ overlayOpacity: 0.85, /** * A background image to use for browsers such as FF Mac that don't * support displaying movie content over backgrounds that aren't 100% * opaque. * * @var {String} overlayBgImage */ overlayBgImage: 'img/sbox/overlay-85.png', /** * Listen to the overlay for clicks. If the user clicks the overlay, * it will trigger Shadowbox.close(). * * @var {Boolean} listenOverlay */ listenOverlay: true, /** * Automatically play movies. * * @var {Boolean} autoplayMovies */ autoplayMovies: true, /** * Enable movie controllers on movie players. * * @var {Boolean} showMovieControls */ showMovieControls: true, /** * The duration of the resizing animations (in seconds). * * @var {Number} resizeDuration */ resizeDuration: 0.35, /** * The duration of the overlay fade animation (in seconds). * * @var {Number} fadeDuration */ fadeDuration: 0.35, /** * Show the navigation controls. * * @var {Boolean} displayNav */ displayNav: true, /** * Enable continuous galleries. When this is true, users will be able * to skip to the first gallery image from the last using next and vice * versa. * * @var {Boolean} continuous */ continuous: false, /** * Display the gallery counter. * * @var {Boolean} displayCounter */ displayCounter: true, /** * This option may be either 'default' or 'skip'. The default counter is * a simple '1 of 5' message. The skip counter displays a link for each * piece in the gallery that enables a user to skip directly to any * piece. * * @var {String} counterType */ counterType: 'default', /** * The amount of padding to maintain around the viewport edge (in * pixels). This only applies when the image is very large and takes up * the entire viewport. * * @var {Number} viewportPadding */ viewportPadding: 20, /** * How to handle images that are too large for the viewport. 'resize' * will resize the image while preserving aspect ratio and display it at * the smaller resolution. 'drag' will display the image at its native * resolution but it will be draggable within the Shadowbox. 'none' will * display the image at its native resolution but it may be cropped. * * @var {String} handleLgImages */ handleLgImages: 'resize', /** * The initial height of Shadowbox (in pixels). * * @var {Number} initialHeight */ initialHeight: 160, /** * The initial width of Shadowbox (in pixels). * * @var {Number} initialWidth */ initialWidth: 320, /** * Enable keyboard control. Note: If you disable the keys, you may want * to change the visual styles for the navigation elements that suggest * keyboard shortcuts. * * @var {Boolean} enableKeys */ enableKeys: true, /** * The keys used to control Shadowbox. Note: In order to use these, * enableKeys must be true. Key values or key codes may be used. * * @var {Array} */ keysClose: ['c', 'q', 27], // c, q, or esc keysNext: ['n', 39], // n or right arrow keysPrev: ['p', 37], // p or left arrow /** * A hook function to be fired when Shadowbox opens. The single argument * will be the current gallery element. * * @var {Function} */ onOpen: null, /** * A hook function to be fired when Shadowbox finishes loading its * content. The single argument will be the current gallery element on * display. * * @var {Function} */ onFinish: null, /** * A hook function to be fired when Shadowbox changes from one gallery * element to the next. The single argument will be the current gallery * element that is about to be displayed. * * @var {Function} */ onChange: null, /** * A hook function that will be fired when Shadowbox closes. The single * argument will be the gallery element most recently displayed. * * @var {Function} */ onClose: null, /** * The mode to use when handling unsupported media. May be either * 'remove' or 'link'. If it is 'remove', the unsupported gallery item * will merely be removed from the gallery. If it is the only item in * the gallery, the link will simply be followed. If it is 'link', a * link will be provided to the appropriate plugin page in place of the * gallery element. * * @var {String} handleUnsupported */ handleUnsupported: 'link', /** * Skips calling Shadowbox.setup() in init(). This means that it must * be called later manually. * * @var {Boolean} skipSetup */ skipSetup: false, /** * Text messages to use for Shadowbox. These are provided so they may be * translated into different languages. * * @var {Object} text */ text: { cancel: 'Cancel', loading: 'loading', close: 'Close', next: 'Next', prev: 'Previous', errors: { single: 'You must install the {1} browser plugin to view this content.', shared: 'You must install both the {1} and {3} browser plugins to view this content.', either: 'You must install either the {1} or the {3} browser plugin to view this content.' } }, /** * An object containing names of plugins and links to their respective * download pages. * * @var {Object} errors */ errors: { fla: { name: 'Flash', url: 'http://www.adobe.com/products/flashplayer/' }, qt: { name: 'QuickTime', url: 'http://www.apple.com/quicktime/download/' }, wmp: { name: 'Windows Media Player', url: 'http://www.microsoft.com/windows/windowsmedia/' }, f4m: { name: 'Flip4Mac', url: 'http://www.flip4mac.com/wmv_download.htm' } }, /** * The HTML markup to use for Shadowbox. Note: The script depends on * most of these elements being present, so don't modify this variable * unless you know what you're doing. * * @var {Object} skin */ skin: { main: '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
', loading: '{1}' + '{2}', counter: '
{0}
', close: '
' + '{0}' + '
', next: '
' + '{0}' + '
', prev: '
' + '{0}' + '
' }, /** * An object containing arrays of all supported file extensions. Each * property of this object contains an array. If this object is to be * modified, it must be done before calling init(). * * - img: Supported image file extensions * - qt: Movie file extensions supported by QuickTime * - wmp: Movie file extensions supported by Windows Media Player * - qtwmp: Movie file extensions supported by both QuickTime and Windows Media Player * - iframe: File extensions that will be display in an iframe * * @var {Object} ext */ ext: { img: ['png', 'jpg', 'jpeg', 'gif', 'bmp'], qt: ['dv', 'mov', 'moov', 'movie', 'mp4'], wmp: ['asf', 'wm', 'wmv'], qtwmp: ['avi', 'mpg', 'mpeg'], iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'pl', 'php', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt', 'vbs'] } }; /** * Stores the default set of options in case a custom set of options is used * on a link-by-link basis so we can restore them later. * * @property {Object} default_options * @private */ var default_options = null; /** * Shorthand for Shadowbox.lib. * * @property {Object} SL * @private */ var SL = Shadowbox.lib; /** * An object containing some regular expressions we'll need later. Compiled * up front for speed. * * @property {Object} RE * @private */ var RE = { resize: /(img|swf|flv)/, // file types to resize overlay: /(img|iframe|html|inline)/, // content types to not use an overlay image for on FF Mac swf: /\.swf\s*$/i, // swf file extension flv: /\.flv\s*$/i, // flv file extension domain: /:\/\/(.*?)[:\/]/, // domain prefix inline: /#(.+)$/, // inline element id rel: /^(light|shadow)box/i, // rel attribute format gallery: /^(light|shadow)box\[(.*?)\]/i, // rel attribute format for gallery link unsupported: /^unsupported-(\w+)/, // unsupported media type param: /\s*([a-z_]*?)\s*=\s*(.+)\s*/, // rel string parameter empty: /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i // elements that don't have children }; /** * A cache of options for links that have been set up for use with * Shadowbox. * * @property {Array} cache * @private */ var cache = []; /** * An array of pieces currently being viewed. In the case of non-gallery * pieces, this will only hold one object. * * @property {Array} current_gallery * @private */ var current_gallery; /** * The array index of the current_gallery that is currently being viewed. * * @property {Number} current * @private */ var current; /** * Keeps track of the current optimal height of the box. We use this so that * if the user resizes the browser window to get a better view, and we're * currently at a size smaller than the optimal, we can resize easily. * * @see resizeContent() * @property {Number} optimal_height * @private */ var optimal_height = options.initialHeight; /** * Keeps track of the current optimal width of the box. See optimal_height * explanation (above). * * @property {Number} optimal_width * @private */ var optimal_width = options.initialWidth; /** * Keeps track of the current height of the box. This is useful in drag * calculations. * * @property {Number} current_height * @private */ var current_height = 0; /** * Keeps track of the current width of the box. Useful in drag calculations. * * @property {Number} current_width * @private */ var current_width = 0; /** * Resource used to preload images. It's class-level so that when a new * image is requested, the same resource can be reassigned, cancelling * the original's callback. * * @property {HTMLElement} preloader * @private */ var preloader; /** * Keeps track of whether or not Shadowbox has been initialized. We never * want to initialize twice. * * @property {Boolean} initialized * @private */ var initialized = false; /** * Keeps track of whether or not Shadowbox is activated. * * @property {Boolean} activated * @private */ var activated = false; /** * Keeps track of 4 floating values (x, y, start_x, & start_y) that are used * in the drag calculations. * * @property {Object} drag * @private */ var drag; /** * Holds the draggable element so we don't have to fetch it every time * the mouse moves. * * @property {HTMLElement} draggable * @private */ var draggable; /** * Keeps track of whether or not we're currently using the overlay * background image to display the current gallery. We do this because we * use different methods for fading the overlay in and out. The color fill * overlay fades in and out nicely, but the image overlay stutters. By * keeping track of the type of overlay in use, we don't have to check again * what type of overlay we're using when it's time to get rid of it later. * * @property {Boolean} overlay_img_needed * @private */ var overlay_img_needed; /** * These parameters for simple browser detection. Used in Ext.js. * * @ignore */ var ua = navigator.userAgent.toLowerCase(); var isStrict = document.compatMode == 'CSS1Compat', isOpera = ua.indexOf("opera") > -1, isIE = ua.indexOf('msie') > -1, isIE7 = ua.indexOf('msie 7') > -1, isBorderBox = isIE && !isStrict, isSafari = (/webkit|khtml/).test(ua), isSafari3 = isSafari && !!(document.evaluate), isGecko = !isSafari && ua.indexOf('gecko') > -1, isWindows = (ua.indexOf('windows') != -1 || ua.indexOf('win32') != -1), isMac = (ua.indexOf('macintosh') != -1 || ua.indexOf('mac os x') != -1), isLinux = (ua.indexOf('linux') != -1); /** * Do we need to hack the position to make Shadowbox appear fixed? We could * hack this using CSS, but let's just get over all the hacks and let IE6 * users get what they deserve! Down with hacks! Hmm...now that I think * about it, I should just flash all kinds of alerts and annoying popups on * their screens, and then redirect them to some foreign spyware site that * will upload a nasty virus... * * @property {Boolean} absolute_pos * @private */ var absolute_pos = isIE && !isIE7; /** * Contains plugin support information. Each property of this object is a * boolean indicating whether that plugin is supported. * * - fla: Flash player * - qt: QuickTime player * - wmp: Windows Media player * - f4m: Flip4Mac plugin * * @property {Object} plugins * @private */ var plugins = null; // detect plugin support if(navigator.plugins && navigator.plugins.length){ var detectPlugin = function(plugin_name){ var detected = false; for (var i = 0, len = navigator.plugins.length; i < len; ++i){ if(navigator.plugins[i].name.indexOf(plugin_name) > -1){ detected = true; break; } } return detected; }; var f4m = detectPlugin('Flip4Mac'); var plugins = { fla: detectPlugin('Shockwave Flash'), qt: detectPlugin('QuickTime'), wmp: !f4m && detectPlugin('Windows Media'), // if it's Flip4Mac, it's not really WMP f4m: f4m }; }else{ var detectPlugin = function(plugin_name){ var detected = false; try { var axo = new ActiveXObject(plugin_name); if(axo){ detected = true; } } catch (e) {} return detected; }; var plugins = { fla: detectPlugin('ShockwaveFlash.ShockwaveFlash'), qt: detectPlugin('QuickTime.QuickTime'), wmp: detectPlugin('wmplayer.ocx'), f4m: false }; } /** * Applies all properties of e to o. This function is recursive so that if * any properties of e are themselves objects, those objects will be applied * to objects with the same key that may exist in o. * * @param {Object} o The original object * @param {Object} e The extension object * @return {Object} The original object with all properties * of the extension object applied (deep) * @private */ var apply = function(o, e){ for(var p in e) o[p] = e[p]; return o; }; /** * Determines if the given object is an anchor/area element. * * @param {mixed} el The object to check * @return {Boolean} True if the object is a link element * @private */ var isLink = function(el){ return typeof el.tagName == 'string' && (el.tagName.toUpperCase() == 'A' || el.tagName.toUpperCase() == 'AREA'); }; /** * Gets the height of the viewport in pixels. Note: This function includes * scrollbars in Safari 3. * * @return {Number} The height of the viewport * @public * @static */ SL.getViewportHeight = function(){ var height = window.innerHeight; // Safari var mode = document.compatMode; if((mode || isIE) && !isOpera){ height = isStrict ? document.documentElement.clientHeight : document.body.clientHeight; } return height; }; /** * Gets the width of the viewport in pixels. Note: This function includes * scrollbars in Safari 3. * * @return {Number} The width of the viewport * @public * @static */ SL.getViewportWidth = function(){ var width = window.innerWidth; // Safari var mode = document.compatMode; if(mode || isIE){ width = isStrict ? document.documentElement.clientWidth : document.body.clientWidth; } return width; }; /** * Gets the height of the document (body and its margins) in pixels. * * @return {Number} The height of the document * @public * @static */ SL.getDocumentHeight = function(){ var scrollHeight = isStrict ? document.documentElement.scrollHeight : document.body.scrollHeight; return Math.max(scrollHeight, SL.getViewportHeight()); }; /** * Gets the width of the document (body and its margins) in pixels. * * @return {Number} The width of the document * @public * @static */ SL.getDocumentWidth = function(){ var scrollWidth = isStrict ? document.documentElement.scrollWidth : document.body.scrollWidth; return Math.max(scrollWidth, SL.getViewportWidth()); }; /** * A utility function used by the fade functions to clear the opacity * style setting of the given element. Required in some cases for IE. * Based on Ext.Element's clearOpacity. * * @param {HTMLElement} el The DOM element * @return void * @private */ var clearOpacity = function(el){ if(isIE){ if(typeof el.style.filter == 'string' && (/alpha/i).test(el.style.filter)){ el.style.filter = ''; } }else{ el.style.opacity = ''; el.style['-moz-opacity'] = ''; el.style['-khtml-opacity'] = ''; } }; /** * Fades the given element from 0 to the specified opacity. * * @param {HTMLElement} el The DOM element to fade * @param {Number} endingOpacity The final opacity to animate to * @param {Number} duration The duration of the animation * (in seconds) * @param {Function} callback A callback function to call * when the animation completes * @return void * @private */ var fadeIn = function(el, endingOpacity, duration, callback){ if(options.animate){ SL.setStyle(el, 'opacity', 0); el.style.visibility = 'visible'; SL.animate(el, { opacity: { to: endingOpacity } }, duration, function(){ if(endingOpacity == 1) clearOpacity(el); if(typeof callback == 'function') callback(); }); }else{ if(endingOpacity == 1){ clearOpacity(el); }else{ SL.setStyle(el, 'opacity', endingOpacity); } el.style.visibility = 'visible'; if(typeof callback == 'function') callback(); } }; /** * Fades the given element from its current opacity to 0. * * @param {HTMLElement} el The DOM element to fade * @param {Number} duration The duration of the fade animation * @param {Function} callback A callback function to call when * the animation completes * @return void * @private */ var fadeOut = function(el, duration, callback){ var cb = function(){ el.style.visibility = 'hidden'; clearOpacity(el); if(typeof callback == 'function') callback(); }; if(options.animate){ SL.animate(el, { opacity: { to: 0 } }, duration, cb); }else{ cb(); } }; /** * Appends an HTML fragment to the given element. * * @param {String/HTMLElement} el The element to append to * @param {String} html The HTML fragment to use * @return {HTMLElement} The newly appended element * @private */ var appendHTML = function(el, html){ el = SL.get(el); if(el.insertAdjacentHTML){ el.insertAdjacentHTML('BeforeEnd', html); return el.lastChild; } if(el.lastChild){ var range = el.ownerDocument.createRange(); range.setStartAfter(el.lastChild); var frag = range.createContextualFragment(html); el.appendChild(frag); return el.lastChild; }else{ el.innerHTML = html; return el.lastChild; } }; /** * Overwrites the HTML of the given element. * * @param {String/HTMLElement} el The element to overwrite * @param {String} html The new HTML to use * @return {HTMLElement} The new firstChild element * @private */ var overwriteHTML = function(el, html){ el = SL.get(el); el.innerHTML = html; return el.firstChild; }; /** * Gets either the offsetHeight or the height of the given element plus * padding and borders (when offsetHeight is not available). Based on * Ext.Element's getComputedHeight. * * @return {Number} The computed height of the element * @private */ var getComputedHeight = function(el){ var h = Math.max(el.offsetHeight, el.clientHeight); if(!h){ h = parseInt(SL.getStyle(el, 'height'), 10) || 0; if(!isBorderBox){ h += parseInt(SL.getStyle(el, 'padding-top'), 10) + parseInt(SL.getStyle(el, 'padding-bottom'), 10) + parseInt(SL.getStyle(el, 'border-top-width'), 10) + parseInt(SL.getStyle(el, 'border-bottom-width'), 10); } } return h; }; /** * Gets either the offsetWidth or the width of the given element plus * padding and borders (when offsetWidth is not available). Based on * Ext.Element's getComputedWidth. * * @return {Number} The computed width of the element * @private */ var getComputedWidth = function(el){ var w = Math.max(el.offsetWidth, el.clientWidth); if(!w){ w = parseInt(SL.getStyle(el, 'width'), 10) || 0; if(!isBorderBox){ w += parseInt(SL.getStyle(el, 'padding-left'), 10) + parseInt(SL.getStyle(el, 'padding-right'), 10) + parseInt(SL.getStyle(el, 'border-left-width'), 10) + parseInt(SL.getStyle(el, 'border-right-width'), 10); } } return w; }; /** * Determines the player needed to display the file at the given URL. If * the file type is not supported, the return value will be 'unsupported'. * If the file type is not supported but the correct player can be * determined, the return value will be 'unsupported-*' where * will be the * player abbreviation (e.g. 'qt' = QuickTime). * * @param {String} url The url of the file * @return {String} The name of the player to use * @private */ var getPlayerType = function(url){ if(RE.img.test(url)) return 'img'; var match = url.match(RE.domain); var this_domain = match ? document.domain == match[1] : false; if(url.indexOf('#') > -1 && this_domain) return 'inline'; var q_index = url.indexOf('?'); if(q_index > -1) url = url.substring(0, q_index); // strip query string for player detection purposes if(RE.swf.test(url)) return plugins.fla ? 'swf' : 'unsupported-swf'; if(RE.flv.test(url)) return plugins.fla ? 'flv' : 'unsupported-flv'; if(RE.qt.test(url)) return plugins.qt ? 'qt' : 'unsupported-qt'; if(RE.wmp.test(url)){ if(plugins.wmp){ return 'wmp'; }else if(plugins.f4m){ return 'qt'; }else{ return isMac ? (plugins.qt ? 'unsupported-f4m' : 'unsupported-qtf4m') : 'unsupported-wmp'; } }else if(RE.qtwmp.test(url)){ if(plugins.qt){ return 'qt'; }else if(plugins.wmp){ return 'wmp'; }else{ return isMac ? 'unsupported-qt' : 'unsupported-qtwmp'; } }else if(!this_domain || RE.iframe.test(url)){ return 'iframe'; } return 'unsupported'; }; /** * Handles all clicks on links that have been set up to work with Shadowbox * and cancels the default event behavior when appropriate. * * @param {Event} ev The click event object * @return void * @private */ var handleClick = function(ev){ // get anchor/area element var link; if(isLink(this)){ link = this; // jQuery, Prototype, YUI }else{ link = SL.getTarget(ev); // Ext while(!isLink(link) && link.parentNode){ link = link.parentNode; } } Shadowbox.open(link); if(current_gallery.length) SL.preventDefault(ev); }; /** * Sets up the current gallery for the given object. Modifies the current * and current_gallery variables to contain the appropriate information. * Also, checks to see if there are any gallery pieces that are not * supported by the client's browser/plugins. If there are, they will be * handled according to the handleUnsupported option. * * @param {Object} obj The content to get the gallery for * @return void * @private */ var setupGallery = function(obj){ // create a copy so it doesn't get modified later var copy = apply({}, obj); // is it part of a gallery? if(!obj.gallery){ // single item, no gallery current_gallery = [copy]; current = 0; }else{ current_gallery = []; // clear the current gallery var index, ci; for(var i = 0, len = cache.length; i < len; ++i){ ci = cache[i]; if(ci.gallery){ if(ci.content == obj.content && ci.gallery == obj.gallery && ci.title == obj.title){ // compare content, gallery, & title index = current_gallery.length; // key element found } if(ci.gallery == obj.gallery){ current_gallery.push(apply({}, ci)); } } } // if not found in cache, prepend to front of gallery if(index == null){ current_gallery.unshift(copy); index = 0; } current = index; } // are any media in the current gallery supported? var match, r; for(var i = 0, len = current_gallery.length; i < len; ++i){ r = false; if(current_gallery[i].type == 'unsupported'){ // don't support this at all r = true; }else if(match = RE.unsupported.exec(current_gallery[i].type)){ // handle unsupported elements if(options.handleUnsupported == 'link'){ current_gallery[i].type = 'html'; // generate a link to the appropriate plugin download page(s) var m; switch(match[1]){ case 'qtwmp': m = String.format(options.text.errors.either, options.errors.qt.url, options.errors.qt.name, options.errors.wmp.url, options.errors.wmp.name); break; case 'qtf4m': m = String.format(options.text.errors.shared, options.errors.qt.url, options.errors.qt.name, options.errors.f4m.url, options.errors.f4m.name); break; default: if(match[1] == 'swf' || match[1] == 'flv') match[1] = 'fla'; m = String.format(options.text.errors.single, options.errors[match[1]].url, options.errors[match[1]].name); } current_gallery[i] = apply(current_gallery[i], { height: 160, // error messages are short so they width: 320, // only need a small box to display properly content: '
' + m + '
' }); }else{ r = true; } }else if(current_gallery[i].type == 'inline'){ // handle inline elements // retrieve the innerHTML of the inline element var match = RE.inline.exec(current_gallery[i].content); if(match){ var el; if(el = SL.get(match[1])){ current_gallery[i].content = el.innerHTML; }else{ throw 'No element found with id ' + match[1]; } }else{ throw 'No element id found for inline content'; } } if(r){ // remove the element from the gallery current_gallery.splice(i, 1); if(i < current) --current; --i; } } }; /** * Hides the title bar and toolbar and populates them with the proper * content. * * @return void * @private */ var buildBars = function(){ var link = current_gallery[current]; if(!link) return; // nothing to build // build the title var title_i = SL.get('shadowbox_title_inner'); title_i.innerHTML = (link.title) ? link.title : ''; // empty the toolbar var tool_i = SL.get('shadowbox_toolbar_inner'); tool_i.innerHTML = ''; // build the nav if(options.displayNav){ tool_i.innerHTML = String.format(options.skin.close, options.text.close); if(current_gallery.length > 1){ if(options.continuous){ // show both appendHTML(tool_i, String.format(options.skin.next, options.text.next)); appendHTML(tool_i, String.format(options.skin.prev, options.text.prev)); }else{ // not last in the gallery, show the next link if((current_gallery.length - 1) > current){ appendHTML(tool_i, String.format(options.skin.next, options.text.next)); } // not first in the gallery, show the previous link if(current > 0){ appendHTML(tool_i, String.format(options.skin.prev, options.text.prev)); } } } } // build the counter if(current_gallery.length > 1 && options.displayCounter){ // append the counter div var counter = ''; if(options.counterType == 'skip'){ for(var i = 0, len = current_gallery.length; i < len; ++i){ counter += ''; } }else{ counter = (current + 1) + ' of ' + current_gallery.length; } appendHTML(tool_i, String.format(options.skin.counter, counter)); } }; /** * Hides the title and tool bars. * * @param {Function} callback A function to call on finish * @return void * @private */ var hideBars = function(callback){ var title_m = getComputedHeight(SL.get('shadowbox_title')); var tool_m = 0 - getComputedHeight(SL.get('shadowbox_toolbar')); var title_i = SL.get('shadowbox_title_inner'); var tool_i = SL.get('shadowbox_toolbar_inner'); if(options.animate && callback){ // animate the transition SL.animate(title_i, { marginTop: { to: title_m } }, 0.2); SL.animate(tool_i, { marginTop: { to: tool_m } }, 0.2, callback); }else{ SL.setStyle(title_i, 'marginTop', title_m + 'px'); SL.setStyle(tool_i, 'marginTop', tool_m + 'px'); } }; /** * Shows the title and tool bars. * * @param {Function} callback A callback function to execute after * the animation completes * @return void * @private */ var showBars = function(callback){ var title_i = SL.get('shadowbox_title_inner'); if(options.animate){ if(title_i.innerHTML != ''){ SL.animate(title_i, { marginTop: { to: 0 } }, 0.35); } SL.animate(SL.get('shadowbox_toolbar_inner'), { marginTop: { to: 0 } }, 0.35, callback); }else{ if(title_i.innerHTML != ''){ SL.setStyle(title_i, 'margin-top', '0px'); } SL.setStyle(SL.get('shadowbox_toolbar_inner'), 'margin-top', '0px'); callback(); } }; /** * Resets the class drag variable. * * @return void * @private */ var resetDrag = function(){ drag = { x: 0, y: 0, start_x: null, start_y: null }; }; /** * Toggles the drag function on and off. * * @param {Boolean} on True to toggle on, false to toggle off * @return void * @private */ var toggleDrag = function(on){ if(on){ resetDrag(); // add drag layer to prevent browser dragging of actual image var styles = [ 'position:absolute', 'cursor:' + (isGecko ? '-moz-grab' : 'move') ]; // make drag layer transparent styles.push(isIE ? 'background-color:#fff;filter:alpha(opacity=0)' : 'background-color:transparent'); appendHTML('shadowbox_body_inner', '
'); SL.addEvent(SL.get('shadowbox_drag_layer'), 'mousedown', listenDrag); }else{ var d = SL.get('shadowbox_drag_layer'); if(d){ SL.removeEvent(d, 'mousedown', listenDrag); SL.remove(d); } } }; /** * Sets up a drag listener on the document. Called when the mouse button is * pressed (mousedown). * * @param {mixed} ev The mousedown event * @return void * @private */ var listenDrag = function(ev){ drag.start_x = ev.clientX; drag.start_y = ev.clientY; draggable = SL.get('shadowbox_content'); SL.addEvent(document, 'mousemove', positionDrag); SL.addEvent(document, 'mouseup', unlistenDrag); if(isGecko) SL.setStyle(SL.get('shadowbox_drag_layer'), 'cursor', '-moz-grabbing'); }; /** * Removes the drag listener. Called when the mouse button is released * (mouseup). * * @return void * @private */ var unlistenDrag = function(){ SL.removeEvent(document, 'mousemove', positionDrag); SL.removeEvent(document, 'mouseup', unlistenDrag); // clean up if(isGecko) SL.setStyle(SL.get('shadowbox_drag_layer'), 'cursor', '-moz-grab'); }; /** * Positions an oversized image on drag. * * @param {mixed} ev The drag event * @return void * @private */ var positionDrag = function(ev){ var move_y = ev.clientY - drag.start_y; drag.start_y = drag.start_y + move_y; drag.y = Math.max(Math.min(0, drag.y + move_y), current_height - optimal_height); // y boundaries SL.setStyle(draggable, 'top', drag.y + 'px'); var move_x = ev.clientX - drag.start_x; drag.start_x = drag.start_x + move_x; drag.x = Math.max(Math.min(0, drag.x + move_x), current_width - optimal_width); // x boundaries SL.setStyle(draggable, 'left', drag.x + 'px'); }; /** * Loads the Shadowbox with the current piece. * * @return void * @private */ var loadContent = function(){ var obj = current_gallery[current]; if(!obj) return; // invalid buildBars(); switch(obj.type){ case 'img': // preload the image preloader = new Image(); preloader.onload = function(){ // images default to image height and width var h = obj.height ? parseInt(obj.height, 10) : preloader.height; var w = obj.width ? parseInt(obj.width, 10) : preloader.width; resizeContent(h, w, function(dims){ showBars(function(){ setContent({ tag: 'img', height: dims.i_height, width: dims.i_width, src: obj.content, style: 'position:absolute' }); if(dims.enableDrag && options.handleLgImages == 'drag'){ // listen for drag toggleDrag(true); SL.setStyle(SL.get('shadowbox_drag_layer'), { height: dims.i_height + 'px', width: dims.i_width + 'px' }); } finishContent(); }); }); preloader.onload = function(){}; // clear onload for IE }; preloader.src = obj.content; break; case 'swf': case 'flv': case 'qt': case 'wmp': var markup = Shadowbox.movieMarkup(obj); resizeContent(markup.height, markup.width, function(){ showBars(function(){ setContent(markup); finishContent(); }); }); break; case 'iframe': // iframes default to full viewport height and width var h = obj.height ? parseInt(obj.height, 10) : SL.getViewportHeight(); var w = obj.width ? parseInt(obj.width, 10) : SL.getViewportWidth(); var content = { tag: 'iframe', name: 'shadowbox_content', height: '100%', width: '100%', frameborder: '0', marginwidth: '0', marginheight: '0', scrolling: 'auto' }; resizeContent(h, w, function(dims){ showBars(function(){ setContent(content); var win = (isIE) ? SL.get('shadowbox_content').contentWindow : window.frames['shadowbox_content']; win.location = obj.content; finishContent(); }); }); break; case 'html': case 'inline': // HTML content defaults to full viewport height and width var h = obj.height ? parseInt(obj.height, 10) : SL.getViewportHeight(); var w = obj.width ? parseInt(obj.width, 10) : SL.getViewportWidth(); var content = { tag: 'div', cls: 'html', /* give special class to make scrollable */ html: obj.content }; resizeContent(h, w, function(){ showBars(function(){ setContent(content); finishContent(); }); }); break; default: // should never happen throw 'Shadowbox cannot open content of type ' + obj.type; } // preload neighboring images if(current_gallery.length > 0){ var next = current_gallery[current + 1]; if(!next){ next = current_gallery[0]; } if(next.type == 'img'){ var preload_next = new Image(); preload_next.src = next.href; } var prev = current_gallery[current - 1]; if(!prev){ prev = current_gallery[current_gallery.length - 1]; } if(prev.type == 'img'){ var preload_prev = new Image(); preload_prev.src = prev.href; } } }; /** * Removes old content and sets the new content of the Shadowbox. * * @param {Object} obj The content to set (appropriate to pass * directly to Shadowbox.createHTML()) * @return {HTMLElement} The newly appended element (or null if * none is provided) * @private */ var setContent = function(obj){ var id = 'shadowbox_content'; var content = SL.get(id); if(content){ // remove old content first switch(content.tagName.toUpperCase()){ case 'OBJECT': // if we're in a gallery (i.e. changing and there's a new // object) we want the LAST link object var link = current_gallery[(obj ? current - 1 : current)]; if(link.type == 'wmp' && isIE){ try{ shadowbox_content.controls.stop(); // stop the movie shadowbox_content.URL = 'non-existent.wmv'; // force player refresh window.shadowbox_content = function(){}; // remove from window }catch(e){} }else if(link.type == 'qt' && isSafari){ try{ document.shadowbox_content.Stop(); // stop QT movie }catch(e){} // stop QT audio stream for movies that have not yet loaded content.innerHTML = ''; // console.log(document.shadowbox_content); } setTimeout(function(){ // using setTimeout prevents browser crashes with WMP SL.remove(content); }, 10); break; case 'IFRAME': SL.remove(content); if(isGecko) delete window.frames[id]; // needed for Firefox break; default: SL.remove(content); } } if(obj){ if(!obj.id) obj.id = id; return appendHTML('shadowbox_body_inner', Shadowbox.createHTML(obj)); } return null; }; /** * This function is used as the callback after the Shadowbox has been * positioned, resized, and loaded with content. * * @return void * @private */ var finishContent = function(){ var obj = current_gallery[current]; if(!obj) return; // invalid hideLoading(function(){ listenKeyboard(true); // fire onFinish handler if(options.onFinish && typeof options.onFinish == 'function'){ options.onFinish(obj); } }); }; /** * Resizes and positions the content box using the given height and width. * If the callback parameter is missing, the transition will not be * animated. If the callback parameter is present, it will be passed the * new calculated dimensions object as its first parameter. Note: the height * and width here should represent the optimal height and width of the box. * * @param {Function} callback A callback function to use when the * resize completes * @return void * @private */ var resizeContent = function(height, width, callback){ // update optimal height and width optimal_height = height; optimal_width = width; var resizable = RE.resize.test(current_gallery[current].type); var dims = getDimensions(optimal_height, optimal_width, resizable); if(callback){ var cb = function(){ callback(dims); }; switch(options.animSequence){ case 'hw': adjustHeight(dims.height, dims.top, true, function(){ adjustWidth(dims.width, true, cb); }); break; case 'wh': adjustWidth(dims.width, true, function(){ adjustHeight(dims.height, dims.top, true, cb); }); break; default: // sync adjustWidth(dims.width, true); adjustHeight(dims.height, dims.top, true, cb); } }else{ // window resize adjustWidth(dims.width, false); adjustHeight(dims.height, dims.top, false); // resize content images & flash in 'resize' mode if(options.handleLgImages == 'resize' && resizable){ var content = SL.get('shadowbox_content'); if(content){ // may be animating, not present content.height = dims.i_height; content.width = dims.i_width; } } } }; /** * Calculates the dimensions for Shadowbox, taking into account the borders, * margins, and surrounding elements of the shadowbox_body. If the image * is still to large for Shadowbox, and options.handleLgImages is 'resize', * the resized dimensions will be returned (preserving the original aspect * ratio). Otherwise, the originally calculated dimensions will be returned. * The returned object will have the following properties: * * - height: The height to use for shadowbox_body_inner * - width: The width to use for shadowbox * - i_height: The height to use for resizable content * - i_width: The width to use for resizable content * - top: The top to use for shadowbox * - enableDrag: True if dragging should be enabled (image is oversized) * * @param {Number} o_height The optimal height * @param {Number} o_width The optimal width * @param {Boolean} resizable True if the content is able to be * resized. Defaults to false. * @return {Object} The resize dimensions (see above) * @private */ var getDimensions = function(o_height, o_width, resizable){ if(typeof resizable == 'undefined') resizable = false; var height = o_height = parseInt(o_height); var width = o_width = parseInt(o_width); var shadowbox_b = SL.get('shadowbox_body'); // calculate the max height var view_height = SL.getViewportHeight(); var extra_height = parseInt(SL.getStyle(shadowbox_b, 'border-top-width'), 10) + parseInt(SL.getStyle(shadowbox_b, 'border-bottom-width'), 10) + parseInt(SL.getStyle(shadowbox_b, 'margin-top'), 10) + parseInt(SL.getStyle(shadowbox_b, 'margin-bottom'), 10) + getComputedHeight(SL.get('shadowbox_title')) + getComputedHeight(SL.get('shadowbox_toolbar')) + (2 * options.viewportPadding); if((height + extra_height) >= view_height){ height = view_height - extra_height; } // calculate the max width var view_width = SL.getViewportWidth(); var extra_body_width = parseInt(SL.getStyle(shadowbox_b, 'border-left-width'), 10) + parseInt(SL.getStyle(shadowbox_b, 'border-right-width'), 10) + parseInt(SL.getStyle(shadowbox_b, 'margin-left'), 10) + parseInt(SL.getStyle(shadowbox_b, 'margin-right'), 10); var extra_width = extra_body_width + (2 * options.viewportPadding); if((width + extra_width) >= view_width){ width = view_width - extra_width; } // handle oversized images & flash var enableDrag = false; var i_height = o_height; var i_width = o_width; var handle = options.handleLgImages; if(resizable && (handle == 'resize' || handle == 'drag')){ var change_h = (o_height - height) / o_height; var change_w = (o_width - width) / o_width; if(handle == 'resize'){ if(change_h > change_w){ width = Math.round((o_width / o_height) * height); }else if(change_w > change_h){ height = Math.round((o_height / o_width) * width); } // adjust image height or width accordingly i_width = width; i_height = height; }else{ // drag on oversized images only var link = current_gallery[current]; if(link) enableDrag = link.type == 'img' && (change_h > 0 || change_w > 0); } } return { height: height, width: width + extra_body_width, i_height: i_height, i_width: i_width, top: ((view_height - (height + extra_height)) / 2) + options.viewportPadding, enableDrag: enableDrag }; }; /** * Centers Shadowbox vertically in the viewport. Needs to be called on * scroll in IE6 because it does not support fixed positioning. * * @return void * @private */ var centerVertically = function(){ var shadowbox = SL.get('shadowbox'); var scroll = document.documentElement.scrollTop; var s_top = scroll + Math.round((SL.getViewportHeight() - (shadowbox.offsetHeight || 0)) / 2); SL.setStyle(shadowbox, 'top', s_top + 'px'); }; /** * Adjusts the height of shadowbox_body_inner and centers Shadowbox * vertically in the viewport. * * @param {Number} height The height of shadowbox_body_inner * @param {Number} top The top of the Shadowbox * @param {Boolean} animate True to animate the transition * @param {Function} callback A callback to use when the animation completes * @return void * @private */ var adjustHeight = function(height, top, animate, callback){ height = parseInt(height); // update current_height current_height = height; // adjust the height var sbi = SL.get('shadowbox_body_inner'); if(animate && options.animate){ SL.animate(sbi, { height: { to: height } }, options.resizeDuration, callback); }else{ SL.setStyle(sbi, 'height', height + 'px'); if(typeof callback == 'function') callback(); } // manually adjust the top because we're using fixed positioning in IE6 if(absolute_pos){ // listen for scroll so we can adjust centerVertically(); SL.addEvent(window, 'scroll', centerVertically); // add scroll to top top += document.documentElement.scrollTop; } // adjust the top var shadowbox = SL.get('shadowbox'); if(animate && options.animate){ SL.animate(shadowbox, { top: { to: top } }, options.resizeDuration); }else{ SL.setStyle(shadowbox, 'top', top + 'px'); } }; /** * Adjusts the width of shadowbox. * * @param {Number} width The width to use * @param {Boolean} animate True to animate the transition * @param {Function} callback A callback to use when the animation completes * @return void * @private */ var adjustWidth = function(width, animate, callback){ width = parseInt(width); // update current_width current_width = width; var shadowbox = SL.get('shadowbox'); if(animate && options.animate){ SL.animate(shadowbox, { width: { to: width } }, options.resizeDuration, callback); }else{ SL.setStyle(shadowbox, 'width', width + 'px'); if(typeof callback == 'function') callback(); } }; /** * Sets up a listener on the document for keystrokes. * * @param {Boolean} on True to enable the listner, false to turn * it off * @return void * @private */ var listenKeyboard = function(on){ if(!options.enableKeys) return; if(on){ document.onkeydown = handleKey; }else{ document.onkeydown = ''; } }; /** * Asserts the given key or code is present in the array of valid keys. * * @param {Array} valid An array of valid keys and codes * @param {String} key The character that was pressed * @param {Number} code The key code that was pressed * @return {Boolean} True if the key is valid * @private */ var assertKey = function(valid, key, code){ return (valid.indexOf(key) != -1 || valid.indexOf(code) != -1); }; /** * A listener function that will act on a key pressed. * * @param {Event} e The event object * @return void * @private */ var handleKey = function(e){ var code = e ? e.which : event.keyCode; var key = String.fromCharCode(code).toLowerCase(); if(assertKey(options.keysClose, key, code)){ Shadowbox.close(); }else if(assertKey(options.keysPrev, key, code)){ Shadowbox.previous(); }else if(assertKey(options.keysNext, key, code)){ Shadowbox.next(); } }; /** * Shows and hides elements that are troublesome for modal overlays. * * @param {Boolean} on True to show the elements, false otherwise * @return void * @private */ var toggleTroubleElements = function(on){ var vis = (on ? 'visible' : 'hidden'); var selects = document.getElementsByTagName('select'); for(i = 0, len = selects.length; i < len; ++i){ selects[i].style.visibility = vis; } var objects = document.getElementsByTagName('object'); for(i = 0, len = objects.length; i < len; ++i){ objects[i].style.visibility = vis; } var embeds = document.getElementsByTagName('embed'); for(i = 0, len = embeds.length; i < len; ++i){ embeds[i].style.visibility = vis; } }; /** * Fills the Shadowbox with the loading skin. * * @return void * @private */ var showLoading = function(){ var loading = SL.get('shadowbox_loading'); overwriteHTML(loading, String.format(options.skin.loading, options.assetURL + options.loadingImage, options.text.loading, options.text.cancel)); loading.style.visibility = 'visible'; }; /** * Hides the Shadowbox loading skin. * * @param {Function} callback The callback function to call after * hiding the loading skin * @return void * @private */ var hideLoading = function(callback){ var t = current_gallery[current].type; var anim = (t == 'img' || t == 'html'); // fade on images & html var loading = SL.get('shadowbox_loading'); if(anim){ fadeOut(loading, 0.35, callback); }else{ loading.style.visibility = 'hidden'; callback(); } }; /** * Sets the size of the overlay to the size of the document. * * @return void * @private */ var resizeOverlay = function(){ var overlay = SL.get('shadowbox_overlay'); SL.setStyle(overlay, { height: '100%', width: '100%' }); SL.setStyle(overlay, 'height', SL.getDocumentHeight() + 'px'); if(!isSafari3){ // Safari3 includes vertical scrollbar in SL.getDocumentWidth()! // Leave overlay width at 100% for now... SL.setStyle(overlay, 'width', SL.getDocumentWidth() + 'px'); } }; /** * Used to determine if the pre-made overlay background image is needed * instead of using the trasparent background overlay. A pre-made background * image is used for all but image pieces in FF Mac because it has problems * displaying correctly if the background layer is not 100% opaque. When * displaying a gallery, if any piece in the gallery meets these criteria, * the pre-made background image will be used. * * @return {Boolean} Whether or not an overlay image is needed * @private */ var checkOverlayImgNeeded = function(){ if(!(isGecko && isMac)) return false; for(var i = 0, len = current_gallery.length; i < len; ++i){ if(!RE.overlay.exec(current_gallery[i].type)) return true; } return false; }; /** * Activates (or deactivates) the Shadowbox overlay. If a callback function * is provided, we know we're activating. Otherwise, deactivate the overlay. * * @param {Function} callback A callback to call after activation * @return void * @private */ var toggleOverlay = function(callback){ var overlay = SL.get('shadowbox_overlay'); if(overlay_img_needed == null){ overlay_img_needed = checkOverlayImgNeeded(); } if(callback){ resizeOverlay(); // size the overlay before showing if(overlay_img_needed){ SL.setStyle(overlay, { visibility: 'visible', backgroundColor: 'transparent', backgroundImage: 'url(' + options.assetURL + options.overlayBgImage + ')', backgroundRepeat: 'repeat', opacity: 1 }); callback(); }else{ SL.setStyle(overlay, { visibility: 'visible', backgroundColor: options.overlayColor, backgroundImage: 'none' }); fadeIn(overlay, options.overlayOpacity, options.fadeDuration, callback); } }else{ if(overlay_img_needed){ SL.setStyle(overlay, 'visibility', 'hidden'); }else{ fadeOut(overlay, options.fadeDuration); } // reset for next time overlay_img_needed = null; } }; /** * Initializes the Shadowbox environment. Appends Shadowbox' HTML to the * document and sets up listeners on the window and overlay element. * * @param {Object} opts The default options to use * @return void * @public * @static */ Shadowbox.init = function(opts){ if(initialized) return; // don't initialize twice options = apply(options, opts || {}); // add markup appendHTML(document.body, options.skin.main); // compile file type regular expressions here for speed RE.img = new RegExp('\.(' + options.ext.img.join('|') + ')\s*$', 'i'); RE.qt = new RegExp('\.(' + options.ext.qt.join('|') + ')\s*$', 'i'); RE.wmp = new RegExp('\.(' + options.ext.wmp.join('|') + ')\s*$', 'i'); RE.qtwmp = new RegExp('\.(' + options.ext.qtwmp.join('|') + ')\s*$', 'i'); RE.iframe = new RegExp('\.(' + options.ext.iframe.join('|') + ')\s*$', 'i'); // handle window resize events var id = null; var resize = function(){ clearInterval(id); id = null; resizeOverlay(); resizeContent(optimal_height, optimal_width); }; SL.addEvent(window, 'resize', function(){ if(activated){ // use event buffering to prevent jerky window resizing if(id){ clearInterval(id); id = null; } if(!id) id = setInterval(resize, 50); } }); if(options.listenOverlay){ // add a listener to the overlay SL.addEvent(SL.get('shadowbox_overlay'), 'click', Shadowbox.close); } // adjust some positioning if needed if(absolute_pos){ // give the container absolute positioning SL.setStyle(SL.get('shadowbox_container'), 'position', 'absolute'); // give shadowbox_body "layout"...whatever that is SL.setStyle('shadowbox_body', 'zoom', 1); // need to listen to the container element because it covers the top // half of the page SL.addEvent(SL.get('shadowbox_container'), 'click', function(e){ var target = SL.getTarget(e); if(target.id && target.id == 'shadowbox_container') Shadowbox.close(); }); } // skip setup, will need to be done manually later if(!options.skipSetup) Shadowbox.setup(); initialized = true; }; /** * Sets up listeners on the given links that will trigger Shadowbox. If no * links are given, this method will set up every anchor element on the page * with the appropriate rel attribute. Note: Because AREA elements do not * support the rel attribute, they must be explicitly passed to this method. * * @param {Array} links An array (or array-like) list of anchor * and/or area elements to set up * @param {Object} opts Some options to use for the given links * @return void * @public * @static */ Shadowbox.setup = function(links, opts){ // get links if none specified if(!links){ var links = []; var a = document.getElementsByTagName('a'), rel; for(var i = 0, len = a.length; i < len; ++i){ rel = a[i].getAttribute('rel'); if(rel && RE.rel.test(rel)) links[links.length] = a[i]; } }else if(!links.length){ links = [links]; // one link } var link; for(var i = 0, len = links.length; i < len; ++i){ link = links[i]; if(typeof link.shadowboxCacheKey == 'undefined'){ // assign cache key expando // use integer primitive to avoid memory leak in IE link.shadowboxCacheKey = cache.length; SL.addEvent(link, 'click', handleClick); // add listener } cache[link.shadowboxCacheKey] = this.buildCacheObj(link, opts); } }; /** * Builds an object from the original link element data to store in cache. * These objects contain (most of) the following keys: * * - el: the link element * - title: the linked file title * - type: the linked file type * - content: the linked file's URL * - gallery: the gallery the file belongs to (optional) * - height: the height of the linked file (only necessary for movies) * - width: the width of the linked file (only necessary for movies) * - options: custom options to use (optional) * * @param {HTMLElement} link The link element to process * @return {Object} An object representing the link * @public * @static */ Shadowbox.buildCacheObj = function(link, opts){ var href = link.href; // don't use getAttribute() here var o = { el: link, title: link.getAttribute('title'), type: getPlayerType(href), options: apply({}, opts || {}), // break the reference content: href }; // remove link-level options from top-level options var opt, l_opts = ['title', 'type', 'height', 'width', 'gallery']; for(var i = 0, len = l_opts.length; i < len; ++i){ opt = l_opts[i]; if(typeof o.options[opt] != 'undefined'){ o[opt] = o.options[opt]; delete o.options[opt]; } } // HTML options always trump JavaScript options, so do these last var rel = link.getAttribute('rel'); if(rel){ // extract gallery name from shadowbox[name] format var match = rel.match(RE.gallery); if(match) o.gallery = escape(match[2]); // other parameters var params = rel.split(';'); for(var i = 0, len = params.length; i < len; ++i){ match = params[i].match(RE.param); if(match){ if(match[1] == 'options'){ eval('o.options = apply(o.options, ' + match[2] + ')'); }else{ o[match[1]] = match[2]; } } } } return o; }; /** * Applies the given set of options to those currently in use. Note: Options * will be reset on Shadowbox.open() so this function is only useful after * it has already been called (while Shadowbox is open). * * @param {Object} opts The options to apply * @return void * @public * @static */ Shadowbox.applyOptions = function(opts){ if(opts){ // use apply here to break references default_options = apply({}, options); // store default options options = apply(options, opts); // apply options } }; /** * Reverts Shadowbox' options to the last default set in use before * Shadowbox.applyOptions() was called. * * @return void * @public * @static */ Shadowbox.revertOptions = function(){ if(default_options){ options = default_options; // revert to default options default_options = null; // erase for next time } }; /** * Opens the given object in Shadowbox. This object may be either an * anchor/area element, or an object similar to the one created by * Shadowbox.buildCacheObj(). * * @param {mixed} obj The object or link element that defines * what to display * @return void * @public * @static */ Shadowbox.open = function(obj, opts){ if(activated) return; // already open activated = true; // is it a link? if(isLink(obj)){ if(typeof obj.shadowboxCacheKey == 'undefined' || typeof cache[obj.shadowboxCacheKey] == 'undefined'){ // link element that hasn't been set up before // create an object on-the-fly obj = this.buildCacheObj(obj, opts); }else{ // link element that has been set up before, get from cache obj = cache[obj.shadowboxCacheKey]; } } this.revertOptions(); if(obj.options || opts){ // use apply here to break references this.applyOptions(apply(apply({}, obj.options || {}), opts || {})); } // update current & current_gallery setupGallery(obj); // anything to display? if(current_gallery.length){ // fire onOpen hook if(options.onOpen && typeof options.onOpen == 'function'){ options.onOpen(obj); } // display:block here helps with correct dimension calculations SL.setStyle(SL.get('shadowbox'), 'display', 'block'); toggleTroubleElements(false); var dims = getDimensions(options.initialHeight, options.initialWidth); adjustHeight(dims.height, dims.top); adjustWidth(dims.width); hideBars(false); // show the overlay and load the content toggleOverlay(function(){ SL.setStyle(SL.get('shadowbox'), 'visibility', 'visible'); showLoading(); loadContent(); }); } }; /** * Jumps to the piece in the current gallery with index num. * * @param {Number} num The gallery index to view * @return void * @public * @static */ Shadowbox.change = function(num){ if(!current_gallery) return; // no current gallery if(!current_gallery[num]){ // index does not exist if(!options.continuous){ return; }else{ num = (num < 0) ? (current_gallery.length - 1) : 0; // loop } } // update current current = num; // stop listening for drag toggleDrag(false); // empty the content setContent(null); // turn this back on when done listenKeyboard(false); // fire onChange handler if(options.onChange && typeof options.onChange == 'function'){ options.onChange(current_gallery[current]); } showLoading(); hideBars(loadContent); }; /** * Jumps to the next piece in the gallery. * * @return {Boolean} True if the gallery changed to next item, false * otherwise * @public * @static */ Shadowbox.next = function(){ return this.change(current + 1); }; /** * Jumps to the previous piece in the gallery. * * @return {Boolean} True if the gallery changed to previous item, * false otherwise * @public * @static */ Shadowbox.previous = function(){ return this.change(current - 1); }; /** * Deactivates Shadowbox. * * @return void * @public * @static */ Shadowbox.close = function(){ if(!activated) return; // already closed // stop listening for keys listenKeyboard(false); // hide SL.setStyle(SL.get('shadowbox'), { display: 'none', visibility: 'hidden' }); // stop listening for scroll on IE if(absolute_pos) SL.removeEvent(window, 'scroll', centerVertically); // stop listening for drag toggleDrag(false); // empty the content setContent(null); // prevent old image requests from loading if(preloader){ preloader.onload = function(){}; preloader = null; } // hide the overlay toggleOverlay(false); // turn on trouble elements toggleTroubleElements(true); // fire onClose handler if(options.onClose && typeof options.onClose == 'function'){ options.onClose(current_gallery[current]); } activated = false; }; /** * Clears Shadowbox' cache and removes listeners and expandos from all * cached link elements. May be used to completely reset Shadowbox in case * links on a page change. * * @return void * @public * @static */ Shadowbox.clearCache = function(){ for(var i = 0, len = cache.length; i < len; ++i){ if(cache[i].el){ SL.removeEvent(cache[i].el, 'click', handleClick); delete cache[i].shadowboxCacheKey; } } cache = []; }; /** * Generates the markup necessary to embed the movie file with the given * link element. This markup will be browser-specific. Useful for generating * the media test suite. * * @param {HTMLElement} link The link to the media file * @return {Object} The proper markup to use (see above) * @public * @static */ Shadowbox.movieMarkup = function(obj){ // movies default to 300x300 pixels var h = obj.height ? parseInt(obj.height, 10) : 300; var w = obj.width ? parseInt(obj.width, 10) : 300; var autoplay = options.autoplayMovies; var controls = options.showMovieControls; if(obj.options){ if(obj.options.autoplayMovies != null){ autoplay = obj.options.autoplayMovies; } if(obj.options.showMovieControls != null){ controls = obj.options.showMovieControls; } } var markup = { tag: 'object', name: 'shadowbox_content' }; switch(obj.type){ case 'swf': var dims = getDimensions(h, w, true); h = dims.height; w = dims.width; markup.type = 'application/x-shockwave-flash'; markup.data = obj.content; markup.children = [ { tag: 'param', name: 'movie', value: obj.content } ]; break; case 'flv': autoplay = autoplay ? 'true' : 'false'; var showicons = 'false'; var a = h/w; // aspect ratio if(controls){ showicons = 'true'; h += 20; // height of JW FLV player controller } var dims = getDimensions(h, h/a, true); // resize h = dims.height; w = (h-(controls?20:0))/a; // maintain aspect ratio var flashvars = [ 'file=' + obj.content, 'height=' + h, 'width=' + w, 'autostart=' + autoplay, 'displayheight=' + (h - (controls?20:0)), 'showicons=' + showicons, 'backcolor=0x000000&frontcolor=0xCCCCCC&lightcolor=0x557722' ]; markup.type = 'application/x-shockwave-flash'; markup.data = options.assetURL + options.flvPlayer; markup.children = [ { tag: 'param', name: 'movie', value: options.assetURL + options.flvPlayer }, { tag: 'param', name: 'flashvars', value: flashvars.join('&') }, { tag: 'param', name: 'allowfullscreen', value: 'true' } ]; break; case 'qt': autoplay = autoplay ? 'true' : 'false'; if(controls){ controls = 'true'; h += 16; // height of QuickTime controller }else{ controls = 'false'; } markup.children = [ { tag: 'param', name: 'src', value: obj.content }, { tag: 'param', name: 'scale', value: 'aspect' }, { tag: 'param', name: 'controller', value: controls }, { tag: 'param', name: 'autoplay', value: autoplay } ]; if(isIE){ markup.classid = 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B'; markup.codebase = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0'; }else{ markup.type = 'video/quicktime'; markup.data = obj.content; } break; case 'wmp': autoplay = autoplay ? 1 : 0; markup.children = [ { tag: 'param', name: 'autostart', value: autoplay } ]; if(isIE){ if(controls){ controls = 'full'; h += 70; // height of WMP controller in IE }else{ controls = 'none'; } // markup.type = 'application/x-oleobject'; markup.classid = 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6'; markup.children[markup.children.length] = { tag: 'param', name: 'url', value: obj.content }; markup.children[markup.children.length] = { tag: 'param', name: 'uimode', value: controls }; }else{ if(controls){ controls = 1; h += 45; // height of WMP controller in non-IE }else{ controls = 0; } markup.type = 'video/x-ms-wmv'; markup.data = obj.content; markup.children[markup.children.length] = { tag: 'param', name: 'showcontrols', value: controls }; } break; } markup.height = h; // new height includes controller markup.width = w; return markup; }; /** * Creates an HTML string from an object representing HTML elements. Based * on Ext.DomHelper's createHtml. * * @param {Object} obj The HTML definition object * @return {String} An HTML string * @public * @static */ Shadowbox.createHTML = function(obj){ var html = '<' + obj.tag; for(var attr in obj){ if(attr == 'tag' || attr == 'html' || attr == 'children') continue; if(attr == 'cls'){ html += ' class="' + obj['cls'] + '"'; }else{ html += ' ' + attr + '="' + obj[attr] + '"'; } } if(RE.empty.test(obj.tag)){ html += '/>\n'; }else{ html += '>\n'; var cn = obj.children; if(cn){ for(var i = 0, len = cn.length; i < len; ++i){ html += this.createHTML(cn[i]); } } if(obj.html) html += obj.html; html += '\n'; } return html; }; /** * Gets an object that lists which plugins are supported by the client. The * keys of this object will be: * * - fla: Adobe Flash Player * - qt: QuickTime Player * - wmp: Windows Media Player * - f4m: Flip4Mac QuickTime Player * * @return {Object} The plugins object * @public * @static */ Shadowbox.getPlugins = function(){ return plugins; }; /** * Gets the current options object in use. * * @return {Object} The options object * @public * @static */ Shadowbox.getOptions = function(){ return options; }; /** * Gets the current gallery object. * * @return {Object} The current gallery item * @public * @static */ Shadowbox.getCurrent = function(){ return current_gallery[current]; }; /** * Gets the current version number of Shadowbox. * * @return {String} The current version * @public * @static */ Shadowbox.getVersion = function(){ return version; }; })(); /** * Finds the index of the given object in this array. * * @param {mixed} o The object to search for * @return {Number} The index of the given object * @public */ Array.prototype.indexOf = Array.prototype.indexOf || function(o){ for(var i = 0, len = this.length; i < len; ++i){ if(this[i] == o) return i; } return -1; }; /** * Formats a string with the given parameters. The string for format must have * placeholders that correspond to the numerical index of the arguments passed * in surrounded by curly braces (e.g. 'Some {0} string {1}'). * * @param {String} format The string to format * @param ... The parameters to put inside the string * @return {String} The string with the specified parameters * replaced * @public * @static */ String.format = String.format || function(format){ var args = Array.prototype.slice.call(arguments, 1); return format.replace(/\{(\d+)\}/g, function(m, i){ return args[i]; }); }; $(document).ready(function(){ $("#WTsubmit").click(function(){ $(".error").hide(); var hasError = false; var emailReg = /^([\w-\.]+@([\w-]+\.)+[\w-]{2,4})?$/; var emailToVal = $("#WTemailTo").val(); if(emailToVal == '') { $("#WTemailTo").after('You forgot to enter the email address to send to.'); hasError = true; } else if(!emailReg.test(emailToVal)) { $("#WTemailTo").after('Enter a valid email address to send to.'); hasError = true; } var emailFromVal = $("#WTemailFrom").val(); if(emailFromVal == '') { $("#WTemailFrom").after('You forgot to enter the email address to send from.'); hasError = true; } else if(!emailReg.test(emailFromVal)) { $("#WTemailFrom").after('Enter a valid email address to send from.'); hasError = true; } var subjectVal = $("#WTsubject").val(); if(subjectVal == '') { $("#WTsubject").after('You forgot to enter the subject.'); hasError = true; } var messageVal = $("#WTmessage").val(); if(messageVal == '') { $("#WTmessage").after('You forgot to enter the message.'); hasError = true; } if(hasError == false) { $(this).hide(); $("#sendEmail li.buttons").append('Loading'); $.post("/php/sendemail.php", { emailTo: emailToVal, emailFrom: emailFromVal, subject: subjectVal, message: messageVal }, function(data){ $("#WTsendEmail").slideUp("normal", function() { $("#WTsendEmail").before('

Success

Your email was sent.

'); }); } ); } return false; }); });