/*
 * jQuery 1.2.6 - 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-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
 * $Rev: 5685 $
 */
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(H(){J w=1b.4M,3m$=1b.$;J D=1b.4M=1b.$=H(a,b){I 2B D.17.5j(a,b)};J u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/,62=/^.[^:#\\[\\.]*$/,12;D.17=D.44={5j:H(d,b){d=d||S;G(d.16){7[0]=d;7.K=1;I 7}G(1j d=="23"){J c=u.2D(d);G(c&&(c[1]||!b)){G(c[1])d=D.4h([c[1]],b);N{J a=S.61(c[3]);G(a){G(a.2v!=c[3])I D().2q(d);I D(a)}d=[]}}N I D(b).2q(d)}N G(D.1D(d))I D(S)[D.17.27?"27":"43"](d);I 7.6Y(D.2d(d))},5w:"1.2.6",8G:H(){I 7.K},K:0,3p:H(a){I a==12?D.2d(7):7[a]},2I:H(b){J a=D(b);a.5n=7;I a},6Y:H(a){7.K=0;2p.44.1p.1w(7,a);I 7},P:H(a,b){I D.P(7,a,b)},5i:H(b){J a=-1;I D.2L(b&&b.5w?b[0]:b,7)},1K:H(c,a,b){J d=c;G(c.1q==56)G(a===12)I 7[0]&&D[b||"1K"](7[0],c);N{d={};d[c]=a}I 7.P(H(i){R(c 1n d)D.1K(b?7.V:7,c,D.1i(7,d[c],b,i,c))})},1g:H(b,a){G((b==\'2h\'||b==\'1Z\')&&3d(a)<0)a=12;I 7.1K(b,a,"2a")},1r:H(b){G(1j b!="49"&&b!=U)I 7.4E().3v((7[0]&&7[0].2z||S).5F(b));J a="";D.P(b||7,H(){D.P(7.3t,H(){G(7.16!=8)a+=7.16!=1?7.76:D.17.1r([7])})});I a},5z:H(b){G(7[0])D(b,7[0].2z).5y().39(7[0]).2l(H(){J a=7;1B(a.1x)a=a.1x;I a}).3v(7);I 7},8Y:H(a){I 7.P(H(){D(7).6Q().5z(a)})},8R:H(a){I 7.P(H(){D(7).5z(a)})},3v:H(){I 7.3W(19,M,Q,H(a){G(7.16==1)7.3U(a)})},6F:H(){I 7.3W(19,M,M,H(a){G(7.16==1)7.39(a,7.1x)})},6E:H(){I 7.3W(19,Q,Q,H(a){7.1d.39(a,7)})},5q:H(){I 7.3W(19,Q,M,H(a){7.1d.39(a,7.2H)})},3l:H(){I 7.5n||D([])},2q:H(b){J c=D.2l(7,H(a){I D.2q(b,a)});I 7.2I(/[^+>] [^+>]/.11(b)||b.1h("..")>-1?D.4r(c):c)},5y:H(e){J f=7.2l(H(){G(D.14.1f&&!D.4n(7)){J a=7.6o(M),5h=S.3h("1v");5h.3U(a);I D.4h([5h.4H])[0]}N I 7.6o(M)});J d=f.2q("*").5c().P(H(){G(7[E]!=12)7[E]=U});G(e===M)7.2q("*").5c().P(H(i){G(7.16==3)I;J c=D.L(7,"3w");R(J a 1n c)R(J b 1n c[a])D.W.1e(d[i],a,c[a][b],c[a][b].L)});I f},1E:H(b){I 7.2I(D.1D(b)&&D.3C(7,H(a,i){I b.1k(a,i)})||D.3g(b,7))},4Y:H(b){G(b.1q==56)G(62.11(b))I 7.2I(D.3g(b,7,M));N b=D.3g(b,7);J a=b.K&&b[b.K-1]!==12&&!b.16;I 7.1E(H(){I a?D.2L(7,b)<0:7!=b})},1e:H(a){I 7.2I(D.4r(D.2R(7.3p(),1j a==\'23\'?D(a):D.2d(a))))},3F:H(a){I!!a&&D.3g(a,7).K>0},7T:H(a){I 7.3F("."+a)},6e:H(b){G(b==12){G(7.K){J c=7[0];G(D.Y(c,"2A")){J e=c.64,63=[],15=c.15,2V=c.O=="2A-2V";G(e<0)I U;R(J i=2V?e:0,2f=2V?e+1:15.K;i<2f;i++){J d=15[i];G(d.2W){b=D.14.1f&&!d.at.2x.an?d.1r:d.2x;G(2V)I b;63.1p(b)}}I 63}N I(7[0].2x||"").1o(/\\r/g,"")}I 12}G(b.1q==4L)b+=\'\';I 7.P(H(){G(7.16!=1)I;G(b.1q==2p&&/5O|5L/.11(7.O))7.4J=(D.2L(7.2x,b)>=0||D.2L(7.34,b)>=0);N G(D.Y(7,"2A")){J a=D.2d(b);D("9R",7).P(H(){7.2W=(D.2L(7.2x,a)>=0||D.2L(7.1r,a)>=0)});G(!a.K)7.64=-1}N 7.2x=b})},2K:H(a){I a==12?(7[0]?7[0].4H:U):7.4E().3v(a)},7b:H(a){I 7.5q(a).21()},79:H(i){I 7.3s(i,i+1)},3s:H(){I 7.2I(2p.44.3s.1w(7,19))},2l:H(b){I 7.2I(D.2l(7,H(a,i){I b.1k(a,i,a)}))},5c:H(){I 7.1e(7.5n)},L:H(d,b){J a=d.1R(".");a[1]=a[1]?"."+a[1]:"";G(b===12){J c=7.5C("9z"+a[1]+"!",[a[0]]);G(c===12&&7.K)c=D.L(7[0],d);I c===12&&a[1]?7.L(a[0]):c}N I 7.1P("9u"+a[1]+"!",[a[0],b]).P(H(){D.L(7,d,b)})},3b:H(a){I 7.P(H(){D.3b(7,a)})},3W:H(g,f,h,d){J e=7.K>1,3x;I 7.P(H(){G(!3x){3x=D.4h(g,7.2z);G(h)3x.9o()}J b=7;G(f&&D.Y(7,"1T")&&D.Y(3x[0],"4F"))b=7.3H("22")[0]||7.3U(7.2z.3h("22"));J c=D([]);D.P(3x,H(){J a=e?D(7).5y(M)[0]:7;G(D.Y(a,"1m"))c=c.1e(a);N{G(a.16==1)c=c.1e(D("1m",a).21());d.1k(b,a)}});c.P(6T)})}};D.17.5j.44=D.17;H 6T(i,a){G(a.4d)D.3Y({1a:a.4d,31:Q,1O:"1m"});N D.5u(a.1r||a.6O||a.4H||"");G(a.1d)a.1d.37(a)}H 1z(){I+2B 8J}D.1l=D.17.1l=H(){J b=19[0]||{},i=1,K=19.K,4x=Q,15;G(b.1q==8I){4x=b;b=19[1]||{};i=2}G(1j b!="49"&&1j b!="H")b={};G(K==i){b=7;--i}R(;i<K;i++)G((15=19[i])!=U)R(J c 1n 15){J a=b[c],2w=15[c];G(b===2w)6M;G(4x&&2w&&1j 2w=="49"&&!2w.16)b[c]=D.1l(4x,a||(2w.K!=U?[]:{}),2w);N G(2w!==12)b[c]=2w}I b};J E="4M"+1z(),6K=0,5r={},6G=/z-?5i|8B-?8A|1y|6B|8v-?1Z/i,3P=S.3P||{};D.1l({8u:H(a){1b.$=3m$;G(a)1b.4M=w;I D},1D:H(a){I!!a&&1j a!="23"&&!a.Y&&a.1q!=2p&&/^[\\s[]?H/.11(a+"")},4n:H(a){I a.1C&&!a.1c||a.2j&&a.2z&&!a.2z.1c},5u:H(a){a=D.3k(a);G(a){J b=S.3H("6w")[0]||S.1C,1m=S.3h("1m");1m.O="1r/4t";G(D.14.1f)1m.1r=a;N 1m.3U(S.5F(a));b.39(1m,b.1x);b.37(1m)}},Y:H(b,a){I b.Y&&b.Y.2r()==a.2r()},1Y:{},L:H(c,d,b){c=c==1b?5r:c;J a=c[E];G(!a)a=c[E]=++6K;G(d&&!D.1Y[a])D.1Y[a]={};G(b!==12)D.1Y[a][d]=b;I d?D.1Y[a][d]:a},3b:H(c,b){c=c==1b?5r:c;J a=c[E];G(b){G(D.1Y[a]){2U D.1Y[a][b];b="";R(b 1n D.1Y[a])1X;G(!b)D.3b(c)}}N{1U{2U c[E]}1V(e){G(c.5l)c.5l(E)}2U D.1Y[a]}},P:H(d,a,c){J e,i=0,K=d.K;G(c){G(K==12){R(e 1n d)G(a.1w(d[e],c)===Q)1X}N R(;i<K;)G(a.1w(d[i++],c)===Q)1X}N{G(K==12){R(e 1n d)G(a.1k(d[e],e,d[e])===Q)1X}N R(J b=d[0];i<K&&a.1k(b,i,b)!==Q;b=d[++i]){}}I d},1i:H(b,a,c,i,d){G(D.1D(a))a=a.1k(b,i);I a&&a.1q==4L&&c=="2a"&&!6G.11(d)?a+"2X":a},1F:{1e:H(c,b){D.P((b||"").1R(/\\s+/),H(i,a){G(c.16==1&&!D.1F.3T(c.1F,a))c.1F+=(c.1F?" ":"")+a})},21:H(c,b){G(c.16==1)c.1F=b!=12?D.3C(c.1F.1R(/\\s+/),H(a){I!D.1F.3T(b,a)}).6s(" "):""},3T:H(b,a){I D.2L(a,(b.1F||b).6r().1R(/\\s+/))>-1}},6q:H(b,c,a){J e={};R(J d 1n c){e[d]=b.V[d];b.V[d]=c[d]}a.1k(b);R(J d 1n c)b.V[d]=e[d]},1g:H(d,e,c){G(e=="2h"||e=="1Z"){J b,3X={30:"5x",5g:"1G",18:"3I"},35=e=="2h"?["5e","6k"]:["5G","6i"];H 5b(){b=e=="2h"?d.8f:d.8c;J a=0,2C=0;D.P(35,H(){a+=3d(D.2a(d,"57"+7,M))||0;2C+=3d(D.2a(d,"2C"+7+"4b",M))||0});b-=29.83(a+2C)}G(D(d).3F(":4j"))5b();N D.6q(d,3X,5b);I 29.2f(0,b)}I D.2a(d,e,c)},2a:H(f,l,k){J e,V=f.V;H 3E(b){G(!D.14.2k)I Q;J a=3P.54(b,U);I!a||a.52("3E")==""}G(l=="1y"&&D.14.1f){e=D.1K(V,"1y");I e==""?"1":e}G(D.14.2G&&l=="18"){J d=V.50;V.50="0 7Y 7W";V.50=d}G(l.1I(/4i/i))l=y;G(!k&&V&&V[l])e=V[l];N G(3P.54){G(l.1I(/4i/i))l="4i";l=l.1o(/([A-Z])/g,"-$1").3y();J c=3P.54(f,U);G(c&&!3E(f))e=c.52(l);N{J g=[],2E=[],a=f,i=0;R(;a&&3E(a);a=a.1d)2E.6h(a);R(;i<2E.K;i++)G(3E(2E[i])){g[i]=2E[i].V.18;2E[i].V.18="3I"}e=l=="18"&&g[2E.K-1]!=U?"2F":(c&&c.52(l))||"";R(i=0;i<g.K;i++)G(g[i]!=U)2E[i].V.18=g[i]}G(l=="1y"&&e=="")e="1"}N G(f.4g){J h=l.1o(/\\-(\\w)/g,H(a,b){I b.2r()});e=f.4g[l]||f.4g[h];G(!/^\\d+(2X)?$/i.11(e)&&/^\\d/.11(e)){J j=V.1A,66=f.65.1A;f.65.1A=f.4g.1A;V.1A=e||0;e=V.aM+"2X";V.1A=j;f.65.1A=66}}I e},4h:H(l,h){J k=[];h=h||S;G(1j h.3h==\'12\')h=h.2z||h[0]&&h[0].2z||S;D.P(l,H(i,d){G(!d)I;G(d.1q==4L)d+=\'\';G(1j d=="23"){d=d.1o(/(<(\\w+)[^>]*?)\\/>/g,H(b,a,c){I c.1I(/^(aK|4f|7E|aG|4T|7A|aB|3n|az|ay|av)$/i)?b:a+"></"+c+">"});J f=D.3k(d).3y(),1v=h.3h("1v");J e=!f.1h("<au")&&[1,"<2A 7w=\'7w\'>","</2A>"]||!f.1h("<ar")&&[1,"<7v>","</7v>"]||f.1I(/^<(aq|22|am|ak|ai)/)&&[1,"<1T>","</1T>"]||!f.1h("<4F")&&[2,"<1T><22>","</22></1T>"]||(!f.1h("<af")||!f.1h("<ad"))&&[3,"<1T><22><4F>","</4F></22></1T>"]||!f.1h("<7E")&&[2,"<1T><22></22><7q>","</7q></1T>"]||D.14.1f&&[1,"1v<1v>","</1v>"]||[0,"",""];1v.4H=e[1]+d+e[2];1B(e[0]--)1v=1v.5T;G(D.14.1f){J g=!f.1h("<1T")&&f.1h("<22")<0?1v.1x&&1v.1x.3t:e[1]=="<1T>"&&f.1h("<22")<0?1v.3t:[];R(J j=g.K-1;j>=0;--j)G(D.Y(g[j],"22")&&!g[j].3t.K)g[j].1d.37(g[j]);G(/^\\s/.11(d))1v.39(h.5F(d.1I(/^\\s*/)[0]),1v.1x)}d=D.2d(1v.3t)}G(d.K===0&&(!D.Y(d,"3V")&&!D.Y(d,"2A")))I;G(d[0]==12||D.Y(d,"3V")||d.15)k.1p(d);N k=D.2R(k,d)});I k},1K:H(d,f,c){G(!d||d.16==3||d.16==8)I 12;J e=!D.4n(d),40=c!==12,1f=D.14.1f;f=e&&D.3X[f]||f;G(d.2j){J g=/5Q|4d|V/.11(f);G(f=="2W"&&D.14.2k)d.1d.64;G(f 1n d&&e&&!g){G(40){G(f=="O"&&D.Y(d,"4T")&&d.1d)7p"O a3 a1\'t 9V 9U";d[f]=c}G(D.Y(d,"3V")&&d.7i(f))I d.7i(f).76;I d[f]}G(1f&&e&&f=="V")I D.1K(d.V,"9T",c);G(40)d.9Q(f,""+c);J h=1f&&e&&g?d.4G(f,2):d.4G(f);I h===U?12:h}G(1f&&f=="1y"){G(40){d.6B=1;d.1E=(d.1E||"").1o(/7f\\([^)]*\\)/,"")+(3r(c)+\'\'=="9L"?"":"7f(1y="+c*7a+")")}I d.1E&&d.1E.1h("1y=")>=0?(3d(d.1E.1I(/1y=([^)]*)/)[1])/7a)+\'\':""}f=f.1o(/-([a-z])/9H,H(a,b){I b.2r()});G(40)d[f]=c;I d[f]},3k:H(a){I(a||"").1o(/^\\s+|\\s+$/g,"")},2d:H(b){J a=[];G(b!=U){J i=b.K;G(i==U||b.1R||b.4I||b.1k)a[0]=b;N 1B(i)a[--i]=b[i]}I a},2L:H(b,a){R(J i=0,K=a.K;i<K;i++)G(a[i]===b)I i;I-1},2R:H(a,b){J i=0,T,2S=a.K;G(D.14.1f){1B(T=b[i++])G(T.16!=8)a[2S++]=T}N 1B(T=b[i++])a[2S++]=T;I a},4r:H(a){J c=[],2o={};1U{R(J i=0,K=a.K;i<K;i++){J b=D.L(a[i]);G(!2o[b]){2o[b]=M;c.1p(a[i])}}}1V(e){c=a}I c},3C:H(c,a,d){J b=[];R(J i=0,K=c.K;i<K;i++)G(!d!=!a(c[i],i))b.1p(c[i]);I b},2l:H(d,a){J c=[];R(J i=0,K=d.K;i<K;i++){J b=a(d[i],i);G(b!=U)c[c.K]=b}I c.7d.1w([],c)}});J v=9B.9A.3y();D.14={5B:(v.1I(/.+(?:9y|9x|9w|9v)[\\/: ]([\\d.]+)/)||[])[1],2k:/75/.11(v),2G:/2G/.11(v),1f:/1f/.11(v)&&!/2G/.11(v),42:/42/.11(v)&&!/(9s|75)/.11(v)};J y=D.14.1f?"7o":"72";D.1l({71:!D.14.1f||S.70=="6Z",3X:{"R":"9n","9k":"1F","4i":y,72:y,7o:y,9h:"9f",9e:"9d",9b:"99"}});D.P({6W:H(a){I a.1d},97:H(a){I D.4S(a,"1d")},95:H(a){I D.3a(a,2,"2H")},91:H(a){I D.3a(a,2,"4l")},8Z:H(a){I D.4S(a,"2H")},8X:H(a){I D.4S(a,"4l")},8W:H(a){I D.5v(a.1d.1x,a)},8V:H(a){I D.5v(a.1x)},6Q:H(a){I D.Y(a,"8U")?a.8T||a.8S.S:D.2d(a.3t)}},H(c,d){D.17[c]=H(b){J a=D.2l(7,d);G(b&&1j b=="23")a=D.3g(b,a);I 7.2I(D.4r(a))}});D.P({6P:"3v",8Q:"6F",39:"6E",8P:"5q",8O:"7b"},H(c,b){D.17[c]=H(){J a=19;I 7.P(H(){R(J i=0,K=a.K;i<K;i++)D(a[i])[b](7)})}});D.P({8N:H(a){D.1K(7,a,"");G(7.16==1)7.5l(a)},8M:H(a){D.1F.1e(7,a)},8L:H(a){D.1F.21(7,a)},8K:H(a){D.1F[D.1F.3T(7,a)?"21":"1e"](7,a)},21:H(a){G(!a||D.1E(a,[7]).r.K){D("*",7).1e(7).P(H(){D.W.21(7);D.3b(7)});G(7.1d)7.1d.37(7)}},4E:H(){D(">*",7).21();1B(7.1x)7.37(7.1x)}},H(a,b){D.17[a]=H(){I 7.P(b,19)}});D.P(["6N","4b"],H(i,c){J b=c.3y();D.17[b]=H(a){I 7[0]==1b?D.14.2G&&S.1c["5t"+c]||D.14.2k&&1b["5s"+c]||S.70=="6Z"&&S.1C["5t"+c]||S.1c["5t"+c]:7[0]==S?29.2f(29.2f(S.1c["4y"+c],S.1C["4y"+c]),29.2f(S.1c["2i"+c],S.1C["2i"+c])):a==12?(7.K?D.1g(7[0],b):U):7.1g(b,a.1q==56?a:a+"2X")}});H 25(a,b){I a[0]&&3r(D.2a(a[0],b,M),10)||0}J C=D.14.2k&&3r(D.14.5B)<8H?"(?:[\\\\w*3m-]|\\\\\\\\.)":"(?:[\\\\w\\8F-\\8E*3m-]|\\\\\\\\.)",6L=2B 4v("^>\\\\s*("+C+"+)"),6J=2B 4v("^("+C+"+)(#)("+C+"+)"),6I=2B 4v("^([#.]?)("+C+"*)");D.1l({6H:{"":H(a,i,m){I m[2]=="*"||D.Y(a,m[2])},"#":H(a,i,m){I a.4G("2v")==m[2]},":":{8D:H(a,i,m){I i<m[3]-0},8C:H(a,i,m){I i>m[3]-0},3a:H(a,i,m){I m[3]-0==i},79:H(a,i,m){I m[3]-0==i},3o:H(a,i){I i==0},3S:H(a,i,m,r){I i==r.K-1},6D:H(a,i){I i%2==0},6C:H(a,i){I i%2},"3o-4u":H(a){I a.1d.3H("*")[0]==a},"3S-4u":H(a){I D.3a(a.1d.5T,1,"4l")==a},"8z-4u":H(a){I!D.3a(a.1d.5T,2,"4l")},6W:H(a){I a.1x},4E:H(a){I!a.1x},8y:H(a,i,m){I(a.6O||a.8x||D(a).1r()||"").1h(m[3])>=0},4j:H(a){I"1G"!=a.O&&D.1g(a,"18")!="2F"&&D.1g(a,"5g")!="1G"},1G:H(a){I"1G"==a.O||D.1g(a,"18")=="2F"||D.1g(a,"5g")=="1G"},8w:H(a){I!a.3R},3R:H(a){I a.3R},4J:H(a){I a.4J},2W:H(a){I a.2W||D.1K(a,"2W")},1r:H(a){I"1r"==a.O},5O:H(a){I"5O"==a.O},5L:H(a){I"5L"==a.O},5p:H(a){I"5p"==a.O},3Q:H(a){I"3Q"==a.O},5o:H(a){I"5o"==a.O},6A:H(a){I"6A"==a.O},6z:H(a){I"6z"==a.O},2s:H(a){I"2s"==a.O||D.Y(a,"2s")},4T:H(a){I/4T|2A|6y|2s/i.11(a.Y)},3T:H(a,i,m){I D.2q(m[3],a).K},8t:H(a){I/h\\d/i.11(a.Y)},8s:H(a){I D.3C(D.3O,H(b){I a==b.T}).K}}},6x:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,2B 4v("^([:.#]*)("+C+"+)")],3g:H(a,c,b){J d,1t=[];1B(a&&a!=d){d=a;J f=D.1E(a,c,b);a=f.t.1o(/^\\s*,\\s*/,"");1t=b?c=f.r:D.2R(1t,f.r)}I 1t},2q:H(t,o){G(1j t!="23")I[t];G(o&&o.16!=1&&o.16!=9)I[];o=o||S;J d=[o],2o=[],3S,Y;1B(t&&3S!=t){J r=[];3S=t;t=D.3k(t);J l=Q,3j=6L,m=3j.2D(t);G(m){Y=m[1].2r();R(J i=0;d[i];i++)R(J c=d[i].1x;c;c=c.2H)G(c.16==1&&(Y=="*"||c.Y.2r()==Y))r.1p(c);d=r;t=t.1o(3j,"");G(t.1h(" ")==0)6M;l=M}N{3j=/^([>+~])\\s*(\\w*)/i;G((m=3j.2D(t))!=U){r=[];J k={};Y=m[2].2r();m=m[1];R(J j=0,3i=d.K;j<3i;j++){J n=m=="~"||m=="+"?d[j].2H:d[j].1x;R(;n;n=n.2H)G(n.16==1){J g=D.L(n);G(m=="~"&&k[g])1X;G(!Y||n.Y.2r()==Y){G(m=="~")k[g]=M;r.1p(n)}G(m=="+")1X}}d=r;t=D.3k(t.1o(3j,""));l=M}}G(t&&!l){G(!t.1h(",")){G(o==d[0])d.4s();2o=D.2R(2o,d);r=d=[o];t=" "+t.6v(1,t.K)}N{J h=6J;J m=h.2D(t);G(m){m=[0,m[2],m[3],m[1]]}N{h=6I;m=h.2D(t)}m[2]=m[2].1o(/\\\\/g,"");J f=d[d.K-1];G(m[1]=="#"&&f&&f.61&&!D.4n(f)){J p=f.61(m[2]);G((D.14.1f||D.14.2G)&&p&&1j p.2v=="23"&&p.2v!=m[2])p=D(\'[@2v="\'+m[2]+\'"]\',f)[0];d=r=p&&(!m[3]||D.Y(p,m[3]))?[p]:[]}N{R(J i=0;d[i];i++){J a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];G(a=="*"&&d[i].Y.3y()=="49")a="3n";r=D.2R(r,d[i].3H(a))}G(m[1]==".")r=D.5m(r,m[2]);G(m[1]=="#"){J e=[];R(J i=0;r[i];i++)G(r[i].4G("2v")==m[2]){e=[r[i]];1X}r=e}d=r}t=t.1o(h,"")}}G(t){J b=D.1E(t,r);d=r=b.r;t=D.3k(b.t)}}G(t)d=[];G(d&&o==d[0])d.4s();2o=D.2R(2o,d);I 2o},5m:H(r,m,a){m=" "+m+" ";J c=[];R(J i=0;r[i];i++){J b=(" "+r[i].1F+" ").1h(m)>=0;G(!a&&b||a&&!b)c.1p(r[i])}I c},1E:H(t,r,h){J d;1B(t&&t!=d){d=t;J p=D.6x,m;R(J i=0;p[i];i++){m=p[i].2D(t);G(m){t=t.8r(m[0].K);m[2]=m[2].1o(/\\\\/g,"");1X}}G(!m)1X;G(m[1]==":"&&m[2]=="4Y")r=62.11(m[3])?D.1E(m[3],r,M).r:D(r).4Y(m[3]);N G(m[1]==".")r=D.5m(r,m[2],h);N G(m[1]=="["){J g=[],O=m[3];R(J i=0,3i=r.K;i<3i;i++){J a=r[i],z=a[D.3X[m[2]]||m[2]];G(z==U||/5Q|4d|2W/.11(m[2]))z=D.1K(a,m[2])||\'\';G((O==""&&!!z||O=="="&&z==m[5]||O=="!="&&z!=m[5]||O=="^="&&z&&!z.1h(m[5])||O=="$="&&z.6v(z.K-m[5].K)==m[5]||(O=="*="||O=="~=")&&z.1h(m[5])>=0)^h)g.1p(a)}r=g}N G(m[1]==":"&&m[2]=="3a-4u"){J e={},g=[],11=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2D(m[3]=="6D"&&"2n"||m[3]=="6C"&&"2n+1"||!/\\D/.11(m[3])&&"8q+"+m[3]||m[3]),3o=(11[1]+(11[2]||1))-0,d=11[3]-0;R(J i=0,3i=r.K;i<3i;i++){J j=r[i],1d=j.1d,2v=D.L(1d);G(!e[2v]){J c=1;R(J n=1d.1x;n;n=n.2H)G(n.16==1)n.4q=c++;e[2v]=M}J b=Q;G(3o==0){G(j.4q==d)b=M}N G((j.4q-d)%3o==0&&(j.4q-d)/3o>=0)b=M;G(b^h)g.1p(j)}r=g}N{J f=D.6H[m[1]];G(1j f=="49")f=f[m[2]];G(1j f=="23")f=6u("Q||H(a,i){I "+f+";}");r=D.3C(r,H(a,i){I f(a,i,m,r)},h)}}I{r:r,t:t}},4S:H(b,c){J a=[],1t=b[c];1B(1t&&1t!=S){G(1t.16==1)a.1p(1t);1t=1t[c]}I a},3a:H(a,e,c,b){e=e||1;J d=0;R(;a;a=a[c])G(a.16==1&&++d==e)1X;I a},5v:H(n,a){J r=[];R(;n;n=n.2H){G(n.16==1&&n!=a)r.1p(n)}I r}});D.W={1e:H(f,i,g,e){G(f.16==3||f.16==8)I;G(D.14.1f&&f.4I)f=1b;G(!g.24)g.24=7.24++;G(e!=12){J h=g;g=7.3M(h,H(){I h.1w(7,19)});g.L=e}J j=D.L(f,"3w")||D.L(f,"3w",{}),1H=D.L(f,"1H")||D.L(f,"1H",H(){G(1j D!="12"&&!D.W.5k)I D.W.1H.1w(19.3L.T,19)});1H.T=f;D.P(i.1R(/\\s+/),H(c,b){J a=b.1R(".");b=a[0];g.O=a[1];J d=j[b];G(!d){d=j[b]={};G(!D.W.2t[b]||D.W.2t[b].4p.1k(f)===Q){G(f.3K)f.3K(b,1H,Q);N G(f.6t)f.6t("4o"+b,1H)}}d[g.24]=g;D.W.26[b]=M});f=U},24:1,26:{},21:H(e,h,f){G(e.16==3||e.16==8)I;J i=D.L(e,"3w"),1L,5i;G(i){G(h==12||(1j h=="23"&&h.8p(0)=="."))R(J g 1n i)7.21(e,g+(h||""));N{G(h.O){f=h.2y;h=h.O}D.P(h.1R(/\\s+/),H(b,a){J c=a.1R(".");a=c[0];G(i[a]){G(f)2U i[a][f.24];N R(f 1n i[a])G(!c[1]||i[a][f].O==c[1])2U i[a][f];R(1L 1n i[a])1X;G(!1L){G(!D.W.2t[a]||D.W.2t[a].4A.1k(e)===Q){G(e.6p)e.6p(a,D.L(e,"1H"),Q);N G(e.6n)e.6n("4o"+a,D.L(e,"1H"))}1L=U;2U i[a]}}})}R(1L 1n i)1X;G(!1L){J d=D.L(e,"1H");G(d)d.T=U;D.3b(e,"3w");D.3b(e,"1H")}}},1P:H(h,c,f,g,i){c=D.2d(c);G(h.1h("!")>=0){h=h.3s(0,-1);J a=M}G(!f){G(7.26[h])D("*").1e([1b,S]).1P(h,c)}N{G(f.16==3||f.16==8)I 12;J b,1L,17=D.1D(f[h]||U),W=!c[0]||!c[0].32;G(W){c.6h({O:h,2J:f,32:H(){},3J:H(){},4C:1z()});c[0][E]=M}c[0].O=h;G(a)c[0].6m=M;J d=D.L(f,"1H");G(d)b=d.1w(f,c);G((!17||(D.Y(f,\'a\')&&h=="4V"))&&f["4o"+h]&&f["4o"+h].1w(f,c)===Q)b=Q;G(W)c.4s();G(i&&D.1D(i)){1L=i.1w(f,b==U?c:c.7d(b));G(1L!==12)b=1L}G(17&&g!==Q&&b!==Q&&!(D.Y(f,\'a\')&&h=="4V")){7.5k=M;1U{f[h]()}1V(e){}}7.5k=Q}I b},1H:H(b){J a,1L,38,5f,4m;b=19[0]=D.W.6l(b||1b.W);38=b.O.1R(".");b.O=38[0];38=38[1];5f=!38&&!b.6m;4m=(D.L(7,"3w")||{})[b.O];R(J j 1n 4m){J c=4m[j];G(5f||c.O==38){b.2y=c;b.L=c.L;1L=c.1w(7,19);G(a!==Q)a=1L;G(1L===Q){b.32();b.3J()}}}I a},6l:H(b){G(b[E]==M)I b;J d=b;b={8o:d};J c="8n 8m 8l 8k 2s 8j 47 5d 6j 5E 8i L 8h 8g 4K 2y 5a 59 8e 8b 58 6f 8a 88 4k 87 86 84 6d 2J 4C 6c O 82 81 35".1R(" ");R(J i=c.K;i;i--)b[c[i]]=d[c[i]];b[E]=M;b.32=H(){G(d.32)d.32();d.80=Q};b.3J=H(){G(d.3J)d.3J();d.7Z=M};b.4C=b.4C||1z();G(!b.2J)b.2J=b.6d||S;G(b.2J.16==3)b.2J=b.2J.1d;G(!b.4k&&b.4K)b.4k=b.4K==b.2J?b.6c:b.4K;G(b.58==U&&b.5d!=U){J a=S.1C,1c=S.1c;b.58=b.5d+(a&&a.2e||1c&&1c.2e||0)-(a.6b||0);b.6f=b.6j+(a&&a.2c||1c&&1c.2c||0)-(a.6a||0)}G(!b.35&&((b.47||b.47===0)?b.47:b.5a))b.35=b.47||b.5a;G(!b.59&&b.5E)b.59=b.5E;G(!b.35&&b.2s)b.35=(b.2s&1?1:(b.2s&2?3:(b.2s&4?2:0)));I b},3M:H(a,b){b.24=a.24=a.24||b.24||7.24++;I b},2t:{27:{4p:H(){55();I},4A:H(){I}},3D:{4p:H(){G(D.14.1f)I Q;D(7).2O("53",D.W.2t.3D.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("53",D.W.2t.3D.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3D";I D.W.1H.1w(7,19)}},3N:{4p:H(){G(D.14.1f)I Q;D(7).2O("51",D.W.2t.3N.2y);I M},4A:H(){G(D.14.1f)I Q;D(7).4e("51",D.W.2t.3N.2y);I M},2y:H(a){G(F(a,7))I M;a.O="3N";I D.W.1H.1w(7,19)}}}};D.17.1l({2O:H(c,a,b){I c=="4X"?7.2V(c,a,b):7.P(H(){D.W.1e(7,c,b||a,b&&a)})},2V:H(d,b,c){J e=D.W.3M(c||b,H(a){D(7).4e(a,e);I(c||b).1w(7,19)});I 7.P(H(){D.W.1e(7,d,e,c&&b)})},4e:H(a,b){I 7.P(H(){D.W.21(7,a,b)})},1P:H(c,a,b){I 7.P(H(){D.W.1P(c,a,7,M,b)})},5C:H(c,a,b){I 7[0]&&D.W.1P(c,a,7[0],Q,b)},2m:H(b){J c=19,i=1;1B(i<c.K)D.W.3M(b,c[i++]);I 7.4V(D.W.3M(b,H(a){7.4Z=(7.4Z||0)%i;a.32();I c[7.4Z++].1w(7,19)||Q}))},7X:H(a,b){I 7.2O(\'3D\',a).2O(\'3N\',b)},27:H(a){55();G(D.2Q)a.1k(S,D);N D.3A.1p(H(){I a.1k(7,D)});I 7}});D.1l({2Q:Q,3A:[],27:H(){G(!D.2Q){D.2Q=M;G(D.3A){D.P(D.3A,H(){7.1k(S)});D.3A=U}D(S).5C("27")}}});J x=Q;H 55(){G(x)I;x=M;G(S.3K&&!D.14.2G)S.3K("69",D.27,Q);G(D.14.1f&&1b==1S)(H(){G(D.2Q)I;1U{S.1C.7V("1A")}1V(3e){3B(19.3L,0);I}D.27()})();G(D.14.2G)S.3K("69",H(){G(D.2Q)I;R(J i=0;i<S.4W.K;i++)G(S.4W[i].3R){3B(19.3L,0);I}D.27()},Q);G(D.14.2k){J a;(H(){G(D.2Q)I;G(S.3f!="68"&&S.3f!="1J"){3B(19.3L,0);I}G(a===12)a=D("V, 7A[7U=7S]").K;G(S.4W.K!=a){3B(19.3L,0);I}D.27()})()}D.W.1e(1b,"43",D.27)}D.P(("7R,7Q,43,85,4y,4X,4V,7P,"+"7O,7N,89,53,51,7M,2A,"+"5o,7L,7K,8d,3e").1R(","),H(i,b){D.17[b]=H(a){I a?7.2O(b,a):7.1P(b)}});J F=H(a,c){J b=a.4k;1B(b&&b!=c)1U{b=b.1d}1V(3e){b=c}I b==c};D(1b).2O("4X",H(){D("*").1e(S).4e()});D.17.1l({67:D.17.43,43:H(g,d,c){G(1j g!=\'23\')I 7.67(g);J e=g.1h(" ");G(e>=0){J i=g.3s(e,g.K);g=g.3s(0,e)}c=c||H(){};J f="2P";G(d)G(D.1D(d)){c=d;d=U}N{d=D.3n(d);f="6g"}J h=7;D.3Y({1a:g,O:f,1O:"2K",L:d,1J:H(a,b){G(b=="1W"||b=="7J")h.2K(i?D("<1v/>").3v(a.4U.1o(/<1m(.|\\s)*?\\/1m>/g,"")).2q(i):a.4U);h.P(c,[a.4U,b,a])}});I 7},aL:H(){I D.3n(7.7I())},7I:H(){I 7.2l(H(){I D.Y(7,"3V")?D.2d(7.aH):7}).1E(H(){I 7.34&&!7.3R&&(7.4J||/2A|6y/i.11(7.Y)||/1r|1G|3Q/i.11(7.O))}).2l(H(i,c){J b=D(7).6e();I b==U?U:b.1q==2p?D.2l(b,H(a,i){I{34:c.34,2x:a}}):{34:c.34,2x:b}}).3p()}});D.P("7H,7G,7F,7D,7C,7B".1R(","),H(i,o){D.17[o]=H(f){I 7.2O(o,f)}});J B=1z();D.1l({3p:H(d,b,a,c){G(D.1D(b)){a=b;b=U}I D.3Y({O:"2P",1a:d,L:b,1W:a,1O:c})},aE:H(b,a){I D.3p(b,U,a,"1m")},aD:H(c,b,a){I D.3p(c,b,a,"3z")},aC:H(d,b,a,c){G(D.1D(b)){a=b;b={}}I D.3Y({O:"6g",1a:d,L:b,1W:a,1O:c})},aA:H(a){D.1l(D.60,a)},60:{1a:5Z.5Q,26:M,O:"2P",2T:0,7z:"4R/x-ax-3V-aw",7x:M,31:M,L:U,5Y:U,3Q:U,4Q:{2N:"4R/2N, 1r/2N",2K:"1r/2K",1m:"1r/4t, 4R/4t",3z:"4R/3z, 1r/4t",1r:"1r/as",4w:"*/*"}},4z:{},3Y:H(s){s=D.1l(M,s,D.1l(M,{},D.60,s));J g,2Z=/=\\?(&|$)/g,1u,L,O=s.O.2r();G(s.L&&s.7x&&1j s.L!="23")s.L=D.3n(s.L);G(s.1O=="4P"){G(O=="2P"){G(!s.1a.1I(2Z))s.1a+=(s.1a.1I(/\\?/)?"&":"?")+(s.4P||"7u")+"=?"}N G(!s.L||!s.L.1I(2Z))s.L=(s.L?s.L+"&":"")+(s.4P||"7u")+"=?";s.1O="3z"}G(s.1O=="3z"&&(s.L&&s.L.1I(2Z)||s.1a.1I(2Z))){g="4P"+B++;G(s.L)s.L=(s.L+"").1o(2Z,"="+g+"$1");s.1a=s.1a.1o(2Z,"="+g+"$1");s.1O="1m";1b[g]=H(a){L=a;1W();1J();1b[g]=12;1U{2U 1b[g]}1V(e){}G(i)i.37(h)}}G(s.1O=="1m"&&s.1Y==U)s.1Y=Q;G(s.1Y===Q&&O=="2P"){J j=1z();J k=s.1a.1o(/(\\?|&)3m=.*?(&|$)/,"$ap="+j+"$2");s.1a=k+((k==s.1a)?(s.1a.1I(/\\?/)?"&":"?")+"3m="+j:"")}G(s.L&&O=="2P"){s.1a+=(s.1a.1I(/\\?/)?"&":"?")+s.L;s.L=U}G(s.26&&!D.4O++)D.W.1P("7H");J n=/^(?:\\w+:)?\\/\\/([^\\/?#]+)/;G(s.1O=="1m"&&O=="2P"&&n.11(s.1a)&&n.2D(s.1a)[1]!=5Z.al){J i=S.3H("6w")[0];J h=S.3h("1m");h.4d=s.1a;G(s.7t)h.aj=s.7t;G(!g){J l=Q;h.ah=h.ag=H(){G(!l&&(!7.3f||7.3f=="68"||7.3f=="1J")){l=M;1W();1J();i.37(h)}}}i.3U(h);I 12}J m=Q;J c=1b.7s?2B 7s("ae.ac"):2B 7r();G(s.5Y)c.6R(O,s.1a,s.31,s.5Y,s.3Q);N c.6R(O,s.1a,s.31);1U{G(s.L)c.4B("ab-aa",s.7z);G(s.5S)c.4B("a9-5R-a8",D.4z[s.1a]||"a7, a6 a5 a4 5N:5N:5N a2");c.4B("X-9Z-9Y","7r");c.4B("9W",s.1O&&s.4Q[s.1O]?s.4Q[s.1O]+", */*":s.4Q.4w)}1V(e){}G(s.7m&&s.7m(c,s)===Q){s.26&&D.4O--;c.7l();I Q}G(s.26)D.W.1P("7B",[c,s]);J d=H(a){G(!m&&c&&(c.3f==4||a=="2T")){m=M;G(f){7k(f);f=U}1u=a=="2T"&&"2T"||!D.7j(c)&&"3e"||s.5S&&D.7h(c,s.1a)&&"7J"||"1W";G(1u=="1W"){1U{L=D.6X(c,s.1O,s.9S)}1V(e){1u="5J"}}G(1u=="1W"){J b;1U{b=c.5I("7g-5R")}1V(e){}G(s.5S&&b)D.4z[s.1a]=b;G(!g)1W()}N D.5H(s,c,1u);1J();G(s.31)c=U}};G(s.31){J f=4I(d,13);G(s.2T>0)3B(H(){G(c){c.7l();G(!m)d("2T")}},s.2T)}1U{c.9P(s.L)}1V(e){D.5H(s,c,U,e)}G(!s.31)d();H 1W(){G(s.1W)s.1W(L,1u);G(s.26)D.W.1P("7C",[c,s])}H 1J(){G(s.1J)s.1J(c,1u);G(s.26)D.W.1P("7F",[c,s]);G(s.26&&!--D.4O)D.W.1P("7G")}I c},5H:H(s,a,b,e){G(s.3e)s.3e(a,b,e);G(s.26)D.W.1P("7D",[a,s,e])},4O:0,7j:H(a){1U{I!a.1u&&5Z.9O=="5p:"||(a.1u>=7e&&a.1u<9N)||a.1u==7c||a.1u==9K||D.14.2k&&a.1u==12}1V(e){}I Q},7h:H(a,c){1U{J b=a.5I("7g-5R");I a.1u==7c||b==D.4z[c]||D.14.2k&&a.1u==12}1V(e){}I Q},6X:H(a,c,b){J d=a.5I("9J-O"),2N=c=="2N"||!c&&d&&d.1h("2N")>=0,L=2N?a.9I:a.4U;G(2N&&L.1C.2j=="5J")7p"5J";G(b)L=b(L,c);G(c=="1m")D.5u(L);G(c=="3z")L=6u("("+L+")");I L},3n:H(a){J s=[];G(a.1q==2p||a.5w)D.P(a,H(){s.1p(3u(7.34)+"="+3u(7.2x))});N R(J j 1n a)G(a[j]&&a[j].1q==2p)D.P(a[j],H(){s.1p(3u(j)+"="+3u(7))});N s.1p(3u(j)+"="+3u(D.1D(a[j])?a[j]():a[j]));I s.6s("&").1o(/%20/g,"+")}});D.17.1l({1N:H(c,b){I c?7.2g({1Z:"1N",2h:"1N",1y:"1N"},c,b):7.1E(":1G").P(H(){7.V.18=7.5D||"";G(D.1g(7,"18")=="2F"){J a=D("<"+7.2j+" />").6P("1c");7.V.18=a.1g("18");G(7.V.18=="2F")7.V.18="3I";a.21()}}).3l()},1M:H(b,a){I b?7.2g({1Z:"1M",2h:"1M",1y:"1M"},b,a):7.1E(":4j").P(H(){7.5D=7.5D||D.1g(7,"18");7.V.18="2F"}).3l()},78:D.17.2m,2m:H(a,b){I D.1D(a)&&D.1D(b)?7.78.1w(7,19):a?7.2g({1Z:"2m",2h:"2m",1y:"2m"},a,b):7.P(H(){D(7)[D(7).3F(":1G")?"1N":"1M"]()})},9G:H(b,a){I 7.2g({1Z:"1N"},b,a)},9F:H(b,a){I 7.2g({1Z:"1M"},b,a)},9E:H(b,a){I 7.2g({1Z:"2m"},b,a)},9D:H(b,a){I 7.2g({1y:"1N"},b,a)},9M:H(b,a){I 7.2g({1y:"1M"},b,a)},9C:H(c,a,b){I 7.2g({1y:a},c,b)},2g:H(k,j,i,g){J h=D.77(j,i,g);I 7[h.36===Q?"P":"36"](H(){G(7.16!=1)I Q;J f=D.1l({},h),p,1G=D(7).3F(":1G"),46=7;R(p 1n k){G(k[p]=="1M"&&1G||k[p]=="1N"&&!1G)I f.1J.1k(7);G(p=="1Z"||p=="2h"){f.18=D.1g(7,"18");f.33=7.V.33}}G(f.33!=U)7.V.33="1G";f.45=D.1l({},k);D.P(k,H(c,a){J e=2B D.28(46,f,c);G(/2m|1N|1M/.11(a))e[a=="2m"?1G?"1N":"1M":a](k);N{J b=a.6r().1I(/^([+-]=)?([\\d+-.]+)(.*)$/),2b=e.1t(M)||0;G(b){J d=3d(b[2]),2M=b[3]||"2X";G(2M!="2X"){46.V[c]=(d||1)+2M;2b=((d||1)/e.1t(M))*2b;46.V[c]=2b+2M}G(b[1])d=((b[1]=="-="?-1:1)*d)+2b;e.3G(2b,d,2M)}N e.3G(2b,a,"")}});I M})},36:H(a,b){G(D.1D(a)||(a&&a.1q==2p)){b=a;a="28"}G(!a||(1j a=="23"&&!b))I A(7[0],a);I 7.P(H(){G(b.1q==2p)A(7,a,b);N{A(7,a).1p(b);G(A(7,a).K==1)b.1k(7)}})},9X:H(b,c){J a=D.3O;G(b)7.36([]);7.P(H(){R(J i=a.K-1;i>=0;i--)G(a[i].T==7){G(c)a[i](M);a.7n(i,1)}});G(!c)7.5A();I 7}});J A=H(b,c,a){G(b){c=c||"28";J q=D.L(b,c+"36");G(!q||a)q=D.L(b,c+"36",D.2d(a))}I q};D.17.5A=H(a){a=a||"28";I 7.P(H(){J q=A(7,a);q.4s();G(q.K)q[0].1k(7)})};D.1l({77:H(b,a,c){J d=b&&b.1q==a0?b:{1J:c||!c&&a||D.1D(b)&&b,2u:b,41:c&&a||a&&a.1q!=9t&&a};d.2u=(d.2u&&d.2u.1q==4L?d.2u:D.28.5K[d.2u])||D.28.5K.74;d.5M=d.1J;d.1J=H(){G(d.36!==Q)D(7).5A();G(D.1D(d.5M))d.5M.1k(7)};I d},41:{73:H(p,n,b,a){I b+a*p},5P:H(p,n,b,a){I((-29.9r(p*29.9q)/2)+0.5)*a+b}},3O:[],48:U,28:H(b,c,a){7.15=c;7.T=b;7.1i=a;G(!c.3Z)c.3Z={}}});D.28.44={4D:H(){G(7.15.2Y)7.15.2Y.1k(7.T,7.1z,7);(D.28.2Y[7.1i]||D.28.2Y.4w)(7);G(7.1i=="1Z"||7.1i=="2h")7.T.V.18="3I"},1t:H(a){G(7.T[7.1i]!=U&&7.T.V[7.1i]==U)I 7.T[7.1i];J r=3d(D.1g(7.T,7.1i,a));I r&&r>-9p?r:3d(D.2a(7.T,7.1i))||0},3G:H(c,b,d){7.5V=1z();7.2b=c;7.3l=b;7.2M=d||7.2M||"2X";7.1z=7.2b;7.2S=7.4N=0;7.4D();J e=7;H t(a){I e.2Y(a)}t.T=7.T;D.3O.1p(t);G(D.48==U){D.48=4I(H(){J a=D.3O;R(J i=0;i<a.K;i++)G(!a[i]())a.7n(i--,1);G(!a.K){7k(D.48);D.48=U}},13)}},1N:H(){7.15.3Z[7.1i]=D.1K(7.T.V,7.1i);7.15.1N=M;7.3G(0,7.1t());G(7.1i=="2h"||7.1i=="1Z")7.T.V[7.1i]="9m";D(7.T).1N()},1M:H(){7.15.3Z[7.1i]=D.1K(7.T.V,7.1i);7.15.1M=M;7.3G(7.1t(),0)},2Y:H(a){J t=1z();G(a||t>7.15.2u+7.5V){7.1z=7.3l;7.2S=7.4N=1;7.4D();7.15.45[7.1i]=M;J b=M;R(J i 1n 7.15.45)G(7.15.45[i]!==M)b=Q;G(b){G(7.15.18!=U){7.T.V.33=7.15.33;7.T.V.18=7.15.18;G(D.1g(7.T,"18")=="2F")7.T.V.18="3I"}G(7.15.1M)7.T.V.18="2F";G(7.15.1M||7.15.1N)R(J p 1n 7.15.45)D.1K(7.T.V,p,7.15.3Z[p])}G(b)7.15.1J.1k(7.T);I Q}N{J n=t-7.5V;7.4N=n/7.15.2u;7.2S=D.41[7.15.41||(D.41.5P?"5P":"73")](7.4N,n,0,1,7.15.2u);7.1z=7.2b+((7.3l-7.2b)*7.2S);7.4D()}I M}};D.1l(D.28,{5K:{9l:9j,9i:7e,74:9g},2Y:{2e:H(a){a.T.2e=a.1z},2c:H(a){a.T.2c=a.1z},1y:H(a){D.1K(a.T.V,"1y",a.1z)},4w:H(a){a.T.V[a.1i]=a.1z+a.2M}}});D.17.2i=H(){J b=0,1S=0,T=7[0],3q;G(T)ao(D.14){J d=T.1d,4a=T,1s=T.1s,1Q=T.2z,5U=2k&&3r(5B)<9c&&!/9a/i.11(v),1g=D.2a,3c=1g(T,"30")=="3c";G(T.7y){J c=T.7y();1e(c.1A+29.2f(1Q.1C.2e,1Q.1c.2e),c.1S+29.2f(1Q.1C.2c,1Q.1c.2c));1e(-1Q.1C.6b,-1Q.1C.6a)}N{1e(T.5X,T.5W);1B(1s){1e(1s.5X,1s.5W);G(42&&!/^t(98|d|h)$/i.11(1s.2j)||2k&&!5U)2C(1s);G(!3c&&1g(1s,"30")=="3c")3c=M;4a=/^1c$/i.11(1s.2j)?4a:1s;1s=1s.1s}1B(d&&d.2j&&!/^1c|2K$/i.11(d.2j)){G(!/^96|1T.*$/i.11(1g(d,"18")))1e(-d.2e,-d.2c);G(42&&1g(d,"33")!="4j")2C(d);d=d.1d}G((5U&&(3c||1g(4a,"30")=="5x"))||(42&&1g(4a,"30")!="5x"))1e(-1Q.1c.5X,-1Q.1c.5W);G(3c)1e(29.2f(1Q.1C.2e,1Q.1c.2e),29.2f(1Q.1C.2c,1Q.1c.2c))}3q={1S:1S,1A:b}}H 2C(a){1e(D.2a(a,"6V",M),D.2a(a,"6U",M))}H 1e(l,t){b+=3r(l,10)||0;1S+=3r(t,10)||0}I 3q};D.17.1l({30:H(){J a=0,1S=0,3q;G(7[0]){J b=7.1s(),2i=7.2i(),4c=/^1c|2K$/i.11(b[0].2j)?{1S:0,1A:0}:b.2i();2i.1S-=25(7,\'94\');2i.1A-=25(7,\'aF\');4c.1S+=25(b,\'6U\');4c.1A+=25(b,\'6V\');3q={1S:2i.1S-4c.1S,1A:2i.1A-4c.1A}}I 3q},1s:H(){J a=7[0].1s;1B(a&&(!/^1c|2K$/i.11(a.2j)&&D.1g(a,\'30\')==\'93\'))a=a.1s;I D(a)}});D.P([\'5e\',\'5G\'],H(i,b){J c=\'4y\'+b;D.17[c]=H(a){G(!7[0])I;I a!=12?7.P(H(){7==1b||7==S?1b.92(!i?a:D(1b).2e(),i?a:D(1b).2c()):7[c]=a}):7[0]==1b||7[0]==S?46[i?\'aI\':\'aJ\']||D.71&&S.1C[c]||S.1c[c]:7[0][c]}});D.P(["6N","4b"],H(i,b){J c=i?"5e":"5G",4f=i?"6k":"6i";D.17["5s"+b]=H(){I 7[b.3y()]()+25(7,"57"+c)+25(7,"57"+4f)};D.17["90"+b]=H(a){I 7["5s"+b]()+25(7,"2C"+c+"4b")+25(7,"2C"+4f+"4b")+(a?25(7,"6S"+c)+25(7,"6S"+4f):0)}})})();',62,669,'|||||||this|||||||||||||||||||||||||||||||||||if|function|return|var|length|data|true|else|type|each|false|for|document|elem|null|style|event||nodeName|||test|undefined||browser|options|nodeType|fn|display|arguments|url|window|body|parentNode|add|msie|css|indexOf|prop|typeof|call|extend|script|in|replace|push|constructor|text|offsetParent|cur|status|div|apply|firstChild|opacity|now|left|while|documentElement|isFunction|filter|className|hidden|handle|match|complete|attr|ret|hide|show|dataType|trigger|doc|split|top|table|try|catch|success|break|cache|height||remove|tbody|string|guid|num|global|ready|fx|Math|curCSS|start|scrollTop|makeArray|scrollLeft|max|animate|width|offset|tagName|safari|map|toggle||done|Array|find|toUpperCase|button|special|duration|id|copy|value|handler|ownerDocument|select|new|border|exec|stack|none|opera|nextSibling|pushStack|target|html|inArray|unit|xml|bind|GET|isReady|merge|pos|timeout|delete|one|selected|px|step|jsre|position|async|preventDefault|overflow|name|which|queue|removeChild|namespace|insertBefore|nth|removeData|fixed|parseFloat|error|readyState|multiFilter|createElement|rl|re|trim|end|_|param|first|get|results|parseInt|slice|childNodes|encodeURIComponent|append|events|elems|toLowerCase|json|readyList|setTimeout|grep|mouseenter|color|is|custom|getElementsByTagName|block|stopPropagation|addEventListener|callee|proxy|mouseleave|timers|defaultView|password|disabled|last|has|appendChild|form|domManip|props|ajax|orig|set|easing|mozilla|load|prototype|curAnim|self|charCode|timerId|object|offsetChild|Width|parentOffset|src|unbind|br|currentStyle|clean|float|visible|relatedTarget|previousSibling|handlers|isXMLDoc|on|setup|nodeIndex|unique|shift|javascript|child|RegExp|_default|deep|scroll|lastModified|teardown|setRequestHeader|timeStamp|update|empty|tr|getAttribute|innerHTML|setInterval|checked|fromElement|Number|jQuery|state|active|jsonp|accepts|application|dir|input|responseText|click|styleSheets|unload|not|lastToggle|outline|mouseout|getPropertyValue|mouseover|getComputedStyle|bindReady|String|padding|pageX|metaKey|keyCode|getWH|andSelf|clientX|Left|all|visibility|container|index|init|triggered|removeAttribute|classFilter|prevObject|submit|file|after|windowData|inner|client|globalEval|sibling|jquery|absolute|clone|wrapAll|dequeue|version|triggerHandler|oldblock|ctrlKey|createTextNode|Top|handleError|getResponseHeader|parsererror|speeds|checkbox|old|00|radio|swing|href|Modified|ifModified|lastChild|safari2|startTime|offsetTop|offsetLeft|username|location|ajaxSettings|getElementById|isSimple|values|selectedIndex|runtimeStyle|rsLeft|_load|loaded|DOMContentLoaded|clientTop|clientLeft|toElement|srcElement|val|pageY|POST|unshift|Bottom|clientY|Right|fix|exclusive|detachEvent|cloneNode|removeEventListener|swap|toString|join|attachEvent|eval|substr|head|parse|textarea|reset|image|zoom|odd|even|before|prepend|exclude|expr|quickClass|quickID|uuid|quickChild|continue|Height|textContent|appendTo|contents|open|margin|evalScript|borderTopWidth|borderLeftWidth|parent|httpData|setArray|CSS1Compat|compatMode|boxModel|cssFloat|linear|def|webkit|nodeValue|speed|_toggle|eq|100|replaceWith|304|concat|200|alpha|Last|httpNotModified|getAttributeNode|httpSuccess|clearInterval|abort|beforeSend|splice|styleFloat|throw|colgroup|XMLHttpRequest|ActiveXObject|scriptCharset|callback|fieldset|multiple|processData|getBoundingClientRect|contentType|link|ajaxSend|ajaxSuccess|ajaxError|col|ajaxComplete|ajaxStop|ajaxStart|serializeArray|notmodified|keypress|keydown|change|mouseup|mousedown|dblclick|focus|blur|stylesheet|hasClass|rel|doScroll|black|hover|solid|cancelBubble|returnValue|wheelDelta|view|round|shiftKey|resize|screenY|screenX|relatedNode|mousemove|prevValue|originalTarget|offsetHeight|keyup|newValue|offsetWidth|eventPhase|detail|currentTarget|cancelable|bubbles|attrName|attrChange|altKey|originalEvent|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|font|gt|lt|uFFFF|u0128|size|417|Boolean|Date|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|wrap|contentWindow|contentDocument|iframe|children|siblings|prevAll|wrapInner|nextAll|outer|prev|scrollTo|static|marginTop|next|inline|parents|able|cellSpacing|adobeair|cellspacing|522|maxLength|maxlength|readOnly|400|readonly|fast|600|class|slow|1px|htmlFor|reverse|10000|PI|cos|compatible|Function|setData|ie|ra|it|rv|getData|userAgent|navigator|fadeTo|fadeIn|slideToggle|slideUp|slideDown|ig|responseXML|content|1223|NaN|fadeOut|300|protocol|send|setAttribute|option|dataFilter|cssText|changed|be|Accept|stop|With|Requested|Object|can|GMT|property|1970|Jan|01|Thu|Since|If|Type|Content|XMLHTTP|th|Microsoft|td|onreadystatechange|onload|cap|charset|colg|host|tfoot|specified|with|1_|thead|leg|plain|attributes|opt|embed|urlencoded|www|area|hr|ajaxSetup|meta|post|getJSON|getScript|marginLeft|img|elements|pageYOffset|pageXOffset|abbr|serialize|pixelLeft'.split('|'),0,{}))

function addEvent(obj, type, fn) {
	if(obj.addEventListener) {
		obj.addEventListener(type, fn, false);
	}
	else if(obj.attachEvent) {
		obj['e' +type +fn] = fn;
		obj[type +fn] = function() {
			obj['e' +type +fn](window.event);
		};
		obj.attachEvent('on' +type, obj[type +fn]);
	}
}	

addEvent(window, 'load', function() {
	LaptopLogic.modules.LaptopFinderSimple.run();
	$('#sub-navigation, #content, #sub-content').equalHeight();
	$('#sitemap > div').equalHeight();
});


var LaptopLogic = {
	init: function() {
		$.imgzoom();
		this.general.maxLengthInputs();
		this.general.captchaRefresh();
		this.general.toggleTitles();
		sc.doClicks();
	}, 

	/*
	 * general
	 *
	 * General JS-funcionality that can be used by
	 * any aFramework-site (any site really...)
	 */
	general: {
		/*
		 * maxLengthInputs
		 *
		 * Displays num characters left information below max-length inputs
		 * (input.maxlength-100 (where 100 is the max allowed characters))
		 * And also prevents user from typing more than allowed amount.
		 * Add a 'maxlength-100' (change the 100) class to any element you want to apply this to
		 */
		maxLengthInputs: function() {
			$('*[class^="maxlength"]').each(function() {
				var t = $(this), 
					maxLength = t.attr('class').substring(10), 
					left = maxLength - t.val().length;

				var charLeft = $('<span class="characters-left">' +left +' characters left</span>').insertAfter(t);

				t.keyup(function() {
					if(t.val().length > maxLength) {
						t.val(t.val().substring(0, maxLength));
					}
					var left = maxLength - t.val().length;

					charLeft.text(left +' characters left');
				});
			});
		}, 

		/*
		 * captchaRefresh
		 *
		 * Refreshes captcha images onclick
		 */
		captchaRefresh: function(src) {
			var captchaSrc = src || '/captcha.png';

			$('img[src^="' +captchaSrc +'"]').attr('title', 'Can\'t see what it says? Click me to get a new string.').click(function() {
				var now = new Date();
				$(this).attr('src', captchaSrc +'?' +now.getTime());
			});
		}, 

		/*
		 * toggleTitles
		 *
		 * Makes all input[title]'s values the
		 * title-attribute and toggles '' onclick
		 */
		toggleTitles: function() {
			$('input[title], textarea[title]').each(function() {
				if($(this).val() === '' || $(this).val() == $(this).attr('title')) {
					$(this).addClass('default-value').val($(this).attr('title'));
				}
			})
			.focus(function() {
				if($(this).val() == $(this).attr('title')) {
					$(this).val('').removeClass('default-value');
				}
			})
			.blur(function() {
				if($(this).val() === '' || $(this).val() == $(this).attr('title')) {
					$(this).addClass('default-value').val($(this).attr('title'));
				}
			});
			$('form').submit(function() {
				$('.default-value', this).val('').removeClass('default-value');
			});
		}
	}, 

	modules: [], 

	initModules: function() {
		for(var module in this.modules) {
			if(typeof(this.modules[module].init) == 'function') {
				this.modules[module].init();
			}
		}
	}
};

$(function() {
	LaptopLogic.init();
	LaptopLogic.initModules();
});

/*
 * jQuery UI @VERSION
 *
 * Copyright (c) 2008 Paul Bakaus (ui.jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;(function($) {

$.ui = {
	plugin: {
		add: function(module, option, set) {
			var proto = $.ui[module].prototype;
			for(var i in set) {
				proto.plugins[i] = proto.plugins[i] || [];
				proto.plugins[i].push([option, set[i]]);
			}
		},
		call: function(instance, name, args) {
			var set = instance.plugins[name];
			if(!set) { return; }
			
			for (var i = 0; i < set.length; i++) {
				if (instance.options[set[i][0]]) {
					set[i][1].apply(instance.element, args);
				}
			}
		}	
	},
	cssCache: {},
	css: function(name) {
		if ($.ui.cssCache[name]) { return $.ui.cssCache[name]; }
		var tmp = $('<div class="ui-gen">').addClass(name).css({position:'absolute', top:'-5000px', left:'-5000px', display:'block'}).appendTo('body');
		
		//if (!$.browser.safari)
			//tmp.appendTo('body'); 
		
		//Opera and Safari set width and height to 0px instead of auto
		//Safari returns rgba(0,0,0,0) when bgcolor is not set
		$.ui.cssCache[name] = !!(
			(!(/auto|default/).test(tmp.css('cursor')) || (/^[1-9]/).test(tmp.css('height')) || (/^[1-9]/).test(tmp.css('width')) || 
			!(/none/).test(tmp.css('backgroundImage')) || !(/transparent|rgba\(0, 0, 0, 0\)/).test(tmp.css('backgroundColor')))
		);
		try { $('body').get(0).removeChild(tmp.get(0));	} catch(e){}
		return $.ui.cssCache[name];
	},
	disableSelection: function(el) {
		$(el).attr('unselectable', 'on').css('MozUserSelect', 'none');
	},
	enableSelection: function(el) {
		$(el).attr('unselectable', 'off').css('MozUserSelect', '');
	},
	hasScroll: function(e, a) {
		var scroll = /top/.test(a||"top") ? 'scrollTop' : 'scrollLeft', has = false;
		if (e[scroll] > 0) return true; e[scroll] = 1;
		has = e[scroll] > 0 ? true : false; e[scroll] = 0;
		return has;
	}
};


/** jQuery core modifications and additions **/

var _remove = $.fn.remove;
$.fn.remove = function() {
	$("*", this).add(this).triggerHandler("remove");
	return _remove.apply(this, arguments );
};

// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
// created by Scott González and Jörn Zaefferer
function getter(namespace, plugin, method) {
	var methods = $[namespace][plugin].getter || [];
	methods = (typeof methods == "string" ? methods.split(/,?\s+/) : methods);
	return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
	var namespace = name.split(".")[0];
	name = name.split(".")[1];
	
	// create plugin method
	$.fn[name] = function(options) {
		var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);
		
		if (isMethodCall && getter(namespace, name, options)) {
			var instance = $.data(this[0], name);
			return (instance ? instance[options].apply(instance, args)
				: undefined);
		}
		
		return this.each(function() {
			var instance = $.data(this, name);
			if (isMethodCall && instance && $.isFunction(instance[options])) {
				instance[options].apply(instance, args);
			} else if (!isMethodCall) {
				$.data(this, name, new $[namespace][name](this, options));
			}
		});
	};
	
	// create widget constructor
	$[namespace][name] = function(element, options) {
		var self = this;
		
		this.widgetName = name;
		this.widgetBaseClass = namespace + '-' + name;
		
		this.options = $.extend({}, $.widget.defaults, $[namespace][name].defaults, options);
		this.element = $(element)
			.bind('setData.' + name, function(e, key, value) {
				return self.setData(key, value);
			})
			.bind('getData.' + name, function(e, key) {
				return self.getData(key);
			})
			.bind('remove', function() {
				return self.destroy();
			});
		this.init();
	};
	
	// add widget prototype
	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);
};

$.widget.prototype = {
	init: function() {},
	destroy: function() {
		this.element.removeData(this.widgetName);
	},
	
	getData: function(key) {
		return this.options[key];
	},
	setData: function(key, value) {
		this.options[key] = value;
		
		if (key == 'disabled') {
			this.element[value ? 'addClass' : 'removeClass'](
				this.widgetBaseClass + '-disabled');
		}
	},
	
	enable: function() {
		this.setData('disabled', false);
	},
	disable: function() {
		this.setData('disabled', true);
	}
};

$.widget.defaults = {
	disabled: false
};


/** Mouse Interaction Plugin **/

$.ui.mouse = {
	mouseInit: function() {
		var self = this;
	
		this.element.bind('mousedown.'+this.widgetName, function(e) {
			return self.mouseDown(e);
		});
		
		// Prevent text selection in IE
		if ($.browser.msie) {
			this._mouseUnselectable = this.element.attr('unselectable');
			this.element.attr('unselectable', 'on');
		}
		
		this.started = false;
	},
	
	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);
		
		// Restore text selection in IE
		($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
	},
	
	mouseDown: function(e) {
		// we may have missed mouseup (out of window)
		(this._mouseStarted && this.mouseUp(e));
		
		this._mouseDownEvent = e;
		
		var self = this,
			btnIsLeft = (e.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(e.target).parents().add(e.target).filter(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this.mouseCapture(e)) {
			return true;
		}
		
		this._mouseDelayMet = !this.options.delay;
		if (!this._mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				self._mouseDelayMet = true;
			}, this.options.delay);
		}
		
		if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
			this._mouseStarted = (this.mouseStart(e) !== false);
			if (!this._mouseStarted) {
				e.preventDefault();
				return true;
			}
		}
		
		// these delegates are required to keep context
		this._mouseMoveDelegate = function(e) {
			return self.mouseMove(e);
		};
		this._mouseUpDelegate = function(e) {
			return self.mouseUp(e);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);
		
		return false;
	},
	
	mouseMove: function(e) {
		// IE mouseup check - mouseup happened when mouse was out of window
		if ($.browser.msie && !e.button) {
			return this.mouseUp(e);
		}
		
		if (this._mouseStarted) {
			this.mouseDrag(e);
			return false;
		}
		
		if (this.mouseDistanceMet(e) && this.mouseDelayMet(e)) {
			this._mouseStarted =
				(this.mouseStart(this._mouseDownEvent, e) !== false);
			(this._mouseStarted ? this.mouseDrag(e) : this.mouseUp(e));
		}
		
		return !this._mouseStarted;
	},
	
	mouseUp: function(e) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);
		
		if (this._mouseStarted) {
			this._mouseStarted = false;
			this.mouseStop(e);
		}
		
		return false;
	},
	
	mouseDistanceMet: function(e) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - e.pageX),
				Math.abs(this._mouseDownEvent.pageY - e.pageY)
			) >= this.options.distance
		);
	},
	
	mouseDelayMet: function(e) {
		return this._mouseDelayMet;
	},
	
	// These are placeholder methods, to be overriden by extending plugin
	mouseStart: function(e) {},
	mouseDrag: function(e) {},
	mouseStop: function(e) {},
	mouseCapture: function(e) { return true; }
};

$.ui.mouse.defaults = {
	cancel: null,
	distance: 1,
	delay: 0
};

})(jQuery);


/*
	FlashReplace is developed by Robert Nyman, http://www.robertnyman.com. License and downloads: http://code.google.com/p/flashreplace/
*/
// ---
var FlashReplace = {
	elmToReplace : null,
	flashIsInstalled : null,
	defaultFlashVersion : 7,
	replace : function (elmToReplace, src, id, width, height, version, params){
		this.elmToReplace = document.getElementById(elmToReplace);
		this.flashIsInstalled = this.checkForFlash(version || this.defaultFlashVersion);
		if(this.elmToReplace && this.flashIsInstalled){
			var obj = '<object' + ((window.ActiveXObject)? ' id="' + id + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" data="' + src + '"' : '');
			obj += ' width="' + width + '"';
			obj += ' height="' + height + '"';
			obj += '>';
			var param = '<param';
			param += ' name="movie"';
			param += ' value="' + src + '"';
			param += '>';
			param += '';
			var extraParams = '';
			var extraAttributes = '';
			for(var i in params){
				extraParams += '<param name="' + i + '" value="' + params[i] + '">';
				extraAttributes += ' ' + i + '="' + params[i] + '"';
			}
			var embed = '<embed id="' + id + '" src="' + src + '" type="application/x-shockwave-flash" width="' + width + '" height="' + height + '"';
			var embedEnd = extraAttributes + '></embed>';
			var objEnd = '</object>';
			this.elmToReplace.innerHTML = obj + param + extraParams + embed + embedEnd + objEnd;			
		}
	},
	
	checkForFlash : function (version){
		this.flashIsInstalled = false;
		var flash;
		if(window.ActiveXObject){
			try{
				flash = new ActiveXObject(("ShockwaveFlash.ShockwaveFlash." + version));
				this.flashIsInstalled = true;
			}
			catch(e){
				// Throws an error if the version isn't available			
			}
		}
		else if(navigator.plugins && navigator.mimeTypes.length > 0){
			flash = navigator.plugins["Shockwave Flash"];
			if(flash){
				var flashVersion = navigator.plugins["Shockwave Flash"].description.replace(/.*\s(\d+\.\d+).*/, "$1");
				if(flashVersion >= version){
					this.flashIsInstalled = true;
				}
			}
		}
		return this.flashIsInstalled;
	}
};
// ---

LaptopLogic.modules.AdminArticle = {
	init: function() {
		this.selectType();
		this.handleMediaUpload();
		this.deleteImage();
		this.deleteVideo();
		
	}, 
	
    deleteImage:function()
    {
        $('#admin-article a[class="remove"]').click(function() {
            
        $.post('/ajax/delete-image/delete-image.php' + $(this).attr('href') ); // ?remove_image=foo.jpg
           
           $(this).parents( 'div' ).eq(0).hide();
            return false;
        });
    },
    
    deleteVideo:function()
    {
        $('#admin-article a[class="remove_video"]').click(function() {
            
        $.post('/ajax/delete-video/delete-video.php' + $(this).attr('href') );
           
           $(this).parents( 'div' ).eq(0).hide();
            return false;
        });
    },
    
	apply_wysiwyg:function(type)
	{		
		if (!$('div.' + type + ' div.markItUp').size())
        {
           $('div.' + type + ' textarea.wysiwyg').markItUp(mySettings);
        }
	},
	
	handleMediaUpload: function() {
	
		$('#admin-article p.video-file-name').hide();
		$('#admin-article p.choose-file').hide();

		$('#admin-article-upload-select label input').click(function() {
			if( $(this).val() == 'movie' )
			{
				$('#admin-article p.video-file-name').show();
				$('#admin-article p.choose-file').show();
			}
			if( $(this).val() == 'image' )
			{
				$('#admin-article p.video-file-name').hide();
				$('#admin-article p.choose-file').show();
			}
		});
	},
	
	getCreateArticle: function() {
	    
		var createDiv;
		var hijaxCreateForm;
		
		if (!$('#create_page').size())
		{
			createDiv = $('<div id="create_page"></div>').appendTo('#admin-article .create');
			hijaxCreateForm = true;
		}
		else
		{
			createDiv = $('#create_page');
			hijaxCreateForm = false;
		}
		 
	 	$('#admin-article #article_type').change(function()
		{
            $('#admin-article').ajaxLoader();
            $.post('/ajax/get-create-article/get-create-article.php?type='+$(this).val(), function(data)
			{
                createDiv.empty().append(data);
                LaptopLogic.modules.AdminArticle.hijaxCreateForm( true );
                $('#admin-article div.submit').show();
                $('#admin-article').ajaxLoaderRemove( true );
                
                LaptopLogic.modules.AdminArticle.apply_wysiwyg('create');
                $('#admin-article dl').togglableDLs();
            });
     	});
	},
	
	getEditArticles: function()
	{
		
		$('#admin-article div.search_radio').hide();
		
	    $('#admin-article #edit_article_type').change(function()
		{			
			$('#admin-article div.search_radio').show();
		
	    	$('#admin-article div.edit input').click(function() {

			var type = $('[name=edit_article_type]').fieldValue();
			
				if( $(this).val() == 'find' )
				{
					$.post('/ajax/get-urls/get-urls.php?type='+type, function(data) 
			   	    {
			               $('.edit_urls').html(data);
			               $('#admin-article p.search_text').hide();
			               $('#admin-article .search_button').hide();
	
			               LaptopLogic.modules.AdminArticle.getEditArticle();
			               LaptopLogic.modules.AdminArticle.apply_wysiwyg('edit');
			               
			               var pageId = $.query.get('pageId');
			               
			               if (pageId !== '')
			               {
			               		// Set value of select to pageId and trigger it.
			               		$('select#edit_urls').find('option[value="' + pageId + '"]').attr('selected',true).end().trigger('change');
			               }
			        }); 
				}
				
				//show searchbox ...
				if( $(this).val() == 'title' || $(this).val() == 'url' )
				{
					$.post('/ajax/get-search/get-search.php', function(data) 
				    {
				    	$('.search').html(data);
				    	$('.edit_urls').empty();
						$('#admin-article .search_button').show();
					});
					
					//..and if posted, load "get urls" with result
					$('#admin-article .search_button').click(function() {
						
						if( $('#admin-article input[name="search_text"]').val() !== '' )
						{
							var word = $('#admin-article input[name="search_text"]').val();
							
							var search_type = ( $('input:radio[@name=search_radio]:checked').val() );
							
							$.post('/ajax/get-urls/get-urls.php?type='+type+'&word='+word+'&search_type='+search_type, function(data) 
					   	    {
					   	    	 $('.edit_urls').html(data);
					   	    	 LaptopLogic.modules.AdminArticle.getEditArticle();
				                 LaptopLogic.modules.AdminArticle.apply_wysiwyg('edit');
							});
						}
					});
				}
			});
		});	
	},
	
	getEditArticle: function()
	{
	    var editDiv;
		var hijaxEditForm;
		
		if (!$('#edit_page').size())
		{
			editDiv = $('<div id="edit_page"></div>').appendTo('#admin-article .edit');
			hijaxEditForm = true;
		}
		else
		{
			editDiv = $('#edit_page');
			hijaxEditForm = false;
		}

	    var editType = $('#admin-article select[name="edit_article_type"]').val();
	    
		$('#admin-article #edit_urls').change(function()
		{
            $('#admin-article').ajaxLoader();
            
			$.post('/ajax/get-edit-article/get-edit-article.php?id='+$(this).val()+'&type='+editType, function(data)
			{
                editDiv.empty().append(data);
                $('#admin-article div.submit').show();
                LaptopLogic.modules.AdminArticle.hijaxEditForm( hijaxEditForm );
                $('#admin-article').ajaxLoaderRemove( true );
                
                LaptopLogic.modules.AdminArticle.apply_wysiwyg('edit');
                
            });
        });
	},
	
	getDeleteArticles: function()
	{
        $('#admin-article #delete_article_type').change(function()
		{
            $('#admin-article').ajaxLoader();
            $.post('/ajax/get-urls/get-urls.php?type='+$(this).val()+'&delete=yes', function(data)
			{
                $('.delete_urls').html(data);
                $('#admin-article div.submit').hide();
                $('#admin-article').ajaxLoaderRemove( true );
                $('#admin-article #delete_urls').change(function()
				{
                    $('#admin-article div.confirm').show();
                    LaptopLogic.modules.AdminArticle.hijaxDeleteForm();
 
	                LaptopLogic.modules.AdminArticle.apply_wysiwyg('delete');
                             
                });
            });
        });
    },
    
    hijaxDeleteForm: function()
	{
        var type = ( $('input:radio[@name=option]:checked').val() );
        if( type == 'delete' )
        {
            $('#admin-article form').submit(function()
			{
                if( $('#admin-article .delete #delete_urls').val() != '' )
                {
                    var agree=confirm("Are you sure you want to delete the article?");
                    if (agree)
                        return true;
                    else
                        return false;
                }
            });
        }
    },
	
	hijaxCreateForm: function( shall )
	{
	    if( shall == true )
	    {
		    var type = ( $('input:radio[@name=option]:checked').val() );
	        if( type == 'create' )
	        {
		        $('#admin-article form').liveValidation({
		            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
		            validIco:   '/css/gfx/icons/form-control-valid.png'
		        }, 
		            { introduction: /^.*/m,
	                  meta_keywords: /^\w+.*/,
	                  meta_description: /^\w+.*/,
                      text: /^.*$/m,
	                  author: /^.+$/,
	                  parent_page: /^.+$/,
	                  publish_date: /^(19|20)[\d]{2,2}\-[\d]{2,2}\-[\d]{2,2}\ [\d]{2,2}\:[\d]{2,2}\:[\d]{2,2}$/
		              
		        });
	            $('#admin-article form').submit(function(){
		            if( $('#admin-article .create #article_type').val() == '' )
		                alert( "Please choose a Type" );
		            if( $('#admin-article .create #parent_page').val() == '' )
		                alert( "Please choose a Parent Page" );
	            })
	        }
	    }
    },
    
    hijaxEditForm: function( shall )
	{
        if( shall == true )
        {
	        $('#admin-article form').liveValidation({
	            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
	            validIco:   '/css/gfx/icons/form-control-valid.png'
	        }, 
	            { introduction: /^.+$/,
	              meta_keywords: /^\w+.*/,
	              meta_description: /^\w+.*/,
	              html_title: /^\w+.*/,
	              text: /^.*$/m,
	              author: /^.+$/,
	              parent_page: /^.+$/,
	              publish_date: /^(19|20)[\d]{2,2}\-[\d]{2,2}\-[\d]{2,2}\ [\d]{2,2}\:[\d]{2,2}\:[\d]{2,2}$/
	        })
	    }
    },
    
    selectType: function()
	{
        var $main_divs = $('#admin-article div[class]').not('div[class*="markItUp"]');

		$main_divs.hide();

        $('#admin-article-type-select label input').click(function()
		{
            if( $(this).val() == 'create' )
            {
                $main_divs.hide();
                $('#admin-article div.create').show();
                LaptopLogic.modules.AdminArticle.getCreateArticle();
            }
            if( $(this).val() == 'edit' )
            {
                $main_divs.hide();
                $('#admin-article div.edit').show();
                LaptopLogic.modules.AdminArticle.getEditArticles();
                
            }
            if( $(this).val() == 'delete' )
            {
                $main_divs.hide();
                $('#admin-article div.delete').show();
                LaptopLogic.modules.AdminArticle.getDeleteArticles();
            }
        });
        
        var pageId = $.query.get('pageId');
		var articleType = $.query.get('articleType'); 

		if (pageId !== '')
		{
			$('input[name="option"][value="edit"]').trigger('click');
			$('select#edit_article_type').find('option[value="' + articleType + '"]').attr('selected',true).end().trigger('change');
			$('input[name="edit_article_type"][value="4"]').trigger('select');

			
			$('input[name="search_radio"][value="find"]').trigger('click');
		
		}
    }
};

LaptopLogic.modules.AdminGlossary = {
    init: function() {
        $('#admin-glossary dl').togglableDLs();
        this.selectType();  
        this.findGlossaryWord(); 
    },
    
    selectType: function() {
        $('#admin-glossary div[class]').hide();
        $('#admin-glossary-select label input').click(function() {
            if( $(this).val() == 'create' )
            {
                $('#admin-glossary div[class]').hide();
                $('#admin-glossary div.create').show();
                $('#admin-glossary div.submit').show();
            }
            if( $(this).val() == 'edit' )
            {
                $('#admin-glossary div[class]').hide();
                $('#admin-glossary div.edit').show();
                $('#admin-glossary div.submit').show();
            }
            if( $(this).val() == 'delete' )
            {
                $('#admin-glossary div[class]').hide();
                $('#admin-glossary div.delete').show();
                $('#admin-glossary div.submit').show();
            }
        });
    },
    
    findGlossaryWord: function() {
       var select = $('#admin-glossary select[name="selectWord"]');
       select.change(function() {
           $.post('/ajax/get-word/get-word.php?word=' +$(this).val(), function(data) {
               $(data).insertAfter(select);
               
           });
       });
    }  
};

LaptopLogic.modules.ArticleListing = {
	init: function()
	{
		var fx = (!$.browser.msie) ? {opacity: 'toggle'} : false;
		
		$('#article-listing > ul').tabs({fx: fx, fxAutoHeight: true});
	}
};

LaptopLogic.modules.ArticleNavigation =
{
	init: function()
	{
		var $art_nav = $('#article-navigation');
		
		var $email_link = $art_nav.find('li a.email');
		
	 	$email_link.click(function()
		{
			var url = $(this).attr('href');
			
			showPopNoScroll(url,200,250);
			
			return false;
		});
		
		$email_link.parent('li').after('<li><a href="#" class="btn-print">Print</a></li>');
		
		$art_nav.find('li a.print').click(function()
		{
			window.print();
			return false;
		});
		
		$art_nav.find('li.delicious a').click(function()
		{
			window.open('http://delicious.com/save?v=5&amp;noui&amp;jump=close&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title), 'delicious','toolbar=no,width=550,height=550');
			return false;
		});
	}
};

LaptopLogic.modules.Article = {
	init: function() {
		this.hijaxRatingForm();
	},

	hijaxRatingForm: function() {
		var ratableItem = $('#article-rating input[name="ratable_item"]').val();
		var ajax_url = $('#article-rating input[name="ajax_url"]').val(); // Where to send the ajax request
		var feature_id = $('#article-rating input[name="feature_id"]').val(); // Where to send the ajax request

		$('#article-rating select[name="rating"]').starRating(function(rating) {
			$.post(ajax_url+'?rating='+rating +'&ratable_item=' +ratableItem+'&feature_id='+feature_id, function(data) {
				$('#article-rating').html($(data).html());
				$('#article img[alt^="Rating: "]').attr('src', $('#article-rating img').attr('src'));
			});
		}, true);
	}
};

LaptopLogic.modules.AutoLink = {
	init: function() {
		this.findUrl();
		this.findAutoLink();
		this.selectType();
	}, 
	
	findUrl: function() {
		$('#auto-link input[name="linkTarget"], #auto-link input[name="editLinkTarget"]').keyup(function() {
		    var input = $(this);
			$.post('/ajax/media-admin-get-url/get-url.php?url='+$(this).val(), function(data) {
				input.next('span').html(data);
			});
			return false;
		});
	},
	
   findAutoLink: function() {
       var select = $('#auto-link select[name="editSource"]');
       select.change(function() {
           $.post('/ajax/get-auto-link/get-auto-link.php?autoLinkTextId=' +$(this).val(), function(data) {
               $(data).insertAfter(select);
               LaptopLogic.modules.AutoLink.findUrl();
           });
       });
    },
    
    selectType: function() {
        $('#auto-link div[class]').hide();
        $('#auto-link-type-select label input').click(function() {
            if( $(this).val() == 'create' )
            {
                $('#auto-link div[class]').hide();
                $('#auto-link div.create').show();
                $('#auto-link div.submit').show();
            }
            if( $(this).val() == 'edit' )
            {
                $('#auto-link div[class]').hide();
                $('#auto-link div.edit').show();
                $('#auto-link div.submit').show();
            }
            if( $(this).val() == 'delete' )
            {
                $('#auto-link div[class]').hide();
                $('#auto-link div.delete').show();
                $('#auto-link div.submit').show();
            }
        });
    }
};

LaptopLogic.modules.AwardListing =
{
	init: function()
	{
		$('#award-listing ul.products').ExpandableList();
	}
};

LaptopLogic.modules.Contact = {
	init: function() {
		this.hijaxForm();
	}, 

	hijaxForm: function() {
		$('#contact form').liveValidation({
			invalidIco: '/css/gfx/icons/form-control-invalid.png', 
			validIco: 	'/css/gfx/icons/form-control-valid.png'
		}, {
			subject: /^.+$/
		}).ajaxForm({
			url: '/ajax/form/contact.php', 
			beforeSubmit: function() {
				if($('img[src="/css/gfx/icons/form-control-invalid.png"]').length) {
					return false;
				}
			}, 
			success: function(data) {
				$('#contact').html($(data).html());
				LaptopLogic.modules.Contact.init();
			}
		});
	}
};

LaptopLogic.modules.Faq = {
	init: function() {
		$('#faq dl').togglableDLs();
	}
};

LaptopLogic.modules.Glossary = {
	init: function() {
		$('#glossary dl').togglableDLs();
		this.hijaxGlossaryLink();
	}, 

	hijaxGlossaryLink: function() {
		$('#random-glossary-word p a#random-word').click(function() {
			$(this).text('Loading...');

			$.get('/ajax/get-random-glossary-word/random-glossary-word.php', function(data) {
				$('#random-glossary-word').html($(data).html());
				LaptopLogic.modules.Glossary.hijaxGlossaryLink();
			});
			
			return false;
		});
	}
};

/**
 * ExpandableList 1.0
 *
 * Takes one or a set of ul's and shortens it.
 * Then inserts a link after it for toggling the list to full view or just a set number of li's to show
 *
 * Usage: $('ul.type-a, ul.type-b').ExpandableList();
 *
 * @class ExpandableList
 *
 * Copyright (c) 2008 Patrik Engborg (patrik@engborg.nu)
 * Released under a GNU General Public License v3 (http://creativecommons.org/licenses/by/3.0/)
 */

(function($)
{  
	$.fn.ExpandableList = function(options)
	{	
		var defaults =
		{  
			show_num: 5 // Default number to show (rest should be hidden)
		};  
	
		var options = $.extend(defaults, options);

		return this.each(function()
		{
			var $this = $(this); // ul 
			
			var $items = $this.find('li'); // li's in ul
			
			var num_items = $items.length; // num li's
			
			if (num_items <= options.show_num) // quit if num_items is not higher than default number to show
			{
				return false;
			}
			
			var $items_to_hide = $items.filter(':gt(' + (options.show_num-1) + ')'); // Get all li's with higher index than default number to show
			
			$items_to_hide.hide(); // Hide those
			
			var toggle_link_text = 'View all'; // Default text for link
			
			$this.after('<p><a href="#" class="toggle-open">' + toggle_link_text + '</a></p>'); // Insert toggle link after text
			
			var $toggle_link = $this.parent().find('a.toggle-open,a.toggle-close'); // Store toggle link
			
			$toggle_link.toggle // Toggle hidden li's. Also set class and appropriate link text
			(
				function()
				{
					$items.slideDown(function()
					{
						$toggle_link.text('Minimize').addClass('toggle-close').removeClass('toggle-open');
					});
					
					return false;
				},
				function()
				{
					$items_to_hide.slideUp(function()
					{
						$toggle_link.text(toggle_link_text).addClass('toggle-open').removeClass('toggle-close');
					});
					
					return false;
				}
			);
			
		});
	};
})(jQuery); 

/**
 * LabelInsideInput 1.0
 *
 * Takes a set of inputs. Hides the label, and fetches the text from it. 
 * Then puts it as value of textfield and applies som show/hide actions on the text
 *
 * Usage: $('input[name="username"],input[name="city"]').LabelInsideInput();
 *
 * @class LabelInsideInput
 *
 * Copyright (c) 2008 Patrik Engborg (patrik@engborg.nu)
 * Released under a GNU General Public License v3 (http://creativecommons.org/licenses/by/3.0/)
 */

(function($)
{  
	$.fn.LabelInsideInput = function(options)
	{	
		var defaults =
		{  
			// no defaults so far...
		};  
	
		var options = $.extend(defaults, options);

		return this.each(function()
		{
			var $this = $(this); // The input
			
			var input_type = $this.attr('type');
			
			if (input_type != 'text' && input_type != 'password') // Check that it's some kind of textfield
			{
				return
			}
			
			var $text_container = $this.parent('label').find('span'); // Element containing the label text
			
			$text_container.hide(); // Hide text
			
			var default_text = $this.parent('label').find('span').text(); // Store text from container as default
			
			$this.val(default_text); // Set value to input
			
			$this.focus(function() // On focus field
			{
				if ($this.val() != default_text) // Check that the value has not been altered
				{
					return;
				}
				
				$this.val(''); // Empty value
			});

			$this.blur(function() // On blur field
			{
				if ($this.val() !== '') // Make sure the field is empty. If not, we dont wanna apply the default text 
				{
					return;
				}

				$this.val(default_text); // Set default text
			});
		});
	};
})(jQuery);

jQuery.fn.ajaxLoader = function(conf) {
	var config = jQuery.extend({
		className:	'jquery-ajax-loader'
	}, conf);

	return this.each(function() {
		var t = jQuery(this);

		if(!this.ajaxLoader) {
			var offset = t.offset();
			var dim = {
				left:	offset.left, 
				top:	offset.top, 
				width:	t.outerWidth(), 
				height:	t.outerHeight()
			};

			this.ajaxLoader = jQuery('<div class="' +config.className +'"></div>').css({
				position:	'absolute', 
				left:		dim.left +'px', 
				top:		dim.top +'px',
				width:		dim.width +'px',
				height:		dim.height +'px'
			}).appendTo(document.body).hide();
		}

		this.ajaxLoader.fadeIn(500);
	});
};

jQuery.fn.ajaxLoaderRemove = function(remove) {
	return this.each(function() {
		if(this.ajaxLoader) {
			this.ajaxLoader.fadeOut(500);
			if(remove) {
			    this.ajaxLoader.remove();
			    this.ajaxLoader = false;
			}
		}
	});
};

/**
 * ColourPicker 1.0
 *
 * Centers all matched elements using position: fixed (no IE)
 *
 * Usage: jQuery('div.img-overlay').center();
 *
 * @class center
 *
 * Copyright (c) 2008 Andreas Lagerkvist (andreaslagerkvist.com)
 * Released under a GNU General Public License v3 (http://creativecommons.org/licenses/by/3.0/)
 */
jQuery.fn.center = function() {
	// Always return each...
	return this.each(function() {
		var t = jQuery(this);

		// Set position to other than 'static' so element shrink-wraps and width/height is calculated properly
		t.css({position: 'fixed'});

		// Why are there no jQuery.fn.outerWidth/Height:s?
		var w = t.width(), 
			h = t.height(), 
			lrPadding = parseInt(t.css('paddingLeft'), 10) + parseInt(t.css('paddingRight'), 10), 
			lrBorder = parseInt(t.css('borderLeftWidth'), 10) + parseInt(t.css('borderRightWidth'), 10), 
			tbPadding = parseInt(t.css('paddingTop'), 10) + parseInt(t.css('paddingBottom'), 10), 
			tbBorder = parseInt(t.css('borderTopWidth'), 10) + parseInt(t.css('borderBottomWidth'), 10), 
			leftMargin = (w + lrPadding + lrBorder) / 2;
			topMargin = (h + tbPadding + tbBorder) / 2;

		t.css({
			position: 'fixed', 
			left: '50%', 
			top: '50%', 
			marginLeft: '-' +leftMargin +'px', 
			marginTop: '-' +topMargin +'px', 
			zIndex: '99'
		});

		/* Use this code if you care about IE<7, this requires the dimensions plug-in tho
		// Calculate left and top pos values
		var leftPos = (jQuery(window).width() - jQuery(this).outerWidth()) / 2 + jQuery(window).scrollLeft(), 
			topPos = (jQuery(window).height() - jQuery(this).outerHeight()) / 2 + jQuery(window).scrollTop();

		// Make sure element is not out of bounds
		leftPos = (leftPos < 0) ? 0 : leftPos;
		topPos = (topPos < 0) ? 0 : topPos;

		jQuery(this).css({left: leftPos +'px', top: topPos +'px', zIndex: '1000'});
		*/
	});
};
/*
// If dimensions plug-in isn't available
// Why is there no jQuery.fn.outerWidth bundled with jQuery?
if(!jQuery.fn.outerWidth) {
	jQuery.fn.outerWidth = function() {
		var t = jQuery(this[0]), 
			w = t.width(), 
			lrPadding = parseInt(t.css('paddingLeft'), 10) + parseInt(t.css('paddingRight'), 10), 
			lrBorder = parseInt(t.css('borderLeftWidth'), 10) + parseInt(t.css('borderRightWidth'), 10);

		return w + lrPadding + lrBorder;
	};
}
if(!jQuery.fn.outerHeight) {
	jQuery.fn.outerHeight = function() {
		return this.each(function() {
			var t = jQuery(this)[0], 
				h = t.height(), 
				tbPadding = parseInt(t.css('paddingTop'), 10) + parseInt(t.css('paddingBottom'), 10), 
				tbBorder = parseInt(t.css('borderTopWidth'), 10) + parseInt(t.css('borderBottomWidth'), 10);

			return h + tbPadding + tbBorder;
		});
	};
}
*/

/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // CAUTION: Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};

/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-08-17 13:14:11 -0500 (Fri, 17 Aug 2007) $
 * $Rev: 2759 $
 *
 * Version: 1.1.2
 *
 * Requires: jQuery 1.1.3+
 */

(function($){

// store a copy of the core height and width methods
var height = $.fn.height,
    width  = $.fn.width;

$.fn.extend({
	/**
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").height()
	 * @result 200
	 *
	 * @example $(document).height()
	 * @result 800
	 *
	 * @example $(window).height()
	 * @result 400
	 *
	 * @name height
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	height: function() {
		if ( !this[0] ) error();
		if ( this[0] == window )
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
				return self.innerHeight - (($(document).height() > self.innerHeight) ? getScrollbarWidth() : 0);
			else if ( $.browser.safari )
				return self.innerHeight;
			else
                return $.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
		
		if ( this[0] == document ) 
			return Math.max( ($.boxModel && document.documentElement.scrollHeight || document.body.scrollHeight), document.body.offsetHeight );
		
		return height.apply(this, arguments);
	},
	
	/**
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 * See core docs on width() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").width()
	 * @result 200
	 *
	 * @example $(document).width()
	 * @result 800
	 *
	 * @example $(window).width()
	 * @result 400
	 *
	 * @name width
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	width: function() {
		if (!this[0]) error();
		if ( this[0] == window )
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
				return self.innerWidth - (($(document).width() > self.innerWidth) ? getScrollbarWidth() : 0);
			else if ( $.browser.safari )
				return self.innerWidth;
			else
                return $.boxModel && document.documentElement.clientWidth || document.body.clientWidth;

		if ( this[0] == document )
			if ($.browser.mozilla) {
				// mozilla reports scrollWidth and offsetWidth as the same
				var scrollLeft = self.pageXOffset;
				self.scrollTo(99999999, self.pageYOffset);
				var scrollWidth = self.pageXOffset;
				self.scrollTo(scrollLeft, self.pageYOffset);
				return document.body.offsetWidth + scrollWidth;
			}
			else 
				return Math.max( (($.boxModel && !$.browser.safari) && document.documentElement.scrollWidth || document.body.scrollWidth), document.body.offsetWidth );

		return width.apply(this, arguments);
	},
	
	/**
	 * Gets the inner height (excludes the border and includes the padding) for the first matched element.
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 *
	 * @example $("#testdiv").innerHeight()
	 * @result 210
	 *
	 * @name innerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerHeight: function() {
		if (!this[0]) error();
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
				this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
	},
	
	/**
	 * Gets the inner width (excludes the border and includes the padding) for the first matched element.
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 *
	 * @example $("#testdiv").innerWidth()
	 * @result 210
	 *
	 * @name innerWidth
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerWidth: function() {
		if (!this[0]) error();
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
				this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
	},
	
	/**
	 * Gets the outer height (includes the border and padding) for the first matched element.
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 *
	 * The margin can be included in the calculation by passing an options map with margin
	 * set to true.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 220
	 *
	 * @example $("#testdiv").outerHeight({ margin: true })
	 * @result 240
	 *
	 * @name outerHeight
	 * @type Number
	 * @param Map options Optional settings to configure the way the outer height is calculated.
	 * @cat Plugins/Dimensions
	 */
	outerHeight: function(options) {
		if (!this[0]) error();
		options = $.extend({ margin: false }, options || {});
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0) :
				this.height() 
					+ num(this,'borderTopWidth') + num(this, 'borderBottomWidth') 
					+ num(this, 'paddingTop') + num(this, 'paddingBottom')
					+ (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0);
	},
	
	/**
	 * Gets the outer width (including the border and padding) for the first matched element.
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 *
	 * The margin can be included in the calculation by passing an options map with margin
	 * set to true.
	 *
	 * @example $("#testdiv").outerWidth()
	 * @result 1000
	 *
	 * @example $("#testdiv").outerWidth({ margin: true })
	 * @result 1020
	 * 
	 * @name outerHeight
	 * @type Number
	 * @param Map options Optional settings to configure the way the outer width is calculated.
	 * @cat Plugins/Dimensions
	 */
	outerWidth: function(options) {
		if (!this[0]) error();
		options = $.extend({ margin: false }, options || {});
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0) :
				this.width() 
					+ num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') 
					+ num(this, 'paddingLeft') + num(this, 'paddingRight')
					+ (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0);
	},
	
	/**
	 * Gets how many pixels the user has scrolled to the right (scrollLeft).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollLeft()
	 * @result 100
	 *
	 * @example $(document).scrollLeft()
	 * @result 100
	 * 
	 * @example $("#testdiv").scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollLeft property for each element and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollLeft(100).scrollLeft()
	 * @result 100
	 * 
	 * @example $(document).scrollLeft(100).scrollLeft()
	 * @result 100
	 *
	 * @example $("#testdiv").scrollLeft(100).scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @param Number value A positive number representing the desired scrollLeft.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollLeft: function(val) {
		if (!this[0]) error();
		if ( val != undefined )
			// set the scroll left
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( val, $(window).scrollTop() );
				else
					this.scrollLeft = val;
			});
		
		// return the scroll left offest in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageXOffset ||
				$.boxModel && document.documentElement.scrollLeft ||
				document.body.scrollLeft;
				
		return this[0].scrollLeft;
	},
	
	/**
	 * Gets how many pixels the user has scrolled to the bottom (scrollTop).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollTop()
	 * @result 100
	 *
	 * @example $(document).scrollTop()
	 * @result 100
	 * 
	 * @example $("#testdiv").scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollTop property for each element and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollTop(100).scrollTop()
	 * @result 100
	 * 
	 * @example $(document).scrollTop(100).scrollTop()
	 * @result 100
	 *
	 * @example $("#testdiv").scrollTop(100).scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @param Number value A positive number representing the desired scrollTop.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollTop: function(val) {
		if (!this[0]) error();
		if ( val != undefined )
			// set the scroll top
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( $(window).scrollLeft(), val );
				else
					this.scrollTop = val;
			});
		
		// return the scroll top offset in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageYOffset ||
				$.boxModel && document.documentElement.scrollTop ||
				document.body.scrollTop;

		return this[0].scrollTop;
	},
	
	/** 
	 * Gets the top and left positioned offset in pixels.
	 * The positioned offset is the offset between a positioned
	 * parent and the element itself.
	 *
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
	 *
	 * @example $("#testdiv").position()
	 * @result { top: 100, left: 100 }
	 *
	 * @example var position = {};
	 * $("#testdiv").position(position)
	 * @result position = { top: 100, left: 100 }
	 * 
	 * @name position
	 * @param Object returnObject Optional An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	position: function(returnObject) {
		return this.offset({ margin: false, scroll: false, relativeTo: this.offsetParent() }, returnObject);
	},
	
	/**
	 * Gets the location of the element in pixels from the top left corner of the viewport.
	 * The offset method takes an optional map of key value pairs to configure the way
	 * the offset is calculated. Here are the different options.
	 *
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
	 * (Boolean) padding - Should the padding of the element be included in the calculations? False by default. 
	 * (Boolean) scroll - Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
	 *                    properties to the returned object, scrollTop and scrollLeft.
	 * (Boolean) lite - When true it will use the offsetLite method instead of the full-blown, slower offset method. False by default.
	 *                  Only use this when margins, borders and padding calculations don't matter.
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
	 *
	 * Also an object can be passed as the second paramater to
	 * catch the value of the return and continue the chain.
	 *
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
	 * 
	 * Known issues:
	 *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
	 *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
	 *
	 * @example $("#testdiv").offset()
	 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
	 *
	 * @example $("#testdiv").offset({ scroll: false })
	 * @result { top: 90, left: 90 }
	 *
	 * @example var offset = {}
	 * $("#testdiv").offset({ scroll: false }, offset)
	 * @result offset = { top: 90, left: 90 }
	 *
	 * @name offset
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offset: function(options, returnObject) {
		if (!this[0]) error();
		var x = 0, y = 0, sl = 0, st = 0,
		    elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
		    mo = $.browser.mozilla, ie = $.browser.msie, oa = $.browser.opera,
		    sf = $.browser.safari, sf3 = $.browser.safari && parseInt($.browser.version) > 520,
		    absparent = false, relparent = false, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false, relativeTo: document.body }, options || {});
		
		// Use offsetLite if lite option is true
		if (options.lite) return this.offsetLite(options, returnObject);
		// Get the HTMLElement if relativeTo is a jquery collection
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
		
		if (elem.tagName == 'BODY') {
			// Safari 2 is the only one to get offsetLeft and offsetTop properties of the body "correct"
			// Except they all mess up when the body is positioned absolute or relative
			x = elem.offsetLeft;
			y = elem.offsetTop;
			// Mozilla ignores margin and subtracts border from body element
			if (mo) {
				x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
				y += num(elem, 'marginTop')  + (num(elem, 'borderTopWidth') *2);
			} else
			// Opera ignores margin
			if (oa) {
				x += num(elem, 'marginLeft');
				y += num(elem, 'marginTop');
			} else
			// IE does not add the border in Standards Mode
			if ((ie && jQuery.boxModel)) {
				x += num(elem, 'borderLeftWidth');
				y += num(elem, 'borderTopWidth');
			} else
			// Safari 3 doesn't not include border or margin
			if (sf3) {
				x += num(elem, 'marginLeft') + num(elem, 'borderLeftWidth');
				y += num(elem, 'marginTop')  + num(elem, 'borderTopWidth');
			}
		} else {
			do {
				parPos = $.css(parent, 'position');
			
				x += parent.offsetLeft;
				y += parent.offsetTop;

				// Mozilla and IE do not add the border
				// Mozilla adds the border for table cells
				if ((mo && !parent.tagName.match(/^t[d|h]$/i)) || ie || sf3) {
					// add borders to offset
					x += num(parent, 'borderLeftWidth');
					y += num(parent, 'borderTopWidth');

					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					if (mo && parPos == 'absolute') absparent = true;
					// IE does not include the border on the body if an element is position static and without an absolute or relative parent
					if (ie && parPos == 'relative') relparent = true;
				}

				op = parent.offsetParent || document.body;
				if (options.scroll || mo) {
					do {
						if (options.scroll) {
							// get scroll offsets
							sl += parent.scrollLeft;
							st += parent.scrollTop;
						}
						
						// Opera sometimes incorrectly reports scroll offset for elements with display set to table-row or inline
						if (oa && ($.css(parent, 'display') || '').match(/table-row|inline/)) {
							sl = sl - ((parent.scrollLeft == parent.offsetLeft) ? parent.scrollLeft : 0);
							st = st - ((parent.scrollTop == parent.offsetTop) ? parent.scrollTop : 0);
						}
				
						// Mozilla does not add the border for a parent that has overflow set to anything but visible
						if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
							x += num(parent, 'borderLeftWidth');
							y += num(parent, 'borderTopWidth');
						}
				
						parent = parent.parentNode;
					} while (parent != op);
				}
				parent = op;
				
				// exit the loop if we are at the relativeTo option but not if it is the body or html tag
				if (parent == options.relativeTo && !(parent.tagName == 'BODY' || parent.tagName == 'HTML'))  {
					// Mozilla does not add the border for a parent that has overflow set to anything but visible
					if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					// Safari 2 and opera includes border on positioned parents
					if ( ((sf && !sf3) || oa) && parPos != 'static' ) {
						x -= num(op, 'borderLeftWidth');
						y -= num(op, 'borderTopWidth');
					}
					break;
				}
				if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {
					// Safari 2 and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
					if (((sf && !sf3) || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
						x += num(parent, 'marginLeft');
						y += num(parent, 'marginTop');
					}
					// Safari 3 does not include the border on body
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					// IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
					if ( sf3 || (mo && !absparent && elemPos != 'fixed') || 
					     (ie && elemPos == 'static' && !relparent) ) {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					break; // Exit the loop
				}
			} while (parent);
		}

		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Gets the location of the element in pixels from the top left corner of the viewport.
	 * This method is much faster than offset but not as accurate when borders and margins are
	 * on the element and/or its parents. This method can be invoked
	 * by setting the lite option to true in the offset method.
	 * The offsetLite method takes an optional map of key value pairs to configure the way
	 * the offset is calculated. Here are the different options.
	 *
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
	 * (Boolean) padding - Should the padding of the element be included in the calcuations? False by default. 
	 * (Boolean) scroll - Sould the scroll offsets of the parent elements be included int he calculations? True by default.
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
	 *                    properties to the returned object, scrollTop and scrollLeft.
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
	 *
	 * @name offsetLite
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offsetLite: function(options, returnObject) {
		if (!this[0]) error();
		var x = 0, y = 0, sl = 0, st = 0, parent = this[0], offsetParent, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, relativeTo: document.body }, options || {});
				
		// Get the HTMLElement if relativeTo is a jquery collection
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
		
		do {
			x += parent.offsetLeft;
			y += parent.offsetTop;

			offsetParent = parent.offsetParent || document.body;
			if (options.scroll) {
				// get scroll offsets
				do {
					sl += parent.scrollLeft;
					st += parent.scrollTop;
					parent = parent.parentNode;
				} while(parent != offsetParent);
			}
			parent = offsetParent;
		} while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML' && parent != options.relativeTo);

		var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Returns a jQuery collection with the positioned parent of 
	 * the first matched element. This is the first parent of 
	 * the element that has position (as in relative or absolute).
	 *
	 * @name offsetParent
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	offsetParent: function() {
		if (!this[0]) error();
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (offsetParent.tagName != 'BODY' && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

/**
 * Throws an error message when no elements are in the jQuery collection
 * @private
 */
var error = function() {
	throw "Dimensions: jQuery collection is empty";
};

/**
 * Handles converting a CSS Style into an Integer.
 * @private
 */
var num = function(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

/**
 * Handles the return value of the offset and offsetLite methods.
 * @private
 */
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
	if ( !options.margin ) {
		x -= num(elem, 'marginLeft');
		y -= num(elem, 'marginTop');
	}

	// Safari and Opera do not add the border for the element
	if ( options.border && (($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
		x += num(elem, 'borderLeftWidth');
		y += num(elem, 'borderTopWidth');
	} else if ( !options.border && !(($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
		x -= num(elem, 'borderLeftWidth');
		y -= num(elem, 'borderTopWidth');
	}

	if ( options.padding ) {
		x += num(elem, 'paddingLeft');
		y += num(elem, 'paddingTop');
	}
	
	// do not include scroll offset on the element ... opera sometimes reports scroll offset as actual offset
	if ( options.scroll && (!$.browser.opera || elem.offsetLeft != elem.scrollLeft && elem.offsetTop != elem.scrollLeft) ) {
		sl -= elem.scrollLeft;
		st -= elem.scrollTop;
	}

	return options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
	                      : { top: y, left: x };
};

/**
 * Gets the width of the OS scrollbar
 * @private
 */
var scrollbarWidth = 0;
var getScrollbarWidth = function() {
	if (!scrollbarWidth) {
		var testEl = $('<div>')
				.css({
					width: 100,
					height: 100,
					overflow: 'auto',
					position: 'absolute',
					top: -1000,
					left: -1000
				})
				.appendTo('body');
		scrollbarWidth = 100 - testEl
			.append('<div>')
			.find('div')
				.css({
					width: '100%',
					height: 200
				})
				.width();
		testEl.remove();
	}
	return scrollbarWidth;
};

})(jQuery);

/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2008 George McGinley Smith
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright Â© 2001 Robert Penner
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of 
 * conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list 
 * of conditions and the following disclaimer in the documentation and/or other materials 
 * provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse 
 * or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 *
 */

/**
 * EqualHeight 1.0
 *
 * Makes all matched elements equal height. Does not work in
 * browsers that do not support min-height (no IE.. who cares)
 *
 * Usage: jQuery('#content, #sub-content').equoalHeight();
 *
 * @class equalHeight
 *
 * Copyright (c) 2008 Andreas Lagerkvist (andreaslagerkvist.com)
 * Released under a GNU General Public License v3 (http://creativecommons.org/licenses/by/3.0/)
 */
jQuery.fn.equalHeight = function() {
	
	var height = 0, 
		maxHeight = 0;

	// Store the tallest element's height
	this.each(function() {
		var t = jQuery(this);
		height = t.height() + parseInt(t.css('paddingTop'), 10) + parseInt(t.css('paddingBottom'), 10) + parseInt(t.css('borderTopWidth'), 10) + parseInt(t.css('borderBottomWidth'), 10);
		maxHeight = (height > maxHeight) ? height : maxHeight;
	});

	// Set element's min-height to tallest element's height
	return this.each(function(j) {
		var t = jQuery(this), 
			mh = maxHeight - (parseInt(t.css('paddingTop'), 10) + parseInt(t.css('paddingBottom'), 10) + parseInt(t.css('borderTopWidth'), 10) + parseInt(t.css('borderBottomWidth'), 10)), 
			properties = $.browser.msie && $.browser.version < 7 ? {height: mh +'px'} : {minHeight: mh +'px'};

		t.css(properties);
	});
};

/*
 * jQuery Form Plugin
 * version: 2.12 (06/07/2008)
 * @requires jQuery v1.2.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Revision: $Id$
 */
(function($) {

/*
    Usage Note:  
    -----------
    Do not use both ajaxSubmit and ajaxForm on the same form.  These
    functions are intended to be exclusive.  Use ajaxSubmit if you want
    to bind your own submit handler to the form.  For example,

    $(document).ready(function() {
        $('#myForm').bind('submit', function() {
            $(this).ajaxSubmit({
                target: '#output'
            });
            return false; // <-- important!
        });
    });

    Use ajaxForm when you want the plugin to manage all the event binding
    for you.  For example,

    $(document).ready(function() {
        $('#myForm').ajaxForm({
            target: '#output'
        });
    });
        
    When using ajaxForm, the ajaxSubmit function will be invoked for you
    at the appropriate time.  
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting 
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
    if (!this.length) {
        log('ajaxSubmit: skipping submit process - no element selected');
        return this;
    }

    if (typeof options == 'function')
        options = { success: options };

    options = $.extend({
        url:  this.attr('action') || window.location.toString(),
        type: this.attr('method') || 'GET'
    }, options || {});

    // hook for manipulating the form data before it is extracted;
    // convenient for use with rich editors like tinyMCE or FCKEditor
    var veto = {};
    this.trigger('form-pre-serialize', [this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
        return this;
   }

    var a = this.formToArray(options.semantic);
    if (options.data) {
        options.extraData = options.data;
        for (var n in options.data)
            a.push( { name: n, value: options.data[n] } );
    }

    // give pre-submit callback an opportunity to abort the submit
    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSubmit callback');
        return this;
    }    

    // fire vetoable 'validate' event
    this.trigger('form-submit-validate', [a, this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
        return this;
    }    

    var q = $.param(a);

    if (options.type.toUpperCase() == 'GET') {
        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
        options.data = null;  // data is null for 'get'
    }
    else
        options.data = q; // data is the query string for 'post'

    var $form = this, callbacks = [];
    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

    // perform a load on the target only if dataType is not provided
    if (!options.dataType && options.target) {
        var oldSuccess = options.success || function(){};
        callbacks.push(function(data) {
            $(options.target).html(data).each(oldSuccess, arguments);
        });
    }
    else if (options.success)
        callbacks.push(options.success);

    options.success = function(data, status) {
        for (var i=0, max=callbacks.length; i < max; i++)
            callbacks[i](data, status, $form);
    };

    // are there files to upload?
    var files = $('input:file', this).fieldValue();
    var found = false;
    for (var j=0; j < files.length; j++)
        if (files[j])
            found = true;

    // options.iframe allows user to force iframe mode
   if (options.iframe || found) { 
       // hack to fix Safari hang (thanks to Tim Molendijk for this)
       // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
       if ($.browser.safari && options.closeKeepAlive)
           $.get(options.closeKeepAlive, fileUpload);
       else
           fileUpload();
       }
   else
       $.ajax(options);

    // fire 'notify' event
    this.trigger('form-submit-notify', [this, options]);
    return this;


    // private function for handling file uploads (hat tip to YAHOO!)
    function fileUpload() {
        var form = $form[0];
        
        if ($(':input[@name=submit]', form).length) {
            alert('Error: Form elements must not be named "submit".');
            return;
        }
        
        var opts = $.extend({}, $.ajaxSettings, options);

        var id = 'jqFormIO' + (new Date().getTime());
        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
        var io = $io[0];

        if ($.browser.msie || $.browser.opera) 
            io.src = 'javascript:false;document.write("");';
        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

        var xhr = { // mock object
            responseText: null,
            responseXML: null,
            status: 0,
            statusText: 'n/a',
            getAllResponseHeaders: function() {},
            getResponseHeader: function() {},
            setRequestHeader: function() {}
        };

        var g = opts.global;
        // trigger ajax global events so that activity/block indicators work like normal
        if (g && ! $.active++) $.event.trigger("ajaxStart");
        if (g) $.event.trigger("ajaxSend", [xhr, opts]);

        var cbInvoked = 0;
        var timedOut = 0;

        // add submitting element to data if we know it
        var sub = form.clk;
        if (sub) {
            var n = sub.name;
            if (n && !sub.disabled) {
                options.extraData = options.extraData || {};
                options.extraData[n] = sub.value;
                if (sub.type == "image") {
                    options.extraData[name+'.x'] = form.clk_x;
                    options.extraData[name+'.y'] = form.clk_y;
                }
            }
        }
        
        // take a breath so that pending repaints get some cpu time before the upload starts
        setTimeout(function() {
            // make sure form attrs are set
            var t = $form.attr('target'), a = $form.attr('action');
            $form.attr({
                target:   id,
                encoding: 'multipart/form-data',
                enctype:  'multipart/form-data',
                method:   'POST',
                action:   opts.url
            });

            // support timout
            if (opts.timeout)
                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

            // add "extra" data to form if provided in options
            var extraInputs = [];
            try {
                if (options.extraData)
                    for (var n in options.extraData)
                        extraInputs.push(
                            $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
                                .appendTo(form)[0]);
            
                // add iframe to doc and submit the form
                $io.appendTo('body');
                io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
                form.submit();
            }
            finally {
                // reset attrs and remove "extra" input elements
                $form.attr('action', a);
                t ? $form.attr('target', t) : $form.removeAttr('target');
                $(extraInputs).remove();
            }
        }, 10);

        function cb() {
            if (cbInvoked++) return;
            
            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

            var operaHack = 0;
            var ok = true;
            try {
                if (timedOut) throw 'timeout';
                // extract the server response from the iframe
                var data, doc;

                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
                
                if (doc.body == null && !operaHack && $.browser.opera) {
                    // In Opera 9.2.x the iframe DOM is not always traversable when
                    // the onload callback fires so we give Opera 100ms to right itself
                    operaHack = 1;
                    cbInvoked--;
                    setTimeout(cb, 100);
                    return;
                }
                
                xhr.responseText = doc.body ? doc.body.innerHTML : null;
                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
                xhr.getResponseHeader = function(header){
                    var headers = {'content-type': opts.dataType};
                    return headers[header];
                };

                if (opts.dataType == 'json' || opts.dataType == 'script') {
                    var ta = doc.getElementsByTagName('textarea')[0];
                    xhr.responseText = ta ? ta.value : xhr.responseText;
                }
                else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
                    xhr.responseXML = toXml(xhr.responseText);
                }
                data = $.httpData(xhr, opts.dataType);
            }
            catch(e){
                ok = false;
                $.handleError(opts, xhr, 'error', e);
            }

            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
            if (ok) {
                opts.success(data, 'success');
                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
            }
            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
            if (g && ! --$.active) $.event.trigger("ajaxStop");
            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

            // clean up
            setTimeout(function() {
                $io.remove();
                xhr.responseXML = null;
            }, 100);
        };

        function toXml(s, doc) {
            if (window.ActiveXObject) {
                doc = new ActiveXObject('Microsoft.XMLDOM');
                doc.async = 'false';
                doc.loadXML(s);
            }
            else
                doc = (new DOMParser()).parseFromString(s, 'text/xml');
            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
        };
    };
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *    is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *    used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */ 
$.fn.ajaxForm = function(options) {
    return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
        $(this).ajaxSubmit(options);
        return false;
    }).each(function() {
        // store options in hash
        $(":submit,input:image", this).bind('click.form-plugin',function(e) {
            var $form = this.form;
            $form.clk = this;
            if (this.type == 'image') {
                if (e.offsetX != undefined) {
                    $form.clk_x = e.offsetX;
                    $form.clk_y = e.offsetY;
                } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
                    var offset = $(this).offset();
                    $form.clk_x = e.pageX - offset.left;
                    $form.clk_y = e.pageY - offset.top;
                } else {
                    $form.clk_x = e.pageX - this.offsetLeft;
                    $form.clk_y = e.pageY - this.offsetTop;
                }
            }
            // clear form vars
            setTimeout(function() { $form.clk = $form.clk_x = $form.clk_y = null; }, 10);
        });
    });
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
    this.unbind('submit.form-plugin');
    return this.each(function() {
        $(":submit,input:image", this).unbind('click.form-plugin');
    });

};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
    var a = [];
    if (this.length == 0) return a;

    var form = this[0];
    var els = semantic ? form.getElementsByTagName('*') : form.elements;
    if (!els) return a;
    for(var i=0, max=els.length; i < max; i++) {
        var el = els[i];
        var n = el.name;
        if (!n) continue;

        if (semantic && form.clk && el.type == "image") {
            // handle image inputs on the fly when semantic == true
            if(!el.disabled && form.clk == el)
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
            continue;
        }

        var v = $.fieldValue(el, true);
        if (v && v.constructor == Array) {
            for(var j=0, jmax=v.length; j < jmax; j++)
                a.push({name: n, value: v[j]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: n, value: v});
    }

    if (!semantic && form.clk) {
        // input type=='image' are not found in elements array! handle them here
        var inputs = form.getElementsByTagName("input");
        for(var i=0, max=inputs.length; i < max; i++) {
            var input = inputs[i];
            var n = input.name;
            if(n && !input.disabled && input.type == "image" && form.clk == input)
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
        }
    }
    return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
    //hand off to jQuery.param for proper encoding
    return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
    var a = [];
    this.each(function() {
        var n = this.name;
        if (!n) return;
        var v = $.fieldValue(this, successful);
        if (v && v.constructor == Array) {
            for (var i=0,max=v.length; i < max; i++)
                a.push({name: n, value: v[i]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: this.name, value: v});
    });
    //hand off to jQuery.param for proper encoding
    return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *      <input name="A" type="text" />
 *      <input name="A" type="text" />
 *      <input name="B" type="checkbox" value="B1" />
 *      <input name="B" type="checkbox" value="B2"/>
 *      <input name="C" type="radio" value="C1" />
 *      <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *       array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
    for (var val=[], i=0, max=this.length; i < max; i++) {
        var el = this[i];
        var v = $.fieldValue(el, successful);
        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
            continue;
        v.constructor == Array ? $.merge(val, v) : val.push(v);
    }
    return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    if (typeof successful == 'undefined') successful = true;

    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
        (t == 'checkbox' || t == 'radio') && !el.checked ||
        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
        tag == 'select' && el.selectedIndex == -1))
            return null;

    if (tag == 'select') {
        var index = el.selectedIndex;
        if (index < 0) return null;
        var a = [], ops = el.options;
        var one = (t == 'select-one');
        var max = (one ? index+1 : ops.length);
        for(var i=(one ? index : 0); i < max; i++) {
            var op = ops[i];
            if (op.selected) {
                // extra pain for IE...
                var v = $.browser.msie && !(op.attributes['value'].specified) ? op.text : op.value;
                if (one) return v;
                a.push(v);
            }
        }
        return a;
    }
    return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
    return this.each(function() {
        $('input,select,textarea', this).clearFields();
    });
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
    return this.each(function() {
        var t = this.type, tag = this.tagName.toLowerCase();
        if (t == 'text' || t == 'password' || tag == 'textarea')
            this.value = '';
        else if (t == 'checkbox' || t == 'radio')
            this.checked = false;
        else if (tag == 'select')
            this.selectedIndex = -1;
    });
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
    return this.each(function() {
        // guard against an input with the name of 'reset'
        // note that IE reports the reset function as an 'object'
        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
            this.reset();
    });
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) { 
    if (b == undefined) b = true;
    return this.each(function() { 
        this.disabled = !b 
    });
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.select = function(select) {
    if (select == undefined) select = true;
    return this.each(function() { 
        var t = this.type;
        if (t == 'checkbox' || t == 'radio')
            this.checked = select;
        else if (this.tagName.toLowerCase() == 'option') {
            var $sel = $(this).parent('select');
            if (select && $sel[0] && $sel[0].type == 'select-one') {
                // deselect all other options
                $sel.find('option').select(false);
            }
            this.selected = select;
        }
    });
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
    if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
        window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);

/**
 * Imgzoom 1.2 (Requires the dimensions-plugin)
 *
 * Opens links that point to images in the "Imgzoom" (zooms out the image)
 *
 * Usage: jQuery.imgzoom();
 *
 * @class imgzoom
 * @param {Object} conf, custom config-object {speed: 500, dontFadeIn: 0, hideClicked: 0} // pelase note that i've removed the ability to fade in/out the zoomed image because it caused a bug in IE. If you don't care about IE uncomment the opacity-stuff on line ~50
 *
 * Copyright (c) 2008 Andreas Lagerkvist (andreaslagerkvist.com)
 * Released under a GNU General Public License v3 (http://creativecommons.org/licenses/by/3.0/)
 */
jQuery.imgzoom = function(conf) {
	// Some config. If you set dontFadeIn: 0 and hideClicked: 0 imgzoom will act exactly like fancyzoom
	var config = jQuery.extend({
		speed: 200,		// Animation-speed of zoom
		dontFadeIn: 1,	// 1 = Do not fade in, 0 = Do fade in
		hideClicked: 1,	// Whether to hide the image that was clicked to bring up the imgzoom
		loading: 'Loading...'
	}, conf);
	config.doubleSpeed = config.speed / 4; // Used for fading in the close-button

	// Set one click-event on body and then check what the target (actual) clicked element was
	// Doing it this way instead of applying an event to each link (like imgbox) supports dynamically inserted links
	jQuery(document.body).click(function(e) {
		// Make sure the target-element is a link (or an element inside a link)
		var clickedElement	= jQuery(e.target); // The element that was actually clicked
		var clickedLink		= clickedElement.is('a') ? clickedElement : clickedElement.parents('a'); // If it's not an a, check if any of its parents is
			clickedLink		= (clickedLink && clickedLink.is('a') && clickedLink.attr('href').search(/(.*)\.(jpg|jpeg|gif|png|bmp|tif|tiff)$/gi) != -1) ? clickedLink : false; // If it was an a or child of an a, make sure it points to an image
		var clickedImg		= (clickedLink && clickedLink.find('img').length) ? clickedLink.find('img') : false; // See if the clicked link contains and image

		// Only continue if a link pointing to an image was clicked
		if(clickedLink) {
			// These functions are used when the imaeg starts and stops loading (displays either 'loading..' or fades out the clicked img slightly)
			clickedLink.oldText	= clickedLink.text();

			clickedLink.setLoadingImg = function() {
				if(clickedImg) {
					clickedImg.css({opacity: '0.5'});
				}
				else {
					clickedLink.text(config.loading);
				}
			};

			clickedLink.setNotLoadingImg = function() {
				if(clickedImg) {
					clickedImg.css({opacity: '1'});
				}
				else {
					clickedLink.text(clickedLink.oldText);
				}
			};

			// The URI to the image we are going to display
			var displayImgSrc = clickedLink.attr('href');

			// If an imgzoom wiv this image is already open dont do nathin
			if(jQuery('div.imgzoom img[src="' +displayImgSrc +'"]').length) {
				return false;
			}

			// This function is run once the displayImgSrc-img has loaded (below)
			var preloadOnload = function() {
				// The clicked-link is faded out during loading, fade it back in
				clickedLink.setNotLoadingImg();

				// Now set some vars we need
				var linkContainsImg	= clickedLink.find('img').length;
				var dimElement		= linkContainsImg ? clickedLink.find('img') : clickedLink; // The element used to retrieve dimensions of imgzoom before zoom (either clicked link or img inside)
				var hideClicked		= linkContainsImg ? config.hideClicked : 0; // Whether to hide clicked link (set in config but always false for non-image-links)
				var offset			= dimElement.offset(); // Offset of clicked link (or image inside)
				var imgzoomBefore	= { // The dimensions of the imgzoom _before_ it is zoomed out
					width:		dimElement.outerWidth(), 
					height:		dimElement.outerHeight(), 
					left:		offset.left, 
					top:		offset.top/*, 
					opacity:	config.dontFadeIn*/
				};
				var imgzoom			= jQuery('<div><img src="' +displayImgSrc +'" alt="" /></div>').css({position: 'absolute'}).appendTo(document.body); // We don't want any class-name or any other contents part from the image when we calculate the new dimensions of the imgzoom
				var imgzoomAfter	= { // The dimensions of the imgzoom _after_ it is zoomed out
					width:		imgzoom.outerWidth(), 
					height:		imgzoom.outerHeight()/*, 
					opacity:	1*/
				};
				var windowDim = {
					width: jQuery(window).width(), 
					height: jQuery(window).height()
				};
				// Make sure imgzoom isn't wider than screen
				if(imgzoomAfter.width > windowDim.width) {
					var nWidth			= windowDim.width - 100;
					imgzoomAfter.height	= (nWidth / imgzoomAfter.width) * imgzoomAfter.height;
					imgzoomAfter.width	= nWidth;
				}
				// Now make sure it isn't taller
				if(imgzoomAfter.height > windowDim.height) {
					var nHeight = windowDim.height - 100;
					imgzoomAfter.width	= (nHeight / imgzoomAfter.height) * imgzoomAfter.width;
					imgzoomAfter.height	= nHeight;
				}
				// Center imgzoom
				imgzoomAfter.left	= (windowDim.width - imgzoomAfter.width) / 2 + jQuery(window).scrollLeft();
				imgzoomAfter.top	= (windowDim.height - imgzoomAfter.height) / 2 + jQuery(window).scrollTop();
				var closeButton		= jQuery('<a href="#">Close</a>').appendTo(imgzoom).hide(); // The button that closes the imgzoom (we're adding this after the calculation of the dimensions)

				// Hide the clicked link if set so in config
				if(hideClicked) {
					clickedLink.css({visibility: 'hidden'});
				}

				// Now animate the imgzoom from its small size to its large size, and then fade in the close-button
				imgzoom.addClass('imgzoom').css(imgzoomBefore).animate(imgzoomAfter, config.speed, function() {
					closeButton.fadeIn(config.doubleSpeed);
				});

				// This function closes the imgzoom
				var hideImgzoom = function() {
					closeButton.fadeOut(config.doubleSpeed, function() {
						imgzoom.animate(imgzoomBefore, config.speed, function() {
							clickedLink.css({visibility: 'visible'});
							imgzoom.remove();
						});
					});

					return false;
				};

				// Close imgzoom when you click the closeButton or the imgzoom
				imgzoom.click(hideImgzoom);
				closeButton.click(hideImgzoom);
			};

			// Preload image
			var preload = new Image();
				preload.src = displayImgSrc;

			if(preload.complete) {
				preloadOnload();
			}
			else {
				clickedLink.setLoadingImg();
				preload.onload = preloadOnload;
			}

			// Finally return false from the click so the browser doesn't actually follow the link...
			return false;
		}
	});
};

/**
 * @title:		Live Validation
 * @version:	2.0
 * @author:		Andreas Lagerkvist
 * @date:		2008-08-31
 * @url:		http://andreaslagerkvist.com/jquery/live-validation/
 * @license:	http://creativecommons.org/licenses/by/3.0/
 * @copyright:	2008 Andreas Lagerkvist (andreaslagerkvist.com)
 * @requires:	jQuery
 * @usage:		jQuery('#contact form').liveValidation(); Adds live-validation to all required fields in the #contact form.
 **/
jQuery.fn.liveValidation = function(conf, addedFields) {
	
	var config = jQuery.extend(
	{
		formControls:	'input[type="text"], textarea, select',						// form-controls to be validated
		validIco:		'',													// src to valid icon
		invalidIco:		'',													// src to invalid ico
		valid:			'Valid',											// alt for valid icon
		invalid:		'Invalid'											// alt for invalid icon
	}, conf);

	var commonFields = jQuery.extend(
	{
		name: 			/^.+$/,												// name (atleast one character)
		full_name: 		/^.+$/,												// name (atleast one character)
		title: 			/^.+$/,												// title (atleast one character)
		message: 		/^.+$/,												// message (atleast one character)
		comment: 		/^.+$/,												// comment (atleast one character)
		description:	/^.+$/,												// description (atleast one character)
		dimensions:		/^\d+x\d+$/,										// dimensions (DIGITxDIGIT)
		price:			/^\d+$/,											// price (atleast one digit)
		url: 			/^(http:\/\/)?(www)?([^ |\.]*?)\.([^ ]){2,5}$/,		// url
		email: 			/^.+?@.+?\..{2,4}$/								// email
	}, addedFields);

	return this.each(function() 
	{
		var form = jQuery(this);

		// For every form-control in the form
		jQuery(config.formControls, form).each(function() 
		{
			var t = jQuery(this);
			
			// Don't do anything if this field isn't required
			if(typeof(commonFields[t.attr('name')]) === 'undefined') 
			{
				return;
			}

			var validator = t.parent('label').find('img'); // Store pressumed validator

			// Add invalid icon if none is found
			if ( ! validator.length)
			{
				// Add invalid icon
				validator = jQuery('<img src="' +config.invalidIco +'" alt="' +config.invalid +'" />').insertAfter(t);
			}
			
			//log(validator);
			
			// This function is run now and on key up
			var validate = function() 
			{
				var key = t.attr('name');
				var val = t.val();
				var tit = t.attr('title');

				// If value and title are the same it is assumed formHints is used
				// set value to empty so validation isn't done on the hint
				val = tit == val ? '' : val;

				// Make sure the value matches
				if(val.match(commonFields[key])) 
				{
					// If it's not already valid
					if(validator.attr('alt') != config.valid) {
						validator.attr('src', config.validIco);
						validator.attr('alt', config.valid);
					}
				}
				// It didn't validate
				else 
				{
					// If it's not already invalid 
					if(validator.attr('alt') != config.invalid) {
						validator.attr('src', config.invalidIco);
						validator.attr('alt', config.invalid);
					}
				}
			};

			validate();
			t.keyup(validate);
			t.change(validate);
		});

		// If form contains any invalid icon on submission, return false
		form.submit(function() 
		{
			if(form.find('img[src="' +config.invalidIco +'"]').length) 
			{
				return false;
			}
		});
	});
};

/**
 * jQuery.query - Query String Modification and Creation for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2008/05/28
 *
 * @author Blair Mitchelmore
 * @version 2.0.1
 *
 **/
new function(settings) { 
  // Various Settings
  var $separator = settings.separator || '&';
  var $spaces = settings.spaces === false ? false : true;
  var $suffix = settings.suffix === false ? '' : '[]';
  var $prefix = settings.prefix === false ? false : true;
  var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
  
  jQuery.query = new function() {
    var is = function(o, t) {
      return o != undefined && o !== null && (!!t ? o.constructor == t : true);
    };
    var parse = function(path) {
      var m, rx = /\[([^[]*)\]/g, match = /^(\S+?)(\[\S*\])?$/.exec(path), base = match[1], tokens = [];
      while (m = rx.exec(match[2])) tokens.push(m[1]);
      return [base, tokens];
    };
    var set = function(target, tokens, value) {
      var o, token = tokens.shift();
      if (typeof target != 'object') target = null;
      if (token === "") {
        if (!target) target = [];
        if (is(target, Array)) {
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        } else if (is(target, Object)) {
          var i = 0;
          while (target[i++] != null);
          target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
        } else {
          target = [];
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        }
      } else if (token && token.match(/^\s*[0-9]+\s*$/)) {
        var index = parseInt(token, 10);
        if (!target) target = [];
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else if (token) {
        var index = token.replace(/^\s*|\s*$/g, "");
        if (!target) target = {};
        if (is(target, Array)) {
          var temp = {};
          for (var i = 0; i < target.length; ++i) {
            temp[i] = target[i];
          }
          target = temp;
        }
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else {
        return value;
      }
      return target;
    };
    
    var queryObject = function(a) {
      var self = this;
      self.keys = {};
      
      if (a.queryObject) {
        jQuery.each(a.get(), function(key, val) {
          self.SET(key, val);
        });
      } else {
        jQuery.each(arguments, function() {
          var q = "" + this;
          q = q.replace(/^[?#]/,''); // remove any leading ? || #
          q = q.replace(/[;&]$/,''); // remove any trailing & || ;
          if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces
          
          jQuery.each(q.split(/[&;]/), function(){
            var key = this.split('=')[0];
            var val = this.split('=')[1];
            
            if (!key) return;
            
            if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
              val = parseFloat(val);
            else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
              val = parseInt(val, 10);
            
            val = (!val && val !== 0) ? true : val;
            
            if (val !== false && val !== true && typeof val != 'number')
              val = decodeURIComponent(val);
            
            self.SET(key, val);
          });
        });
      }
      return self;
    };
    
    queryObject.prototype = {
      queryObject: true,
      has: function(key, type) {
        var value = this.get(key);
        return is(value, type);
      },
      GET: function(key) {
        if (!is(key)) return this.keys;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        while (target != null && tokens.length != 0) {
          target = target[tokens.shift()];
        }
        return typeof target == 'number' ? target : target || "";
      },
      get: function(key) {
        var target = this.GET(key);
        if (is(target, Object))
          return jQuery.extend(true, {}, target);
        else if (is(target, Array))
          return target.slice(0);
        return target;
      },
      SET: function(key, val) {
        var value = !is(val) ? null : val;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        this.keys[base] = set(target, tokens.slice(0), value);
        return this;
      },
      set: function(key, val) {
        return this.copy().SET(key, val);
      },
      REMOVE: function(key) {
        return this.SET(key, null).COMPACT();
      },
      remove: function(key) {
        return this.copy().REMOVE(key);
      },
      EMPTY: function() {
        var self = this;
        jQuery.each(self.keys, function(key, value) {
          delete self.keys[key];
        });
        return self;
      },
      empty: function() {
        return this.copy().EMPTY();
      },
      copy: function() {
        return new queryObject(this);
      },
      COMPACT: function() {
        function build(orig) {
          var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
          if (typeof orig == 'object') {
            function add(o, key, value) {
              if (is(o, Array))
                o.push(value);
              else
                o[key] = value;
            }
            jQuery.each(orig, function(key, value) {
              if (!is(value)) return true;
              add(obj, key, build(value));
            });
          }
          return obj;
        }
        this.keys = build(this.keys);
        return this;
      },
      compact: function() {
        return this.copy().COMPACT();
      },
      toString: function() {
        var i = 0, queryString = [], chunks = [], self = this;
        var addFields = function(arr, key, value) {
          if (!is(value) || value === false) return;
          var o = [key];
          if (value !== true) {
            o.push("=");
            o.push(encodeURIComponent(value));
          }
          arr.push(o.join(""));
        };
        var build = function(obj, base) {
          var newKey = function(key) {
            return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
          };
          jQuery.each(obj, function(key, value) {
            if (typeof value == 'object') 
              build(value, newKey(key));
            else
              addFields(chunks, newKey(key), value);
          });
        };
        
        build(this.keys);
        
        if (chunks.length > 0) queryString.push($hash);
        queryString.push(chunks.join($separator));
        
        return queryString.join("");
      }
    };
    
    return new queryObject(location.search, location.hash);
  };
}(jQuery.query || {}); // Pass in jQuery.query as settings object


jQuery.fn.starRating = function(clickCallback, replaceForm) {
	return this.each(function() {
		// Replace form with list
		var select = $(this);
		var replace = replaceForm ? select.parents('form').eq(0) : select;
		var ol = '<ol class="jquery-star-rating" class="self-clear">';
		var currentlySelected = -1;
		var selectName = select.attr('name');

		$('option', select).each(function(i) {
			if(jQuery(this).is(':selected')) {
				currentlySelected = i + 1;
			}

			ol += '<li><a href="#" rel="' +$(this).val() +'" title="' +$(this).text() +'">' +$(this).text() +'</a></li>';
		});

		ol += '</ol>';
		ol = $(ol).replaceAll(replace);

		var hidden = $('<input type="hidden" name="' +selectName +'" value="' +currentlySelected +'" />').insertAfter(ol);

		var hoverAllBefore = function(num, select) {
			var removeSel = select ? ' selected' : '';
			$('a', ol).removeClass('over' +removeSel).each(function(i) {
				if(i < num) {
					$(this).addClass('over');

					if(select && i == (num - 1)) {
						$(this).addClass('selected');
						hidden.val(num);
					}
				}
				else {
					return;
				}
			});
		};

		hoverAllBefore(currentlySelected, true);

		// On mouse over - change class of currently hovered link and all previous links
		$('a', ol).mouseover(function() {
			hoverAllBefore($(this).attr('rel'));
		})
		// On mouse out - remove all classes
		.mouseout(function() {
			$('a', ol).removeClass('over');

			var selected = $('a.selected', ol);

			if(selected.length) {
				hoverAllBefore(selected.attr('rel'));
			}
		})
		// On click - callback
		.click(function() {
			var link = $(this);
			var rating = link.attr('rel');

			hoverAllBefore(rating, true);

			if(typeof(clickCallback) === 'function') {
				clickCallback(rating);
			}

			return false;
		});
	});
};

jQuery.fn.togglableDLs = function(conf) {
	var config = jQuery.extend({
		speed: 	100
	}, conf);

	return this.each(function() {
		var dds = $('dd', this).slideUp(config.speed);

		$('dt', this).each(function() {
			var dt = $(this);

			dt.html('<a href="#">' +dt.html() +'</a>').find('a').toggle(function() {
				var isDT = false;

				dt.nextAll().each(function() {
					if(isDT || $(this).is('dt')) {
						isDT = true;
						return;
					}

					$(this).slideDown(config.speed);
				});
			}, 
			function() {
				dds.slideUp(100);
			});
		});
	});
};


/*
 * jQuery UI Tabs
 *
 * Copyright (c) 2007, 2008 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI/Tabs
 *
 * Depends:
 *	ui.core.js
 */
(function($) {

$.widget("ui.tabs", {
	init: function() {
		this.options.event += '.tabs'; // namespace event
		
		// create tabs
		this.tabify(true);
	},
	setData: function(key, value) {
		if ((/^selected/).test(key))
			this.select(value);
		else {
			this.options[key] = value;
			this.tabify();
		}
	},
	length: function() {
		return this.$tabs.length;
	},
	tabId: function(a) {
		return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '')
			|| this.options.idPrefix + $.data(a);
	},
	ui: function(tab, panel) {
		return {
			options: this.options,
			tab: tab,
			panel: panel,
			index: this.$tabs.index(tab)
		};
	},
	tabify: function(init) {

		this.$lis = $('li:has(a[href])', this.element);
		this.$tabs = this.$lis.map(function() { return $('a', this)[0]; });
		this.$panels = $([]);

		var self = this, o = this.options;

		this.$tabs.each(function(i, a) {
			// inline tab
			if (a.hash && a.hash.replace('#', '')) // Safari 2 reports '#' for an empty hash
				self.$panels = self.$panels.add(a.hash);
			// remote tab
			else if ($(a).attr('href') != '#') { // prevent loading the page itself if href is just "#"
				$.data(a, 'href.tabs', a.href); // required for restore on destroy
				$.data(a, 'load.tabs', a.href); // mutable
				var id = self.tabId(a);
				a.href = '#' + id;
				var $panel = $('#' + id);
				if (!$panel.length) {
					$panel = $(o.panelTemplate).attr('id', id).addClass(o.panelClass)
						.insertAfter( self.$panels[i - 1] || self.element );
					$panel.data('destroy.tabs', true);
				}
				self.$panels = self.$panels.add( $panel );
			}
			// invalid tab href
			else
				o.disabled.push(i + 1);
		});

		if (init) {

			// attach necessary classes for styling if not present
			this.element.addClass(o.navClass);
			this.$panels.each(function() {
				var $this = $(this);
				$this.addClass(o.panelClass);
			});

			// Selected tab
			// use "selected" option or try to retrieve:
			// 1. from fragment identifier in url
			// 2. from cookie
			// 3. from selected class attribute on <li>
			if (o.selected === undefined) {
				if (location.hash) {
					this.$tabs.each(function(i, a) {
						if (a.hash == location.hash) {
							o.selected = i;
							// prevent page scroll to fragment
							if ($.browser.msie || $.browser.opera) { // && !o.remote
								var $toShow = $(location.hash), toShowId = $toShow.attr('id');
								$toShow.attr('id', '');
								setTimeout(function() {
									$toShow.attr('id', toShowId); // restore id
								}, 500);
							}
							scrollTo(0, 0);
							return false; // break
						}
					});
				}
				else if (o.cookie) {
					var index = parseInt($.cookie('ui-tabs' + $.data(self.element)),10);
					if (index && self.$tabs[index])
						o.selected = index;
				}
				else if (self.$lis.filter('.' + o.selectedClass).length)
					o.selected = self.$lis.index( self.$lis.filter('.' + o.selectedClass)[0] );
			}
			o.selected = o.selected === null || o.selected !== undefined ? o.selected : 0; // first tab selected by default

			// Take disabling tabs via class attribute from HTML
			// into account and update option properly.
			// A selected tab cannot become disabled.
			o.disabled = $.unique(o.disabled.concat(
				$.map(this.$lis.filter('.' + o.disabledClass),
					function(n, i) { return self.$lis.index(n); } )
			)).sort();
			if ($.inArray(o.selected, o.disabled) != -1)
				o.disabled.splice($.inArray(o.selected, o.disabled), 1);
			
			// highlight selected tab
			this.$panels.addClass(o.hideClass);
			this.$lis.removeClass(o.selectedClass);
			if (o.selected !== null) {
				this.$panels.eq(o.selected).show().removeClass(o.hideClass); // use show and remove class to show in any case no matter how it has been hidden before
				this.$lis.eq(o.selected).addClass(o.selectedClass);
				
				// seems to be expected behavior that the show callback is fired
				var onShow = function() {
					$(self.element).triggerHandler('tabsshow',
						[self.fakeEvent('tabsshow'), self.ui(self.$tabs[o.selected], self.$panels[o.selected])], o.show);
				}; 

				// load if remote tab
				if ($.data(this.$tabs[o.selected], 'load.tabs'))
					this.load(o.selected, onShow);
				// just trigger show event
				else
					onShow();
				
			}
			
			// clean up to avoid memory leaks in certain versions of IE 6
			$(window).bind('unload', function() {
				self.$tabs.unbind('.tabs');
				self.$lis = self.$tabs = self.$panels = null;
			});

		}

		// disable tabs
		for (var i = 0, li; li = this.$lis[i]; i++)
			$(li)[$.inArray(i, o.disabled) != -1 && !$(li).hasClass(o.selectedClass) ? 'addClass' : 'removeClass'](o.disabledClass);

		// reset cache if switching from cached to not cached
		if (o.cache === false)
			this.$tabs.removeData('cache.tabs');
		
		// set up animations
		var hideFx, showFx, baseFx = { 'min-width': 0, duration: 1 }, baseDuration = 'normal';
		if (o.fx && o.fx.constructor == Array)
			hideFx = o.fx[0] || baseFx, showFx = o.fx[1] || baseFx;
		else
			hideFx = showFx = o.fx || baseFx;

		// reset some styles to maintain print style sheets etc.
		var resetCSS = { display: '', overflow: '', height: '' };
		if (!$.browser.msie) // not in IE to prevent ClearType font issue
			resetCSS.opacity = '';

		// Hide a tab, animation prevents browser scrolling to fragment,
		// $show is optional.
		function hideTab(clicked, $hide, $show) {
			$hide.animate(hideFx, hideFx.duration || baseDuration, function() { //
				$hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
				if ($.browser.msie && hideFx.opacity)
					$hide[0].style.filter = '';
				if ($show)
					showTab(clicked, $show, $hide);
			});
		}

		// Show a tab, animation prevents browser scrolling to fragment,
		// $hide is optional.
		function showTab(clicked, $show, $hide) {
			if (showFx === baseFx)
				$show.css('display', 'block'); // prevent occasionally occuring flicker in Firefox cause by gap between showing and hiding the tab panels
			$show.animate(showFx, showFx.duration || baseDuration, function() {
				$show.removeClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
				if ($.browser.msie && showFx.opacity)
					$show[0].style.filter = '';

				// callback
				$(self.element).triggerHandler('tabsshow',
					[self.fakeEvent('tabsshow'), self.ui(clicked, $show[0])], o.show);

			});
		}

		// switch a tab
		function switchTab(clicked, $li, $hide, $show) {
			/*if (o.bookmarkable && trueClick) { // add to history only if true click occured, not a triggered click
				$.ajaxHistory.update(clicked.hash);
			}*/
			$li.addClass(o.selectedClass)
				.siblings().removeClass(o.selectedClass);
			hideTab(clicked, $hide, $show);
		}

		// attach tab event handler, unbind to avoid duplicates from former tabifying...
		this.$tabs.unbind('.tabs').bind(o.event, function() {

			//var trueClick = e.clientX; // add to history only if true click occured, not a triggered click
			var $li = $(this).parents('li:eq(0)'),
				$hide = self.$panels.filter(':visible'),
				$show = $(this.hash);

			// If tab is already selected and not unselectable or tab disabled or 
			// or is already loading or click callback returns false stop here.
			// Check if click handler returns false last so that it is not executed
			// for a disabled or loading tab!
			if (($li.hasClass(o.selectedClass) && !o.unselect)
				|| $li.hasClass(o.disabledClass) 
				|| $(this).hasClass(o.loadingClass)
				|| $(self.element).triggerHandler('tabsselect', [self.fakeEvent('tabsselect'), self.ui(this, $show[0])], o.select) === false
				) {
				this.blur();
				return false;
			}

			self.options.selected = self.$tabs.index(this);

			// if tab may be closed
			if (o.unselect) {
				if ($li.hasClass(o.selectedClass)) {
					self.options.selected = null;
					$li.removeClass(o.selectedClass);
					self.$panels.stop();
					hideTab(this, $hide);
					this.blur();
					return false;
				} else if (!$hide.length) {
					self.$panels.stop();
					var a = this;
					self.load(self.$tabs.index(this), function() {
						$li.addClass(o.selectedClass).addClass(o.unselectClass);
						showTab(a, $show);
					});
					this.blur();
					return false;
				}
			}

			if (o.cookie)
				$.cookie('ui-tabs' + $.data(self.element), self.options.selected, o.cookie);

			// stop possibly running animations
			self.$panels.stop();

			// show new tab
			if ($show.length) {

				// prevent scrollbar scrolling to 0 and than back in IE7, happens only if bookmarking/history is enabled
				/*if ($.browser.msie && o.bookmarkable) {
					var showId = this.hash.replace('#', '');
					$show.attr('id', '');
					setTimeout(function() {
						$show.attr('id', showId); // restore id
					}, 0);
				}*/

				var a = this;
				self.load(self.$tabs.index(this), $hide.length ? 
					function() {
						switchTab(a, $li, $hide, $show);
					} :
					function() {
						$li.addClass(o.selectedClass);
						showTab(a, $show);
					}
				);

				// Set scrollbar to saved position - need to use timeout with 0 to prevent browser scroll to target of hash
				/*var scrollX = window.pageXOffset || document.documentElement && document.documentElement.scrollLeft || document.body.scrollLeft || 0;
				var scrollY = window.pageYOffset || document.documentElement && document.documentElement.scrollTop || document.body.scrollTop || 0;
				setTimeout(function() {
					scrollTo(scrollX, scrollY);
				}, 0);*/

			} else
				throw 'jQuery UI Tabs: Mismatching fragment identifier.';

			// Prevent IE from keeping other link focussed when using the back button
			// and remove dotted border from clicked link. This is controlled in modern
			// browsers via CSS, also blur removes focus from address bar in Firefox
			// which can become a usability and annoying problem with tabsRotate.
			if ($.browser.msie)
				this.blur();

			//return o.bookmarkable && !!trueClick; // convert trueClick == undefined to Boolean required in IE
			return false;

		});

		// disable click if event is configured to something else
		if (!(/^click/).test(o.event))
			this.$tabs.bind('click.tabs', function() { return false; });

	},
	add: function(url, label, index) {
		if (index == undefined) 
			index = this.$tabs.length; // append by default

		var o = this.options;
		var $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label));
		$li.data('destroy.tabs', true);

		var id = url.indexOf('#') == 0 ? url.replace('#', '') : this.tabId( $('a:first-child', $li)[0] );

		// try to find an existing element before creating a new one
		var $panel = $('#' + id);
		if (!$panel.length) {
			$panel = $(o.panelTemplate).attr('id', id)
				.addClass(o.hideClass)
				.data('destroy.tabs', true);
		}
		$panel.addClass(o.panelClass);
		if (index >= this.$lis.length) {
			$li.appendTo(this.element);
			$panel.appendTo(this.element[0].parentNode);
		} else {
			$li.insertBefore(this.$lis[index]);
			$panel.insertBefore(this.$panels[index]);
		}
		
		o.disabled = $.map(o.disabled,
			function(n, i) { return n >= index ? ++n : n });
			
		this.tabify();

		if (this.$tabs.length == 1) {
			$li.addClass(o.selectedClass);
			$panel.removeClass(o.hideClass);
			var href = $.data(this.$tabs[0], 'load.tabs');
			if (href)
				this.load(index, href);
		}

		// callback
		this.element.triggerHandler('tabsadd',
			[this.fakeEvent('tabsadd'), this.ui(this.$tabs[index], this.$panels[index])], o.add
		);
	},
	remove: function(index) {
		var o = this.options, $li = this.$lis.eq(index).remove(),
			$panel = this.$panels.eq(index).remove();

		// If selected tab was removed focus tab to the right or
		// in case the last tab was removed the tab to the left.
		if ($li.hasClass(o.selectedClass) && this.$tabs.length > 1)
			this.select(index + (index + 1 < this.$tabs.length ? 1 : -1));

		o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),
			function(n, i) { return n >= index ? --n : n });

		this.tabify();

		// callback
		this.element.triggerHandler('tabsremove',
			[this.fakeEvent('tabsremove'), this.ui($li.find('a')[0], $panel[0])], o.remove
		);
	},
	enable: function(index) {
		var o = this.options;
		if ($.inArray(index, o.disabled) == -1)
			return;
			
		var $li = this.$lis.eq(index).removeClass(o.disabledClass);
		if ($.browser.safari) { // fix disappearing tab (that used opacity indicating disabling) after enabling in Safari 2...
			$li.css('display', 'inline-block');
			setTimeout(function() {
				$li.css('display', 'block');
			}, 0);
		}

		o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });

		// callback
		this.element.triggerHandler('tabsenable',
			[this.fakeEvent('tabsenable'), this.ui(this.$tabs[index], this.$panels[index])], o.enable
		);

	},
	disable: function(index) {
		var self = this, o = this.options;
		if (index != o.selected) { // cannot disable already selected tab
			this.$lis.eq(index).addClass(o.disabledClass);

			o.disabled.push(index);
			o.disabled.sort();

			// callback
			this.element.triggerHandler('tabsdisable',
				[this.fakeEvent('tabsdisable'), this.ui(this.$tabs[index], this.$panels[index])], o.disable
			);
		}
	},
	select: function(index) {
		if (typeof index == 'string')
			index = this.$tabs.index( this.$tabs.filter('[href$=' + index + ']')[0] );
		this.$tabs.eq(index).trigger(this.options.event);
	},
	load: function(index, callback) { // callback is for internal usage only
		
		var self = this, o = this.options, $a = this.$tabs.eq(index), a = $a[0],
				bypassCache = callback == undefined || callback === false, url = $a.data('load.tabs');

		callback = callback || function() {};
		
		// no remote or from cache - just finish with callback
		if (!url || !bypassCache && $.data(a, 'cache.tabs')) {
			callback();
			return;
		}

		// load remote from here on
		
		var inner = function(parent) {
			var $parent = $(parent), $inner = $parent.find('*:last');
			return $inner.length && $inner.is(':not(img)') && $inner || $parent;
		};
		var cleanup = function() {
			self.$tabs.filter('.' + o.loadingClass).removeClass(o.loadingClass)
						.each(function() {
							if (o.spinner)
								inner(this).parent().html(inner(this).data('label.tabs'));
						});
			self.xhr = null;
		};
		
		if (o.spinner) {
			var label = inner(a).html();
			inner(a).wrapInner('<em></em>')
				.find('em').data('label.tabs', label).html(o.spinner);
		}

		var ajaxOptions = $.extend({}, o.ajaxOptions, {
			url: url,
			success: function(r, s) {
				$(a.hash).html(r);
				cleanup();
				
				if (o.cache)
					$.data(a, 'cache.tabs', true); // if loaded once do not load them again

				// callbacks
				$(self.element).triggerHandler('tabsload',
					[self.fakeEvent('tabsload'), self.ui(self.$tabs[index], self.$panels[index])], o.load
				);
				o.ajaxOptions.success && o.ajaxOptions.success(r, s);
				
				// This callback is required because the switch has to take
				// place after loading has completed. Call last in order to 
				// fire load before show callback...
				callback();
			}
		});
		if (this.xhr) {
			// terminate pending requests from other tabs and restore tab label
			this.xhr.abort();
			cleanup();
		}
		$a.addClass(o.loadingClass);
		setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
			self.xhr = $.ajax(ajaxOptions);
		}, 0);

	},
	url: function(index, url) {
		this.$tabs.eq(index).removeData('cache.tabs').data('load.tabs', url);
	},
	destroy: function() {
		var o = this.options;
		this.element.unbind('.tabs')
			.removeClass(o.navClass).removeData('tabs');
		this.$tabs.each(function() {
			var href = $.data(this, 'href.tabs');
			if (href)
				this.href = href;
			var $this = $(this).unbind('.tabs');
			$.each(['href', 'load', 'cache'], function(i, prefix) {
				$this.removeData(prefix + '.tabs');
			});
		});
		this.$lis.add(this.$panels).each(function() {
			if ($.data(this, 'destroy.tabs'))
				$(this).remove();
			else
				$(this).removeClass([o.selectedClass, o.unselectClass,
					o.disabledClass, o.panelClass, o.hideClass].join(' '));
		});
	},
	fakeEvent: function(type) {
		return $.event.fix({
			type: type,
			target: this.element[0]
		});
	}
});

$.ui.tabs.defaults = {
	// basic setup
	unselect: false,
	event: 'click',
	disabled: [],
	cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }
	// TODO history: false,

	// Ajax
	spinner: 'Loading&#8230;',
	cache: false,
	idPrefix: 'ui-tabs-',
	ajaxOptions: {},

	// animations
	fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }

	// templates
	tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>',
	panelTemplate: '<div></div>',

	// CSS classes
	navClass: 'ui-tabs-nav',
	selectedClass: 'ui-tabs-selected',
	unselectClass: 'ui-tabs-unselect',
	disabledClass: 'ui-tabs-disabled',
	panelClass: 'ui-tabs-panel',
	hideClass: 'ui-tabs-hide',
	loadingClass: 'ui-tabs-loading'
};

$.ui.tabs.getter = "length";

/*
 * Tabs Extensions
 */

/*
 * Rotate
 */
$.extend($.ui.tabs.prototype, {
	rotation: null,
	rotate: function(ms, continuing) {
		
		continuing = continuing || false;
		
		var self = this, t = this.options.selected;
		
		function start() {
			self.rotation = setInterval(function() {
				t = ++t < self.$tabs.length ? t : 0;
				self.select(t);
			}, ms); 
		}
		
		function stop(e) {
			if (!e || e.clientX) { // only in case of a true click
				clearInterval(self.rotation);
			}
		}
		
		// start interval
		if (ms) {
			start();
			if (!continuing)
				this.$tabs.bind(this.options.event, stop);
			else
				this.$tabs.bind(this.options.event, function() {
					stop();
					t = self.options.selected;
					start();
				});
		}
		// stop interval
		else {
			stop();
			this.$tabs.unbind(this.options.event, stop);
		}
	}
});

})(jQuery);

LaptopLogic.modules.LaptopFinderAdvanced =
{
	init: function()
	{
		// Only run if we're on the right page
		if (!$('#laptop-finder-advanced').size())
		{
			return false;
		}

		this.make_steps();
		$('p.submit-area').hide();
		
		$('p.nav-btns').append('<input class="show-results" type="image" src="/images/buttons/show-results.png" alt="Show results" style="display:none;" />');
		$('body').append( "<div class='js-loader-preloader' ></div>" );
		this.make_loading_screen();
	},
	
	make_steps:function()
	{
		var $step_list = $('ol.steps');
	
		var $fieldsets = $('#laptop-finder-advanced fieldset'); // Store fieldsets
		
		$fieldsets.wrapAll('<div class="viewport"><div class="inner self-clear"></div></div>'); // wrap fieldsets to be able to slide them when navigating
		
		$step_list.find('li:first').addClass('sel'); // Add select class to first step in list
				
		var num;
		var next_num;
		var prev_num;
		
		var num_fieldsets = $fieldsets.size();
		
		$fieldsets.each(function(i) // Loop fieldsets and add prev/next buttons
		{
			num = i + 1;		// Current fieldset num
			next_num = i + 2;	// Next fieldset num
			prev_num = i;		// prev fieldset num
			
			var $this = $(this); // Store current fieldset
			
			$this.addClass('not-completed'); // Add not-completed class to fieldset. This gets removed once an input has been clicked
			
			$this.find('input').click(function() // Assign clicks to all inputs
			{
				LaptopLogic.modules.LaptopFinderAdvanced.input_click($this);
			});
			
			$this.append('<p class="nav-btns"></p>'); // Append container for nav btns
			
			var $nav_btns = $this.find('p.nav-btns'); // Store nav btns container
			
			if (num < num_fieldsets) // Append next btn if we're not on the last one
			{
				$nav_btns.append('<a href="#" class="next-step">Next step (' + next_num + '/' + num_fieldsets + ')</a>');
			}
			
			if (num > 1) // Append prev btn if we're not on the first one
			{
				$nav_btns.prepend('<a href="#" class="prev-step">Prev step (' + prev_num + '/' + num_fieldsets + ')</a>');
			}
		});
		
		$step_list.find('a').click(function() // Assign clicks to steps links
		{
			LaptopLogic.modules.LaptopFinderAdvanced.switch_step($(this),'steps');
			return false;
		});	
		
		$('p.nav-btns a').click(function() // Assign clicks to nav btns
		{
			LaptopLogic.modules.LaptopFinderAdvanced.switch_step($(this),'btns');
			return false;
		});
	},
	
	// Tries to switch step when a step link or nav btn is clicked
	switch_step:function($this,type)
	{		
		var $target_fieldset;
		
		var target_fieldset_id;
		
		var $step_list = $('ol.steps');
				
		// The currently selected step and its index
		var $selected_li = $step_list.find('li.sel');
		var selected_li_index = $step_list.find('li').index($selected_li);
		
		var current_fieldset_id = $selected_li.find('a').attr('href')
		
		var $current_fieldset = $(current_fieldset_id);
		
		if (type == 'steps') // If click in steps list
		{
			// The clicked step and its index
			var $clicked_li = $this.parent('li');
			var clicked_li_index = $step_list.find('li').index($clicked_li);
			
			// The last completed step and its index
			var $last_completed_li = $step_list.find('li.complete:last');
			var last_completed_li_index = $step_list.find('li').index($last_completed_li);
			
			var $step_to_complete = $step_list.find('li').not('.complete').filter(':first'); // Get the step to complete
			
			if (!$step_to_complete.size()) // If not found - get the first one
			{
				$step_to_complete = $step_list.find('li:first');
			}
			
			var step_to_complete_index = $step_list.find('li').index($step_to_complete);
			
			// console.log('last completed: ' + last_completed_li_index)
			// console.log('clicked: ' + clicked_li_index)
			// console.log('step to complete: ' + step_to_complete_index)
			
			// Make selected step not clickable
			if (
				($clicked_li.hasClass('sel'))
				)
			{
				return false;
			}
			
			// If selected step isnt completed and clicked step is above the last completed step
			// OR
			// if clicked step is above the step to complete
			// Then we should prevent the click from going thru and display an error note
			
			if 	(
					(!$selected_li.hasClass('complete') && clicked_li_index > last_completed_li_index)
				||	
					(clicked_li_index > step_to_complete_index)
				)
			{
				
				$step_list.find('span.note').remove(); // Make sure no error note is visible by removing anyone present
				
				// Build alert text
				var step_to_complete_text = $step_to_complete.text();
				
				if ($.browser.msie)
				{
					var alert_text = 'You need to complete the steps in order. Please continue with: "' + step_to_complete_text + '"';
					alert(alert_text);
				}
				else
				{
					var alert_text = 'You need to complete the steps in order. Please continue with: <strong>' + step_to_complete_text + '</strong>';

					
					
					//console.log($step_list.find('span.note'))
					
					$clicked_li.append('<span class="note">' + alert_text + '</span>'); // Append the note to the clicked li

					var $note = $clicked_li.find('span.note');

					// Make note disappear when clicked
					$note.click(function()
					{
						$note.fadeOut(function()
						{
							$note.remove();
						});
					});

					// if not clicked - make it disappear by itself
					setTimeout(function()
					{
						$note.fadeOut(function()
						{
							$note.remove();
						});
					},
					2500);
				}
				
				return false;
			}
			
			target_fieldset_id = $this.attr('href'); // Get the id of the fieldset we're about to show from the clicked steps href
			
			$target_fieldset = $('fieldset' + target_fieldset_id); // Store that fieldset
		}
		else // If click is on a prev/next btn
		{
			if (type == 'btns' && $this.hasClass('next-step')) // next click
			{
				if ($current_fieldset.hasClass('not-completed'))
				{
					var $nav_btns = $current_fieldset.find('p.nav-btns');
					
					if (!$nav_btns.find('span.error-msg').size())
					{
						$nav_btns.append('<span class="error-msg">Please make a selection before you continue!</span>');
					}
					return false;
				}
				
				$target_fieldset = $current_fieldset.next();
				
			}
			else if (type == 'btns' && $this.hasClass('prev-step')) // prev click
			{
				$target_fieldset = $current_fieldset.prev();
			}			
			
			target_fieldset_id = "#" + $target_fieldset.attr('id');
			
			// The clicked step and its index
			var $clicked_li = $step_list.find('a[href="' + target_fieldset_id +'"]').parent('li');
			var clicked_li_index = $step_list.find('li').index($clicked_li);
			
		}
		
		// Mark current step in list
		$step_list.find('li.sel').removeClass('sel');
		$step_list.find('a[href="' + target_fieldset_id + '"]').parent('li').addClass('sel');
		
		var new_left_pos = clicked_li_index * 564;
		new_left_pos = '-' + new_left_pos + 'px';
		
		$all_nav_btns = $('p.nav-btns');
		
		//$all_nav_btns.hide();
		
		// Animate the requested fieldset into postion
		$("div.viewport div.inner").animate(
		{ 
			left:new_left_pos
		},
		500,function()
		{
			//$all_nav_btns.show();
		});
	},
	
	// This runs when an input (checkbox/radio is clicked)
	input_click:function($fieldset)
	{
		var $fieldset_inputs = $fieldset.find('input'); // Get all inputs
		
		var fieldset_id = $fieldset.attr('id');
		
		var $input_ok = false; // Flag for completed fieldset (at least one choice has been made)
		
		$('ol.steps span.note').remove(); // Remove error note if any in steps list
		
		// Check fieldset for at least one value. If found - set flag to true
		$fieldset_inputs.each(function()
		{
			if ($(this).attr('checked') || $(this).attr('selected'))
			{
				$input_ok = true;
			}
		});
		
		// Get the step in the list that corresponds to this fieldset
		var corresponding_step_li = $('ol.steps li a[href*="' + fieldset_id + '"]').parent('li');
		
		if ($input_ok) // If values found
		{
			$fieldset.removeClass('not-completed'); // remove not completed class from fieldset
			$fieldset.find('p.nav-btns span.error-msg').remove(); // remove error note by the nav btns (if any)
			
			corresponding_step_li.addClass('complete'); // Add complete class to corresponding step
		}
		else // If no value was found
		{
			$fieldset.addClass('not-completed'); // Add not completed class to fieldset (might already be there)
			
			corresponding_step_li.removeClass('complete'); // // Remove complete class from corresponding step (if any)
		}
		
		var $steps = $('ol.steps li'); // Get all steps
		
		var num_steps = $steps.size(); // count them
		
		var num_steps_complete = $steps.filter('.complete').size(); // count completed steps
		
		if (num_steps == num_steps_complete) // If all steps are completed
		{
			$('input.show-results').fadeIn();
		}
		else // if not all completed
		{
			$('input.show-results').fadeOut();
		}
	},
	
	make_loading_screen:function(){
	  
	   $('input.show-results').click(function(){
	   
	       $('#laptop-finder-advanced').ajaxLoader();
	   });
	}
};

LaptopLogic.modules.LaptopFinderSimple = {
	run: function() {
		if($('#laptop-finder-simple').length) {
			this.makeLabelsClickable();
			this.hijaxForm();
		}
	},
	
	makeLabelsClickable: function() {
		// Mark selected label's
		$('#laptop-finder-simple input:checked').each(function() {
			$(this).parents('label').eq(0).addClass('sel');
		});

		$('#laptop-finder-simple label').click(function() {
			var label		= $(this);
			var currentStep	= label.parents('div').eq(0);
			var isRadio		= $('input[type="radio"]', currentStep).length;

			if(isRadio) {
				$('label', currentStep).removeClass('sel');
				$('input[type="radio"]', currentStep).attr('checked', false);

				label.addClass('sel').find('input').attr('checked', true);
			}
			else
			{	
				// Make sure not important can't be combined with any of the other options
				if (label.find('input[type="checkbox"]').val() == "")
				{
					label.parents('ul').find('label').removeClass('sel');
				}
				else
				{
					$('div#lf-step-1 input[type="checkbox"][value=""]').parent('label').removeClass('sel');
				}
				
				if(label.is('.sel')) {
					label.removeClass('sel');
					label.find('input').attr('checked', false);
				}
				else {
					label.addClass('sel');
					label.find('input').attr('checked', true);
				}
			}

			return false;
		});
	}, 

	hijaxForm: function() {
		// Make all steps as high as the highest by adding to margin-bottom
		var adjustAllStepsHeight = function() {
			var highest = 0;

			$('#laptop-finder-simple form > div').each(function() {
				var thisHeight = $(this).outerHeight();
				if(thisHeight > highest) {
					highest = thisHeight;
				}
			}).each(function() {
				var thisHeight = $(this).outerHeight();
				var newMarginBottom = highest - thisHeight + 50;
				$(this).css('marginBottom', newMarginBottom +'px');
			});

			return highest;
		};

		var highest = adjustAllStepsHeight();

		// Now make the container as high as the steps and set overflow to hidden so only first step is shown
		$('#laptop-finder-simple').css({overflow: 'hidden', height: (highest + 30) +'px'});
		$('#laptop-finder-simple form').css({position: 'relative', top: 0});

		// Replace submit-button with link pointing to results
		$('#laptop-finder-simple input[type="image"]').replaceWith('<a href="#lf-step-4" class="cta cta-red">Get Laptops</a>');

		// Add results-div
		$('<div id="lf-step-4"><div id="laptop-finder-results"></div><ul class="last"><li><a href="#lf-step-1" class="cta cta-red">Start over</a></li></ul></div>').appendTo('#laptop-finder-simple form');

		// Animate when clicking on-to-step-x-buttons
		$('#laptop-finder-simple ul.last a').click(function() {
			var stepNum = $(this).attr('href').replace(/.*?step-([0-9]+).*/, '$1');
			var animationOptions = {duration: 500, easing: 'easeOutExpo'};

			// Make sure at least one checkbox is checked
			if(stepNum != 1 && !$(this).parents('div').eq(0).find('input:checked').length) {
				alert('Please select at least one option before going to the next step');
				return false;
			}
			// This is the "Get laptops-button", ajax the results
			if(stepNum == 4) {
				var link = $(this);
				var oldText = link.text();

				link.text('Loading...');
				$('#lf-step-3').ajaxLoader({className: 'jquery-ajax-loader-no-bg'});

				$.post('/ajax/laptop-finder/laptop-finder.php', $('#laptop-finder-simple form').formToArray(), function(data) {
					// Put them in the results-div
					$('#laptop-finder-results').html($(data).html());

					// Give all the images a sec to load...
					setTimeout(function() {
						link.text(oldText);
						$('#lf-step-3').ajaxLoaderRemove();

						// Adjust the height of the laptop-finder in case results are higher than any other box
						highest = adjustAllStepsHeight();
						$('#laptop-finder-simple').css('height', (highest + 30) +'px').find('form').css({top: '-' +((highest + 50) * (stepNum - 2)) +'px'});

						// Scroll up the results
						$('#laptop-finder-simple form').animate({top: '-' +((highest + 50) * (stepNum - 1)) +'px'}, animationOptions);
					}, '1000');
				});
			}
			// Else just scroll to required step
			else {
				$('#laptop-finder-simple form').animate({top: '-' +((highest + 50) * (stepNum - 1)) +'px'}, animationOptions);
			}

			return false;
		});
	}
};

LaptopLogic.modules.LaptopRepairAdmin = {
	init: function() {
	    this.selectType();
		this.getCountries();
		this.getRepairCompany();
	}, 
	
	getCountries: function() {
	    $('#laptop-repair-admin #continent').change(function() {
	    $('#laptop-repair-admin .create #countryTD').remove();
	    var cell = $('<td id="countryTD"></td>').appendTo('#laptop-repair-admin tr:last');
    	    $('#laptop-repair-admin').ajaxLoader();
    	    $.post('/ajax/get-countries/get-countries.php?continent='+$(this).val(), function(data) {
                cell.html(data);
                $('#laptop-repair-admin').ajaxLoaderRemove( true );
                LaptopLogic.modules.LaptopRepairAdmin.getStates();
            });
	    });
	},
	
	getStates: function() {
	    $('#laptop-repair-admin #country').change(function() {
		    if( $(this).val() == 'US' )
		    {
		        $('#laptop-repair-admin .create #stateTD').remove();
		        var cell = $('<td id="stateTD"></td>').appendTo('#laptop-repair-admin tr:last');
	            $('#laptop-repair-admin').ajaxLoader();
	            $.post('/ajax/get-states/get-states.php?country='+$(this).val(), function(data) {
	                cell.html(data);
	                $('#laptop-repair-admin').ajaxLoaderRemove( true );
	            });
    	    }
    	    else
    	       $('#laptop-repair-admin .create #stateTD').remove();
	    });
	},
	
	selectType: function() {
        $('#laptop-repair-admin div[class]').hide();
        $('#laptop-repair-admin-type-select label input').click(function() {
            if( $(this).val() == 'create' )
            {
                $('#laptop-repair-admin div[class]').hide();
                $('#laptop-repair-admin div.create').show();
            }
            if( $(this).val() == 'edit' )
            {
                $('#laptop-repair-admin div[class]').hide();
                $('#laptop-repair-admin div.edit').show();
                
            }
            if( $(this).val() == 'delete' )
            {
                $('#laptop-repair-admin div[class]').hide();
                $('#laptop-repair-admin div.delete').show();
            }
        });
    },
    
    getRepairCompany: function() {
        var editDiv = $('<div id="edit_repair"></div>').appendTo('#laptop-repair-admin .edit');
        $('#laptop-repair-admin #repair').change(function() {
            $('#laptop-repair-admin').ajaxLoader();
            $.post('/ajax/get-repair-company/get-repair-company.php?content='+$(this).val(), function(data) {
                editDiv.html(data);
                $('#laptop-repair-admin').ajaxLoaderRemove( true );
                LaptopLogic.modules.LaptopRepairAdmin.getEditCountries();
                LaptopLogic.modules.LaptopRepairAdmin.hijaxEditForm();
            });
        }); 
    },
    
    getEditCountries: function() {
        if( $('#laptop-repair-admin .edit #continent').val() != 'undefined' )
            var continent = $('#laptop-repair-admin .edit #continent').val(); 
            
        var content = $('#laptop-repair-admin .edit input[name="content"]').val();   
        var cell = $('<td></td>').appendTo('#laptop-repair-admin .edit tr:last');
        $('#laptop-repair-admin').ajaxLoader();
        $.post('/ajax/get-countries/get-countries.php?continent='+continent+'&content='+content, function(data) {
            cell.html(data);
            $('#laptop-repair-admin').ajaxLoaderRemove( true );
            LaptopLogic.modules.LaptopRepairAdmin.getEditStates();
        });
    },
    
    getEditStates: function() {
        if( $('#laptop-repair-admin .edit #country').val() != 'undefined' )
            var country = $('#laptop-repair-admin .edit #country').val();
            
        if( country == 'US' )
        {
            var content = $('#laptop-repair-admin .edit input[name="content"]').val();
            var cell = $('<td></td>').appendTo('#laptop-repair-admin .edit tr:last');
            $('#laptop-repair-admin').ajaxLoader();
            $.post('/ajax/get-states/get-states.php?country='+country+'&content='+content, function(data) {
                cell.html(data);
                $('#laptop-repair-admin').ajaxLoaderRemove( true );
            });
        }
        
        $('#laptop-repair-admin .edit #country').change(function() {
            var chosen = $('#laptop-repair-admin .edit #country').val();
            if( chosen == 'US' )
            {
                var content = $('#laptop-repair-admin .edit input[name="content"]').val();
	            var cell = $('<td></td>').appendTo('#laptop-repair-admin .edit tr:last');
	            $('#laptop-repair-admin').ajaxLoader();
	            $.post('/ajax/get-states/get-states.php?country='+chosen+'&content='+content, function(data) {
	                cell.html(data);
	                $('#laptop-repair-admin').ajaxLoaderRemove( true );
	            });
	        }
	        else
	        {
	           $('#laptop-repair-admin .edit #state').hide();
	        }
        });
    },
	
	hijaxEditForm: function() {
        $('#laptop-repair-admin .edit form').liveValidation({
            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
            validIco:   '/css/gfx/icons/form-control-valid.png'
        }, 
            { tracker: /^(http:\/\/)?(www)?(.+)\.(.+)$/
       });
    }
};

var mboxCopyright = "&copy; 2003-2009. Omniture, Inc. All rights reserved.";mboxUrlBuilder = function(a, b) { this.a = a; this.b = b; this.c = new Array(); this.d = function(e) { return e; }; this.f = null;};mboxUrlBuilder.prototype.addParameter = function(g, h) { var i = new RegExp('(\'|")'); if (i.exec(g)) { throw "Parameter '" + g + "' contains invalid characters"; } for (var j = 0; j < this.c.length; j++) { var k = this.c[j]; if (k.name == g) { k.value = h; return this; } } var l = new Object(); l.name = g; l.value = h; this.c[this.c.length] = l; return this;};mboxUrlBuilder.prototype.addParameters = function(c) { if (!c) { return this; } for (var j = 0; j < c.length; j++) { var m = c[j].indexOf('='); if (m == -1 || m == 0) { continue; } this.addParameter(c[j].substring(0, m), c[j].substring(m + 1, c[j].length)); } return this;};mboxUrlBuilder.prototype.setServerType = function(n) { this.o = n;};mboxUrlBuilder.prototype.setBasePath = function(f) { this.f = f;};mboxUrlBuilder.prototype.setUrlProcessAction = function(p) { this.d = p;};mboxUrlBuilder.prototype.buildUrl = function() { var q = this.f ? this.f : '/m2/' + this.b + '/mbox/' + this.o; var r = document.location.protocol == 'file:' ? 'http:' : document.location.protocol; var e = r + "//" + this.a + q; var s = e.indexOf('?') != -1 ? '&' : '?'; for (var j = 0; j < this.c.length; j++) { var k = this.c[j]; e += s + encodeURIComponent(k.name) + '=' + encodeURIComponent(k.value); s = '&'; } return this.t(this.d(e));};mboxUrlBuilder.prototype.getParameters = function() { return this.c;};mboxUrlBuilder.prototype.setParameters = function(c) { this.c = c;};mboxUrlBuilder.prototype.clone = function() { var u = new mboxUrlBuilder(this.a, this.b); u.setServerType(this.o); u.setBasePath(this.f); u.setUrlProcessAction(this.d); for (var j = 0; j < this.c.length; j++) { u.addParameter(this.c[j].name, this.c[j].value); } return u;};mboxUrlBuilder.prototype.t = function(v) { return v.replace(/\"/g, '&quot;').replace(/>/g, '&gt;');};mboxStandardFetcher = function() { };mboxStandardFetcher.prototype.getType = function() { return 'standard';};mboxStandardFetcher.prototype.fetch = function(w) { w.setServerType(this.getType()); document.write('<' + 'scr' + 'ipt src="' + w.buildUrl() + '" language="JavaScript"><' + '\/scr' + 'ipt>');};mboxStandardFetcher.prototype.cancel = function() { };mboxAjaxFetcher = function() { };mboxAjaxFetcher.prototype.getType = function() { return 'ajax';};mboxAjaxFetcher.prototype.fetch = function(w) { w.setServerType(this.getType()); var e = w.buildUrl(); this.x = document.createElement('script'); this.x.src = e; document.body.appendChild(this.x);};mboxAjaxFetcher.prototype.cancel = function() { };mboxMap = function() { this.y = new Object(); this.z = new Array();};mboxMap.prototype.put = function(A, h) { if (!this.y[A]) { this.z[this.z.length] = A; } this.y[A] = h;};mboxMap.prototype.get = function(A) { return this.y[A];};mboxMap.prototype.remove = function(A) { this.y[A] = undefined;};mboxMap.prototype.each = function(p) { for (var j = 0; j < this.z.length; j++ ) { var A = this.z[j]; var h = this.y[A]; if (h) { p(A, h); } }};mboxFactory = function(B, b, C) { this.D = false; this.B = B; this.C = C; this.E = new mboxList(); mboxFactories.put(C, this); this.F = typeof document.createElement('div').replaceChild != 'undefined' && (function() { return true; })() && typeof document.getElementById != 'undefined' && typeof (window.attachEvent || document.addEventListener || window.addEventListener) != 'undefined' && typeof encodeURIComponent != 'undefined'; this.G = this.F && mboxGetPageParameter('mboxDisable') == null; var H = C == 'default'; this.I = new mboxCookieManager( 'mbox' + (H ? '' : ('-' + C)), (function() { return mboxCookiePageDomain(); })()); this.G = this.G && this.I.isEnabled() && (this.I.getCookie('disable') == null); if (this.isAdmin()) { this.enable(); } this.J = mboxGenerateId(); this.K = new mboxSession(this.J, 'mboxSession', 'session', 31 * 60, this.I); this.L = new mboxPC('PC', 1209600, this.I); this.w = new mboxUrlBuilder(B, b); this.M(this.w, H); this.N = new Date().getTime(); this.O = this.N; var P = this; this.addOnLoad(function() { P.O = new Date().getTime(); }); if (this.F) { this.addOnLoad(function() { P.D = true; P.getMboxes().each(function(Q) { Q.setFetcher(new mboxAjaxFetcher()); Q.finalize(); }); }); this.limitTraffic(100, 10368000); if (this.G) { this.R(); this.S = new mboxSignaler(function(T, c) { return P.create(T, c); }, this.I); } }};mboxFactory.prototype.isEnabled = function() { return this.G;};mboxFactory.prototype.getDisableReason = function() { return this.I.getCookie('disable');};mboxFactory.prototype.isSupported = function() { return this.F;};mboxFactory.prototype.disable = function(U, V) { if (typeof U == 'undefined') { U = 60 * 60; } if (typeof V == 'undefined') { V = 'unspecified'; } if (!this.isAdmin()) { this.G = false; this.I.setCookie('disable', V, U); }};mboxFactory.prototype.enable = function() { this.G = true; this.I.deleteCookie('disable');};mboxFactory.prototype.isAdmin = function() { return document.location.href.indexOf('mboxEnv') != -1;};mboxFactory.prototype.limitTraffic = function(W, U) {};mboxFactory.prototype.addOnLoad = function(p) { if (window.addEventListener) { window.addEventListener('load', p, false); } else if (document.addEventListener) { document.addEventListener('load', p, false); } else if (document.attachEvent) { window.attachEvent('onload', p); }};mboxFactory.prototype.getEllapsedTime = function() { return this.O - this.N;};mboxFactory.prototype.getEllapsedTimeUntil = function(X) { return X - this.N;};mboxFactory.prototype.getMboxes = function() { return this.E;};mboxFactory.prototype.get = function(T, Y) { return this.E.get(T).getById(Y || 0);};mboxFactory.prototype.update = function(T, c) { if (!this.isEnabled()) { return; } if (this.E.get(T).length() == 0) { throw "Mbox " + T + " is not defined"; } this.E.get(T).each(function(Q) { Q.getUrlBuilder() .addParameter('mboxPage', mboxGenerateId()); Q.load(c); });};mboxFactory.prototype.create = function( T, c, Z) { if (!this.isSupported()) { return null; } var e = this.w.clone(); e.addParameter('mboxCount', this.E.length() + 1); e.addParameters(c); var Y = this.E.get(T).length(); var _ = this.C + '-' + T + '-' + Y; var ab; if (Z) { ab = new mboxLocatorNode(Z); } else { if (this.D) { throw 'The page has already been loaded, can\'t write marker'; } ab = new mboxLocatorDefault(_); } try { var P = this; var bb = 'mboxImported-' + _; var Q = new mbox(T, Y, e, ab, bb); if (this.G) { Q.setFetcher(this.D ? new mboxAjaxFetcher() : new mboxStandardFetcher()); } Q.setOnError(function(cb, n) { Q.setMessage(cb); Q.activate(); if (!Q.isActivated()) { P.disable(60 * 60, cb); window.location.reload(false); } }); this.E.add(Q); } catch (db) { this.disable(); throw 'Failed creating mbox "' + T + '", the error was: ' + db; } var eb = new Date(); e.addParameter('mboxTime', eb.getTime() - (eb.getTimezoneOffset() * 60000)); return Q;};mboxFactory.prototype.getCookieManager = function() { return this.I;};mboxFactory.prototype.getPageId = function() { return this.J;};mboxFactory.prototype.getPCId = function() { return this.L;};mboxFactory.prototype.getSessionId = function() { return this.K;};mboxFactory.prototype.getSignaler = function() { return this.S;};mboxFactory.prototype.getUrlBuilder = function() { return this.w;};mboxFactory.prototype.M = function(e, H) { e.addParameter('mboxHost', document.location.hostname) .addParameter('mboxSession', this.K.getId()); if (!H) { e.addParameter('mboxFactoryId', this.C); } if (this.L.getId() != null) { e.addParameter('mboxPC', this.L.getId()); } e.addParameter('mboxPage', this.J); e.addParameter('mboxXDomain', "enabled"); e.setUrlProcessAction(function(e) { e += '&mboxURL=' + encodeURIComponent(document.location); var fb = encodeURIComponent(document.referrer); if (e.length + fb.length < 2000) { e += '&mboxReferrer=' + fb; } e += '&mboxVersion=' + mboxVersion; return e; });};mboxFactory.prototype.gb = function() { return "";};mboxFactory.prototype.R = function() { document.write('<style>.' + 'mboxDefault' + ' { visibility:hidden; }</style>');};mboxFactory.prototype.isDomLoaded = function() { return this.D;};mboxSignaler = function(hb, I) { this.I = I; var ib = I.getCookieNames('signal-'); for (var j = 0; j < ib.length; j++) { var jb = ib[j]; var kb = I.getCookie(jb).split('&'); var Q = hb(kb[0], kb); Q.load(); I.deleteCookie(jb); }};mboxSignaler.prototype.signal = function(lb, T ) { this.I.setCookie('signal-' + lb, mboxShiftArray(arguments).join('&'), 45 * 60);};mboxList = function() { this.E = new Array();};mboxList.prototype.add = function(Q) { if (Q != null) { this.E[this.E.length] = Q; }};mboxList.prototype.get = function(T) { var mb = new mboxList(); for (var j = 0; j < this.E.length; j++) { var Q = this.E[j]; if (Q.getName() == T) { mb.add(Q); } } return mb;};mboxList.prototype.getById = function(nb) { return this.E[nb];};mboxList.prototype.length = function() { return this.E.length;};mboxList.prototype.each = function(p) { if (typeof p != 'function') { throw 'Action must be a function, was: ' + typeof(p); } for (var j = 0; j < this.E.length; j++) { p(this.E[j]); }};mboxLocatorDefault = function(g) { this.g = 'mboxMarker-' + g; document.write('<div id="' + this.g + '" style="visibility:hidden;display:none">&nbsp;</div>');};mboxLocatorDefault.prototype.locate = function() { var ob = document.getElementById(this.g); while (ob != null) { if (ob.nodeType == 1) { if (ob.className == 'mboxDefault') { return ob; } } ob = ob.previousSibling; } return null;};mboxLocatorDefault.prototype.force = function() { var pb = document.createElement('div'); pb.className = 'mboxDefault'; var qb = document.getElementById(this.g); qb.parentNode.insertBefore(pb, qb); return pb;};mboxLocatorNode = function(rb) { this.ob = rb;};mboxLocatorNode.prototype.locate = function() { return typeof this.ob == 'string' ? document.getElementById(this.ob) : this.ob;};mboxLocatorNode.prototype.force = function() { return null;};mboxCreate = function(T ) { var Q = mboxFactoryDefault.create( T, mboxShiftArray(arguments)); if (Q) { Q.load(); } return Q;};mboxDefine = function(Z, T ) { var Q = mboxFactoryDefault.create(T, mboxShiftArray(mboxShiftArray(arguments)), Z); return Q;};mboxUpdate = function(T ) { mboxFactoryDefault.update(T, mboxShiftArray(arguments));};mbox = function(g, sb, w, tb, bb) { this.ub = null; this.vb = 0; this.ab = tb; this.bb = bb; this.wb = null; this.xb = new mboxOfferContent(); this.pb = null; this.w = w; this.message = ''; this.yb = new Object(); this.zb = 0; this.sb = sb; this.g = g; this.Ab(); w.addParameter('mbox', g) .addParameter('mboxId', sb); this.Bb = function() {}; this.Cb = function() {}; this.Db = null;};mbox.prototype.getId = function() { return this.sb;};mbox.prototype.Ab = function() { if (this.g.length > 250) { throw "Mbox Name " + this.g + " exceeds max length of " + "250 characters."; } else if (this.g.match(/^\s+|\s+$/g)) { throw "Mbox Name " + this.g + " has leading/trailing whitespace(s)."; }};mbox.prototype.getName = function() { return this.g;};mbox.prototype.getParameters = function() { var c = this.w.getParameters(); var mb = new Array(); for (var j = 0; j < c.length; j++) { if (c[j].name.indexOf('mbox') != 0) { mb[mb.length] = c[j].name + '=' + c[j].value; } } return mb;};mbox.prototype.setOnLoad = function(p) { this.Cb = p; return this;};mbox.prototype.setMessage = function(cb) { this.message = cb; return this;};mbox.prototype.setOnError = function(Bb) { this.Bb = Bb; return this;};mbox.prototype.setFetcher = function(Eb) { if (this.wb) { this.wb.cancel(); } this.wb = Eb; return this;};mbox.prototype.getFetcher = function() { return this.wb;};mbox.prototype.load = function(c) { if (this.wb == null) { return this; } this.setEventTime("load.start"); this.cancelTimeout(); this.vb = 0; var w = (c && c.length > 0) ? this.w.clone().addParameters(c) : this.w; this.wb.fetch(w); var P = this; this.Fb = setTimeout(function() { P.Bb('browser timeout', P.wb.getType()); }, 15000); this.setEventTime("load.end"); return this;};mbox.prototype.loaded = function() { this.cancelTimeout(); if (!this.activate()) { var P = this; setTimeout(function() { P.loaded(); }, 100); }};mbox.prototype.activate = function() { if (this.vb) { return this.vb; } this.setEventTime('activate' + ++this.zb + '.start'); if (this.show()) { this.cancelTimeout(); this.vb = 1; } this.setEventTime('activate' + this.zb + '.end'); return this.vb;};mbox.prototype.isActivated = function() { return this.vb;};mbox.prototype.setOffer = function(xb) { if (xb && xb.show && xb.setOnLoad) { this.xb = xb; } else { throw 'Invalid offer'; } return this;};mbox.prototype.getOffer = function() { return this.xb;};mbox.prototype.show = function() { this.setEventTime('show.start'); var mb = this.xb.show(this); this.setEventTime(mb == 1 ? "show.end.ok" : "show.end"); return mb;};mbox.prototype.showContent = function(Gb) { if (Gb == null) { return 0; } if (this.pb == null || !this.pb.parentNode) { this.pb = this.getDefaultDiv(); if (this.pb == null) { return 0; } } if (this.pb != Gb) { this.Hb(this.pb); this.pb.parentNode.replaceChild(Gb, this.pb); this.pb = Gb; } this.Ib(Gb); this.Cb(); return 1;};mbox.prototype.hide = function() { this.setEventTime('hide.start'); var mb = this.showContent(this.getDefaultDiv()); this.setEventTime(mb == 1 ? 'hide.end.ok' : 'hide.end.fail'); return mb;};mbox.prototype.finalize = function() { this.setEventTime('finalize.start'); this.cancelTimeout(); if (this.getDefaultDiv() == null) { if (this.ab.force() != null) { this.setMessage('No default content, an empty one has been added'); } else { this.setMessage('Unable to locate mbox'); } } if (!this.activate()) { this.hide(); this.setEventTime('finalize.end.hide'); } this.setEventTime('finalize.end.ok');};mbox.prototype.cancelTimeout = function() { if (this.Fb) { clearTimeout(this.Fb); } if (this.wb != null) { this.wb.cancel(); }};mbox.prototype.getDiv = function() { return this.pb;};mbox.prototype.getDefaultDiv = function() { if (this.Db == null) { this.Db = this.ab.locate(); } return this.Db;};mbox.prototype.setEventTime = function(Jb) { this.yb[Jb] = (new Date()).getTime();};mbox.prototype.getEventTimes = function() { return this.yb;};mbox.prototype.getImportName = function() { return this.bb;};mbox.prototype.getURL = function() { return this.w.buildUrl();};mbox.prototype.getUrlBuilder = function() { return this.w;};mbox.prototype.Kb = function(pb) { return pb.style.display != 'none';};mbox.prototype.Ib = function(pb) { this.Lb(pb, true);};mbox.prototype.Hb = function(pb) { this.Lb(pb, false);};mbox.prototype.Lb = function(pb, Mb) { pb.style.visibility = Mb ? "visible" : "hidden"; pb.style.display = Mb ? "block" : "none";};mboxOfferContent = function() { this.Cb = function() {};};mboxOfferContent.prototype.show = function(Q) { var mb = Q.showContent(document.getElementById(Q.getImportName())); if (mb == 1) { this.Cb(); } return mb;};mboxOfferContent.prototype.setOnLoad = function(Cb) { this.Cb = Cb;};mboxOfferAjax = function(Gb) { this.Gb = Gb; this.Cb = function() {};};mboxOfferAjax.prototype.setOnLoad = function(Cb) { this.Cb = Cb;};mboxOfferAjax.prototype.show = function(Q) { var Nb = document.createElement('div'); Nb.id = Q.getImportName(); Nb.innerHTML = this.Gb; var mb = Q.showContent(Nb); if (mb == 1) { this.Cb(); } return mb;};mboxOfferDefault = function() { this.Cb = function() {};};mboxOfferDefault.prototype.setOnLoad = function(Cb) { this.Cb = Cb;};mboxOfferDefault.prototype.show = function(Q) { var mb = Q.hide(); if (mb == 1) { this.Cb(); } return mb;};mboxCookieManager = function mboxCookieManager(g, Ob) { this.g = g; this.Ob = Ob == '' || Ob.indexOf('.') == -1 ? '' : '; domain=' + Ob; this.Pb = new mboxMap(); this.loadCookies();};mboxCookieManager.prototype.isEnabled = function() { this.setCookie('check', 'true', 60); this.loadCookies(); return this.getCookie('check') == 'true';};mboxCookieManager.prototype.setCookie = function(g, h, U) { if (typeof g != 'undefined' && typeof h != 'undefined' && typeof U != 'undefined') { var Qb = new Object(); Qb.name = g; Qb.value = escape(h); Qb.expireOn = Math.ceil(U + new Date().getTime() / 1000); this.Pb.put(g, Qb); this.saveCookies(); }};mboxCookieManager.prototype.getCookie = function(g) { var Qb = this.Pb.get(g); return Qb ? unescape(Qb.value) : null;};mboxCookieManager.prototype.deleteCookie = function(g) { this.Pb.remove(g); this.saveCookies();};mboxCookieManager.prototype.getCookieNames = function(Rb) { var Sb = new Array(); this.Pb.each(function(g, Qb) { if (g.indexOf(Rb) == 0) { Sb[Sb.length] = g; } }); return Sb;};mboxCookieManager.prototype.saveCookies = function() { var Tb = new Array(); var Ub = 0; this.Pb.each(function(g, Qb) { Tb[Tb.length] = g + '#' + Qb.value + '#' + Qb.expireOn; if (Ub < Qb.expireOn) { Ub = Qb.expireOn; } }); var Vb = new Date(Ub * 1000); document.cookie = this.g + '=' + Tb.join('|') + '; expires=' + Vb.toGMTString() + '; path=/' + this.Ob;};mboxCookieManager.prototype.loadCookies = function() { this.Pb = new mboxMap(); var Wb = document.cookie.indexOf(this.g + '='); if (Wb != -1) { var Xb = document.cookie.indexOf(';', Wb); if (Xb == -1) { Xb = document.cookie.indexOf(',', Wb); if (Xb == -1) { Xb = document.cookie.length; } } var Yb = document.cookie.substring( Wb + this.g.length + 1, Xb).split('|'); var Zb = Math.ceil(new Date().getTime() / 1000); for (var j = 0; j < Yb.length; j++) { var Qb = Yb[j].split('#'); if (Zb <= Qb[2]) { var _b = new Object(); _b.name = Qb[0]; _b.value = Qb[1]; _b.expireOn = Qb[2]; this.Pb.put(_b.name, _b); } } }};mboxSession = function(ac, bc, jb, cc, I) { this.bc = bc; this.jb = jb; this.cc = cc; this.I = I; this.dc = false; this.sb = typeof mboxForceSessionId != 'undefined' ? mboxForceSessionId : mboxGetPageParameter(this.bc); if (this.sb == null || this.sb.length == 0) { this.sb = I.getCookie(jb); if (this.sb == null || this.sb.length == 0) { this.sb = ac; this.dc = true; } } I.setCookie(jb, this.sb, cc);};mboxSession.prototype.getId = function() { return this.sb;};mboxSession.prototype.forceId = function(ec) { this.sb = ec; this.I.setCookie(this.jb, this.sb, this.cc);};mboxPC = function(jb, cc, I) { this.jb = jb; this.cc = cc; this.I = I; this.sb = typeof mboxForcePCId != 'undefined' ? mboxForcePCId : I.getCookie(jb); if (this.sb != null) { I.setCookie(jb, this.sb, cc); }};mboxPC.prototype.getId = function() { return this.sb;};mboxPC.prototype.forceId = function(ec) { if (this.sb != ec) { this.sb = ec; this.I.setCookie(this.jb, this.sb, this.cc); return true; } return false;};mboxGetPageParameter = function(g) { var mb = null; var fc = new RegExp(g + "=([^\&]*)"); var gc = fc.exec(document.location); if (gc != null && gc.length >= 2) { mb = gc[1]; } return mb;};mboxSetCookie = function(g, h, U) { return mboxFactoryDefault.getCookieManager().setCookie(g, h, U);};mboxGetCookie = function(g) { return mboxFactoryDefault.getCookieManager().getCookie(g);};mboxCookiePageDomain = function() { var Ob = (/([^:]*)(:[0-9]{0,5})?/).exec(document.location.host)[1]; var hc = /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/; if (!hc.exec(Ob)) { var ic = (/([^\.]+\.[^\.]{3}|[^\.]+\.[^\.]+\.[^\.]{2})$/).exec(Ob); if (ic) { Ob = ic[0]; } } return Ob ? Ob: "";};mboxShiftArray = function(jc) { var mb = new Array(); for (var j = 1; j < jc.length; j++) { mb[mb.length] = jc[j]; } return mb;};mboxGenerateId = function() { return (new Date()).getTime() + "-" + Math.floor(Math.random() * 999999);};if (typeof mboxVersion == 'undefined') { var mboxVersion = 38; var mboxFactories = new mboxMap(); var mboxFactoryDefault = new mboxFactory('function.tt.omtrdc.net', 'function', 'default');};if (mboxGetPageParameter("mboxDebug") != null || mboxFactoryDefault.getCookieManager() .getCookie("debug") != null) { setTimeout(function() { if (typeof mboxDebugLoaded == 'undefined') { alert('Could not load the remote debug.\nPlease check your connection' + ' to Test&amp;Target servers'); } }, 60*60); document.write('<' + 'scr' + 'ipt language="Javascript1.2" src=' + '"http://admin12.testandtarget.omniture.com/admin/mbox/mbox_debug.jsp?mboxServerHost=function.tt.omtrdc.net' + '&clientCode=function"><' + '\/scr' + 'ipt>');};mboxScPluginFetcher = function(b, kc) { this.b = b; this.kc = kc;};mboxScPluginFetcher.prototype.lc = function(w) { w.setBasePath('/m2/' + this.b + '/sc/standard'); this.mc(w); var e = w.buildUrl(); e += '&scPluginVersion=1'; return e;};mboxScPluginFetcher.prototype.mc = function(w) { var nc = [ "dynamicVariablePrefix","visitorID","vmk","ppu","charSet", "visitorNamespace","cookieDomainPeriods","cookieLifetime","pageName", "currencyCode","variableProvider","channel","server", "pageType","transactionID","purchaseID","campaign","state","zip","events", "products","linkName","linkType","resolution","colorDepth", "javascriptVersion","javaEnabled","cookiesEnabled","browserWidth", "browserHeight","connectionType","homepage","pe","pev1","pev2","pev3", "visitorSampling","visitorSamplingGroup","dynamicAccountSelection", "dynamicAccountList","dynamicAccountMatch","trackDownloadLinks", "trackExternalLinks","trackInlineStats","linkLeaveQueryString", "linkDownloadFileTypes","linkExternalFilters","linkInternalFilters", "linkTrackVars","linkTrackEvents","linkNames","lnk","eo" ]; for (var j = 0; j < nc.length; j++) { this.oc(nc[j], w); } for (var j = 1; j <= 50; j++) { this.oc('prop' + j, w); this.oc('eVar' + j, w); this.oc('hier' + j, w); }};mboxScPluginFetcher.prototype.oc = function(g, w) { var h = this.kc[g]; if (typeof(h) === 'undefined' || h === null || h === '') { return; } w.addParameter(g, h);};mboxScPluginFetcher.prototype.cancel = function() { };mboxStandardScPluginFetcher = function(b, kc) { mboxScPluginFetcher.call(this, b, kc);};mboxStandardScPluginFetcher.prototype = new mboxScPluginFetcher;mboxStandardScPluginFetcher.prototype.getType = function() { return 'standard';};mboxStandardScPluginFetcher.prototype.fetch = function(w) { w.setServerType(this.getType()); var e = this.lc(w); document.write('<' + 'scr' + 'ipt src="' + e + '" language="JavaScript"><' + '\/scr' + 'ipt>');};mboxAjaxScPluginFetcher = function(b, kc) { mboxScPluginFetcher.call(this, b, kc);};mboxAjaxScPluginFetcher.prototype = new mboxScPluginFetcher;mboxAjaxScPluginFetcher.prototype.fetch = function(w) { w.setServerType(this.getType()); var e = this.lc(w); this.x = document.createElement('script'); this.x.src = e; document.body.appendChild(this.x);};mboxAjaxScPluginFetcher.prototype.getType = function() { return 'ajax';};function mboxLoadSCPlugin(kc) { if (!kc) { return null; } kc.m_tt = function(kc) { var pc = kc.m_i('tt'); pc.G = true; pc.b = 'function'; pc['_t'] = function() { if (!this.isEnabled()) { return; } var Q = this.rc(); if (Q) { var Eb = mboxFactoryDefault.isDomLoaded() ? new mboxAjaxScPluginFetcher(this.b, this.s) : new mboxStandardScPluginFetcher(this.b, this.s); Q.setFetcher(Eb); Q.load(); } }; pc.isEnabled = function() { return this.G && mboxFactoryDefault.isEnabled(); }; pc.rc = function() { var T = this.sc(); var pb = document.createElement('DIV'); return mboxFactoryDefault.create(T, new Array(), pb); }; pc.sc = function() { var tc = this.s.events && this.s.events.indexOf('purchase') != -1; return 'SiteCatalyst: ' + (tc ? 'purchase' : 'event'); }; }; return kc.loadModule('tt');};mboxFactoryDefault.addOnLoad(mboxAppendSession);

var mboxSessionKeyword = "OFM";
function mboxAppendAnchorTags() {
 var anchorTags = document.getElementsByTagName('a');
 for(i = 0; i < anchorTags.length; i++) {
 if (anchorTags[i].href.indexOf(mboxSessionKeyword) != -1) {
 anchorTags[i].href = anchorTags[i].href.replace(
 mboxSessionKeyword,"mboxSession="+mboxFactoryDefault.getSessionId().getId());
 }
 }
}
function mboxAppendForm() {
 var formTags = document.getElementsByTagName('form');
 for(i = 0; i < formTags.length; i++) {
 if (formTags[i].action.indexOf(mboxSessionKeyword) != -1) {
 formTags[i].action = formTags[i].action.replace(
 mboxSessionKeyword,"mboxSession="+mboxFactoryDefault.getSessionId().getId());
 }
 }
}
function mboxAppendSession() {
 mboxAppendAnchorTags();
 mboxAppendForm();
}

LaptopLogic.modules.MediaAdmin = {
	init: function() {
		//this.autoCreateSelect();
		this.autoCreateImageInput();
		this.deleteUnusedInputsOnSubmit();
		this.findImages();
		//this.findPollImages();
		this.findOldUrl();
		this.makeNewImagesDeletable();
		this.selectUploadFormat();
		$('#media-admin dl').togglableDLs();
	}, 
	
	autoCreateSelect: function() {
		$('#media-admin p[class]').hide();
		$('<p class="choose-type"><label>Do you want to upload images for:<br /><select name="type"><option value="">Choose type</option><option value="articles">Article</option><option value="news">News</option><option value="reviews">Review</option><option value="poll">Poll</option></select></label></p>')
		.appendTo('#media-admin form').find('select').change(function() {
			$('#media-admin p[class]').hide();
			$('#media-admin p.' +$(this).val()).show();
			
			if( $(this).val() == 'news' )
			{
				 $('#media-admin').ajaxLoader();
					$.post('/ajax/get-media-admin-urls/get-media-admin-urls.php?type=4', function(data) {
						$('.edit_urls').html(data);
						$('#media-admin').ajaxLoaderRemove( true );
						LaptopLogic.modules.MediaAdmin.findImages();
				 });
			}
			else
			{	
			     LaptopLogic.modules.MediaAdmin.findImages();
			}
			LaptopLogic.modules.MediaAdmin.findPollImages();
			$('#media-admin p.choose-file').show();
			$('#media-admin p.submit').show();
		});
	}, 

	deleteUnusedInputsOnSubmit: function() {
		$('#media-admin form').submit(function() {
			$('p:hidden', this).remove();
		});
	}, 

	autoCreateImageInput: function() {
		var cloningFunc = function() {
			var p = $(this).parents('p').eq(0);

			p.clone().insertAfter(p).find('input').val('').change(cloningFunc);
		};

		$('#media-admin input[type="file"]').change(cloningFunc);
	},
	
	findImages: function() {
	
		var imagesDiv = $('<div id="media-admin-images"></div>').appendTo('#media-admin');

		$('#media-admin select[name="page"]').change(function() {
			$.post('/ajax/get-images/get-images.php?id=' + $(this).val() + '&choose-upload=' + $('#media-admin input[name=choose-upload]:checked').val(), function(data) {
				imagesDiv.html(data);
				LaptopLogic.modules.MediaAdmin.makeImagesDeletable();
			});
		});
	}, 
	
	findPollImages: function() {
        var imagesDiv = $('#media-admin-images');

        $('select[name="poll"]').change(function() {
            $.post('/ajax/get-images/get-images.php?poll=' + $(this).val() + '&choose-upload=' + $('#media-admin input[name=choose-upload]:checked').val(), function(data) {
                imagesDiv.html(data);
                //LaptopLogic.modules.MediaAdmin.makeImagesDeletable();
            });
        });
    },
	
	makeImagesDeletable: function() {
		$('#media-admin-images a[name=delete]').click(function() {
			$.post('/ajax/delete-image/delete-image.php' + $(this).attr('href') + '&choose-upload=' + $('#media-admin input[name=choose-upload]:checked').val() ); // ?remove_image=foo.jpg
			$(this).parents('li').eq(0).remove();
			return false;
		});
	},
	
	makeNewImagesDeletable: function() {
		$('#media-admin-new-images a').click(function() {
			$.post('/ajax/delete-image/delete-image.php' +$(this).attr('href')); // ?remove_image=foo.jpg
			$(this).parents('li').eq(0).remove();
			return false;
		});
	},
	
	findOldUrl: function() {
		var urlDiv = $('#media-admin-older-urls');
		$('input[name="olderUrl"]').keyup(function() {
			$.post('/ajax/media-admin-get-url/get-url.php?url='+$(this).val(), function(data) {
				urlDiv.html(data);
			});
			return false;
		});
	},
	
	selectUploadFormat: function() {
		$('#media-admin p[class]').hide();
		$('#media-admin-upload-select label input').click(function() {
			if( $(this).val() == 'movie' )
			{
			    $('#media-admin p[class]').hide();
				$('#media-admin p.reviews').show();
				$('#media-admin p.older-urls').show();
				$('#media-admin p.video-file-name').show();
				$('#media-admin p.choose-file').show();
				$('#media-admin p.submit').show();
				$('#media-admin p.choose-type').hide();
			}
			if( $(this).val() == 'image' )
			{
				LaptopLogic.modules.MediaAdmin.autoCreateSelect();
			}
		});
	}
};

LaptopLogic.modules.MostPopularLaptops = {
	init: function()
	{
		var fx = (!$.browser.msie) ? {opacity: 'toggle'} : false;
		
		$('#most-popular-laptops > ul').tabs({fx: fx});
		$('#most-popular-laptops-alt > ul').tabs({fx: fx});

		this.addViewPricesButtons();
	}, 

	addViewPricesButtons: function() {
		$('div[id^="mpl-"] p').each(function() {
			var id = $(this).parents('[class^="masterid-"]').eq(0);

			if(id.length && id.attr('class').substring(9) != '' && id.attr('class').substring(9) != 0) {
				
				$('<p><a href="#" class="best-prices"><span>View best prices</span></a></p>').insertAfter(this).find('a.best-prices').priceGrabberPrices();
			}
		});
		
		//$('a.best-prices:first').trigger('click');
	}
};

LaptopLogic.modules.News = {
	init: function() {
		this.arrangeImagesInLatestNewsSpecial();
	}, 

	arrangeImagesInLatestNewsSpecial: function() {
		$('#latest-news-special img').each(function(i) {
			var left = i * 110 + 10;
			$(this).css({left: left +'px'});
		});
	}
};

LaptopLogic.modules.Newsletter = {
	init: function() {
		this.hijaxForm();
	}, 

	hijaxForm: function() {
		$('#newsletter-signup form').liveValidation(//{
			//invalidIco: '/css/gfx/icons/form-control-invalid.png', 
			//validIco: 	'/css/gfx/icons/form-control-valid.png'},
			{
			  from:  /^.+?@.+?\..{2,4}$/       // email
			});
	}
};

LaptopLogic.modules.PollAdmin = {
	init: function() {
		$('#poll-admin form').liveValidation({
			invalidIco:	'/css/gfx/icons/form-control-invalid.png', 
			validIco:	'/css/gfx/icons/form-control-valid.png'
		}, {
			quiz:		/^\S.*$/
		});

	}
};

LaptopLogic.modules.Poll =
{
	init: function()
	{
		this.submit_form();
		this.show_results();
	},
	
	submit_form:function()
	{
		var $poll = $('#wh-poll');
		
		$poll.find('form').submit(function()
		{
			
			var vote_id = $('input[name="vote_id"]:checked').val();
			if( vote_id == undefined )
			{
				alert( 'Please choose a option.' );
				return false;
			}
				
			var quiz_id = $('input[name="quiz_id"]').val();
			
			$.post('/ajax/results-poll/get-results-poll.php',
			{
				'vote_id':vote_id,
				'quiz_id':quiz_id
			},
			function(data)
			{
				$poll.fadeOut('normal',function()
				{
					$poll.replaceWith(data);
				});
			});
			
			return false;
		});
	},
	
	show_results:function()
	{
		var $poll = $('#wh-poll');
		
		$poll.find('p.submit-area').append('<a href="#" class="results">View results</a>');
		
		var quiz_id = $('input[name="quiz_id"]').val();
		
		$('a.results').click(function()
		{
			$.post('/ajax/results-poll/get-results-poll.php', 
			{
				'quiz_id':quiz_id
			},
			function(data)
			{
				$poll.fadeOut('normal',function()
				{
					$poll.replaceWith(data);
				});
			});
			
			return false;
		});
	}
};

function showPopNoScroll(u,w,h){ mywin = window.open(u,"pop",'toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=0,resizable=0,width='+w+',height='+h+''); }

LaptopLogic.modules.PostComment = {
	init: function() {
		$('#post-comment form').ajaxForm({
			url: '/ajax/post-comment/post-comment.php', 
			success: function() {
				$.post('/ajax/comment-listing/get-comments.php', {pageId: $('#post-comment input[name="pageId"]').val()}, function(data) {
					$('#comment-listing').html($(data).html());
					$('#post-comment').remove();
				});
			}
		});
	}
};

LaptopLogic.modules.PriceGrabber = {
	init: function()
	{
		
		if ($('#price-grabber-push').size())
		{
			var fx = (!$.browser.msie) ? {opacity: 'toggle'} : false;

			$('#price-grabber-push ul').tabs({fx: fx});

			$('#pgp-electronics').load('/ajax/get-laptops/get-laptops.php?topcat_id=2', function() {
				$('#pgp-software').load('/ajax/get-laptops/get-laptops.php?topcat_id=6', function() {
					$('#pgp-photography').load('/ajax/get-laptops/get-laptops.php?topcat_id=11', function() {
						LaptopLogic.modules.PriceGrabber.addViewPricesButtons();
						LaptopLogic.modules.PriceGrabber.addToggleInfoButtons();
					});
				});
			});	
		}
		
		this.addViewPricesButtonToSearchResults();
	}, 

	addViewPricesButtonToSearchResults: function() {
		$('#price-grabber-search-results li dl').each(function() {
			var id = $(this).parents('[class^="masterid-"]').eq(0);

			if(id.length && id.attr('class').substring(9) != '' && id.attr('class').substring(9) != 0) {
				$('<p><a href="#" class="best-prices"><span>View best prices</span></a></p>').insertAfter(this).find('a.best-prices').priceGrabberPrices();
			}
		});
	}, 

	addToggleInfoButtons: function() {
		
		var priceGrabberDivs = $('div[id^="pgp-"]');
		
		$('dl', priceGrabberDivs).slideUp();

		var showInfo = 'More Info';
		var showClass = 'show';
		var hideInfo = 'Hide Info';
		var hideClass = 'hide';

		$('li', priceGrabberDivs).each(function() {
			var item = $(this);
			var info = item.find('dl');

			if(info.length) {
				var link = $('<a href="#" class="' +showClass +'">' +showInfo +'</a>').appendTo(item);

				link.toggle(function() {
					link.addClass(hideClass).removeClass(showClass).text(hideInfo);
					info.slideDown(100);
				}, 
				function() {
					link.addClass(showClass).removeClass(hideClass).text(showInfo);
					info.slideUp(100);
				});
			}
		});
	}, 

	addViewPricesButtons: function() {
		$('div[id^="pgp-"] li p').each(function() {
			var id = $(this).parents('[class^="masterid-"]').eq(0);
            
			if(id.length && id.attr('class').substring(9) != '' && id.attr('class').substring(9) != 0) {
				$('<p><a href="#" class="best-prices"><span>View best prices</span></a></p>').insertAfter(this).find('a.best-prices').priceGrabberPrices();
			}
		});
		
		// For toprated tab on review page
		$('div#toprated-laptops li').each(function()
		{
			$this = $(this); 
			
			if($this.length && $this.attr('class').substring(9) != '' && $this.attr('class').substring(9) != 0) {
				$this.append('<p><a href="#" class="best-prices"><span>View best prices</span></a></p>').find('a.best-prices').priceGrabberPrices();
			}
		});		
	}
};

jQuery.fn.priceGrabberPrices = function() {
	return this.each(function() {
		var clicked = $(this);
		var oldText	= clicked.text();
		var id		= clicked.parents('[class^="masterid-"]').eq(0).attr('class').substring(9);

		if(id == '') {
			return;
		}

		clicked.click(function() {
			var table = clicked.parents('li').find('div.price-grabber-prices');

			if(table.length) {
				if(table.is(':visible')) {
					clicked.removeClass('visible').addClass('hidden');
					clicked.html('<span>' + oldText + '</span>');
					table.slideUp(100);
				}
				else {
					clicked.removeClass('hidden').addClass('visible');
					clicked.html('<span>Hide prices</span>');
					table.slideDown(100);
				}
			}
			else {
				clicked.html('<span>Loading...</span>');

				jQuery.get('/ajax/get-prices/get-prices.php?masterid=' +id, function(data) {
					clicked.parents('li').append(data).slideDown(100);
					clicked.removeClass('hidden').addClass('visible');
					clicked.html('<span>Hide prices</span>');
				});
			}

			return false;
		});
	});
};

LaptopLogic.modules.QuickLogin =
{
	init: function()
	{		
		var $text_inputs = $('#quick-login form').find('input[name="username"],input[name="password"]');
		
		$text_inputs.LabelInsideInput();
	}
};

LaptopLogic.modules.Quiz =
{
	init:function()
	{
		var $quiz = $('#quiz');
		
		if (! $quiz.size())
		{
			return false;
		}
		
		$quiz.find('div.question:first').fadeIn();
		
		$quiz.find('ul.progress li:first').addClass('current');
		
		$quiz.find('ul.nav li:first').hide();
		
		this.init_nav_clicks();
		
		//this.go_to_last();
	},
	
	init_nav_clicks:function()
	{
		var $quiz = $('#quiz');
		
		$quiz.find('li.prev a').click(function()
		{
			LaptopLogic.modules.Quiz.change_pos('prev');
			return false;
		});
		
		$quiz.find('li.next a').click(function()
		{
			LaptopLogic.modules.Quiz.change_pos('next');
			return false;
		});
		
	},
	
	go_to_last:function()
	{
		var $next = $('#quiz li.next a');
		
		for(var i=0;i<9;i++)
		{
			setTimeout(function()
			{
				var rand_num = Math.floor ( Math.random ( ) * 4 + 1 );
				
				$('div.question:visible input:eq(' + rand_num + ')').trigger('click');
				$next.trigger('click');
			},
			50);
		}
	},
	
	change_pos:function(direction)
	{		
		var $quiz = $('#quiz');
		
		var $current_question = $('div.question:visible');
		
		if (direction == 'next' &&  ! $current_question.find('input:checked').size())
		{
			$current_question.fadeOut('fast',function()
			{
				$(this).fadeIn('fast',function()
				{
					$(this).fadeOut('fast',function()
					{
						$(this).fadeIn('fast');
					});
				});
			});
			
			return false;
		}
		
		var $nav_bar = $('ul.nav');
				
		var $progress_bar = $('ul.progress');
		
		var $current_pos = $progress_bar.find('li.current');
		
		var current_pos = $current_pos.text();
		
		var num_questions = $('div.question').size();
		
		$progress_bar.find('li.done').removeClass('done');
		
		$current_pos.removeClass('current');
		
		var new_pos;
		
		if (direction == 'prev')
		{
			var prev_pos = current_pos-2;
			
			new_pos = prev_pos;
			
			$progress_bar.find('li:eq(' + prev_pos + ')').addClass('current');
		}
		
		if (direction == 'next')
		{
			var next_pos = current_pos;
			
			new_pos = next_pos;
			
			if (current_pos == num_questions)
			{
				var quiz_height = $quiz.height();
				//alert(quiz_height)
				
				$quiz.css('min-height',quiz_height);
				
				$quiz.find('div.inner').fadeOut(function()
				{
					$quiz.append('<div class="score-loading"></div>');
					
					LaptopLogic.modules.Quiz.calculate_score();
				
				});
				
				return false;
			}
			else
			{
				$progress_bar.find('li:eq(' + next_pos + ')').addClass('current');
			}			
		}
		
		$('div.question:visible').hide();	
		
		$question_to_show = $('div.question:eq(' + new_pos + ')');
		
		if (direction == 'next')
		{
			$question_to_show.fadeIn('normal');
		}
		else
		{
			$question_to_show.show();
		}
		
		$progress_bar.find('li:lt(' + new_pos + ')').addClass('done');
		
		$nav_prev = $nav_bar.find('li.prev');
		$nav_next = $nav_bar.find('li.next');
		
		$nav_prev.find('a').text('Prev (' + (parseInt(new_pos)) + '/' + num_questions + ')');
		
		if (new_pos == num_questions-1)
		{
			$nav_next.find('a').fadeOut(function()
			{
				$nav_next.addClass('show-results');
				$(this).text('Show score!').fadeIn();
			});
		}
		else
		{
			$nav_next.find('a').text('Next (' + (parseInt(new_pos)+2) + '/' + num_questions + ')');
			$nav_next.removeClass('show-results');
		}
		
		if (new_pos == 0)
		{
			$nav_prev.fadeOut();
		}
		else
		{
			$nav_prev.fadeIn();
		}
	},
	
	calculate_score:function()
	{
		var total_score = 0;
		
		$('#quiz input[name^="q"]:checked').each(function()
		{
			total_score+= parseInt($(this).val());
		});
		
		var total_score_ceiled = Math.ceil(total_score / 10);
		
		setTimeout(function()
		{
			$("#quiz").load("/quiz-result-" + total_score_ceiled + " #quiz > div",function()
			{
				$(this).find('span.points').text(total_score);
				$('div.score-loading').fadeOut();
			});
		},
		1000);
	}
};




LaptopLogic.modules.ReviewAdminContentSite = {
	init: function() {
		this.hijaxForm();
	},
	
    hijaxForm: function() {
        $('#review-admin-content-site form').liveValidation({
            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
            validIco:   '/css/gfx/icons/form-control-valid.png'
        }, 
            {
				rating_design: /^[1-5]{1}$/,
				rating_feature: /^[1-5]{1}$/,
				rating_mobility: /^[1-5]{1}$/,
				rating_system: /^[1-5]{1}$/,
				rating_threed_performance:/^[1-5]{1}$/,
				rating_performance: /^[1-5]{1}$/,
				rating_battery_life: /^[1-5]{1}$/,
				recommended_gamers: /^[1-5]{1}$/,
				recommended_travelers: /^[1-5]{1}$/,
				recommended_entertainment: /^[1-5]{1}$/,
				recommended_business: /^[1-5]{1}$/,
				recommended_students: /^[1-5]{1}$/
        });
    }
};	

LaptopLogic.modules.ReviewAdminContentText = {
	init: function() {
		this.hijaxForm();
		$('#review-admin-content-text dl').togglableDLs();
	},
	
    hijaxForm: function() {
        $('#review-admin-content-text form').liveValidation({
            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
            validIco:   '/css/gfx/icons/form-control-valid.png'
        }, 
            { summary_full: /^.*$/m,
              summary_in_listings: /^.*$/m
              //hits: /^\w+.*/,
              //misses: /^\w+.*/
        });
    }
};

LaptopLogic.modules.ReviewAdminContent = {
	init: function() {
		this.hijaxForm();
	},
	
    hijaxForm: function() {
        $('#review-admin-content form').liveValidation({
            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
            validIco:   '/css/gfx/icons/form-control-valid.png'
        }, 
            { content_name: /^.+$/
        });
    }
};

LaptopLogic.modules.ReviewAdminMedia = {

    init:function(){
        this.selectMedia();
        this.deleteUnusedInputsOnSubmit();
        this.autoCreateImageInput();
        $('#review-admin-media dl').togglableDLs();
    },

    selectMedia:function()
    {
      $( 'label[class="hidden-new-name"]' ).hide();
      $( 'label[class="hidden-file-upload"]' ).hide();
      $( 'label[class="hidden-main-checkbox"]').hide();
      $( '#media-submit').hide();
      $('input[name="choose-upload"]').click(function()
      {

            if( $(this).val() == 'movie' )
            {
                $( 'label[class="hidden-new-name"]' ).show();
                $( 'label[class="hidden-file-upload"]' ).show();
                $( 'label[class="hidden-main-checkbox"]').show();
                $( '#media-submit').show();
            }
            else if( $(this).val() == 'image' )
            {
                $( 'label[class="hidden-new-name"]' ).hide();
                $( 'label[class="hidden-file-upload"]' ).show();
                $( 'label[class="hidden-main-checkbox"]').show();
                $( '#media-submit').show();
            }

       });

    },

    deleteUnusedInputsOnSubmit: function()
    {

        $('#review-admin-media form').submit(function() {
			$('p:hidden', this).remove();
		});

	},

	autoCreateImageInput: function()
    {
		var cloningFunc = function()
        {
			var p = $(this).parents('p').eq(0);

			p.clone().insertAfter(p).find('input').val('').change(cloningFunc);
		};

		$('#review-admin-media input[type="file"]').change(cloningFunc);
	}

}



LaptopLogic.modules.ReviewAdminPage = {
	init: function() {
		this.hijaxForm();
	},
	
    hijaxForm: function() {
        $('#review-admin-page form').liveValidation({
            invalidIco: '/css/gfx/icons/form-control-invalid.png', 
            validIco:   '/css/gfx/icons/form-control-valid.png'
        }, 
            { meta_keywords: /^.+$/,
              meta_description: /^.+$/
        });
    }
};

LaptopLogic.modules.ReviewAdminReviewList = {
	init: function() {
		this.hijaxForm();
	},
	
    hijaxForm: function() {
        $('input.all-reviews').click(function()
        {
            $('form#all-reviews').submit();
        });
        $('input.non-pricegrabber').click(function()
        {
            $('form#all-reviews').submit();
        });
    }
};

LaptopLogic.modules.Review = {
	init: function()
	{	
		var fx = (!$.browser.msie) ? {opacity: 'toggle'} : false;
		
		$('#review-tabs > ul').tabs({fx: fx, fxAutoHeight: true});
		
		if ($('span.no-review').size())
		{
			$('#review-tabs ul.tabs li:eq(1) a').trigger('click');
		}
		
		
		
		this.doLatestVideoReviewsThingy();
		//this.doReviewImagesHoverThing();
		this.getTopratedLaptops();
		this.postReview();
		this.sortReview();
		this.priceGrabberPricesButtonInReviewListing();
		this.getHowWeTest();
	}, 

    getTopratedLaptops: function()
	{
        if ( ! $('#review-intro').size())
		{
			return false;
		}

		var brandId = $('#review-intro').attr('class');
        $.post('/ajax/toplist/get-toplist.php', {
            brand_id : brandId
        },
        function(data)
		{
       		$('#toprated-laptops').append(data);
			
			//$('#toprated-laptops').html( $( data ).html() );
            //$('#review-post-review').remove();
        });
    },
    
    getHowWeTest: function() {
        var $how_we_test = $('#how-we-test');
        
        if (!$how_we_test.size())
        {
            return false;
        }
        
        $.post('/ajax/get-how-we-test/get-how-we-test.php', {},
        function(data) {
            $how_we_test.append(data);
        });
    },

	priceGrabberPricesButtonInReviewListing: function() {
		$('#review-listing li').each(function() {
			if($(this).attr('class').substring(9) != '' && $(this).attr('class').substring(9) != 0) {
				$('<p><a href="#" class="best-prices"><span>View best prices</span></a></p>').appendTo(this).find('a.best-prices').priceGrabberPrices();
			}
		});
	}, 

	doReviewImagesHoverThing: function() {
		$('#review-images img').mouseover(function() {
			$('#review-intro img').attr('src', $(this).attr('src').replace(/\/icon\//, '/small_thumb/'));
		});
	}, 

	doLatestVideoReviewsThingy: function() {
		// Add show-class to first li
		$('#latest-video-reviews li:first-child').addClass('show');

		$('#latest-video-reviews img').each(function(i) {
			// Position all the images properlings
			var left = i * 50 + 5;
			$(this).css({left: left +'px'});

			// Change show-class when hovering images
			$(this).mouseover(function() {
				$('#latest-video-reviews li.show').removeClass('show');
				$(this).parents('li').eq(0).addClass('show');;
			});
		});
	},
	
	postReview: function() {
		var hiddenRating = $('<input type="hidden" name="rating" value="" />').appendTo('#review-post-review form > p:last-child');

		$('#review-post-review select[name="rating"]').starRating(function(rating) {
			hiddenRating[0].value = rating;
		});
	
		$('#review-post-review form').ajaxForm({
			url: '/ajax/review/post-review.php', 
			success: function() {
				$.post('/ajax/review/get-user-reviews.php', {
					content_id: $('#review-post-review input[name="content_id"]').val(), 
					page_id: $('#review-post-review input[name="page_id"]').val(),
					sort : 'date-desc'
				}, 
				function(data) {
					$('#review-ugc').html($(data).html());
					$('#review-post-review').remove();
					LaptopLogic.modules.Review.sortReview();
				});
			}
		});
	},
	
	sortReview: function() {
        $('#review-ugc label input[type="radio"]').click(function() {
            $('#review-ugc').fadeOut( 300 );
            var sortBy = $(this).val();
	        $('#review-ugc form label input').ajaxSubmit({
	            url: '/ajax/review/sort-ugc-review.php', 
	            success: function() { 
	                $.post('/ajax/review/sort-ugc-review.php', {
	                    page_id: $('#review-ugc input[name="page_id"]').val(),
	                    sort: sortBy 
	                }, 
	                function(data) {
	                
	                   $('#review-ugc').html($(data).html());
	                   $('#review-ugc').fadeIn( 500 )
                       LaptopLogic.modules.Review.sortReview();
	                     
	                });
	            }
	        });
       }); 
    }
		
};

var sc =
{
	doClicks: function()
	{
		$(document.body).click(function(e)
		{
			var testName = false;
			
			var clickedElement	= $(e.target);
			var clickedLink		= clickedElement.is('a') ? clickedElement : clickedElement.parents('a');
				clickedLink		= clickedLink.is('a') ? clickedLink : false;
			var href			= clickedLink ? clickedLink.attr('href') : false;

			if(href && href.indexOf('laptoplogic.pricegrabber.com') != -1) {
			 
				var product	= 'Pricegrabber click';
				var type	= window.location.pathname;
				var score	= 0.5;

				var s = s_gi(s_account);

				s.pageName = '/exitclick/pricegrabber';

				setTimeout('s.trackDownloadLinks=' +s.trackDownloadLinks, 600);
				s.trackDownloadLinks = false;

				s.linkTrackVars = 'eVar1,eVar2,events,products';
				setTimeout('s.trackExternalLinks=' +s.trackExternalLinks, 600);
				s.trackExternalLinks = false;

				s.linkTrackVars = 'eVar1,eVar2,events,products';
				s.linkTrackEvents = 'purchase,event1';
				s.eVar1 = 1;
				s.eVar2 = type;
				s.events = 'purchase,event1';
				s.products = type +';' +product +';1;' +score;

				void(s.t());
				window.open( href );
				
				if (clickedLink.parents('#most-popular-laptops-org, #most-popular-laptops-alt').size())
				{
					testName = 'mostpop-toplist-click';
				}
								
				/* Track mbox click */
				if ( mboxFactoryDefault.getCookieManager().getCookie('PC') != null )
				{	
					currentValue = s.prop1;
					if( testName )
					{
						s.prop1 = "Conversion: ll-" + testName;
					}
					
					sc.trackScEvent( s );
					s.prop1 = currentValue;
				}


                return false;
			}
		});
	},
	
	trackScEvent:function( sc_obj )
	{ 
		var s = sc_obj;
		var tc = s.events && s.events.indexOf('purchase') != -1;
		var T = 'SiteCatalyst: ' + (tc ? 'purchase' : 'event');
		var pb = document.createElement('DIV');
		Q = mboxFactoryDefault.create(T, new Array(), pb );
		Q.setFetcher( new mboxAjaxScPluginFetcher('function', s ) ); 
		Q.load();
	}
};

//sc.doClicks();

/* SiteCatalyst code version: H.17.
Copyright 1997-2008 Omniture, Inc. More info available at
http://www.omniture.com */

var s_account="wlaptoplogic"
var s=s_gi(s_account)
/************************** CONFIG SECTION **************************/
/* You may add or alter any code config here. */
s.charSet="UTF-8"
/* Conversion Config */
s.currencyCode="USD"
/* Link Tracking Config */
s.trackDownloadLinks=true
s.trackExternalLinks=true
s.trackInlineStats=true
s.linkDownloadFileTypes="exe,zip,wav,mp3,mov,mpg,avi,wmv,doc,pdf,xls"
s.linkInternalFilters="javascript:,laptoplogic.com"
s.linkLeaveQueryString=false
s.linkTrackVars="None"
s.linkTrackEvents="None"

/* WARNING: Changing any of the below variables will cause drastic
changes to how your visitor data is collected.  Changes should only be
made when instructed to do so by your account manager.*/
s.visitorNamespace="wlaptoplogic"
s.trackingServer="omni.laptoplogic.com"
s.dc=122

/************* DO NOT ALTER ANYTHING BELOW THIS LINE ! **************/
var s_code='',s_objectID;function s_gi(un,pg,ss){var c="=fun@6(~){`Ks=^S~$h ~.substring(~.indexOf(~;@t~';`Bt`t~=new Fun@6(~.toLowerCase()~s_c_il['+s^sn+']~};s.~`m@t~.length~.toUpperCase~=new Object~s"
+".wd~','~){@t~')q='~.location~var ~s.pt(~dynamicAccount~link~s.apv~='+@y(~)@tx^m!Object$eObject.prototype$eObject.prototype[x])~);s.~Element~.getTime()~=new Array~ookieDomainPeriods~s.m_~referrer~.p"
+"rotocol~=new Date~BufferedRequests~}c$s(e){~visitor~;@X^js[k],255)}~=''~javaEnabled~conne@6^M~@0c_i~Name~:'')~onclick~}@t~else ~ternalFilters~javascript~s.dl~@Os.b.addBehavior(\"# default# ~=parseF"
+"loat(~'+tm.get~=='~cookie~s.rep(~s.^T~track~o@0oid~browser~.parent~window~colorDepth~String~while(~.host~.lastIndexOf('~s.sq~s.maxDelay~s.vl_g~r=s.m(f)?s[f](~for(~s.un~s.eo~&&s.~parseInt(~t=s.ot(o)"
+"~j='1.~#4URL~lugins~dynamicVariablePrefix~document~Type~Sampling~s.rc[un]~Download~Event~');~this~tfs~resolution~s.c_r(~s.c_w(~s.eh~s.isie~s.vl_l~s.vl_t~Height~t,h){t=t?t~tcf~isopera~ismac~escape(~"
+".href~screen.~s.fl(~Version~harCode~&&(~_'+~variableProvider~s.pe~)?'Y':'N'~:'';h=h?h~._i~e&&l$HSESSION'~f',~onload~name~home#4~objectID~}else{~.s_~s.rl[u~Width~s.ssl~o.type~Timeout(~ction~Lifetime"
+"~.mrq(\"'+un+'\")~sEnabled~;i++)~'){q='~&&l$HNONE'){~ExternalLinks~charSet~onerror~lnk~currencyCode~.src~s=s_gi(~etYear(~&&!~Opera~'s_~;try{~Math.~s.fsg~s.ns6~s.oun~InlineStats~Track~'0123456789~&&"
+"t~s[k]=~s.epa(~m._d~n=s.oid(o)~,'sqs',q);~LeaveQuery~')>=~'=')~)+'/~){n=~\",''),~vo)~s.sampled~=s.oh(o);~+(y<1900?~s.disable~ingServer~n]=~true~sess~campaign~lif~if(~'http~,100)~s.co(~x in ~s.ape~f"
+"fset~s.c_d~s.br~'&pe~s.gg(~s.gv(~s[mn]~s.qav~,'vo~s.pl~=(apn~Listener~\"s_gs(\")~vo._t~b.attach~d.create~=s.n.app~(''+~!='~'||t~'+n~s()+'~){p=~():''~a):f(~+1))~a['!'+t]~){v=s.n.~channel~un)~.target"
+"~o.value~g+\"_c\"]~\".tl(\")~etscape~(ns?ns:~s_')t=t~k',s.bc~omePage~s.d.get~')<~||!~[b](e);~m[t+1](~return~mobile~height~events~random~code~'MSIE ~rs,~un,~,pev~floor(~atch~s.num(~[\"s_\"+~s.c_gd~s"
+".dc~s.pg~,'lt~.inner~transa~;s.gl(~\"m_\"+n~idt='+~page~Group,~.fromC~sByTag~?'&~+';'~t&&~1);~){s.~[t]=~>=5)~[t](~=l[n];~!a[t])~~s._c=@Nc';`F=^1`5!`F`hn){`F`hl`U;`F`hn=0;}s^sl=`F`hl;s^sn=`F`hn;s^sl"
+"[s^s@os;`F`hn++;s.m`0m){`2$Gm)`4'{$d0`Afl`0x,l){`2x?$Gx)`30,l):x`Aco`0o`H!o)`2o;`Kn`E,x;^B@xo)@tx`4'select$d0&&x`4'filter$d0)n[x]=o[x];`2n`Anum`0x){x`e+x;^B`Kp=0;p<x`C;p++)@t(@V')`4x`3p,p$O<0)`20;`"
+"21`Arep=s_r;@y`0x`1,h=@VABCDEF',i,c=s.@E,n,l,e,y`e;c=c?c`D$M`5x){x`e+x`5c`tAUTO'^m'').c^lAt){^Bi=0;i<x`C@A{c=x`3i,i+#Bn=x.c^lAt(i)`5n>127){l=0;e`e;^4n||l<4){e=h`3n%16,n%16+1)+e;n=(n-n%16)/16;l++}y+"
+"='%u'+e}`Bc`t+')y+='%2B';`my+=^gc)}x=y^zx=x?`v^g''+x),'+`G%2B'):x`5x&&c^Eem==1&&x`4'%u$d0&&x`4'%U$d0){i=x`4'%^R^4i>=0){i++`5h`38)`4x`3i,i+1)`D())>=0)`2x`30,i)+'u00'+x`3i);i=x`4'%',i)}}}}`2x`Aepa`0x"
+"`1;`2x?un^g`v''+x,'+`G ')):x`Apt`0x,d,f,a`1,t=x,z=0,y,r;^4t){y=t`4d);y=y<0?t`C:y;t=t`30,y);^At,$Nt,a)`5r)`2r;z+=y+d`C;t=x`3z,x`C);t=z<x`C?t:''}`2''`Aisf`0t,a){`Kc=a`4':')`5c>=0)a=a`30,c)`5t`30,2)`t"
+"$Z`32);`2(t!`e@W==a)`Afsf`0t,a`1`5`La,`G,'is^ut))@Q+=(@Q!`e?`G`j+t;`20`Afs`0x,f`1;@Q`e;`Lx,`G,'fs^uf);`2@Q`Ac_d`e;$vf`0t,a`1`5!$tt))`21;`20`Ac_gd`0`1,d=`F`J^5^w,n=s.fpC`V,p`5!n)n=s.c`V`5d@L$0@gn?^F"
+"n):2;n=n>2?n:2;p=d^6.')`5p>=0){^4p>=0&&n>1$Ld^6.',p-#Bn--}$0=p>0&&`Ld,'.`Gc_gd^u0)?d`3p):d}}`2$0`Ac_r`0k`1;k=@y(k);`Kc=' '+s.d.`u,i=c`4' '+k+@e,e=i<0?i:c`4';',i),v=i<0?'':@Yc`3i+2+k`C,e<0?c`C:e));`"
+"2v$H[[B]]'?v:''`Ac_w`0k,v,e`1,d=$v(),l=s.`u@7,t;v`e+v;l=l?$Gl)`D$M`5^t@Ct=(v!`e?^Fl?l:0):-60)`5t){e`Z;e.setTime(e`T+(t*1000))}`lk@Cs.d.`u=k+'`Pv!`e?v:'[[B]]')+'; path=/;'+(^t?' expires='+e.toGMT^3("
+")#9`j+(d?' domain='+d#9`j;`2^Vk)==v}`20`Aeh`0o,e,r,f`1,b='s^ne+'^ns^sn,n=-1,l,i,x`5!^Xl)^Xl`U;l=^Xl;^Bi=0;i<l`C&&n<0;i++`Hl[i].o==o&&l[i].e==e)n=i`ln<0@gi;l[n]`E}x#Gx.o=o;x.e=e;f=r?x.b:f`5r||f){x.b"
+"=r?0:o[e];x.o[e]=f`lx.b){x.o[b]=x.b;`2b}`20`Acet`0f,a,t,o,b`1,r,^d`5`O>=5^m!s.^e||`O>=7)){^d`7's`Gf`Ga`Gt`G`Ke,r@O^A$Na)`br=s.m(t)?s#Fe):t(e)}`2r^Rr=^d(s,f,a,t)^z@ts.^f^Eu`4$n4@d0)r=s.m(b)?s[b](a):"
+"b(a);else{^X(`F,'@F',0,o);^A$Na`Reh(`F,'@F',1)}}`2r`Ag^Tet`0e`1;`2`w`Ag^Toe`7'e`G`Ks=`9,c;^X(^1,\"@F\",1`Re^T=1;c=s.t()`5c)s.d.write(c`Re^T=0;`2@p'`Rg^Tfb`0a){`2^1`Ag^Tf`0w`1,p=w^0,l=w`J;`w=w`5p&&p"
+"`J!=l&&p`J^5==l^5){`w=p;`2s.g^Tf(`w)}`2`w`Ag^T`0`1`5!`w){`w=`F`5!s.e^T)`w=s.cet('g^T^u`w,'g^Tet',s.g^Toe,'g^Tfb')}`2`w`Amrq`0u`1,l=@1],n,r;@1]=0`5l)^Bn=0;n<l`C;n++){r#Gs.mr(0,0,r.r,0,r.t,r.u)}`Abr`"
+"0id,rs`1`5@m`a$e^W@Nbr',rs))$1l=rs`Aflush`a`0`1;s.fbr(0)`Afbr`0id`1,br=^V@Nbr')`5!br)br=$1l`5br`H!@m`a)^W@Nbr`G'`Rmr(0,0,br)}$1l=0`Amr`0@q,q,$oid,ta,u`1,dc=$w,t1=s.`x@n,t2=s.`x@nSecure,ns=s.`c`ispa"
+"ce,un=u?u:$Ys.f$S,unc=`v$p'_`G-'),r`E,l,imn=@Ni^n($S,im,b,e`5!rs){rs=@u'+(@3?'s'`j+'://'+(t1?(@3@W2?t2:t1):($Y(@3?'102':unc))+'.'+($w?$w:112)+'.2o7.net')@fb/ss/'+^C+'/'+(s.$i?'5.1':'1'@fH.17/'+@q+'"
+"?AQB=1&ndh=1'+(q?q`j+'&AQE=1'`5^Y@Ls.^f`H`O>5.5)rs=^j$o4095);`mrs=^j$o2047)`lid){$1(id,rs);$h}`ls.d.images&&`O>=3^m!s.^e||`O>=7)^m@R<0||`O>=6.1)`H!s.rc)s.rc`E`5!^O){^O=1`5!s.rl)s.rl`E;@1n]`U;set@5'"
+"@t^1`hl)^1.`9@8',750)^zl=@1n]`5l){r.t=ta;r.u=un;r.r=rs;l[l`C]=r;`2''}imn+='^n^O;^O++}im=`F[imn]`5!im)im=`F[im@onew Image;im@0l=0;im.^v`7'e`G^S@0l=1`5^1`hl)^1.`9@8^Rim@I=rs`5rs`4$2=@d0^m!ta||ta`t_se"
+"lf$Ia`t_top'||(`F.^w@Wa==`F.^w))){b=e`Z;^4!im@0l&&e`T-b`T<500)e`Z}`2''}`2'<im'+'g sr'+'c=\"'+rs+'\" width=1 $j=1 border=0 alt=\"\">'`Agg`0v`1`5!`F['s^nv])`F['s^nv]`e;`2`F['s^nv]`Aglf`0t,a`Ht`30,2)`"
+"t$Z`32);`Ks=^S,v=$3t)`5v)s#Dv`Agl`0v`1`5$x)`Lv,`G,'gl^u0)`Agv`0v`1;`2s['vpm^nv]?s['vpv^nv]:(s[v]?s[v]`j`Ahavf`0t,a`1,b=t`30,4),x=t`34),n=^Fx),k='g^nt,m='vpm^nt,q=t,v=s.`N@UVa$oe=s.`N@U^Qs,mn;@X$4t)"
+"`5s.@G||^D||^p`H^p^Epe`30,4)$H@G_'){mn=^p`30,1)`D()+^p`31)`5$5){v=$5.`xVars;e=$5.`x^Qs}}v=v?v+`G+^Z+`G+^Z2:''`5v@L`Lv,`G,'is^ut))s[k]`e`5t`t$k'&&e)@Xs.fs(s[k],e)}s[m]=0`5t`t^K`ID`6`cID`Ivid`6^I@Bg'"
+"`d`Bt`t`X@Br'`d`Bt`tvmk`Ivmt`6@E@Bce'`5s[k]&&s[k]`D()`tAUTO')@X'ISO8859-1';`Bs[k]^Eem==2)@X'UTF-8'}`Bt`t`c`ispace`Ins`6c`V`Icdp`6`u@7`Icl`6^o`Ivvp`6@H`Icc`6$R`Ich`6#0@6ID`Ixact`6@r`Iv0`6^U`Is`6^2`I"
+"c`6`o^k`Ij`6`f`Iv`6`u@9`Ik`6`z@2`Ibw`6`z^b`Ibh`6`g`Ict`6^x`Ihp`6p^J`Ip';`B$tx)`Hb`tprop`Ic$J;`Bb`teVar`Iv$J;`Bb`thier@Bh$J`d`ls[k]@W$H`N`i'@W$H`N^M')$6+='&'+q+'`Ps[k]);`2''`Ahav`0`1;$6`e;`L^a,`G,'h"
+"av^u0);`2$6`Alnf`0^c`8^r`8:'';`Kte=t`4@e`5t@We>0&&h`4t`3te$O>=0)`2t`30,te);`2''`Aln`0h`1,n=s.`N`is`5n)`2`Ln,`G,'ln^uh);`2''`Altdf`0^c`8^r`8:'';`Kqi=h`4'?^Rh=qi>=0?h`30,qi):h`5#Ah`3h`C-(t`C$O`t.'+t)"
+"`21;`20`Altef`0^c`8^r`8:''`5#Ah`4t)>=0)`21;`20`Alt`0h`1,lft=s.`N^PFile^Ms,lef=s.`NEx`n,@s=s.`NIn`n;@s=@s?@s:`F`J^5^w;h=h`8`5s.`x^PLinks&&lf#A`Llft,`G$yd^uh))`2'd'`5s.`x@D&&h`30,1)$H# '^mlef||@s)^m!"
+"lef||`Llef,`G$ye^uh))^m!@s$e`L@s,`G$ye^uh)))`2'e';`2''`Alc`7'e`G`Ks=`9,b=^X(^S,\"`k\"`R@G=@w^S`Rt(`R@G=0`5b)`2^S$f`2@p'`Rbc`7'e`G`Ks=`9,f,^d`5s.d^Ed.all^Ed.all.cppXYctnr)$h;^D=e@I`S?e@I`S:e$T;^d`7"
+"\"s\",\"`Ke@O@t^D^m^D.tag`i||^D^0`S||^D^0Node))s.t()`b}\");^d(s`Reo=0'`Roh`0o`1,l=`F`J,h=o^h?o^h:'',i,j,k,p;i=h`4':^Rj=h`4'?^Rk=h`4'/')`5h^mi<0||(j>=0&&i>j)||(k>=0&&i>k))$Lo`Y&&o`Y`C>1?o`Y:(l`Y?l`Y"
+"`j;i=l.path^w^6/^Rh=(p?p+'//'`j+(o^5?o^5:(l^5?l^5`j)+(h`30,1)$H/'?l.path^w`30,i<0?0:i@f'`j+h}`2h`Aot`0o){`Kt=o.tag`i;t=t@W`D?t`D$M`5t`tSHAPE')t`e`5t`Ht`tINPUT'&&@4&&@4`D)t=@4`D();`B!#Ao^h)t='A';}`2"
+"t`Aoid`0o`1,^G,p,c,n`e,x=0`5t@L`y$Lo`Y;c=o.`k`5o^h^mt`tA$I`tAREA')^m!c$ep||p`8`4'`o$d0))n@k`Bc@g`vs.rep(`vs.rep$Gc,\"\\r@h\"\\n@h\"\\t@h' `G^Rx=2}`B$U^mt`tINPUT$I`tSUBMIT')@g$U;x=3}`Bo@I@W`tIMAGE')"
+"n=o@I`5n){`y=^jn@v;`yt=x}}`2`y`Arqf`0t,un`1,e=t`4@e,u=e>=0?`G+t`30,e)+`G:'';`2u&&u`4`G+un+`G)>=0?@Yt`3e$O:''`Arq`0un`1,c=un`4`G),v=^V@Nsq'),q`e`5c<0)`2`Lv,'&`Grq^u$S;`2`L$p`G,'rq',0)`Asqp`0t,a`1,e="
+"t`4@e,q=e<0?'':@Yt`3e+1)`Rsqq[q]`e`5e>=0)`Lt`30,e),`G@b`20`Asqs`0$pq`1;^7u[u@oq;`20`Asq`0q`1,k=@Nsq',v=^Vk),x,c=0;^7q`E;^7u`E;^7q[q]`e;`Lv,'&`Gsqp',0);`L^C,`G@bv`e;^B@x^7u`Q)^7q[^7u[x]]+=(^7q[^7u[x"
+"]]?`G`j+x;^B@x^7q`Q&&^7q[x]^mx==q||c<2)){v+=(v#8'`j+^7q[x]+'`Px);c++}`2^Wk,v,0)`Awdl`7'e`G`Ks=`9,r=@p,b=^X(`F,\"^v\"),i,o,oc`5b)r=^S$f^Bi=0;i<s.d.`Ns`C@A{o=s.d.`Ns[i];oc=o.`k?\"\"+o.`k:\"\"`5(oc`4$"
+"B<0||oc`4\"@0oc(\")>=0)&&oc`4$W<0)^X(o,\"`k\",0,s.lc);}`2r^R`Fs`0`1`5`O>3^m!^Y$es.^f||`O#E`Hs.b^E$D^Q)s.$D^Q('`k',s.bc);`Bs.b^Eb.add^Q$A)s.b.add^Q$A('clic$a,false);`m^X(`F,'^v',0,`Fl)}`Avs`0x`1,v=s"
+".`c^N,g=s.`c^N#5k=@Nvsn^n^C+(g?'^ng`j,n=^Vk),e`Z,y=e.g@K);e.s@Ky+10@l1900:0))`5v){v*=100`5!n`H!^Wk,x,e))`20;n=x`ln%10000>v)`20}`21`Adyasmf`0t,m`H#Am&&m`4t)>=0)`21;`20`Adyasf`0t,m`1,i=t?t`4@e:-1,n,x"
+"`5i>=0&&m){`Kn=t`30,i),x=t`3i+1)`5`Lx,`G,'dyasm^um))`2n}`20`Auns`0`1,x=s.`MSele@6,l=s.`MList,m=s.`MM$s,n,i;^C=^C`8`5x&&l`H!m)m=`F`J^5`5!m.toLowerCase)m`e+m;l=l`8;m=m`8;n=`Ll,';`Gdyas^um)`5n)^C=n}i="
+"^C`4`G`Rfun=i<0?^C:^C`30,i)`Asa`0un`1;^C=un`5!@S)@S=un;`B(`G+@S+`G)`4$S<0)@S+=`G+un;^Cs()`Am_i`0n,a`1,m,f=n`30,1),r,l,i`5!`Wl)`Wl`E`5!`Wnl)`Wnl`U;m=`Wl[n]`5!a&&m&&m._e@Lm^s)`Wa(n)`5!m){m`E,m._c=@Nm"
+"';m^sn=`F`hn;m^sl=s^sl;m^sl[m^s@om;`F`hn++;m.s=s;m._n=n;m._l`U('_c`G_in`G_il`G_i`G_e`G_d`G_dl`Gs`Gn`G_r`G_g`G_g1`G_t`G_t1`G_x`G_x1`G_l'`Rm_l[@om;`Wnl[`Wnl`C]=n}`Bm._r@Lm._m){r=m._r;r._m=m;l=m._l;^B"
+"i=0;i<l`C@A@tm[l[i]])r[l[i]]=m[l[i]];r^sl[r^s@or;m=`Wl[@or`lf==f`D())s[@om;`2m`Am_a`7'n`Gg`G@t!g)g=#2;`Ks=`9,c=s[$V,m,x,f=0`5!c)c=`F$u$V`5c&&s_d)s[g]`7\"s\",s_ft(s_d(c)));x=s[g]`5!x)x=`F$ug];m=`Wi("
+"n,1)`5x){m^s=f=1`5(\"\"+x)`4\"fun@6\")>=0)x(s);`m`Wm(\"x\",n,x)}m=`Wi(n,1)`5@Zl)@Zl=@Z=0;`pt();`2f'`Rm_m`0t,n,d){t='^nt;`Ks=^S,i,x,m,f='^nt`5`Wl&&`Wnl)^Bi=0;i<`Wnl`C@A{x=`Wnl[i]`5!n||x==n){m=`Wi(x)"
+"`5m[t]`Ht`t_d')`21`5d)m#Fd);`mm#F)`lm[t+1]@Lm[f]`Hd)$gd);`m$g)}m[f]=1}}`20`AloadModule`0n,u,d,l`1,m,i=n`4':'),g=i<0?#2:n`3i+1),o=0,f,c=s.h?s.h:s.b,^d`5i>=0)n=n`30,i);m=`Wi(n)`5(l$e`Wa(n,g))&&u^Ed&&"
+"c^E$E`S`Hd){@Z=1;@Zl=1`l@3)u=`vu,@u:`Ghttps:^Rf`7'e`G`9.m_a(\"$J+'\",\"'+g+'\")^R^d`7's`Gf`Gu`Gc`G`Ke,o=0@Oo=s.$E`S(\"script\")`5o){@4=\"text/`o\"`5f)o.^v=f;o@I=u;c.appendChild(o)}`bo=0}`2o^Ro=^d(s"
+",f,u,c)}`mm=`Wi(n);m._e=1;`2m`Avo1`0t,a`Ha[t]||$P)^S#Da[t]`Avo2`0t,a`H#H{a#D^S[t]`5#H$P=1}`Adlt`7'`Ks=`9,d`Z,i,vo,f=0`5`pl)^Bi=0;i<`pl`C@A{vo=`pl[i]`5vo`H!`Wm(\"d\")||d`T-$C>=^8){`pl[i]=0;s.t(@i}`m"
+"f=1}`l`pi)clear@5`pi`Rdli=0`5f`H!`pi)`pi=set@5`pt,^8)}`m`pl=0'`Rdl`0vo`1,d`Z`5!@ivo`E;`L^9,`G$72',@i;$C=d`T`5!`pl)`pl`U;`pl[`pl`C]=vo`5!^8)^8=250;`pt()`At`0vo,id`1,trk=1,tm`Z,sed=Math&&@P$l?@P$r@P$"
+"l()*10000000000000):tm`T,@q='s'+@P$rtm`T/10800000)%10+sed,y=tm.g@K),vt=tm.getDate(@f`sMonth(@f'@ly+1900:y)+' `sHour$K:`sMinute$K:`sSecond$K `sDay()+' `sTimezoneO@z(),^d,^T=s.g^T(),ta`e,q`e,qs`e,$m`"
+"e,vb`E#1^9`Runs()`5!s.td){`Ktl=^T`J,a,o,i,x`e,c`e,v`e,p`e,bw`e,bh`e,^H0',k=^W@Ncc`G@p',0^q,hp`e,ct`e,pn=0,ps`5^3&&^3.prototype){^H1'`5j.m$s){^H2'`5tm.setUTCDate){^H3'`5^Y^E^f&&`O#E^H4'`5pn.toPrecis"
+"ion){^H5';a`U`5a.forEach){^H6';i=0;o`E;^d`7'o`G`Ke,i=0@Oi=new Iterator(o)`b}`2i^Ri=^d(o)`5i&&i.next)^H7'}}}}`l`O>=4)x=^iwidth+'x'+^i$j`5s.isns||s.^e`H`O>=3$Q`f(^q`5`O>=4){c=^ipixelDepth;bw=`F$z@2;b"
+"h=`F$z^b}}$8=s.n.p^J}`B^Y`H`O>=4$Q`f(^q;c=^i^2`5`O#E{bw=s.d.^L`S.o@z@2;bh=s.d.^L`S.o@z^b`5!s.^f^Eb){^d`7's`Gtl`G`Ke,hp=0`qh$b\");hp=s.b.isH$b(tl)?\"Y\":\"N\"`b}`2hp^Rhp=^d(s,tl);^d`7's`G`Ke,ct=0`qc"
+"lientCaps\");ct=s.b.`g`b}`2ct^Rct=^d(s)}}}`mr`e`l$8)^4pn<$8`C&&pn<30){ps=^j$8[pn].^w@v#9`5p`4ps)<0)p+=ps;pn++}s.^U=x;s.^2=c;s.`o^k=j;s.`f=v;s.`u@9=k;s.`z@2=bw;s.`z^b=bh;s.`g=ct;s.^x=hp;s.p^J=p;s.td"
+"=1`l@i{`L^9,`G$72',vb);`L^9,`G$71',@i`ls.useP^J)s.doP^J(s);`Kl=`F`J,r=^T.^L.`X`5!s.^I)s.^I=l^h?l^h:l`5!s.`X@Ls._1_`X#C`X=r;s._1_`X=1}`Wm('g')`5(vo&&$C)$e`Wm('d')`Hs.@G||^D){`Ko=^D?^D:s.@G`5!o)`2'';"
+"`Kp=$4'#4`i'),w=1,^G,@a,x=`yt,h,l,i,oc`5^D&&o==^D){^4o@Ln@W$HBODY'){o=o^0`S?o^0`S:o^0Node`5!o)`2'';^G;@a;x=`yt}oc=o.`k?''+o.`k:''`5(oc`4$B>=0&&oc`4\"@0oc(\")<0)||oc`4$W>=0)`2''}ta=n?o$T:1;h@ki=h`4'"
+"?^Rh=s.`N@c^3||i<0?h:h`30,i);l=s.`N`i?s.`N`i:s.ln(h);t=s.`N^M?s.`N^M`8:s.lt(h)`5t^mh||l))q+=$2=@G^n(t`td$I`te'?@y(t):'o')+(h?$2v1`Ph)`j+(l?$2v2`Pl)`j;`mtrk=0`5s.`x@T`H!p$L$4'^I^Rw=0}^G;i=o.sourceIn"
+"dex`5$3'^y')@g$3'^y^Rx=1;i=1`lp&&n@W)qs='&pid`P^jp,255))+(w#8p#3w`j+'&oid`P^jn@v)+(x#8o#3x`j+'&ot`Pt)+(i#8oi='+i`j}`l!trk@Lqs)`2'';@j=s.vs(sed)`5trk`H@j)$m=s.mr(@q,(vt#8t`Pvt)`j+s.hav()+q+(qs?qs:s."
+"rq(^C)),0,id,ta);qs`e;`Wm('t')`5s.p_r)s.p_r(`R`X`e}^7(qs);^z`p(@i;`l@i`L^9,`G$71',vb`R@G=^D=s.`N`i=s.`N^M=`F@0^y=s.ppu=^p=^pv1=^pv2=^pv3`e`5$x)`F@0@G=`F@0eo=`F@0`N`i=`F@0`N^M`e`5!id@Ls.tc#Ctc=1;s.f"
+"lush`a()}`2$m`Atl`0o,t,n,vo`1;s.@G=@wo`R`N^M=t;s.`N`i=n;s.t(@i}`5pg){`F@0co`0o){`K@J\"_\",1,#B`2@wo)`Awd@0gs`0$S{`K@J$p1,#B`2s.t()`Awd@0dc`0$S{`K@J$p#B`2s.t()}}@3=(`F`J`Y`8`4@us@d0`Rd=^L;s.b=s.d.bo"
+"dy`5$c`S#7`i#Ch=$c`S#7`i('HEAD')`5s.h)s.h=s.h[0]}s.n=navigator;s.u=s.n.userAgent;@R=s.u`4'N$X6/^R`Kapn$F`i,v$F^k,ie=v`4$n'),o=s.u`4'@M '),i`5v`4'@M@d0||o>0)apn='@M';^Y$9`tMicrosoft Internet Explore"
+"r'`Risns$9`tN$X'`R^e$9`t@M'`R^f=(s.u`4'Mac@d0)`5o>0)`O`rs.u`3o+6));`Bie>0){`O=^Fi=v`3ie+5))`5`O>3)`O`ri)}`B@R>0)`O`rs.u`3@R+10));`m`O`rv`Rem=0`5^3#6^l){i=^g^3#6^l(256))`D(`Rem=(i`t%C4%80'?2:(i`t%U0"
+"100'?1:0))}s.sa(un`Rvl_l='^K,`cID,vmk,ppu,@E,`c`ispace,c`V,`u@7,#4`i,^I,`X,@H';^a=^Z+',^o,$R,server,#4^M,#0@6ID,purchaseID,@r,state,zip,$k,products,`N`i,`N^M';^B`Kn=1;n<51;n++)^a+=',prop$J+',eVar$J"
+"+',hier$J;^Z2=',^U,^2,`o^k,`f,`u@9,`z@2,`z^b,`g,^x,pe$q1$q2$q3,p^J';^a+=^Z2;^9=^a+',$i,`c^N,`c^N#5`MSele@6,`MList,`MM$s,`x^PLinks,`x@D,`x@T,`N@c^3,`N^PFile^Ms,`NEx`n,`NIn`n,`N@UVa$o`N@U^Qs,`N`is,@G"
+",eo';$x=pg#1^9)`5!ss)`Fs()",
w=window,l=w.s_c_il,n=navigator,u=n.userAgent,v=n.appVersion,e=v.indexOf('MSIE '),m=u.indexOf('Netscape6/'),a,i,s;if(un){un=un.toLowerCase();if(l)for(i=0;i<l.length;i++){s=l[i];if(s._c=='s_c'){if(s.oun==un)return s;else if(s.fs&&s.sa&&s.fs(s.oun,un)){s.sa(un);return s}}}}
w.s_r=new Function("x","o","n","var i=x.indexOf(o);if(i>=0&&x.split)x=(x.split(o)).join(n);else while(i>=0){x=x.substring(0,i)+n+x.substring(i+o.length);i=x.indexOf(o)}return x");
w.s_d=new Function("x","var t='`^@$#',l='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',d,n=0,b,k,w,i=x.lastIndexOf('~~');if(i>0){d=x.substring(0,i);x=x.substring(i+2);while(d){w=d;i"
+"=d.indexOf('~');if(i>0){w=d.substring(0,i);d=d.substring(i+1)}else d='';b=(n-n%62)/62;k=n-b*62;k=t.substring(b,b+1)+l.substring(k,k+1);x=s_r(x,k,w);n++}for(i=0;i<5;i++){w=t.substring(i,i+1);x=s_r(x"
+",w+' ',w)}}return x");
w.s_fe=new Function("c","return s_r(s_r(s_r(c,'\\\\','\\\\\\\\'),'\"','\\\\\"'),\"\\n\",\"\\\\n\")");
w.s_fa=new Function("f","var s=f.indexOf('(')+1,e=f.indexOf(')'),a='',c;while(s>=0&&s<e){c=f.substring(s,s+1);if(c==',')a+='\",\"';else if((\"\\n\\r\\t \").indexOf(c)<0)a+=c;s++}return a?'\"'+a+'\"':"
+"a");
w.s_ft=new Function("c","c+='';var s,e,o,a,d,q,f,h,x;s=c.indexOf('=function(');while(s>=0){s++;d=1;q='';x=0;f=c.substring(s);a=s_fa(f);e=o=c.indexOf('{',s);e++;while(d>0){h=c.substring(e,e+1);if(q){i"
+"f(h==q&&!x)q='';if(h=='\\\\')x=x?0:1;else x=0}else{if(h=='\"'||h==\"'\")q=h;if(h=='{')d++;if(h=='}')d--}if(d>0)e++}c=c.substring(0,s)+'new Function('+(a?a+',':'')+'\"'+s_fe(c.substring(o+1,e))+'\")"
+"'+c.substring(e+1);s=c.indexOf('=function(')}return c;");
c=s_d(c);if(e>0){a=parseInt(i=v.substring(e+5));if(a>3)a=parseFloat(i)}else if(m>0)a=parseFloat(u.substring(m+10));else a=parseFloat(v);if(a>=5&&v.indexOf('Opera')<0&&u.indexOf('Opera')<0){w.s_c=new Function("un","pg","ss","var s=this;"+c);return new s_c(un,pg,ss)}else s=new Function("un","pg","ss","var s=new Object;"+s_ft(c)+";return s");return s(un,pg,ss)}



LaptopLogic.modules.SubNavigation =
{
	init: function()
	{
		//this.addToggleLinks();
	}, 

	addToggleLinks: function()
	{
		var cookieName = 'sub_navigation_boxes';
		
		// See if uses has a cookie set
		if(!$.cookie(cookieName)) {
			$.cookie(cookieName, '');
		}

		// Add toggle-links to all headings that slide up/down the links and sets cookies
		$('#sub-navigation h2').each(function(i) {
			var h2 = $(this);
			var ul = h2.next('ul');

			// Add a link
			h2.html('<a href="#">' +h2.html() +'</a>');

			var a = h2.find('a');

			// Has the user already minimized this list?
			if($.cookie(cookieName) && $.cookie(cookieName).indexOf(i) !== -1) {
				ul.slideUp(0);
				a.addClass('mini');
			}

			// When clicking the link
			a.click(function() {
				if(a.is('.mini')) {
					a.removeClass('mini');
					ul.slideDown(100);
					$.cookie(cookieName, $.cookie(cookieName).replace(i, ''));
				}
				else {
					a.addClass('mini');
					ul.slideUp(100);
					$.cookie(cookieName, $.cookie(cookieName) +i);
				}
				
				return false;
			});
		});
	}
};

LaptopLogic.modules.ToplistAdmin = {
	init: function() {
		//this.selectType();
	}, 
	
    selectType: function() {
        var toplistDiv = $('<div id="topist-data"></div>').appendTo('#toplist-admin');
        $('#toplist-admin #choose-toplist').change(function() {
            $('#toplist-admin').ajaxLoader();
            $.post('/ajax/get-toplist-data/get-toplist-data.php?id='+$(this).val(), function(data) {
                toplistDiv.html(data);
                $('#toplist-admin').ajaxLoaderRemove( true );
            });
        });
    }
};

LaptopLogic.modules.VideoAdmin = {
	init: function() {
		this.editVideo(); // Gets the forms and their data using ajax
		this.connectArticle(); // Gets a list of pages, either reviews or articles depending on choice
		
	}, 
	
	editVideo: function()
	{
        var $edit_div = $('#video-admin #video-admin-content');        

        $('#video-admin #video_page_id').change(function() // Trigger when the select box changes
		{
			$.get('/ajax/video-admin/get-edit-video.php?page_id='+$(this).val(), function(data)	// Send an ajax get request and append the result to edit_div. 	
			{
				$edit_div.empty().append(data);
				LaptopLogic.modules.VideoAdmin.connectArticle(); // Run this function again after the result has been appended to make it work with the new data.
				LaptopLogic.modules.VideoAdmin.init_delete_connected_ids(); // Make connected id's deleteable
			});	
	    });
	    var page_id = $.query.get('pageId');
		               
        if (page_id !== '')
        {
       		// Set value of select to page_id and trigger it.
       		$('select#video_page_id').find('option[value="' + page_id + '"]').attr('selected',true).end().trigger('change');
        }
    },
	  
    connectArticle: function()
	{
        var $connect_div = $('#video-admin div.connect-choice'); // Div contain a select box with options: reviews, articles
        var $createDiv = $('#video-admin #video-admin-content div.connect-list');  // Empty div used to display the ajax result  

		$connect_div.hide(); // Hide the select boxes until the user needs them
		
        $('#video-admin #video-admin-content #connect-article').click(function() // Triggers when the user wants to connect the video (clicks the link)
		{
			$connect_div.show(); //Show div with select boxes
			$('#video-admin #video-admin-content div.connect-choice label input').click(function() // Triggers when the users chooses a page type (review or article)
			{
				$.get('/ajax/video-admin/get-list.php?type='+$(this).val(), function(data) // Sends get request using ajax
				{
					$createDiv.empty().append(data); // Append the ajax result
					
					var $connect_select = $('div.connect-list select');
					
					$connect_select.change(function() // Change event to connected id's select
					{
						var $selected_option = $(this).find('option:selected'); // The one user selected
						
						LaptopLogic.modules.VideoAdmin.update_connect_list($selected_option); // Send to function below
					});
				});
	    	});			
	    });
    },
	
	// Updates list of connected id's
	update_connect_list:function($selected_option)
	{
		var name = $selected_option.text();				// Name of review of article
		var value = $selected_option.attr('value');		// and the id
		
		// If no no list is present - append one
		if ( ! $('div.connected_ids').size())
		{
			$('div.connect-list').after('<div class="connected_ids"><p><strong>Connected to:</strong></p><ul></ul></div>');
		}
		
		var $list = $('div.connected_ids ul');
		
		// Check that user doesn't try to add an item more than once
		if ($list.find('input[value="' + value + '"]').size())
		{
			alert('The item you chose is already in the list. Pleaste select another one.');
			
			return;
		}
		
		// Append list item with name and a hidden input holding the id
		$list.append('<li><input type="hidden" name="connected_ids[]" value="' + value + '" />' + name + '&nbsp;&nbsp;<a href="#" class="delete">Delete</a></li>');
		
		LaptopLogic.modules.VideoAdmin.init_delete_connected_ids(); // Init clicks for deleteing items
	},
	
	init_delete_connected_ids:function()
	{
		$('div.connected_ids li a.delete').unbind('click').click(function()
		{
			var $item = $(this).parent();
			
			$item.remove();
		})
	}
};

LaptopLogic.modules.VideoPage = {
	init: function() {
		this.hijaxForm();
        this.postComment();
	},

    hijaxForm: function() {
        $('#video-page form').liveValidation({
            invalidIco: '/css/gfx/icons/form-control-invalid.png',
            validIco:   '/css/gfx/icons/form-control-valid.png'
        },
            { content_name: /^.+$/
        });
    },

    postComment: function() {

		$('#video-page #commentForm').ajaxForm({
			url: '/ajax/post-comment/video-comment.php',
			success: function() {
				$.post('/ajax/comment-listing/video-comment-list.php', {
                    featureType: $('#video-page input[name="featureType"]').val(),
					JS: true,
                    email: $('#video-page input[name="email"]').val(),
                    captcha: $('#video-page input[name="captcha"]').val(),
                    name: $('#video-page input[name="name"]').val(),
                    commentText: $('#video-page textarea[name="commentText"]').val(),
                    pageId: $('#video-page input[name="pageId"]').val()

				},
				function(data) {
					$('#video-page .comments').empty().append(data);
				});
			}
		});
	}

};




jQuery.videoViewer = function() {
	var videoViewerOverlay = $('<div id="video-viewer-overlay"></div>').appendTo('body').hide();
	var videoViewer = $('<div id="video-viewer"><div id="video-viewer-video"></div></div>').appendTo('body').css({position: 'absolute'}).hide().click(function() {
		videoViewer.fadeOut(500, function() {
			$(this).find('#video-viewer-video').html('');
			videoViewerOverlay.fadeOut(500);
		});
	});

	$(document.body).click(function(e) {
		var clickedElement = jQuery(e.target);
			clickedElement = clickedElement.is('a') ? clickedElement : clickedElement.parents('a').eq(0);

		if(clickedElement.length && clickedElement.attr('href').search(/.*\.flv$/gi) != -1) {
			FlashReplace.replace('video-viewer-video', '/upload-videos/player.swf', 'video-viewer-video-flash', 640, 480, 7,
				{
					wmode : "transparent",
					quality: "high",
					bgcolor: "#ffffff", 
					flashVars: 'pathToMovie=' +clickedElement.attr('href')
				}
			);

			videoViewerOverlay.fadeIn(500, function() {
				videoViewer.center().fadeIn(500);
			});

			return false;
		}
	});
};

$.videoViewer();

LaptopLogic.modules.WhatsHot = {
	init: function()
	{
		var fx = (!$.browser.msie) ? {opacity: 'toggle'} : false;
		
		$('#whats-hot > ul').tabs({fx: fx, fxAutoHeight: true}).tabs('rotate', 5000);
		
		$('#content div.ui-tabs-panel').equalHeight();
	}
};

LaptopLogic.modules.WriteReview = {
	init: function() {
		$('#write-review form').liveValidation({
			invalidIco:	'/css/gfx/icons/form-control-invalid.png', 
			validIco:	'/css/gfx/icons/form-control-valid.png'
		}, {
			about:		/^\S.*$/, 
			title:		/^\S.*$/,
			content:	/^\S.*$/
		});

		$('#write-review select[name="overall_rating"]').starRating();
		$('#write-review select[name="rating_design"]').starRating();
		$('#write-review select[name="rating_feature"]').starRating();
		$('#write-review select[name="rating_system"]').starRating();
		$('#write-review select[name="rating_threed_preformance"]').starRating();
		$('#write-review select[name="rating_preformance"]').starRating();
		$('#write-review select[name="rating_battery_life"]').starRating();
		
		$('#write-review select[name="rating_gamers"]').starRating();
		$('#write-review select[name="rating_travelers"]').starRating();
		$('#write-review select[name="rating_entertainment"]').starRating();
		$('#write-review select[name="rating_business"]').starRating();
		$('#write-review select[name="rating_students"]').starRating();
		
		$rating_selects = $('#write-review form p.alt-yellow');
		$recommended_selects = $('#write-review form p.alt-blue');
		
		// Hide recommended selects when clicking review_type radios except with value "review"
		$('input[type="radio"][name="review_type"][value!="review"]').click(function()
		{
			$rating_selects.hide();
			$recommended_selects.hide();
		});
		
		// Show recommended selects when clicking review_type radio with value "review"
		$('input[type="radio"][name="review_type"][value="review"]').click(function()
		{
			$rating_selects.show();
			$recommended_selects.show();
		});
		
	}
};

LaptopLogic.modules.Conv =
{
	init:function()
	{
		// 14. WHS, Review - Pulse 1, Q1_09
		if( typeof( most_pop_version ) !== 'undefined')
		{
			//this.most_pop_q2_09_test();
		}		
	},
	
	most_pop_q2_09_test:function()
	{		
		switch(most_pop_version)
		{
			case 'b':
				$('#most-popular-laptops, div[id^="mpl-"]').wrapAll('<div id="most-popular-laptops-alt"></div>');
				$('#most-popular-laptops').removeAttr('id');

				var $container = $('#most-popular-laptops-alt');

				$container.find('ul.tabs').removeAttr('class');
			break;

			case 'a':
			default:
			
				$('#most-popular-laptops, div[id^="mpl-"]').wrapAll('<div id="most-popular-laptops-org"></div>');
			
			break;
		}
		
		$('#most-popular-laptops-org, #most-popular-laptops-alt').find('p.review a').click(function()
		{
			return LaptopLogic.modules.Conv.trackMboxClick(this,'mostpop-toplist-review-click');
		});
	},
	
	trackMboxClick:function( obj, tracker )
	{
		href = $(obj).attr('href');

		if( !href )
		{
			return false;
		}

		href = href.substr( href.indexOf( obj.pathname ) );

		if( href.substr( 0, 1 ) != '/' )
		{
			href = '/' + href;
		}
		
		var sessID = mboxFactoryDefault.getSessionId().getId();

		href = encodeURIComponent( href );
		
		var host = document.location.host;
				
		href = 'http://function.tt.omtrdc.net/m2/function/ubox/page?mboxHost=' + host + '&mbox=tracker-ll-' + tracker + '&mboxSession=' +sessID +'&mboxDefault=http://' + host + href;

		window.location = href;
		
		return false;		
	}
};

