(function(jQuery,undefined){var plugin="parallax";var options={mouseport:'body',xparallax:true,yparallax:true,xorigin:0.5,yorigin:0.5,decay:0.66,frameDuration:30,freezeClass:'freeze'},value={left:0,top:0,middle:0.5,center:0.5,right:1,bottom:1},regex={px:/^\d+\s?px$/,percent:/^\d+\s?%$/},frameEvent='frame.'+plugin,abs=Math.abs,pointer=[0,0];function parseValue(value){return this.lib[value];}
parseValue.lib=value;function parseBool(x){return typeof x==="boolean"?x:!!(parseFloat(x));}
function parseCoord(x){return(regex.percent.exec(x))?parseFloat(x)/100:x;}
function Mouse(options,pointer){var parallax=[parseBool(options.xparallax),parseBool(options.yparallax)];this.ontarget=false;this.decay=options.decay;this.pointer=pointer||[0.5,0.5];this.update=function(pointer,threshold){if(this.ontarget){this.pointer=pointer;}
else if((!parallax[0]||abs(pointer[0]-this.pointer[0])<threshold[0])&&(!parallax[1]||abs(pointer[1]-this.pointer[1])<threshold[1])){this.ontarget=true;this.pointer=pointer;}
else{var lagPointer=[],x=2;while(x--){if(parallax[x]){lagPointer[x]=pointer[x]+this.decay*(this.pointer[x]-pointer[x]);}}
this.pointer=lagPointer;}};}
function Port(object,options){var self=this,elem=object instanceof jQuery?object:jQuery(object),parallax=[parseBool(options.xparallax),parseBool(options.yparallax)],inside=0,leaveCoords;this.pointer=[0,0];this.active=false;this.activeOutside=(options&&options.activeOutside)||false;this.update=function(coords){var pos=this.pos,size=this.size,pointer=[],x=2;if(inside>0){if(inside===2){inside=0;if(leaveCoords){coords=leaveCoords};}
while(x--){if(parallax[x]){pointer[x]=(coords[x]-pos[x])/size[x];pointer[x]=pointer[x]<0?0:pointer[x]>1?1:pointer[x];}}
this.active=true;this.pointer=pointer;}
else{this.active=false;}};this.updateSize=function(){var width=elem.width(),height=elem.height();self.size=[width,height];self.threshold=[1/width,1/height];};this.updatePos=function(){var offset=elem.offset()||{left:0,top:0},left=parseInt(elem.css('borderLeftWidth'))+parseInt(elem.css('paddingLeft')),top=parseInt(elem.css('borderTopWidth'))+parseInt(elem.css('paddingTop'));self.pos=[offset.left+left,offset.top+top];};jQuery(window).bind('resize.'+plugin,self.updateSize).bind('resize.'+plugin,self.updatePos);elem.bind('mouseenter.'+plugin,function(e){inside=1;}).bind('mouseleave.'+plugin,function(e){inside=2;leaveCoords=[e.pageX,e.pageY];});this.updateSize();this.updatePos();}
function Layer(elem,options){var px=[],parallax=[],offset=[],position=[];this.update=function(pointer){var pos=[],cssPosition,cssMargin,x=2,css={};while(x--){if(parallax[x]){pos[x]=parallax[x]*pointer[x]+offset[x];if(px[x]){cssPosition=position[x];cssMargin=pos[x]*-1;}
else{cssPosition=pos[x]*100+'%';cssMargin=pos[x]*this.size[x]*-1;}
if(x===0){css.left=cssPosition;css.marginLeft=cssMargin;}
else{css.top=cssPosition;css.marginTop=cssMargin;}}}
elem.css(css);};this.setParallax=function(xp,yp,xo,yo){var p=[xp||options.xparallax,yp||options.yparallax],origin=[xo||options.xorigin,yo||options.yorigin],i=2,css={};while(i--){px[i]=regex.px.test(p[i]);if(typeof origin[i]==='string'){origin[i]=origin[i]===undefined?1:value[origin[i]]||parseCoord(origin[i]);}
if(px[i]){parallax[i]=parseInt(p[i]);offset[i]=origin[i]*(this.size[i]-parallax[i]);position[i]=origin[i]*100+'%';}
else{parallax[i]=p[i]===true?1:parseCoord(p[i]);offset[i]=parallax[i]?origin[i]*(1-parallax[i]):0;}}};this.getPointer=function(){var viewport=elem.offsetParent(),pos=elem.position(),position=[],pointer=[],i=2;while(i--){if(px[i]){position[i]=0;}
else{position[i]=pos[i===0?'left':'top']/(viewport[i===0?'outerWidth':'outerHeight']()-this.size[i]);}
pointer[i]=(position[i]-offset[i])/parallax[i];}
return pointer;};this.setSize=function(x,y){this.size=[x||elem.outerWidth(),y||elem.outerHeight()];};this.setSize(options.width,options.height);this.setParallax(options.xparallax,options.yparallax,options.xorigin,options.yorigin);}
function update(e){var elem=jQuery(this),global=e.data,local=elem.data(plugin),port=global.port,mouse=global.mouse,localmouse=local.mouse,process=global.timeStamp!==e.timeStamp;if(process){global.timeStamp=e.timeStamp;port.update(pointer);if(port.active||!mouse.ontarget){mouse.update(port.pointer,port.threshold);}}
if(localmouse){localmouse.update(local.freeze?local.freeze.pointer:port.pointer,port.threshold);if(localmouse.ontarget){delete local.mouse;if(local.freeze){elem.unbind(frameEvent).addClass(global.freezeClass);}}
mouse=localmouse;}
else{if(mouse.ontarget&&!port.active){elem.unbind(frameEvent);}}
local.layer.update(mouse.pointer);}
jQuery.fn[plugin]=function(o){var global=jQuery.extend({},jQuery.fn[plugin].options,o),args=arguments,layers=this;if(!(global.mouseport instanceof jQuery)){global.mouseport=jQuery(global.mouseport);}
global.port=new Port(global.mouseport,global);global.mouse=new Mouse(global);global.mouseport.bind("mouseenter",function(e){global.mouse.ontarget=false;layers.each(function(i){var layer=jQuery(this);if(!layer.data(plugin).freeze){layer.bind(frameEvent,global,update);}});});return layers.bind("freeze",function(e){var elem=jQuery(this),local=elem.data(plugin),mouse=local.mouse||local.freeze||global.mouse,coords=coords=[e.x===undefined?mouse.pointer[0]:parseCoord(e.x),e.y===undefined?mouse.pointer[1]:parseCoord(e.y)],decay=e.decay;local.freeze={pointer:coords};local.mouse=new Mouse(global,mouse.pointer);if(decay!==undefined){local.mouse.decay=decay;};elem.bind(frameEvent,global,update);}).bind("unfreeze",function(e){var elem=jQuery(this),local=elem.data(plugin),decay=e.decay,pointer;if(local.freeze){pointer=local.mouse?local.mouse.pointer:local.freeze.pointer;local.mouse=new Mouse(global);local.mouse.pointer=pointer;if(decay!==undefined)local.mouse.decay=decay;delete local.freeze;elem.removeClass(options.freezeClass).bind(frameEvent,global,update);}}).each(function(i){var elem=jQuery(this),layerOptions=args[i+1]?jQuery.extend({},global,args[i+1]):global,layer=new Layer(elem,layerOptions);elem.data(plugin,{layer:layer,mouse:new Mouse(layerOptions,layer.getPointer())});});};jQuery.fn[plugin].options=options;jQuery(document).ready(function(){jQuery(document).mousemove(function(e){pointer=[e.pageX,e.pageY];});});}(jQuery));
