/*
 * jQuery 1.2.3 - New Wave Javascript
 *
 * Copyright (c) 2008 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2008-02-06 00:21:25 -0500 (Wed, 06 Feb 2008) $
 * $Rev: 4663 $
 */
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}('(J(){7(1e.3N)L w=1e.3N;L E=1e.3N=J(a,b){K 1B E.2l.4T(a,b)};7(1e.$)L D=1e.$;1e.$=E;L u=/^[^<]*(<(.|\\s)+>)[^>]*$|^#(\\w+)$/;L G=/^.[^:#\\[\\.]*$/;E.1n=E.2l={4T:J(d,b){d=d||T;7(d.15){6[0]=d;6.M=1;K 6}N 7(1o d=="25"){L c=u.2O(d);7(c&&(c[1]||!b)){7(c[1])d=E.4a([c[1]],b);N{L a=T.5J(c[3]);7(a)7(a.2w!=c[3])K E().2s(d);N{6[0]=a;6.M=1;K 6}N d=[]}}N K 1B E(b).2s(d)}N 7(E.1q(d))K 1B E(T)[E.1n.21?"21":"3U"](d);K 6.6E(d.1k==1M&&d||(d.5h||d.M&&d!=1e&&!d.15&&d[0]!=10&&d[0].15)&&E.2I(d)||[d])},5h:"1.2.3",87:J(){K 6.M},M:0,22:J(a){K a==10?E.2I(6):6[a]},2F:J(b){L a=E(b);a.54=6;K a},6E:J(a){6.M=0;1M.2l.1g.1i(6,a);K 6},R:J(a,b){K E.R(6,a,b)},4X:J(b){L a=-1;6.R(J(i){7(6==b)a=i});K a},1J:J(c,a,b){L d=c;7(c.1k==4e)7(a==10)K 6.M&&E[b||"1J"](6[0],c)||10;N{d={};d[c]=a}K 6.R(J(i){Q(c 1p d)E.1J(b?6.W:6,c,E.1l(6,d[c],b,i,c))})},1j:J(b,a){7((b==\'27\'||b==\'1R\')&&2M(a)<0)a=10;K 6.1J(b,a,"2o")},1u:J(b){7(1o b!="3V"&&b!=V)K 6.4x().3t((6[0]&&6[0].2i||T).5r(b));L a="";E.R(b||6,J(){E.R(6.3p,J(){7(6.15!=8)a+=6.15!=1?6.6K:E.1n.1u([6])})});K a},5m:J(b){7(6[0])E(b,6[0].2i).5k().3o(6[0]).2c(J(){L a=6;2b(a.1C)a=a.1C;K a}).3t(6);K 6},8w:J(a){K 6.R(J(){E(6).6z().5m(a)})},8p:J(a){K 6.R(J(){E(6).5m(a)})},3t:J(){K 6.3O(18,P,S,J(a){7(6.15==1)6.38(a)})},6q:J(){K 6.3O(18,P,P,J(a){7(6.15==1)6.3o(a,6.1C)})},6o:J(){K 6.3O(18,S,S,J(a){6.1a.3o(a,6)})},5a:J(){K 6.3O(18,S,P,J(a){6.1a.3o(a,6.2B)})},3h:J(){K 6.54||E([])},2s:J(b){L c=E.2c(6,J(a){K E.2s(b,a)});K 6.2F(/[^+>] [^+>]/.17(b)||b.1f("..")>-1?E.57(c):c)},5k:J(e){L f=6.2c(J(){7(E.14.1d&&!E.3E(6)){L a=6.69(P),4Y=T.3s("1x");4Y.38(a);K E.4a([4Y.3d])[0]}N K 6.69(P)});L d=f.2s("*").4R().R(J(){7(6[F]!=10)6[F]=V});7(e===P)6.2s("*").4R().R(J(i){7(6.15==3)K;L c=E.O(6,"2R");Q(L a 1p c)Q(L b 1p c[a])E.16.1b(d[i],a,c[a][b],c[a][b].O)});K f},1E:J(b){K 6.2F(E.1q(b)&&E.3y(6,J(a,i){K b.1P(a,i)})||E.3e(b,6))},56:J(b){7(b.1k==4e)7(G.17(b))K 6.2F(E.3e(b,6,P));N b=E.3e(b,6);L a=b.M&&b[b.M-1]!==10&&!b.15;K 6.1E(J(){K a?E.33(6,b)<0:6!=b})},1b:J(a){K!a?6:6.2F(E.37(6.22(),a.1k==4e?E(a).22():a.M!=10&&(!a.12||E.12(a,"3u"))?a:[a]))},3H:J(a){K a?E.3e(a,6).M>0:S},7j:J(a){K 6.3H("."+a)},5O:J(b){7(b==10){7(6.M){L c=6[0];7(E.12(c,"2k")){L e=c.3T,5I=[],11=c.11,2X=c.U=="2k-2X";7(e<0)K V;Q(L i=2X?e:0,2f=2X?e+1:11.M;i<2f;i++){L d=11[i];7(d.2p){b=E.14.1d&&!d.9J.1A.9y?d.1u:d.1A;7(2X)K b;5I.1g(b)}}K 5I}N K(6[0].1A||"").1r(/\\r/g,"")}K 10}K 6.R(J(){7(6.15!=1)K;7(b.1k==1M&&/5u|5t/.17(6.U))6.3k=(E.33(6.1A,b)>=0||E.33(6.31,b)>=0);N 7(E.12(6,"2k")){L a=b.1k==1M?b:[b];E("98",6).R(J(){6.2p=(E.33(6.1A,a)>=0||E.33(6.1u,a)>=0)});7(!a.M)6.3T=-1}N 6.1A=b})},3q:J(a){K a==10?(6.M?6[0].3d:V):6.4x().3t(a)},6S:J(a){K 6.5a(a).1V()},6Z:J(i){K 6.2K(i,i+1)},2K:J(){K 6.2F(1M.2l.2K.1i(6,18))},2c:J(b){K 6.2F(E.2c(6,J(a,i){K b.1P(a,i,a)}))},4R:J(){K 6.1b(6.54)},O:J(d,b){L a=d.23(".");a[1]=a[1]?"."+a[1]:"";7(b==V){L c=6.5n("8P"+a[1]+"!",[a[0]]);7(c==10&&6.M)c=E.O(6[0],d);K c==V&&a[1]?6.O(a[0]):c}N K 6.1N("8K"+a[1]+"!",[a[0],b]).R(J(){E.O(6,d,b)})},35:J(a){K 6.R(J(){E.35(6,a)})},3O:J(g,f,h,d){L e=6.M>1,3n;K 6.R(J(){7(!3n){3n=E.4a(g,6.2i);7(h)3n.8D()}L b=6;7(f&&E.12(6,"1O")&&E.12(3n[0],"4v"))b=6.3S("1U")[0]||6.38(6.2i.3s("1U"));L c=E([]);E.R(3n,J(){L a=e?E(6).5k(P)[0]:6;7(E.12(a,"1m")){c=c.1b(a)}N{7(a.15==1)c=c.1b(E("1m",a).1V());d.1P(b,a)}});c.R(6A)})}};E.2l.4T.2l=E.2l;J 6A(i,a){7(a.3Q)E.3P({1c:a.3Q,3l:S,1H:"1m"});N E.5g(a.1u||a.6x||a.3d||"");7(a.1a)a.1a.34(a)}E.1s=E.1n.1s=J(){L b=18[0]||{},i=1,M=18.M,5c=S,11;7(b.1k==8d){5c=b;b=18[1]||{};i=2}7(1o b!="3V"&&1o b!="J")b={};7(M==1){b=6;i=0}Q(;i<M;i++)7((11=18[i])!=V)Q(L a 1p 11){7(b===11[a])6w;7(5c&&11[a]&&1o 11[a]=="3V"&&b[a]&&!11[a].15)b[a]=E.1s(b[a],11[a]);N 7(11[a]!=10)b[a]=11[a]}K b};L F="3N"+(1B 3v()).3L(),6t=0,5b={};L H=/z-?4X|86-?84|1w|6k|7Z-?1R/i;E.1s({7Y:J(a){1e.$=D;7(a)1e.3N=w;K E},1q:J(a){K!!a&&1o a!="25"&&!a.12&&a.1k!=1M&&/J/i.17(a+"")},3E:J(a){K a.1F&&!a.1h||a.28&&a.2i&&!a.2i.1h},5g:J(a){a=E.3g(a);7(a){L b=T.3S("6f")[0]||T.1F,1m=T.3s("1m");1m.U="1u/4m";7(E.14.1d)1m.1u=a;N 1m.38(T.5r(a));b.38(1m);b.34(1m)}},12:J(b,a){K b.12&&b.12.2E()==a.2E()},1T:{},O:J(c,d,b){c=c==1e?5b:c;L a=c[F];7(!a)a=c[F]=++6t;7(d&&!E.1T[a])E.1T[a]={};7(b!=10)E.1T[a][d]=b;K d?E.1T[a][d]:a},35:J(c,b){c=c==1e?5b:c;L a=c[F];7(b){7(E.1T[a]){2V E.1T[a][b];b="";Q(b 1p E.1T[a])1Q;7(!b)E.35(c)}}N{1S{2V c[F]}1X(e){7(c.52)c.52(F)}2V E.1T[a]}},R:J(c,a,b){7(b){7(c.M==10){Q(L d 1p c)7(a.1i(c[d],b)===S)1Q}N Q(L i=0,M=c.M;i<M;i++)7(a.1i(c[i],b)===S)1Q}N{7(c.M==10){Q(L d 1p c)7(a.1P(c[d],d,c[d])===S)1Q}N Q(L i=0,M=c.M,1A=c[0];i<M&&a.1P(1A,i,1A)!==S;1A=c[++i]){}}K c},1l:J(b,a,c,i,d){7(E.1q(a))a=a.1P(b,i);K a&&a.1k==51&&c=="2o"&&!H.17(d)?a+"2S":a},1t:{1b:J(c,b){E.R((b||"").23(/\\s+/),J(i,a){7(c.15==1&&!E.1t.3Y(c.1t,a))c.1t+=(c.1t?" ":"")+a})},1V:J(c,b){7(c.15==1)c.1t=b!=10?E.3y(c.1t.23(/\\s+/),J(a){K!E.1t.3Y(b,a)}).6a(" "):""},3Y:J(b,a){K E.33(a,(b.1t||b).3X().23(/\\s+/))>-1}},68:J(b,c,a){L e={};Q(L d 1p c){e[d]=b.W[d];b.W[d]=c[d]}a.1P(b);Q(L d 1p c)b.W[d]=e[d]},1j:J(d,e,c){7(e=="27"||e=="1R"){L b,46={43:"4W",4U:"1Z",19:"3D"},3c=e=="27"?["7O","7M"]:["7J","7I"];J 5E(){b=e=="27"?d.7H:d.7F;L a=0,2N=0;E.R(3c,J(){a+=2M(E.2o(d,"7E"+6,P))||0;2N+=2M(E.2o(d,"2N"+6+"5X",P))||0});b-=24.7C(a+2N)}7(E(d).3H(":4d"))5E();N E.68(d,46,5E);K 24.2f(0,b)}K E.2o(d,e,c)},2o:J(e,k,j){L d;J 3x(b){7(!E.14.2d)K S;L a=T.4c.4K(b,V);K!a||a.4M("3x")==""}7(k=="1w"&&E.14.1d){d=E.1J(e.W,"1w");K d==""?"1":d}7(E.14.2z&&k=="19"){L c=e.W.50;e.W.50="0 7r 7o";e.W.50=c}7(k.1D(/4g/i))k=y;7(!j&&e.W&&e.W[k])d=e.W[k];N 7(T.4c&&T.4c.4K){7(k.1D(/4g/i))k="4g";k=k.1r(/([A-Z])/g,"-$1").2h();L h=T.4c.4K(e,V);7(h&&!3x(e))d=h.4M(k);N{L f=[],2C=[];Q(L a=e;a&&3x(a);a=a.1a)2C.4J(a);Q(L i=0;i<2C.M;i++)7(3x(2C[i])){f[i]=2C[i].W.19;2C[i].W.19="3D"}d=k=="19"&&f[2C.M-1]!=V?"2H":(h&&h.4M(k))||"";Q(L i=0;i<f.M;i++)7(f[i]!=V)2C[i].W.19=f[i]}7(k=="1w"&&d=="")d="1"}N 7(e.4n){L g=k.1r(/\\-(\\w)/g,J(a,b){K b.2E()});d=e.4n[k]||e.4n[g];7(!/^\\d+(2S)?$/i.17(d)&&/^\\d/.17(d)){L l=e.W.26,3K=e.3K.26;e.3K.26=e.4n.26;e.W.26=d||0;d=e.W.7f+"2S";e.W.26=l;e.3K.26=3K}}K d},4a:J(l,h){L k=[];h=h||T;7(1o h.3s==\'10\')h=h.2i||h[0]&&h[0].2i||T;E.R(l,J(i,d){7(!d)K;7(d.1k==51)d=d.3X();7(1o d=="25"){d=d.1r(/(<(\\w+)[^>]*?)\\/>/g,J(b,a,c){K c.1D(/^(aa|a6|7e|a5|4D|7a|a0|3m|9W|9U|9S)$/i)?b:a+"></"+c+">"});L f=E.3g(d).2h(),1x=h.3s("1x");L e=!f.1f("<9P")&&[1,"<2k 74=\'74\'>","</2k>"]||!f.1f("<9M")&&[1,"<73>","</73>"]||f.1D(/^<(9G|1U|9E|9B|9x)/)&&[1,"<1O>","</1O>"]||!f.1f("<4v")&&[2,"<1O><1U>","</1U></1O>"]||(!f.1f("<9w")||!f.1f("<9v"))&&[3,"<1O><1U><4v>","</4v></1U></1O>"]||!f.1f("<7e")&&[2,"<1O><1U></1U><6V>","</6V></1O>"]||E.14.1d&&[1,"1x<1x>","</1x>"]||[0,"",""];1x.3d=e[1]+d+e[2];2b(e[0]--)1x=1x.5o;7(E.14.1d){L g=!f.1f("<1O")&&f.1f("<1U")<0?1x.1C&&1x.1C.3p:e[1]=="<1O>"&&f.1f("<1U")<0?1x.3p:[];Q(L j=g.M-1;j>=0;--j)7(E.12(g[j],"1U")&&!g[j].3p.M)g[j].1a.34(g[j]);7(/^\\s/.17(d))1x.3o(h.5r(d.1D(/^\\s*/)[0]),1x.1C)}d=E.2I(1x.3p)}7(d.M===0&&(!E.12(d,"3u")&&!E.12(d,"2k")))K;7(d[0]==10||E.12(d,"3u")||d.11)k.1g(d);N k=E.37(k,d)});K k},1J:J(d,e,c){7(!d||d.15==3||d.15==8)K 10;L f=E.3E(d)?{}:E.46;7(e=="2p"&&E.14.2d)d.1a.3T;7(f[e]){7(c!=10)d[f[e]]=c;K d[f[e]]}N 7(E.14.1d&&e=="W")K E.1J(d.W,"9u",c);N 7(c==10&&E.14.1d&&E.12(d,"3u")&&(e=="9r"||e=="9o"))K d.9m(e).6K;N 7(d.28){7(c!=10){7(e=="U"&&E.12(d,"4D")&&d.1a)6Q"U 9i 9h\'t 9g 9e";d.9b(e,""+c)}7(E.14.1d&&/6O|3Q/.17(e)&&!E.3E(d))K d.4z(e,2);K d.4z(e)}N{7(e=="1w"&&E.14.1d){7(c!=10){d.6k=1;d.1E=(d.1E||"").1r(/6M\\([^)]*\\)/,"")+(2M(c).3X()=="96"?"":"6M(1w="+c*6L+")")}K d.1E&&d.1E.1f("1w=")>=0?(2M(d.1E.1D(/1w=([^)]*)/)[1])/6L).3X():""}e=e.1r(/-([a-z])/95,J(a,b){K b.2E()});7(c!=10)d[e]=c;K d[e]}},3g:J(a){K(a||"").1r(/^\\s+|\\s+$/g,"")},2I:J(b){L a=[];7(1o b!="93")Q(L i=0,M=b.M;i<M;i++)a.1g(b[i]);N a=b.2K(0);K a},33:J(b,a){Q(L i=0,M=a.M;i<M;i++)7(a[i]==b)K i;K-1},37:J(a,b){7(E.14.1d){Q(L i=0;b[i];i++)7(b[i].15!=8)a.1g(b[i])}N Q(L i=0;b[i];i++)a.1g(b[i]);K a},57:J(a){L c=[],2r={};1S{Q(L i=0,M=a.M;i<M;i++){L b=E.O(a[i]);7(!2r[b]){2r[b]=P;c.1g(a[i])}}}1X(e){c=a}K c},3y:J(c,a,d){L b=[];Q(L i=0,M=c.M;i<M;i++)7(!d&&a(c[i],i)||d&&!a(c[i],i))b.1g(c[i]);K b},2c:J(d,a){L c=[];Q(L i=0,M=d.M;i<M;i++){L b=a(d[i],i);7(b!==V&&b!=10){7(b.1k!=1M)b=[b];c=c.71(b)}}K c}});L v=8Y.8W.2h();E.14={5K:(v.1D(/.+(?:8T|8S|8R|8O)[\\/: ]([\\d.]+)/)||[])[1],2d:/77/.17(v),2z:/2z/.17(v),1d:/1d/.17(v)&&!/2z/.17(v),48:/48/.17(v)&&!/(8L|77)/.17(v)};L y=E.14.1d?"6H":"75";E.1s({8I:!E.14.1d||T.6F=="79",46:{"Q":"8F","8E":"1t","4g":y,75:y,6H:y,3d:"3d",1t:"1t",1A:"1A",2Y:"2Y",3k:"3k",8C:"8B",2p:"2p",8A:"8z",3T:"3T",6C:"6C",28:"28",12:"12"}});E.R({6B:J(a){K a.1a},8y:J(a){K E.4u(a,"1a")},8x:J(a){K E.2Z(a,2,"2B")},8v:J(a){K E.2Z(a,2,"4t")},8u:J(a){K E.4u(a,"2B")},8t:J(a){K E.4u(a,"4t")},8s:J(a){K E.5i(a.1a.1C,a)},8r:J(a){K E.5i(a.1C)},6z:J(a){K E.12(a,"8q")?a.8o||a.8n.T:E.2I(a.3p)}},J(c,d){E.1n[c]=J(b){L a=E.2c(6,d);7(b&&1o b=="25")a=E.3e(b,a);K 6.2F(E.57(a))}});E.R({6y:"3t",8m:"6q",3o:"6o",8l:"5a",8k:"6S"},J(c,b){E.1n[c]=J(){L a=18;K 6.R(J(){Q(L i=0,M=a.M;i<M;i++)E(a[i])[b](6)})}});E.R({8j:J(a){E.1J(6,a,"");7(6.15==1)6.52(a)},8i:J(a){E.1t.1b(6,a)},8h:J(a){E.1t.1V(6,a)},8g:J(a){E.1t[E.1t.3Y(6,a)?"1V":"1b"](6,a)},1V:J(a){7(!a||E.1E(a,[6]).r.M){E("*",6).1b(6).R(J(){E.16.1V(6);E.35(6)});7(6.1a)6.1a.34(6)}},4x:J(){E(">*",6).1V();2b(6.1C)6.34(6.1C)}},J(a,b){E.1n[a]=J(){K 6.R(b,18)}});E.R(["8f","5X"],J(i,c){L b=c.2h();E.1n[b]=J(a){K 6[0]==1e?E.14.2z&&T.1h["5e"+c]||E.14.2d&&1e["8e"+c]||T.6F=="79"&&T.1F["5e"+c]||T.1h["5e"+c]:6[0]==T?24.2f(24.2f(T.1h["5d"+c],T.1F["5d"+c]),24.2f(T.1h["5L"+c],T.1F["5L"+c])):a==10?(6.M?E.1j(6[0],b):V):6.1j(b,a.1k==4e?a:a+"2S")}});L C=E.14.2d&&4s(E.14.5K)<8c?"(?:[\\\\w*4r-]|\\\\\\\\.)":"(?:[\\\\w\\8b-\\8a*4r-]|\\\\\\\\.)",6v=1B 4q("^>\\\\s*("+C+"+)"),6u=1B 4q("^("+C+"+)(#)("+C+"+)"),6s=1B 4q("^([#.]?)("+C+"*)");E.1s({6r:{"":J(a,i,m){K m[2]=="*"||E.12(a,m[2])},"#":J(a,i,m){K a.4z("2w")==m[2]},":":{89:J(a,i,m){K i<m[3]-0},88:J(a,i,m){K i>m[3]-0},2Z:J(a,i,m){K m[3]-0==i},6Z:J(a,i,m){K m[3]-0==i},3j:J(a,i){K i==0},3J:J(a,i,m,r){K i==r.M-1},6n:J(a,i){K i%2==0},6l:J(a,i){K i%2},"3j-4p":J(a){K a.1a.3S("*")[0]==a},"3J-4p":J(a){K E.2Z(a.1a.5o,1,"4t")==a},"83-4p":J(a){K!E.2Z(a.1a.5o,2,"4t")},6B:J(a){K a.1C},4x:J(a){K!a.1C},82:J(a,i,m){K(a.6x||a.81||E(a).1u()||"").1f(m[3])>=0},4d:J(a){K"1Z"!=a.U&&E.1j(a,"19")!="2H"&&E.1j(a,"4U")!="1Z"},1Z:J(a){K"1Z"==a.U||E.1j(a,"19")=="2H"||E.1j(a,"4U")=="1Z"},80:J(a){K!a.2Y},2Y:J(a){K a.2Y},3k:J(a){K a.3k},2p:J(a){K a.2p||E.1J(a,"2p")},1u:J(a){K"1u"==a.U},5u:J(a){K"5u"==a.U},5t:J(a){K"5t"==a.U},59:J(a){K"59"==a.U},3I:J(a){K"3I"==a.U},58:J(a){K"58"==a.U},6j:J(a){K"6j"==a.U},6i:J(a){K"6i"==a.U},2G:J(a){K"2G"==a.U||E.12(a,"2G")},4D:J(a){K/4D|2k|6h|2G/i.17(a.12)},3Y:J(a,i,m){K E.2s(m[3],a).M},7X:J(a){K/h\\d/i.17(a.12)},7W:J(a){K E.3y(E.3G,J(b){K a==b.Y}).M}}},6g:[/^(\\[) *@?([\\w-]+) *([!*$^~=]*) *(\'?"?)(.*?)\\4 *\\]/,/^(:)([\\w-]+)\\("?\'?(.*?(\\(.*?\\))?[^(]*?)"?\'?\\)/,1B 4q("^([:.#]*)("+C+"+)")],3e:J(a,c,b){L d,2m=[];2b(a&&a!=d){d=a;L f=E.1E(a,c,b);a=f.t.1r(/^\\s*,\\s*/,"");2m=b?c=f.r:E.37(2m,f.r)}K 2m},2s:J(t,p){7(1o t!="25")K[t];7(p&&p.15!=1&&p.15!=9)K[];p=p||T;L d=[p],2r=[],3J,12;2b(t&&3J!=t){L r=[];3J=t;t=E.3g(t);L o=S;L g=6v;L m=g.2O(t);7(m){12=m[1].2E();Q(L i=0;d[i];i++)Q(L c=d[i].1C;c;c=c.2B)7(c.15==1&&(12=="*"||c.12.2E()==12))r.1g(c);d=r;t=t.1r(g,"");7(t.1f(" ")==0)6w;o=P}N{g=/^([>+~])\\s*(\\w*)/i;7((m=g.2O(t))!=V){r=[];L l={};12=m[2].2E();m=m[1];Q(L j=0,3f=d.M;j<3f;j++){L n=m=="~"||m=="+"?d[j].2B:d[j].1C;Q(;n;n=n.2B)7(n.15==1){L h=E.O(n);7(m=="~"&&l[h])1Q;7(!12||n.12.2E()==12){7(m=="~")l[h]=P;r.1g(n)}7(m=="+")1Q}}d=r;t=E.3g(t.1r(g,""));o=P}}7(t&&!o){7(!t.1f(",")){7(p==d[0])d.4l();2r=E.37(2r,d);r=d=[p];t=" "+t.6e(1,t.M)}N{L k=6u;L m=k.2O(t);7(m){m=[0,m[2],m[3],m[1]]}N{k=6s;m=k.2O(t)}m[2]=m[2].1r(/\\\\/g,"");L f=d[d.M-1];7(m[1]=="#"&&f&&f.5J&&!E.3E(f)){L q=f.5J(m[2]);7((E.14.1d||E.14.2z)&&q&&1o q.2w=="25"&&q.2w!=m[2])q=E(\'[@2w="\'+m[2]+\'"]\',f)[0];d=r=q&&(!m[3]||E.12(q,m[3]))?[q]:[]}N{Q(L i=0;d[i];i++){L a=m[1]=="#"&&m[3]?m[3]:m[1]!=""||m[0]==""?"*":m[2];7(a=="*"&&d[i].12.2h()=="3V")a="3m";r=E.37(r,d[i].3S(a))}7(m[1]==".")r=E.55(r,m[2]);7(m[1]=="#"){L e=[];Q(L i=0;r[i];i++)7(r[i].4z("2w")==m[2]){e=[r[i]];1Q}r=e}d=r}t=t.1r(k,"")}}7(t){L b=E.1E(t,r);d=r=b.r;t=E.3g(b.t)}}7(t)d=[];7(d&&p==d[0])d.4l();2r=E.37(2r,d);K 2r},55:J(r,m,a){m=" "+m+" ";L c=[];Q(L i=0;r[i];i++){L b=(" "+r[i].1t+" ").1f(m)>=0;7(!a&&b||a&&!b)c.1g(r[i])}K c},1E:J(t,r,h){L d;2b(t&&t!=d){d=t;L p=E.6g,m;Q(L i=0;p[i];i++){m=p[i].2O(t);7(m){t=t.7V(m[0].M);m[2]=m[2].1r(/\\\\/g,"");1Q}}7(!m)1Q;7(m[1]==":"&&m[2]=="56")r=G.17(m[3])?E.1E(m[3],r,P).r:E(r).56(m[3]);N 7(m[1]==".")r=E.55(r,m[2],h);N 7(m[1]=="["){L g=[],U=m[3];Q(L i=0,3f=r.M;i<3f;i++){L a=r[i],z=a[E.46[m[2]]||m[2]];7(z==V||/6O|3Q|2p/.17(m[2]))z=E.1J(a,m[2])||\'\';7((U==""&&!!z||U=="="&&z==m[5]||U=="!="&&z!=m[5]||U=="^="&&z&&!z.1f(m[5])||U=="$="&&z.6e(z.M-m[5].M)==m[5]||(U=="*="||U=="~=")&&z.1f(m[5])>=0)^h)g.1g(a)}r=g}N 7(m[1]==":"&&m[2]=="2Z-4p"){L e={},g=[],17=/(-?)(\\d*)n((?:\\+|-)?\\d*)/.2O(m[3]=="6n"&&"2n"||m[3]=="6l"&&"2n+1"||!/\\D/.17(m[3])&&"7U+"+m[3]||m[3]),3j=(17[1]+(17[2]||1))-0,d=17[3]-0;Q(L i=0,3f=r.M;i<3f;i++){L j=r[i],1a=j.1a,2w=E.O(1a);7(!e[2w]){L c=1;Q(L n=1a.1C;n;n=n.2B)7(n.15==1)n.4k=c++;e[2w]=P}L b=S;7(3j==0){7(j.4k==d)b=P}N 7((j.4k-d)%3j==0&&(j.4k-d)/3j>=0)b=P;7(b^h)g.1g(j)}r=g}N{L f=E.6r[m[1]];7(1o f=="3V")f=f[m[2]];7(1o f=="25")f=6c("S||J(a,i){K "+f+";}");r=E.3y(r,J(a,i){K f(a,i,m,r)},h)}}K{r:r,t:t}},4u:J(b,c){L d=[];L a=b[c];2b(a&&a!=T){7(a.15==1)d.1g(a);a=a[c]}K d},2Z:J(a,e,c,b){e=e||1;L d=0;Q(;a;a=a[c])7(a.15==1&&++d==e)1Q;K a},5i:J(n,a){L r=[];Q(;n;n=n.2B){7(n.15==1&&(!a||n!=a))r.1g(n)}K r}});E.16={1b:J(f,i,g,e){7(f.15==3||f.15==8)K;7(E.14.1d&&f.53!=10)f=1e;7(!g.2D)g.2D=6.2D++;7(e!=10){L h=g;g=J(){K h.1i(6,18)};g.O=e;g.2D=h.2D}L j=E.O(f,"2R")||E.O(f,"2R",{}),1v=E.O(f,"1v")||E.O(f,"1v",J(){L a;7(1o E=="10"||E.16.5f)K a;a=E.16.1v.1i(18.3R.Y,18);K a});1v.Y=f;E.R(i.23(/\\s+/),J(c,b){L a=b.23(".");b=a[0];g.U=a[1];L d=j[b];7(!d){d=j[b]={};7(!E.16.2y[b]||E.16.2y[b].4j.1P(f)===S){7(f.3F)f.3F(b,1v,S);N 7(f.6b)f.6b("4i"+b,1v)}}d[g.2D]=g;E.16.2a[b]=P});f=V},2D:1,2a:{},1V:J(e,h,f){7(e.15==3||e.15==8)K;L i=E.O(e,"2R"),29,4X;7(i){7(h==10||(1o h=="25"&&h.7T(0)=="."))Q(L g 1p i)6.1V(e,g+(h||""));N{7(h.U){f=h.2q;h=h.U}E.R(h.23(/\\s+/),J(b,a){L c=a.23(".");a=c[0];7(i[a]){7(f)2V i[a][f.2D];N Q(f 1p i[a])7(!c[1]||i[a][f].U==c[1])2V i[a][f];Q(29 1p i[a])1Q;7(!29){7(!E.16.2y[a]||E.16.2y[a].4h.1P(e)===S){7(e.67)e.67(a,E.O(e,"1v"),S);N 7(e.66)e.66("4i"+a,E.O(e,"1v"))}29=V;2V i[a]}}})}Q(29 1p i)1Q;7(!29){L d=E.O(e,"1v");7(d)d.Y=V;E.35(e,"2R");E.35(e,"1v")}}},1N:J(g,c,d,f,h){c=E.2I(c||[]);7(g.1f("!")>=0){g=g.2K(0,-1);L a=P}7(!d){7(6.2a[g])E("*").1b([1e,T]).1N(g,c)}N{7(d.15==3||d.15==8)K 10;L b,29,1n=E.1q(d[g]||V),16=!c[0]||!c[0].36;7(16)c.4J(6.4Z({U:g,2L:d}));c[0].U=g;7(a)c[0].65=P;7(E.1q(E.O(d,"1v")))b=E.O(d,"1v").1i(d,c);7(!1n&&d["4i"+g]&&d["4i"+g].1i(d,c)===S)b=S;7(16)c.4l();7(h&&E.1q(h)){29=h.1i(d,b==V?c:c.71(b));7(29!==10)b=29}7(1n&&f!==S&&b!==S&&!(E.12(d,\'a\')&&g=="4V")){6.5f=P;1S{d[g]()}1X(e){}}6.5f=S}K b},1v:J(c){L a;c=E.16.4Z(c||1e.16||{});L b=c.U.23(".");c.U=b[0];L f=E.O(6,"2R")&&E.O(6,"2R")[c.U],42=1M.2l.2K.1P(18,1);42.4J(c);Q(L j 1p f){L d=f[j];42[0].2q=d;42[0].O=d.O;7(!b[1]&&!c.65||d.U==b[1]){L e=d.1i(6,42);7(a!==S)a=e;7(e===S){c.36();c.44()}}}7(E.14.1d)c.2L=c.36=c.44=c.2q=c.O=V;K a},4Z:J(c){L a=c;c=E.1s({},a);c.36=J(){7(a.36)a.36();a.7S=S};c.44=J(){7(a.44)a.44();a.7R=P};7(!c.2L)c.2L=c.7Q||T;7(c.2L.15==3)c.2L=a.2L.1a;7(!c.4S&&c.5w)c.4S=c.5w==c.2L?c.7P:c.5w;7(c.64==V&&c.63!=V){L b=T.1F,1h=T.1h;c.64=c.63+(b&&b.2v||1h&&1h.2v||0)-(b.62||0);c.7N=c.7L+(b&&b.2x||1h&&1h.2x||0)-(b.60||0)}7(!c.3c&&((c.4f||c.4f===0)?c.4f:c.5Z))c.3c=c.4f||c.5Z;7(!c.7b&&c.5Y)c.7b=c.5Y;7(!c.3c&&c.2G)c.3c=(c.2G&1?1:(c.2G&2?3:(c.2G&4?2:0)));K c},2y:{21:{4j:J(){5M();K},4h:J(){K}},3C:{4j:J(){7(E.14.1d)K S;E(6).2j("4P",E.16.2y.3C.2q);K P},4h:J(){7(E.14.1d)K S;E(6).3w("4P",E.16.2y.3C.2q);K P},2q:J(a){7(I(a,6))K P;18[0].U="3C";K E.16.1v.1i(6,18)}},3B:{4j:J(){7(E.14.1d)K S;E(6).2j("4O",E.16.2y.3B.2q);K P},4h:J(){7(E.14.1d)K S;E(6).3w("4O",E.16.2y.3B.2q);K P},2q:J(a){7(I(a,6))K P;18[0].U="3B";K E.16.1v.1i(6,18)}}}};E.1n.1s({2j:J(c,a,b){K c=="4H"?6.2X(c,a,b):6.R(J(){E.16.1b(6,c,b||a,b&&a)})},2X:J(d,b,c){K 6.R(J(){E.16.1b(6,d,J(a){E(6).3w(a);K(c||b).1i(6,18)},c&&b)})},3w:J(a,b){K 6.R(J(){E.16.1V(6,a,b)})},1N:J(c,a,b){K 6.R(J(){E.16.1N(c,a,6,P,b)})},5n:J(c,a,b){7(6[0])K E.16.1N(c,a,6[0],S,b);K 10},2g:J(){L b=18;K 6.4V(J(a){6.4N=0==6.4N?1:0;a.36();K b[6.4N].1i(6,18)||S})},7D:J(a,b){K 6.2j(\'3C\',a).2j(\'3B\',b)},21:J(a){5M();7(E.2Q)a.1P(T,E);N E.3A.1g(J(){K a.1P(6,E)});K 6}});E.1s({2Q:S,3A:[],21:J(){7(!E.2Q){E.2Q=P;7(E.3A){E.R(E.3A,J(){6.1i(T)});E.3A=V}E(T).5n("21")}}});L x=S;J 5M(){7(x)K;x=P;7(T.3F&&!E.14.2z)T.3F("5W",E.21,S);7(E.14.1d&&1e==3b)(J(){7(E.2Q)K;1S{T.1F.7B("26")}1X(3a){3z(18.3R,0);K}E.21()})();7(E.14.2z)T.3F("5W",J(){7(E.2Q)K;Q(L i=0;i<T.4L.M;i++)7(T.4L[i].2Y){3z(18.3R,0);K}E.21()},S);7(E.14.2d){L a;(J(){7(E.2Q)K;7(T.39!="5V"&&T.39!="1y"){3z(18.3R,0);K}7(a===10)a=E("W, 7a[7A=7z]").M;7(T.4L.M!=a){3z(18.3R,0);K}E.21()})()}E.16.1b(1e,"3U",E.21)}E.R(("7y,7x,3U,7w,5d,4H,4V,7v,"+"7G,7u,7t,4P,4O,7s,2k,"+"58,7K,7q,7p,3a").23(","),J(i,b){E.1n[b]=J(a){K a?6.2j(b,a):6.1N(b)}});L I=J(a,c){L b=a.4S;2b(b&&b!=c)1S{b=b.1a}1X(3a){b=c}K b==c};E(1e).2j("4H",J(){E("*").1b(T).3w()});E.1n.1s({3U:J(g,d,c){7(E.1q(g))K 6.2j("3U",g);L e=g.1f(" ");7(e>=0){L i=g.2K(e,g.M);g=g.2K(0,e)}c=c||J(){};L f="4Q";7(d)7(E.1q(d)){c=d;d=V}N{d=E.3m(d);f="61"}L h=6;E.3P({1c:g,U:f,1H:"3q",O:d,1y:J(a,b){7(b=="1W"||b=="5U")h.3q(i?E("<1x/>").3t(a.4b.1r(/<1m(.|\\s)*?\\/1m>/g,"")).2s(i):a.4b);h.R(c,[a.4b,b,a])}});K 6},7n:J(){K E.3m(6.5T())},5T:J(){K 6.2c(J(){K E.12(6,"3u")?E.2I(6.7m):6}).1E(J(){K 6.31&&!6.2Y&&(6.3k||/2k|6h/i.17(6.12)||/1u|1Z|3I/i.17(6.U))}).2c(J(i,c){L b=E(6).5O();K b==V?V:b.1k==1M?E.2c(b,J(a,i){K{31:c.31,1A:a}}):{31:c.31,1A:b}}).22()}});E.R("5S,6d,5R,6D,5Q,6m".23(","),J(i,o){E.1n[o]=J(f){K 6.2j(o,f)}});L B=(1B 3v).3L();E.1s({22:J(d,b,a,c){7(E.1q(b)){a=b;b=V}K E.3P({U:"4Q",1c:d,O:b,1W:a,1H:c})},7l:J(b,a){K E.22(b,V,a,"1m")},7k:J(c,b,a){K E.22(c,b,a,"3i")},7i:J(d,b,a,c){7(E.1q(b)){a=b;b={}}K E.3P({U:"61",1c:d,O:b,1W:a,1H:c})},85:J(a){E.1s(E.4I,a)},4I:{2a:P,U:"4Q",2U:0,5P:"4o/x-7h-3u-7g",5N:P,3l:P,O:V,6p:V,3I:V,49:{3M:"4o/3M, 1u/3M",3q:"1u/3q",1m:"1u/4m, 4o/4m",3i:"4o/3i, 1u/4m",1u:"1u/a7",4G:"*/*"}},4F:{},3P:J(s){L f,2W=/=\\?(&|$)/g,1z,O;s=E.1s(P,s,E.1s(P,{},E.4I,s));7(s.O&&s.5N&&1o s.O!="25")s.O=E.3m(s.O);7(s.1H=="4E"){7(s.U.2h()=="22"){7(!s.1c.1D(2W))s.1c+=(s.1c.1D(/\\?/)?"&":"?")+(s.4E||"7d")+"=?"}N 7(!s.O||!s.O.1D(2W))s.O=(s.O?s.O+"&":"")+(s.4E||"7d")+"=?";s.1H="3i"}7(s.1H=="3i"&&(s.O&&s.O.1D(2W)||s.1c.1D(2W))){f="4E"+B++;7(s.O)s.O=(s.O+"").1r(2W,"="+f+"$1");s.1c=s.1c.1r(2W,"="+f+"$1");s.1H="1m";1e[f]=J(a){O=a;1W();1y();1e[f]=10;1S{2V 1e[f]}1X(e){}7(h)h.34(g)}}7(s.1H=="1m"&&s.1T==V)s.1T=S;7(s.1T===S&&s.U.2h()=="22"){L i=(1B 3v()).3L();L j=s.1c.1r(/(\\?|&)4r=.*?(&|$)/,"$a4="+i+"$2");s.1c=j+((j==s.1c)?(s.1c.1D(/\\?/)?"&":"?")+"4r="+i:"")}7(s.O&&s.U.2h()=="22"){s.1c+=(s.1c.1D(/\\?/)?"&":"?")+s.O;s.O=V}7(s.2a&&!E.5H++)E.16.1N("5S");7((!s.1c.1f("a3")||!s.1c.1f("//"))&&s.1H=="1m"&&s.U.2h()=="22"){L h=T.3S("6f")[0];L g=T.3s("1m");g.3Q=s.1c;7(s.7c)g.a2=s.7c;7(!f){L l=S;g.9Z=g.9Y=J(){7(!l&&(!6.39||6.39=="5V"||6.39=="1y")){l=P;1W();1y();h.34(g)}}}h.38(g);K 10}L m=S;L k=1e.78?1B 78("9X.9V"):1B 76();k.9T(s.U,s.1c,s.3l,s.6p,s.3I);1S{7(s.O)k.4C("9R-9Q",s.5P);7(s.5C)k.4C("9O-5A-9N",E.4F[s.1c]||"9L, 9K 9I 9H 5z:5z:5z 9F");k.4C("X-9C-9A","76");k.4C("9z",s.1H&&s.49[s.1H]?s.49[s.1H]+", */*":s.49.4G)}1X(e){}7(s.6Y)s.6Y(k);7(s.2a)E.16.1N("6m",[k,s]);L c=J(a){7(!m&&k&&(k.39==4||a=="2U")){m=P;7(d){6I(d);d=V}1z=a=="2U"&&"2U"||!E.6X(k)&&"3a"||s.5C&&E.6J(k,s.1c)&&"5U"||"1W";7(1z=="1W"){1S{O=E.6W(k,s.1H)}1X(e){1z="5x"}}7(1z=="1W"){L b;1S{b=k.5q("6U-5A")}1X(e){}7(s.5C&&b)E.4F[s.1c]=b;7(!f)1W()}N E.5v(s,k,1z);1y();7(s.3l)k=V}};7(s.3l){L d=53(c,13);7(s.2U>0)3z(J(){7(k){k.9t();7(!m)c("2U")}},s.2U)}1S{k.9s(s.O)}1X(e){E.5v(s,k,V,e)}7(!s.3l)c();J 1W(){7(s.1W)s.1W(O,1z);7(s.2a)E.16.1N("5Q",[k,s])}J 1y(){7(s.1y)s.1y(k,1z);7(s.2a)E.16.1N("5R",[k,s]);7(s.2a&&!--E.5H)E.16.1N("6d")}K k},5v:J(s,a,b,e){7(s.3a)s.3a(a,b,e);7(s.2a)E.16.1N("6D",[a,s,e])},5H:0,6X:J(r){1S{K!r.1z&&9q.9p=="59:"||(r.1z>=6T&&r.1z<9n)||r.1z==6R||r.1z==9l||E.14.2d&&r.1z==10}1X(e){}K S},6J:J(a,c){1S{L b=a.5q("6U-5A");K a.1z==6R||b==E.4F[c]||E.14.2d&&a.1z==10}1X(e){}K S},6W:J(r,b){L c=r.5q("9k-U");L d=b=="3M"||!b&&c&&c.1f("3M")>=0;L a=d?r.9j:r.4b;7(d&&a.1F.28=="5x")6Q"5x";7(b=="1m")E.5g(a);7(b=="3i")a=6c("("+a+")");K a},3m:J(a){L s=[];7(a.1k==1M||a.5h)E.R(a,J(){s.1g(3r(6.31)+"="+3r(6.1A))});N Q(L j 1p a)7(a[j]&&a[j].1k==1M)E.R(a[j],J(){s.1g(3r(j)+"="+3r(6))});N s.1g(3r(j)+"="+3r(a[j]));K s.6a("&").1r(/%20/g,"+")}});E.1n.1s({1G:J(c,b){K c?6.2e({1R:"1G",27:"1G",1w:"1G"},c,b):6.1E(":1Z").R(J(){6.W.19=6.5s||"";7(E.1j(6,"19")=="2H"){L a=E("<"+6.28+" />").6y("1h");6.W.19=a.1j("19");7(6.W.19=="2H")6.W.19="3D";a.1V()}}).3h()},1I:J(b,a){K b?6.2e({1R:"1I",27:"1I",1w:"1I"},b,a):6.1E(":4d").R(J(){6.5s=6.5s||E.1j(6,"19");6.W.19="2H"}).3h()},6N:E.1n.2g,2g:J(a,b){K E.1q(a)&&E.1q(b)?6.6N(a,b):a?6.2e({1R:"2g",27:"2g",1w:"2g"},a,b):6.R(J(){E(6)[E(6).3H(":1Z")?"1G":"1I"]()})},9f:J(b,a){K 6.2e({1R:"1G"},b,a)},9d:J(b,a){K 6.2e({1R:"1I"},b,a)},9c:J(b,a){K 6.2e({1R:"2g"},b,a)},9a:J(b,a){K 6.2e({1w:"1G"},b,a)},99:J(b,a){K 6.2e({1w:"1I"},b,a)},97:J(c,a,b){K 6.2e({1w:a},c,b)},2e:J(l,k,j,h){L i=E.6P(k,j,h);K 6[i.2P===S?"R":"2P"](J(){7(6.15!=1)K S;L g=E.1s({},i);L f=E(6).3H(":1Z"),4A=6;Q(L p 1p l){7(l[p]=="1I"&&f||l[p]=="1G"&&!f)K E.1q(g.1y)&&g.1y.1i(6);7(p=="1R"||p=="27"){g.19=E.1j(6,"19");g.32=6.W.32}}7(g.32!=V)6.W.32="1Z";g.40=E.1s({},l);E.R(l,J(c,a){L e=1B E.2t(4A,g,c);7(/2g|1G|1I/.17(a))e[a=="2g"?f?"1G":"1I":a](l);N{L b=a.3X().1D(/^([+-]=)?([\\d+-.]+)(.*)$/),1Y=e.2m(P)||0;7(b){L d=2M(b[2]),2A=b[3]||"2S";7(2A!="2S"){4A.W[c]=(d||1)+2A;1Y=((d||1)/e.2m(P))*1Y;4A.W[c]=1Y+2A}7(b[1])d=((b[1]=="-="?-1:1)*d)+1Y;e.45(1Y,d,2A)}N e.45(1Y,a,"")}});K P})},2P:J(a,b){7(E.1q(a)||(a&&a.1k==1M)){b=a;a="2t"}7(!a||(1o a=="25"&&!b))K A(6[0],a);K 6.R(J(){7(b.1k==1M)A(6,a,b);N{A(6,a).1g(b);7(A(6,a).M==1)b.1i(6)}})},94:J(b,c){L a=E.3G;7(b)6.2P([]);6.R(J(){Q(L i=a.M-1;i>=0;i--)7(a[i].Y==6){7(c)a[i](P);a.72(i,1)}});7(!c)6.5p();K 6}});L A=J(b,c,a){7(!b)K 10;c=c||"2t";L q=E.O(b,c+"2P");7(!q||a)q=E.O(b,c+"2P",a?E.2I(a):[]);K q};E.1n.5p=J(a){a=a||"2t";K 6.R(J(){L q=A(6,a);q.4l();7(q.M)q[0].1i(6)})};E.1s({6P:J(b,a,c){L d=b&&b.1k==92?b:{1y:c||!c&&a||E.1q(b)&&b,2u:b,3Z:c&&a||a&&a.1k!=91&&a};d.2u=(d.2u&&d.2u.1k==51?d.2u:{90:8Z,9D:6T}[d.2u])||8X;d.5y=d.1y;d.1y=J(){7(d.2P!==S)E(6).5p();7(E.1q(d.5y))d.5y.1i(6)};K d},3Z:{70:J(p,n,b,a){K b+a*p},5j:J(p,n,b,a){K((-24.8V(p*24.8U)/2)+0.5)*a+b}},3G:[],3W:V,2t:J(b,c,a){6.11=c;6.Y=b;6.1l=a;7(!c.47)c.47={}}});E.2t.2l={4y:J(){7(6.11.30)6.11.30.1i(6.Y,[6.2J,6]);(E.2t.30[6.1l]||E.2t.30.4G)(6);7(6.1l=="1R"||6.1l=="27")6.Y.W.19="3D"},2m:J(a){7(6.Y[6.1l]!=V&&6.Y.W[6.1l]==V)K 6.Y[6.1l];L r=2M(E.1j(6.Y,6.1l,a));K r&&r>-8Q?r:2M(E.2o(6.Y,6.1l))||0},45:J(c,b,d){6.5B=(1B 3v()).3L();6.1Y=c;6.3h=b;6.2A=d||6.2A||"2S";6.2J=6.1Y;6.4B=6.4w=0;6.4y();L e=6;J t(a){K e.30(a)}t.Y=6.Y;E.3G.1g(t);7(E.3W==V){E.3W=53(J(){L a=E.3G;Q(L i=0;i<a.M;i++)7(!a[i]())a.72(i--,1);7(!a.M){6I(E.3W);E.3W=V}},13)}},1G:J(){6.11.47[6.1l]=E.1J(6.Y.W,6.1l);6.11.1G=P;6.45(0,6.2m());7(6.1l=="27"||6.1l=="1R")6.Y.W[6.1l]="8N";E(6.Y).1G()},1I:J(){6.11.47[6.1l]=E.1J(6.Y.W,6.1l);6.11.1I=P;6.45(6.2m(),0)},30:J(a){L t=(1B 3v()).3L();7(a||t>6.11.2u+6.5B){6.2J=6.3h;6.4B=6.4w=1;6.4y();6.11.40[6.1l]=P;L b=P;Q(L i 1p 6.11.40)7(6.11.40[i]!==P)b=S;7(b){7(6.11.19!=V){6.Y.W.32=6.11.32;6.Y.W.19=6.11.19;7(E.1j(6.Y,"19")=="2H")6.Y.W.19="3D"}7(6.11.1I)6.Y.W.19="2H";7(6.11.1I||6.11.1G)Q(L p 1p 6.11.40)E.1J(6.Y.W,p,6.11.47[p])}7(b&&E.1q(6.11.1y))6.11.1y.1i(6.Y);K S}N{L n=t-6.5B;6.4w=n/6.11.2u;6.4B=E.3Z[6.11.3Z||(E.3Z.5j?"5j":"70")](6.4w,n,0,1,6.11.2u);6.2J=6.1Y+((6.3h-6.1Y)*6.4B);6.4y()}K P}};E.2t.30={2v:J(a){a.Y.2v=a.2J},2x:J(a){a.Y.2x=a.2J},1w:J(a){E.1J(a.Y.W,"1w",a.2J)},4G:J(a){a.Y.W[a.1l]=a.2J+a.2A}};E.1n.5L=J(){L b=0,3b=0,Y=6[0],5l;7(Y)8M(E.14){L d=Y.1a,41=Y,1K=Y.1K,1L=Y.2i,5D=2d&&4s(5K)<8J&&!/a1/i.17(v),2T=E.1j(Y,"43")=="2T";7(Y.6G){L c=Y.6G();1b(c.26+24.2f(1L.1F.2v,1L.1h.2v),c.3b+24.2f(1L.1F.2x,1L.1h.2x));1b(-1L.1F.62,-1L.1F.60)}N{1b(Y.5G,Y.5F);2b(1K){1b(1K.5G,1K.5F);7(48&&!/^t(8H|d|h)$/i.17(1K.28)||2d&&!5D)2N(1K);7(!2T&&E.1j(1K,"43")=="2T")2T=P;41=/^1h$/i.17(1K.28)?41:1K;1K=1K.1K}2b(d&&d.28&&!/^1h|3q$/i.17(d.28)){7(!/^8G|1O.*$/i.17(E.1j(d,"19")))1b(-d.2v,-d.2x);7(48&&E.1j(d,"32")!="4d")2N(d);d=d.1a}7((5D&&(2T||E.1j(41,"43")=="4W"))||(48&&E.1j(41,"43")!="4W"))1b(-1L.1h.5G,-1L.1h.5F);7(2T)1b(24.2f(1L.1F.2v,1L.1h.2v),24.2f(1L.1F.2x,1L.1h.2x))}5l={3b:3b,26:b}}J 2N(a){1b(E.2o(a,"a8",P),E.2o(a,"a9",P))}J 1b(l,t){b+=4s(l)||0;3b+=4s(t)||0}K 5l}})();',62,631,'||||||this|if||||||||||||||||||||||||||||||||||||||function|return|var|length|else|data|true|for|each|false|document|type|null|style||elem||undefined|options|nodeName||browser|nodeType|event|test|arguments|display|parentNode|add|url|msie|window|indexOf|push|body|apply|css|constructor|prop|script|fn|typeof|in|isFunction|replace|extend|className|text|handle|opacity|div|complete|status|value|new|firstChild|match|filter|documentElement|show|dataType|hide|attr|offsetParent|doc|Array|trigger|table|call|break|height|try|cache|tbody|remove|success|catch|start|hidden||ready|get|split|Math|string|left|width|tagName|ret|global|while|map|safari|animate|max|toggle|toLowerCase|ownerDocument|bind|select|prototype|cur||curCSS|selected|handler|done|find|fx|duration|scrollLeft|id|scrollTop|special|opera|unit|nextSibling|stack|guid|toUpperCase|pushStack|button|none|makeArray|now|slice|target|parseFloat|border|exec|queue|isReady|events|px|fixed|timeout|delete|jsre|one|disabled|nth|step|name|overflow|inArray|removeChild|removeData|preventDefault|merge|appendChild|readyState|error|top|which|innerHTML|multiFilter|rl|trim|end|json|first|checked|async|param|elems|insertBefore|childNodes|html|encodeURIComponent|createElement|append|form|Date|unbind|color|grep|setTimeout|readyList|mouseleave|mouseenter|block|isXMLDoc|addEventListener|timers|is|password|last|runtimeStyle|getTime|xml|jQuery|domManip|ajax|src|callee|getElementsByTagName|selectedIndex|load|object|timerId|toString|has|easing|curAnim|offsetChild|args|position|stopPropagation|custom|props|orig|mozilla|accepts|clean|responseText|defaultView|visible|String|charCode|float|teardown|on|setup|nodeIndex|shift|javascript|currentStyle|application|child|RegExp|_|parseInt|previousSibling|dir|tr|state|empty|update|getAttribute|self|pos|setRequestHeader|input|jsonp|lastModified|_default|unload|ajaxSettings|unshift|getComputedStyle|styleSheets|getPropertyValue|lastToggle|mouseout|mouseover|GET|andSelf|relatedTarget|init|visibility|click|absolute|index|container|fix|outline|Number|removeAttribute|setInterval|prevObject|classFilter|not|unique|submit|file|after|windowData|deep|scroll|client|triggered|globalEval|jquery|sibling|swing|clone|results|wrapAll|triggerHandler|lastChild|dequeue|getResponseHeader|createTextNode|oldblock|checkbox|radio|handleError|fromElement|parsererror|old|00|Modified|startTime|ifModified|safari2|getWH|offsetTop|offsetLeft|active|values|getElementById|version|offset|bindReady|processData|val|contentType|ajaxSuccess|ajaxComplete|ajaxStart|serializeArray|notmodified|loaded|DOMContentLoaded|Width|ctrlKey|keyCode|clientTop|POST|clientLeft|clientX|pageX|exclusive|detachEvent|removeEventListener|swap|cloneNode|join|attachEvent|eval|ajaxStop|substr|head|parse|textarea|reset|image|zoom|odd|ajaxSend|even|before|username|prepend|expr|quickClass|uuid|quickID|quickChild|continue|textContent|appendTo|contents|evalScript|parent|defaultValue|ajaxError|setArray|compatMode|getBoundingClientRect|styleFloat|clearInterval|httpNotModified|nodeValue|100|alpha|_toggle|href|speed|throw|304|replaceWith|200|Last|colgroup|httpData|httpSuccess|beforeSend|eq|linear|concat|splice|fieldset|multiple|cssFloat|XMLHttpRequest|webkit|ActiveXObject|CSS1Compat|link|metaKey|scriptCharset|callback|col|pixelLeft|urlencoded|www|post|hasClass|getJSON|getScript|elements|serialize|black|keyup|keypress|solid|change|mousemove|mouseup|dblclick|resize|focus|blur|stylesheet|rel|doScroll|round|hover|padding|offsetHeight|mousedown|offsetWidth|Bottom|Top|keydown|clientY|Right|pageY|Left|toElement|srcElement|cancelBubble|returnValue|charAt|0n|substring|animated|header|noConflict|line|enabled|innerText|contains|only|weight|ajaxSetup|font|size|gt|lt|uFFFF|u0128|417|Boolean|inner|Height|toggleClass|removeClass|addClass|removeAttr|replaceAll|insertAfter|prependTo|contentWindow|contentDocument|wrap|iframe|children|siblings|prevAll|nextAll|prev|wrapInner|next|parents|maxLength|maxlength|readOnly|readonly|reverse|class|htmlFor|inline|able|boxModel|522|setData|compatible|with|1px|ie|getData|10000|ra|it|rv|PI|cos|userAgent|400|navigator|600|slow|Function|Object|array|stop|ig|NaN|fadeTo|option|fadeOut|fadeIn|setAttribute|slideToggle|slideUp|changed|slideDown|be|can|property|responseXML|content|1223|getAttributeNode|300|method|protocol|location|action|send|abort|cssText|th|td|cap|specified|Accept|With|colg|Requested|fast|tfoot|GMT|thead|1970|Jan|attributes|01|Thu|leg|Since|If|opt|Type|Content|embed|open|area|XMLHTTP|hr|Microsoft|onreadystatechange|onload|meta|adobeair|charset|http|1_|img|br|plain|borderLeftWidth|borderTopWidth|abbr'.split('|'),0,{}));// $Id: drupal.js,v 1.38 2007/09/12 18:29:32 goba Exp $

var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} };

/**
 * Set the variable that indicates if JavaScript behaviors should be applied
 */
Drupal.jsEnabled = document.getElementsByTagName && document.createElement && document.createTextNode && document.documentElement && document.getElementById;

/**
 * Attach all registered behaviors to a page element.
 *
 * Behaviors are event-triggered actions that attach to page elements, enhancing
 * default non-Javascript UIs. Behaviors are registered in the Drupal.behaviors
 * object as follows:
 * @code
 *    Drupal.behaviors.behaviorName = function () {
 *      ...
 *    };
 * @endcode
 *
 * Drupal.attachBehaviors is added below to the jQuery ready event and so
 * runs on initial page load. Developers implementing AHAH/AJAX in their
 * solutions should also call this function after new page content has been
 * loaded, feeding in an element to be processed, in order to attach all
 * behaviors to the new content.
 *
 * Behaviors should use a class in the form behaviorName-processed to ensure
 * the behavior is attached only once to a given element. (Doing so enables
 * the reprocessing of given elements, which may be needed on occasion despite
 * the ability to limit behavior attachment to a particular element.)
 *
 * @param context
 *   An element to attach behaviors to. If none is given, the document element
 *   is used.
 */
Drupal.attachBehaviors = function(context) {
  context = context || document;
  if (Drupal.jsEnabled) {
    // Execute all of them.
    jQuery.each(Drupal.behaviors, function() {
      this(context);
    });
  }
};

/**
 * Encode special characters in a plain-text string for display as HTML.
 */
Drupal.checkPlain = function(str) {
  str = String(str);
  var replace = { '&': '&amp;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
  for (var character in replace) {
    var regex = new RegExp(character, 'g');
    str = str.replace(regex, replace[character]);
  }
  return str;
};

/**
 * Translate strings to the page language or a given language.
 *
 * See the documentation of the server-side t() function for further details.
 *
 * @param str
 *   A string containing the English string to translate.
 * @param args
 *   An object of replacements pairs to make after translation. Incidences
 *   of any key in this array are replaced with the corresponding value.
 *   Based on the first character of the key, the value is escaped and/or themed:
 *    - !variable: inserted as is
 *    - @variable: escape plain text to HTML (Drupal.checkPlain)
 *    - %variable: escape text and theme as a placeholder for user-submitted
 *      content (checkPlain + Drupal.theme('placeholder'))
 * @return
 *   The translated string.
 */
Drupal.t = function(str, args) {
  // Fetch the localized version of the string.
  if (Drupal.locale.strings && Drupal.locale.strings[str]) {
    str = Drupal.locale.strings[str];
  }

  if (args) {
    // Transform arguments before inserting them
    for (var key in args) {
      switch (key.charAt(0)) {
        // Escaped only
        case '@':
          args[key] = Drupal.checkPlain(args[key]);
        break;
        // Pass-through
        case '!':
          break;
        // Escaped and placeholder
        case '%':
        default:
          args[key] = Drupal.theme('placeholder', args[key]);
          break;
      }
      str = str.replace(key, args[key]);
    }
  }
  return str;
};

/**
 * Format a string containing a count of items.
 *
 * This function ensures that the string is pluralized correctly. Since Drupal.t() is
 * called by this function, make sure not to pass already-localized strings to it.
 *
 * See the documentation of the server-side format_plural() function for further details.
 *
 * @param count
 *   The item count to display.
 * @param singular
 *   The string for the singular case. Please make sure it is clear this is
 *   singular, to ease translation (e.g. use "1 new comment" instead of "1 new").
 *   Do not use @count in the singular string.
 * @param plural
 *   The string for the plural case. Please make sure it is clear this is plural,
 *   to ease translation. Use @count in place of the item count, as in "@count
 *   new comments".
 * @param args
 *   An object of replacements pairs to make after translation. Incidences
 *   of any key in this array are replaced with the corresponding value.
 *   Based on the first character of the key, the value is escaped and/or themed:
 *    - !variable: inserted as is
 *    - @variable: escape plain text to HTML (Drupal.checkPlain)
 *    - %variable: escape text and theme as a placeholder for user-submitted
 *      content (checkPlain + Drupal.theme('placeholder'))
 *   Note that you do not need to include @count in this array.
 *   This replacement is done automatically for the plural case.
 * @return
 *   A translated string.
 */
Drupal.formatPlural = function(count, singular, plural, args) {
  var args = args || {};
  args['@count'] = count;
  // Determine the index of the plural form.
  var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);

  if (index == 0) {
    return Drupal.t(singular, args);
  }
  else if (index == 1) {
    return Drupal.t(plural, args);
  }
  else {
    args['@count['+ index +']'] = args['@count'];
    delete args['@count'];
    return Drupal.t(plural.replace('@count', '@count['+ index +']'));
  }
};

/**
 * Generate the themed representation of a Drupal object.
 *
 * All requests for themed output must go through this function. It examines
 * the request and routes it to the appropriate theme function. If the current
 * theme does not provide an override function, the generic theme function is
 * called.
 *
 * For example, to retrieve the HTML that is output by theme_placeholder(text),
 * call Drupal.theme('placeholder', text).
 *
 * @param func
 *   The name of the theme function to call.
 * @param ...
 *   Additional arguments to pass along to the theme function.
 * @return
 *   Any data the theme function returns. This could be a plain HTML string,
 *   but also a complex object.
 */
Drupal.theme = function(func) {
  for (var i = 1, args = []; i < arguments.length; i++) {
    args.push(arguments[i]);
  }

  return (Drupal.theme[func] || Drupal.theme.prototype[func]).apply(this, args);
};

/**
 * Redirects a button's form submission to a hidden iframe and displays the result
 * in a given wrapper. The iframe should contain a call to
 * window.parent.iframeHandler() after submission.
 */
Drupal.redirectFormButton = function (uri, button, handler) {
  // Trap the button
  button.onmouseover = button.onfocus = function() {
    button.onclick = function() {
      // Create target iframe
      Drupal.deleteIframe();
      Drupal.createIframe();

      // Prepare variables for use in anonymous function.
      var button = this;
      var action = button.form.action;
      var target = button.form.target;

      // Redirect form submission to iframe
      this.form.action = uri;
      this.form.target = 'redirect-target';
      this.form.submit();

      handler.onsubmit();

      // Set iframe handler for later
      window.iframeHandler = function () {
        var iframe = $('#redirect-target').get(0);
        // Restore form submission
        button.form.action = action;
        button.form.target = target;

        // Get response from iframe body
        try {
          response = (iframe.contentWindow || iframe.contentDocument || iframe).document.body.innerHTML;
          // Firefox 1.0.x hack: Remove (corrupted) control characters
          response = response.replace(/[\f\n\r\t]/g, ' ');
          if (window.opera) {
            // Opera-hack: it returns innerHTML sanitized.
            response = response.replace(/&quot;/g, '"');
          }
        }
        catch (e) {
          response = null;
        }

        response = eval('('+ response +');');
        // Check response code
        if (!response || response.status == 0) {
          handler.onerror(response.data || Drupal.t('Error parsing response'));
          return;
        }
        handler.oncomplete(response.data);

        return true;
      };

      return true;
    };
  };
  button.onmouseout = button.onblur = function() {
    button.onclick = null;
  };
};

/**
 * Create an invisible iframe for form submissions.
 */
Drupal.createIframe = function () {
  if ($('#redirect-holder').size()) {
    return;
  }
  // Note: some browsers require the literal name/id attributes on the tag,
  // some want them set through JS. We do both.
  window.iframeHandler = function () {};
  var div = document.createElement('div');
  div.id = 'redirect-holder';
  $(div).html('<iframe name="redirect-target" id="redirect-target" class="redirect" onload="window.iframeHandler();"></iframe>');
  var iframe = div.firstChild;
  $(iframe)
    .attr({
      name: 'redirect-target',
      id: 'redirect-target'
    })
    .css({
      position: 'absolute',
      height: '1px',
      width: '1px',
      visibility: 'hidden'
    });
  $('body').append(div);
};

/**
 * Delete the invisible iframe
 */
Drupal.deleteIframe = function () {
  $('#redirect-holder').remove();
};

/**
 * Freeze the current body height (as minimum height). Used to prevent
 * unnecessary upwards scrolling when doing DOM manipulations.
 */
Drupal.freezeHeight = function () {
  Drupal.unfreezeHeight();
  var div = document.createElement('div');
  $(div).css({
    position: 'absolute',
    top: '0px',
    left: '0px',
    width: '1px',
    height: $('body').css('height')
  }).attr('id', 'freeze-height');
  $('body').append(div);
};

/**
 * Unfreeze the body height
 */
Drupal.unfreezeHeight = function () {
  $('#freeze-height').remove();
};

/**
 * Wrapper to address the mod_rewrite url encoding bug
 * (equivalent of drupal_urlencode() in PHP).
 */
Drupal.encodeURIComponent = function (item, uri) {
  uri = uri || location.href;
  item = encodeURIComponent(item).replace(/%2F/g, '/');
  return (uri.indexOf('?q=') != -1) ? item : item.replace(/%26/g, '%2526').replace(/%23/g, '%2523').replace(/\/\//g, '/%252F');
};

/**
 * Get the text selection in a textarea.
 */
Drupal.getSelection = function (element) {
  if (typeof(element.selectionStart) != 'number' && document.selection) {
    // The current selection
    var range1 = document.selection.createRange();
    var range2 = range1.duplicate();
    // Select all text.
    range2.moveToElementText(element);
    // Now move 'dummy' end point to end point of original range.
    range2.setEndPoint('EndToEnd', range1);
    // Now we can calculate start and end points.
    var start = range2.text.length - range1.text.length;
    var end = start + range1.text.length;
    return { 'start': start, 'end': end };
  }
  return { 'start': element.selectionStart, 'end': element.selectionEnd };
};

// Global Killswitch on the <html> element
if (Drupal.jsEnabled) {
  // Global Killswitch on the <html> element
  $(document.documentElement).addClass('js');
  // 'js enabled' cookie
  document.cookie = 'has_js=1';
  // Attach all behaviors.
  $(document).ready(function() {
    Drupal.attachBehaviors(this);
  });
}

/**
 * The default themes.
 */
Drupal.theme.prototype = {

  /**
   * Formats text for emphasized display in a placeholder inside a sentence.
   *
   * @param str
   *   The text to format (plain-text).
   * @return
   *   The formatted text (html).
   */
  placeholder: function(str) {
    return '<em>' + Drupal.checkPlain(str) + '</em>';
  }
};
;function sproutReportsInit() {
    if (!$('#reports').length)
        return;
    if ($.datepicker) {
        $('#edit-from').datepicker({dateFormat: 'yy-mm-dd', defaultDate: -7, mandatory: true, maxDate: new Date});
        $('#edit-to').datepicker({dateFormat: 'yy-mm-dd', mandatory: true, maxDate: new Date});
    }
}

$(document).ready(function() {
  sproutReportsInit();
});

function reportsOnSubmit(uri, form) {
  if ($("#edit-search").length && $("#edit-search").get(0).value.length)
    uri = uri + (uri.match(/\?/) ? '&' : '?') + 'search=' + escape($("#edit-search").get(0).value);  
  if ($("#edit-from-date").length && $("#edit-from-date").get(0).value.length)
    uri = uri + (uri.match(/\?/) ? '&' : '?') + 'from_date=' + escape($("#edit-from-date").get(0).value);
  if ($("#edit-to-date").length && $("#edit-to-date").get(0).value.length)
    uri = uri + (uri.match(/\?/) ? '&' : '?') + 'to_date=' + escape($("#edit-to-date").get(0).value);
  document.location.href = uri;
  return false;
}

var sproutCharts = ['widget_views', 'interface_load', 'post_to_profile', 'social_network', 'custom_events'];
//sproutCharts = ['custom_events'];

var sproutChartsService = '/sprout/reports/fetch';

var sproutChartAttrs = {
    widget_views: {
        type: 'Column2D',
        width: 400
    },
    interface_load: {
        type: 'Column2D',
        width: 400
    },
    post_to_profile: {
        type: 'Column2D',
        width: 400
    },
    social_network: {
        type: 'Pie3D',
        width: 400
    },
    custom_events: {
        type: 'MSColumn2D',
        width: 800
    }
};

Drupal.behaviors.sprout_reports_lightbox = function (context) {
    if (!$('#reports').length)
        return;
    sproutReportsInit();
    $('#edit-refresh').bind('click', function(){
        showCharts();
        return false;
    });
    $('#edit-export').bind('click', function(){
        $(this.form).attr('action', sproutChartsService + '?' + buildQuery());
        return true;
    });
    if ($('#edit-widgets').length) {
        createCharts();
        showCharts();
    }
};

function createCharts() {
    $('#reports').empty();
    for (var i=0; i < sproutCharts.length; i++) {
        $('#reports').append('<div class="report" id="reports-'+sproutCharts[i]+'"></div>');
    }
    $('#reports').append('<div class="reports-error" style="display:none"><div class="reports-message"></div></div>');

    $('#reports').append('<div class="reports-wait">'
                         + '<div class="reports-message">Loading report data - this could take a minute.<br />'
                         + '<img src="/sites/all/modules/sprout/images/loadingAnimation.gif" />'
                         +'</div></div>');
}

function buildQuery() {
    var query = [];
    var cid;
    if ($('#edit-widgets').is('select')) {
        cid = $('#edit-widgets').get(0).options[$('#edit-widgets').get(0).selectedIndex].value;
    }
    else {
        cid = $('#edit-widgets').get(0).value;
    }
    return 'cid=' + cid;
}

function showCharts() {
    $('#reports .reports-wait').show();
    $('#reports .reports-error').hide();
    var ctype = $('#edit-chart-type').get(0).options[$('#edit-chart-type').get(0).selectedIndex].value;

    var showLine = false;
    if (ctype == 'Line')
        showLine = true;
    
    // prefetch a report to get the gigya data in the proxy cache
    // when this query returns, it means that the data is cached and
    // we can request the actual reports - this prevents us doing 5 identical
    // hits on gigya's reports service.
    $.ajax({
        url: makeDataUrl('widget_views', buildQuery()),
        type: 'GET',
        dataType: 'xml',
        timeout: 600000,
        error: function(){
            $('#reports .reports-error .reports-message').text('An error occurred contacting the server, please try again later.')
            $('#reports .reports-error').show();
            $('#reports .reports-wait').hide();
        },
        success: function(xml){
            if ($(xml.documentElement).attr('stat') == 'fail') {
                $('#reports .reports-error .reports-message').text(
                    'An error occurred loading the report data.  You may want to try selecting a narrower date range, or try your query again later.'
                    )
                $('#reports .reports-error').show();
            }
            else {
                for (var i=0; i < sproutCharts.length; i++) {
                    showChart(sproutCharts[i], buildQuery(), showLine);
                }
            }
            $('#reports .reports-wait').hide();
        }
    });
}

function makeDataUrl(chartId, query) {
    var from = $('#edit-from').attr('value');
    var to = $('#edit-to').attr('value');    
    return sproutChartsService + '?report='
            +chartId+'&'+query+'&from='+from+'&to='+to;
}

function showChart(chartId, query, showLine) {
    var chartAttrs = sproutChartAttrs[chartId];
    var type = chartAttrs['type'];
    if (showLine) {
        type = type.replace(/Column/, 'Line');
        type = type.replace(/2D/, '');
    }

    $('#reports-' + chartId).empty().flash(
      {
        src: Drupal.settings.sprout_path + '/flash/charts/' + type + '.swf',
        width: chartAttrs['width'],
        height: '200',
        wmode : 'transparent',
        flashvars: {dataURL: makeDataUrl(chartId, query),
            chartWidth: chartAttrs['width'],
            chartHeight: 200
            }
      },
      {
        expressInstall: true
      }
    );
}

// prefetch reports SWFs into the browser cache
$(document).ready(function(){
    if ($.cookie('sprout_reports_prefetch') == null) {
        $.cookie('sprout_reports_prefetch', 1, {path: '/'});
        var swfs = [
          'MSColumn2D.swf',
          'Column2D.swf',
          'MSLine.swf',
          'Line.swf',
          'Pie3D.swf'
        ];
        var prefetch = '';
        for (var i=0; i<swfs.length;i++)
            prefetch = prefetch + '<embed flashVars="&dataXML=&lt;chart/&gt;" width="0" height="0" src="'+Drupal.settings.sprout_path+'/flash/charts/'+swfs[i]+'" />';
        $('body:first').append(prefetch);
    }
});

function reportsStartBuilding() {
    $("#dialog-close").click();
    window.setTimeout(function(){
        $("#header-button-new").mousedown();
    }, 300);
}

function reportsShowLightbox(cid) {
    if (typeof cid != 'undefined') {
        cid = '&cid=' + cid;
    }
    else {
        cid = '';
    }
    tb_show(null, '/reports?notheme=1&height=500&width=900&modal=true'+cid, false);
    return false;
};/**
 * base.js - common utilities and global behaviors
 */

Drupal.behaviors.sprout_global = function (context) {
  // Make FF select boxes fit their content by appending two non-breaking spaces to each option
  $('select.fit option:not(.fit-processed)').append('&nbsp;&nbsp;').addClass('fit-processed');
};

$(document).ready(function(){
  fixEolas();
});

if (typeof sproutDebug == 'undefined')
  var sproutDebug = false;
var sproutTrace;

var get_ = new Querystring();

if (sproutDebug) {
  sproutTrace = function () {
    if (typeof console != 'undefined' && typeof console.debug != 'undefined') {
      console.log.apply(console, arguments);
    }
  };
}
else {
  sproutTrace = function () {};
}

/**
 * Class to log JS errors to Drupal watchdog.
 */
function spUtilsClass() {

}
// Why wouldn't this work in the class?
var spUtilsStoredErrors = '';

spUtilsClass.prototype = {
  logError          : function (message) {
    message += "<br/>\nBrowser user agent: " + navigator.userAgent;
    $.post('/api/error', { msg: message });
    sproutTrace('ERROR', message);
  },

  storeError        : function (message) {
    spUtilsStoredErrors += message + "<br/>\n";
  },

  getStoredErrors   : function () {
    return spUtilsStoredErrors;
  },

  clearStoredErrors : function () {
    spUtilsStoredErrors = '';
  }
};

if (typeof spUtils == 'undefined') {
  var spUtils = new spUtilsClass();
}

// Cross browser clipboard copy. Firefox will use the flash _clipboard.swf application
var BodyLoaded = 0;
$(document).ready(function() {
  BodyLoaded = 1;
});

function copyToClipboard(inElement) {
  if (inElement.createTextRange) {
    var range = inElement.createTextRange();
    if (range && BodyLoaded==1)
     range.execCommand('Copy');
  } else {
    var flashcopier = 'flashcopier';
    if(!document.getElementById(flashcopier)) {
      var divholder = document.createElement('div');
      divholder.id = flashcopier;
      document.body.appendChild(divholder);
    }
    document.getElementById(flashcopier).innerHTML = '';
    var divinfo = '<embed src="/sites/all/modules/sprout/flash/_clipboard.swf" FlashVars="clipboard='+escape(inElement.value)+'" width="0" height="0" type="application/x-shockwave-flash"></embed>';
    document.getElementById(flashcopier).innerHTML = divinfo;
  }
  inElement.focus();
  inElement.select();
}

/**
 * Force a browser to redraw the window which helps if Flash tries to
 * shine through.
 */
function redrawWindow() {
  var $window = $('#TB_window');
  if ($window.css('margin-bottom') != '1px') {
    $window.css('margin-bottom', '1px');
  }
  else {
    $window.css('margin-bottom', '0');
  }
}

// Rewrite all object tags to avoid IE's active content lameness
// This should only hit objects loaded from the actual HTML source,
// it is not required for objects already loaded by JS
// http://activecontent.blogspot.com/#114553164480870609
function fixEolas() {
  if ($.browser.msie || $.browser.opera) {
    var theObjects = document.getElementsByTagName('object');
    var theObjectsLen = theObjects.length;
    for (var i = 0; i < theObjectsLen; i++) {
      if (theObjects[i].outerHTML) {
        if (theObjects[i].data) {
          theObjects[i].removeAttribute('data');
        }
        var theParams = theObjects[i].getElementsByTagName('param');
        var theParamsLength = theParams.length;
        for (var j = 0; j < theParamsLength; j++) {
          if (theParams[j].name.toLowerCase() == 'flashvars') {
            var theFlashVars = theParams[j].value;
          }
        }
        var theOuterHTML = theObjects[i].outerHTML;
        var re = /<param name="FlashVars" value="">/ig;
        theOuterHTML = theOuterHTML.replace(re, "<param name='FlashVars' value='" + theFlashVars + "'>");
        theObjects[i].outerHTML = theOuterHTML;
      }
    }

    window.onunload = function() {
      if (document.getElementsByTagName) {
        var objs = document.getElementsByTagName("object");
        for (i=0; i<objs.length; i++) {
          objs[i].outerHTML = "";
        }
      }
    };
  }
}

function tb_remove_builder() {
  tb_remove();
  if (typeof showBuilder != 'undefined')
    showBuilder();
}

function decodeSpecialChars(string) {
  string = string.replace(/&lt;/g, '<');
  string = string.replace(/&gt;/g, '>');
  string = string.replace(/&quot;/g, '"');
  string = string.replace(/&#039;/g, "'");
  string = string.replace(/&amp;/g, '&');
  return string;
}

function encodeSpecialChars(string) {
  string = string.replace(/&/g, '&amp;');
  string = string.replace(/</g, '&lt;');
  string = string.replace(/>/g, '&gt;');
  string = string.replace(/"/g, '&quot;');
  string = string.replace(/'/g, '&#039;');
  return string;
}

function Querystring(qs) { // optionally pass a querystring to parse
 this.params = new Object()
 this.get=Querystring_get

 if (qs == null)
  qs=location.search.substring(1,location.search.length)

 if (qs.length == 0) return

// Turn <plus> back to <space>
// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
 qs = qs.replace(/\+/g, ' ')
 var args = qs.split('&') // parse out name/value pairs separated via &

// split out each name=value pair
 for (var i=0;i<args.length;i++) {
  var value;
  var pair = args[i].split('=')
  var name = unescape(pair[0])

  if (pair.length == 2)
   value = unescape(pair[1])
  else
   value = name

  this.params[name] = value
 }
}

function Querystring_get(key, default_) {
 // This silly looking line changes UNDEFINED to NULL
 if (default_ == null) default_ = null;

 var value=this.params[key]
 if (value==null) value=default_;

 return value
};/* Copyright (c) 2006 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.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * $LastChangedDate: 2007-09-11 04:16:09 +0000 (Tue, 11 Sep 2007) $
 * $Rev: 3240 $
 *
 * Version: @VERSION
 * 
 * Requires: jQuery 1.2+
 */

(function($) {
	
var cache = [];
	
$.fn.extend({
	mousewheel: function(f) {
		f.guid = f.guid || $.event.guid++;
		
		return this.each( function() {
			var elem = this, handlers = $.data(elem, 'mwhandlers') || [];
			handlers.push(f);
			$.data(elem, 'mwhandlers', handlers);
			
			// Create handler
			!$.data(elem, 'mwhandler') && $.data(elem, 'mwhandler', function(event) {
				event = $.event.fix(event || window.event);
				$.extend( event, $.data(elem, 'mwcursorpos') || {} );
				var delta = 0, returnValue = true;
				
				if ( event.wheelDelta ) delta = event.wheelDelta/120;
				if ( event.detail     ) delta = -event.detail/3;
				if ( $.browser.opera  ) delta = -event.wheelDelta;
				
				$.each( $.data(elem, 'mwhandlers'), function(i, handler) {
					if ( handler )
						if ( handler.call(elem, event, delta) === false ) {
							returnValue = false;
							event.preventDefault();
							event.stopPropagation();
						}
				});
				
				return returnValue;
			});
			
			// Fix pageX, pageY, clientX and clientY for mozilla
			if ( $.browser.mozilla && !$.data(elem, 'mwfixcursorpos') ) {
				$.data(elem, 'mwfixcursorpos', function(event) {
					$.data(elem, 'mwcursorpos', {
						pageX: event.pageX,
						pageY: event.pageY,
						clientX: event.clientX,
						clientY: event.clientY
					});
				});
				$(elem).bind('mousewheel:mousemove', $.data(elem, 'mwfixcursorpos'));
			}
			
			if ( elem.addEventListener )
				if ( $.browser.mozilla ) elem.addEventListener('DOMMouseScroll', $.data(elem, 'mwhandler'), false);
				else                     elem.addEventListener('mousewheel',     $.data(elem, 'mwhandler'), false);
			else
				elem.onmousewheel = $.data(elem, 'mwhandler');
			
			cache.push( $(elem) );
		});
	},
	
	unmousewheel: function(f) {
		return this.each( function() {
			var elem = this;
			if ( f )
				$.data( elem, 'mwhandlers', $.grep($.data(elem, 'mwhandlers'), function(i, handler) {
					return handler && handler.guid != f.guid;
				}) );
			else {
				if ( $.browser.mozilla )
					$(elem).unbind('mousewheel:mousemove');
					
				if ( elem.addEventListener )
					if ( $.browser.mozilla ) elem.removeEventListener('DOMMouseScroll', $.data(elem, 'mwhandler'), false);
					else                     elem.removeEventListener('mousewheel',     $.data(elem, 'mwhandler'), false);
				else
					elem.onmousewheel = null;
				
				$.removeData(elem, 'mwhandlers');
				$.removeData(elem, 'mwhandler');
				$.removeData(elem, 'mwfixcursorpos');
				$.removeData(elem, 'mwcursorpos');
			}
		});
	}
});

// clean-up
$(window)
	.one('unload', function() {
		var els = cache || [];
		for (var i=0; i<els.length; i++)
			els[i].unmousewheel();
	});
	
})(jQuery);;/* 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-09-11 02:38:31 +0000 (Tue, 11 Sep 2007) $
 * $Rev: 3238 $
 *
 * Version: @VERSION
 *
 * Requires: jQuery 1.2+
 */

(function($){
	
$.dimensions = {
	version: '@VERSION'
};

// Create innerHeight, innerWidth, outerHeight and outerWidth methods
$.each( [ 'Height', 'Width' ], function(i, name){
	
	// innerHeight and innerWidth
	$.fn[ 'inner' + name ] = function() {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		return this[ name.toLowerCase() ]() + num(this, 'padding' + torl) + num(this, 'padding' + borr);
	};
	
	// outerHeight and outerWidth
	$.fn[ 'outer' + name ] = function(options) {
		if (!this[0]) return;
		
		var torl = name == 'Height' ? 'Top'    : 'Left',  // top or left
		    borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
		
		options = $.extend({ margin: false }, options || {});
		
		return this[ name.toLowerCase() ]()
				+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
				+ num(this, 'padding' + torl) + num(this, 'padding' + borr)
				+ (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
	};
});

// Create scrollLeft and scrollTop methods
$.each( ['Left', 'Top'], function(i, name) {
	$.fn[ 'scroll' + name ] = function(val) {
		if (!this[0]) return;
		
		return val != undefined ?
		
			// Set the scroll offset
			this.each(function() {
				this == window || this == document ?
					window.scrollTo( 
						name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
						name == 'Top'  ? val : $(window)[ 'scrollTop'  ]()
					) :
					this[ 'scroll' + name ] = val;
			}) :
			
			// Return the scroll offset
			this[0] == window || this[0] == document ?
				self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
					$.boxModel && document.documentElement[ 'scroll' + name ] ||
					document.body[ 'scroll' + name ] :
				this[0][ 'scroll' + name ];
	};
});

$.fn.extend({
	position: function() {
		var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
		
		if (elem) {
			// Get *real* offsetParent
			offsetParent = this.offsetParent();
			
			// Get correct offsets
			offset       = this.offset();
			parentOffset = offsetParent.offset();
			
			// Subtract element margins
			offset.top  -= num(elem, 'marginTop');
			offset.left -= num(elem, 'marginLeft');
			
			// Add offsetParent borders
			parentOffset.top  += num(offsetParent, 'borderTopWidth');
			parentOffset.left += num(offsetParent, 'borderLeftWidth');
			
			// Subtract the two offsets
			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}
		
		return results;
	},
	
	offsetParent: function() {
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent ? offsetParent : 'body');
	}
});

var num = function(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

})(jQuery);;(function($) {

  //If the UI scope is not availalable, add it
  $.ui = $.ui || {};

  //Add methods that are vital for all mouse interaction stuff (plugin registering)
  $.extend($.ui, {
    plugin: {
      add: function(w, c, o, p) {
        var a = $.ui[w].prototype; if(!a.plugins[c]) a.plugins[c] = [];
        a.plugins[c].push([o,p]);
      },
      call: function(instance, name, arguments) {
        var c = instance.plugins[name]; if(!c) return;
        var o = instance.interaction ? instance.interaction.options : instance.options;
        var e = instance.interaction ? instance.interaction.element : instance.element;

        for (var i = 0; i < c.length; i++) {
          if (o[c[i][0]]) c[i][1].apply(e, arguments);
        }
      }
    }
  });

  $.fn.mouseInteractionDestroy = function() {
    this.each(function() {
      if($.data(this, "ui-mouse")) $.data(this, "ui-mouse").destroy();
    });
  };

  $.ui.mouseInteraction = function(el,o) {

    if(!o) var o = {};
    this.element = el;
    $.data(this.element, "ui-mouse", this);

    this.options = {};
    $.extend(this.options, o);
    $.extend(this.options, {
      handle : o.handle ? ($(o.handle, el)[0] ? $(o.handle, el) : $(el)) : $(el),
      helper: o.helper || 'original',
      preventionDistance: o.preventionDistance || 0,
      dragPrevention: o.dragPrevention ? o.dragPrevention.toLowerCase().split(',') : ['input','textarea','button','select','option'],
      cursorAt: { top: ((o.cursorAt && o.cursorAt.top) ? o.cursorAt.top : 0), left: ((o.cursorAt && o.cursorAt.left) ? o.cursorAt.left : 0), bottom: ((o.cursorAt && o.cursorAt.bottom) ? o.cursorAt.bottom : 0), right: ((o.cursorAt && o.cursorAt.right) ? o.cursorAt.right : 0) },
      cursorAtIgnore: (!o.cursorAt) ? true : false, //Internal property
      appendTo: o.appendTo || 'parent'
    });
    o = this.options; //Just Lazyness

    if(!this.options.nonDestructive && (o.helper == 'clone' || o.helper == 'original')) {

      // Let's save the margins for better reference
      o.margins = {
        top: parseInt($(el).css('marginTop')) || 0,
        left: parseInt($(el).css('marginLeft')) || 0,
        bottom: parseInt($(el).css('marginBottom')) || 0,
        right: parseInt($(el).css('marginRight')) || 0
      };

      // We have to add margins to our cursorAt
      if(o.cursorAt.top != 0) o.cursorAt.top = o.margins.top;
      if(o.cursorAt.left != 0) o.cursorAt.left += o.margins.left;
      if(o.cursorAt.bottom != 0) o.cursorAt.bottom += o.margins.bottom;
      if(o.cursorAt.right != 0) o.cursorAt.right += o.margins.right;


      if(o.helper == 'original')
        o.wasPositioned = $(el).css('position');

    } else {
      o.margins = { top: 0, left: 0, right: 0, bottom: 0 };
    }

    var self = this;
    this.mousedownfunc = function(e) { // Bind the mousedown event
      return self.click.apply(self, [e]);
    }
    o.handle.bind('mousedown', this.mousedownfunc);

    //Prevent selection of text when starting the drag in IE
    if($.browser.msie) $(this.element).attr('unselectable', 'on');

  }

  $.extend($.ui.mouseInteraction.prototype, {
    plugins: {},
    currentTarget: null,
    lastTarget: null,
    timer: null,
    slowMode: false,
    init: false,
    destroy: function() {
      this.options.handle.unbind('mousedown', this.mousedownfunc);
    },
    trigger: function(e) {
      return this.click.apply(this, arguments);
    },
    click: function(e) {

      var o = this.options;

      window.focus();
      if(e.which != 1) return true; //only left click starts dragging

      // Prevent execution on defined elements
      var targetName = (e.target) ? e.target.nodeName.toLowerCase() : e.srcElement.nodeName.toLowerCase();
      for(var i=0;i<o.dragPrevention.length;i++) {
        if(targetName == o.dragPrevention[i]) return true;
      }

      //Prevent execution on condition
      if(o.startCondition && !o.startCondition.apply(this, [e])) return true;

      var self = this;
      this.mouseup = function(e) { return self.stop.apply(self, [e]); }
      this.mousemove = function(e) { return self.drag.apply(self, [e]); }

      var initFunc = function() { //This function get's called at bottom or after timeout
        $(document).bind('mouseup', self.mouseup);
        $(document).bind('mousemove', self.mousemove);
        self.opos = [e.pageX,e.pageY]; // Get the original mouse position
      }

      if(o.preventionTimeout) { //use prevention timeout
        if(this.timer) clearInterval(this.timer);
        this.timer = setTimeout(function() { initFunc(); }, o.preventionTimeout);
        return false;
      }

      initFunc();
      return false;

    },
    start: function(e) {

      var o = this.options; var a = this.element;
      o.co = $(a).offset(); //get the current offset

      this.helper = typeof o.helper == 'function' ? $(o.helper.apply(a, [e,this]))[0] : (o.helper == 'clone' ? $(a).clone()[0] : a);

      if(o.appendTo == 'parent') { // Let's see if we have a positioned parent
        var cp = a.parentNode;
        while (cp) {
          if(cp.style && ($(cp).css('position') == 'relative' || $(cp).css('position') == 'absolute')) {
            o.pp = cp;
            o.po = $(cp).offset();
            o.ppOverflow = !!($(o.pp).css('overflow') == 'auto' || $(o.pp).css('overflow') == 'scroll'); //TODO!
            break;
          }
          cp = cp.parentNode ? cp.parentNode : null;
        }

        if(!o.pp) o.po = { top: 0, left: 0 };
      }

      this.pos = [this.opos[0],this.opos[1]]; //Use the relative position
      this.rpos = [this.pos[0],this.pos[1]]; //Save the absolute position

      if(o.cursorAtIgnore) { // If we want to pick the element where we clicked, we borrow cursorAt and add margins
        o.cursorAt.left = this.pos[0] - o.co.left + o.margins.left;
        o.cursorAt.top = this.pos[1] - o.co.top + o.margins.top;
      }



      if(o.pp) { // If we have a positioned parent, we pick the draggable relative to it
        this.pos[0] -= o.po.left;
        this.pos[1] -= o.po.top;
      }

      this.slowMode = (o.cursorAt && (o.cursorAt.top-o.margins.top > 0 || o.cursorAt.bottom-o.margins.bottom > 0) && (o.cursorAt.left-o.margins.left > 0 || o.cursorAt.right-o.margins.right > 0)) ? true : false; //If cursorAt is within the helper, set slowMode to true

      if(!o.nonDestructive) $(this.helper).css('position', 'absolute');
      if(o.helper != 'original') $(this.helper).appendTo((o.appendTo == 'parent' ? a.parentNode : o.appendTo)).show();

      // Remap right/bottom properties for cursorAt to left/top
      if(o.cursorAt.right && !o.cursorAt.left) o.cursorAt.left = this.helper.offsetWidth+o.margins.right+o.margins.left - o.cursorAt.right;
      if(o.cursorAt.bottom && !o.cursorAt.top) o.cursorAt.top = this.helper.offsetHeight+o.margins.top+o.margins.bottom - o.cursorAt.bottom;

      this.init = true;

      if(o._start) o._start.apply(a, [this.helper, this.pos, o.cursorAt, this, e]); // Trigger the start callback
      this.helperSize = { width: outerWidth(this.helper), height: outerHeight(this.helper) }; //Set helper size property
      return false;

    },
    stop: function(e) {

      var o = this.options; var a = this.element; var self = this;

      $(document).unbind('mouseup', self.mouseup);
      $(document).unbind('mousemove', self.mousemove);

      if(this.init == false) return this.opos = this.pos = null;
      if(o._beforeStop) o._beforeStop.apply(a, [this.helper, this.pos, o.cursorAt, this, e]);

      if(this.helper != a && !o.beQuietAtEnd) { // Remove helper, if it's not the original node
        $(this.helper).remove(); this.helper = null;
      }

      if(!o.beQuietAtEnd) {
        //if(o.wasPositioned)	$(a).css('position', o.wasPositioned);
        if(o._stop) o._stop.apply(a, [this.helper, this.pos, o.cursorAt, this, e]);
      }

      this.init = false;
      this.opos = this.pos = null;
      return false;

    },
    drag: function(e) {

      if (!this.opos || ($.browser.msie && !e.button)) return this.stop.apply(this, [e]); // check for IE mouseup when moving into the document again
      var o = this.options;

      this.pos = [e.pageX,e.pageY]; //relative mouse position
      if(this.rpos && this.rpos[0] == this.pos[0] && this.rpos[1] == this.pos[1]) return false;
      this.rpos = [this.pos[0],this.pos[1]]; //absolute mouse position

      if(o.pp) { //If we have a positioned parent, use a relative position
        this.pos[0] -= o.po.left;
        this.pos[1] -= o.po.top;
      }

      if( (Math.abs(this.rpos[0]-this.opos[0]) > o.preventionDistance || Math.abs(this.rpos[1]-this.opos[1]) > o.preventionDistance) && this.init == false) //If position is more than x pixels from original position, start dragging
        this.start.apply(this,[e]);
      else {
        if(this.init == false) return false;
      }

      if(o._drag) o._drag.apply(this.element, [this.helper, this.pos, o.cursorAt, this, e]);
      return false;

    }
  });

  var num = function(el, prop) {
    return parseInt($.css(el.jquery?el[0]:el,prop))||0;
  };
  function outerWidth(el) {
    var $el = $(el), ow = $el.width();
    for (var i = 0, props = ['borderLeftWidth', 'paddingLeft', 'paddingRight', 'borderRightWidth']; i < props.length; i++)
      ow += num($el, props[i]);
    return ow;
  }
  function outerHeight(el) {
    var $el = $(el), oh = $el.width();
    for (var i = 0, props = ['borderTopWidth', 'paddingTop', 'paddingBottom', 'borderBottomWidth']; i < props.length; i++)
      oh += num($el, props[i]);
    return oh;
  }

 })($);
;(function($) {

	//Web Forms 2.0
	if(window['webforms']) {
		$(document).ready(function() {
			
			$("input").each(function() {
				if(this.getAttribute("type") == "range") {
					var cur = $(this);
					var slider = $("<div class='ui-slider'></div>").css({ width: cur.innerWidth()+"px", height: cur.innerHeight()+"px" }).insertAfter(cur);
					var handle = $("<div class='ui-slider-handle'></div>").appendTo(slider);


					slider.css({
						"position": cur.css("position") == "absolute" ? "absolute" : "relative",
						"left": cur.css("left"),
						"right": cur.css("right"),
						"zIndex": cur.css("zIndex"),
						"float": cur.css("float"),
						"clear": cur.css("clear")
					});
					cur.css({ position: "absolute", opacity: 0, top: "-1000px", left: "-1000px" });
					
					slider.slider({
						maxValue: cur.attr("max"),
						minValue: cur.attr("min"),
						startValue: this.getAttribute("value"),
						stepping: cur.attr("step"),
						change: function(e, ui) { cur[0].value = ui.value; cur[0].setAttribute("value", ui.value); }
					});
					
					slider = slider.sliderInstance();
					
					cur.bind("keydown", function(e) {
						var o = slider.interaction.options;
						switch(e.keyCode) {
							case 37:
								slider.moveTo(slider.interaction.curValue+o.minValue-(o.stepping || 1));
								break;
							case 39:
								slider.moveTo(slider.interaction.curValue+o.minValue+(o.stepping || 1));
								break;	
						}
						if(e.keyCode != 9) return false;
					});
					
				};	
			});
				
		});
	}

	//Make nodes selectable by expression
	$.extend($.expr[':'], { slider: "(' '+a.className+' ').indexOf(' ui-slider ')" });
	
	$.fn.slider = function(o) {
		return this.each(function() {
			new $.ui.slider(this, o);
		});
	}
	
	//Macros for external methods that support chaining
	var methods = "destroy,enable,disable,moveTo".split(",");
	for(var i=0;i<methods.length;i++) {
		var cur = methods[i], f;
		eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-slider")) jQuery.data(this, "ui-slider")["'+cur+'"](a); }); }');
		$.fn["slider"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;
	};
	
	//get instance method
	$.fn.sliderInstance = function() {
		if($(this[0]).is(".ui-slider")) return $.data(this[0], "ui-slider");
		return false;
	};
	
	$.ui.slider = function(el, o) {
		
		var options = {};
		o = o || {};
		$.extend(options, o);
		$.extend(options, {
			axis: o.axis || (el.offsetWidth < el.offsetHeight ? 'vertical' : 'horizontal'),
			maxValue: parseInt(o.maxValue) || 100,
			minValue: parseInt(o.minValue) || 0,
			startValue: parseInt(o.startValue) || 0,
			_start: function(h, p, c, t, e) {
				self.start.apply(t, [self, e]); // Trigger the start callback				
			},
			_beforeStop: function(h, p, c, t, e) {
				self.stop.apply(t, [self, e]); // Trigger the start callback
			},
			_drag: function(h, p, c, t, e) {
				self.drag.apply(t, [self, e]); // Trigger the start callback
			},
			startCondition: function() {
				return !self.disabled;
			}			
		});

		var self = this;
		var o = options;
		$.data(el, "ui-slider", this);
		o.stepping = parseInt(o.stepping) || (o.steps ? o.maxValue/o.steps : 0);
		o.realValue = (o.maxValue - o.minValue);


		this.handle = options.handle ? $(options.handle, el) : $('.ui-slider-handle', el);
		if(this.handle.length == 1) {
			this.interaction = new $.ui.mouseInteraction(this.handle[0], options);
			this.multipleHandles = false;
		} else {
			this.interactions = [];
			this.handle.each(function() {
				self.interactions.push(new $.ui.mouseInteraction(this, options));
			});
			this.multipleHandles = true;
		}
		
		this.element = el;
		$(this.element).addClass("ui-slider");
		
		
		if(o.axis == 'horizontal') {
			this.parentSize = $(this.element).outerWidth() - this.handle.outerWidth();
			this.prop = 'left';
		}
		
		if(o.axis == 'vertical') {
			this.parentSize = $(this.element).outerHeight() - this.handle.outerHeight();
			this.prop = 'top';
		}
		
		if(!this.multipleHandles) {
			$(el).bind('click', function(e) { self.click.apply(self, [e]); });
			if(!isNaN(o.startValue)) this.moveTo(o.startValue,options.realValue, null, false);
		}
		
	}
	
	$.extend($.ui.slider.prototype, {
		currentTarget: null,
		lastTarget: null,
		destroy: function() {
			$(this.element).removeClass("ui-slider").removeClass("ui-slider-disabled");
			this.interaction.destroy();
		},
		enable: function() {
			$(this.element).removeClass("ui-slider-disabled");
			this.disabled = false;
		},
		disable: function() {
			$(this.element).addClass("ui-slider-disabled");
			this.disabled = true;
		},
		nonvalidRange: function(self) {

			for(var i=0;i<this.interactions.length;i++) {
				if(self == this.interactions[i]) {
					if(this.interactions[i-1]) {
						if(this.interactions[i-1].curValue > this.interactions[i].curValue) return this.interactions[i-1].curValue;
					}
					
					if(this.interactions[i+1]) {
						if(this.interactions[i+1].curValue < this.interactions[i].curValue) return this.interactions[i+1].curValue;
					}
				}
			}
			
			return false;
			
		},
		prepareCallbackObj: function(self,m) {
			
			var cur = this;
			var func = function() {
				var retVal = [];
				for(var i=0;i<cur.interactions.length;i++) {
					retVal.push((cur.interactions[i].curValue || 0)+self.options.minValue);
				}
				return retVal;
			};
			
			return {
				handle: self.helper,
				pixel: m,
				value: self.curValue+self.options.minValue,
				values: this.multipleHandles ? func() : self.curValue+self.options.minValue,
				slider: self	
			}			
		},
		click: function(e) {
			var o = this.interaction.options;
			var pointer = [e.pageX,e.pageY];
			var offset = $(this.interaction.element).offsetParent().offset({ border: false });
			if(this.interaction.element == e.target || this.disabled) return;
			
			this.interaction.pickValue = this.interaction.curValue;
			this.drag.apply(this.interaction, [this, e, [pointer[0]-offset.left-this.handle[0].offsetWidth/2,pointer[1]-offset.top-this.handle[0].offsetHeight/2]]);
			
			if(this.interaction.pickValue != this.interaction.curValue)
				$(this.element).triggerHandler("slidechange", [e, this.prepareCallbackObj(this.interaction)], o.change);
				
		},
		start: function(that, e) {
			
			var o = this.options;
			$(that.element).triggerHandler("slidestart", [e, that.prepareCallbackObj(this)], o.start);
			this.pickValue = this.curValue;
			
			return false;
						
		},
		stop: function(that, e) {			
			
			var o = this.options;
			$(that.element).triggerHandler("slidestop", [e, that.prepareCallbackObj(this)], o.stop);
			if(this.pickValue != this.curValue) $(that.element).triggerHandler("slidechange", [e, that.prepareCallbackObj(this)], o.change);

			return false;
			
		},
		drag: function(that, e, pos) {

			var o = this.options;
			this.pos = pos || [this.pos[0]-this.element.offsetWidth/2, this.pos[1]-this.element.offsetHeight/2];
			
			if(o.axis == 'horizontal') var m = this.pos[0];
			if(o.axis == 'vertical')   var m = this.pos[1];
			
			
			var p = that.parentSize;
			var prop = that.prop;

			if(m < 0) m = 0;
			if(m > p) m = p;

			this.curValue = (Math.round((m/p)*o.realValue));
			if(o.stepping) {
				this.curValue = Math.round(this.curValue/o.stepping)*o.stepping;
				m = ((this.curValue)/o.realValue) * p;
			}
			
			if(that.interactions) {
				nonvalidRange = that.nonvalidRange(this);
				if(nonvalidRange) {
					this.curValue = nonvalidRange;
					m = ((this.curValue)/o.realValue) * p;
				}
			}
			
			$(this.element).css(prop, m+'px');
			$(that.element).triggerHandler("slide", [e, that.prepareCallbackObj(this,m)], o.slide);
			return false;
			
		},
		moveTo: function(value,scale,changeslide,p) {	// renamed from goto to moveTo as goto is reserved javascript word
			
			if(this.multipleHandles) return false; //TODO: Multiple handle moveTo function
			
			var o = this.interaction.options;
			var offset = $(this.interaction.element).offsetParent().offset({ border: false });
			this.interaction.pickValue = this.interaction.curValue;
			value = value-o.minValue;
			
			var modifier = scale || o.realValue;
			
			if(!p) var p = this.parentSize;
			var prop = this.prop;
			
			var m = Math.round(((value)/modifier) * p);

			if(m < 0) m = 0;
			if(m > p) m = p;
			
			this.interaction.curValue = (Math.round((m/p)*o.realValue));
			if(o.stepping) {
				this.interaction.curValue = Math.round(this.interaction.curValue/o.stepping)*o.stepping;
				m = ((this.interaction.curValue)/o.realValue) * p;
			}

			$(this.interaction.element).css(prop, m+'px');
			
			if(!changeslide && this.interaction.pickValue != this.interaction.curValue && !p)
				$(this.element).triggerHandler("slidechange", [null, this.prepareCallbackObj(this.interaction)], o.change);
			
			if(changeslide)
				$(this.element).triggerHandler("slide", [null, this.prepareCallbackObj(this.interaction)], o.slide);

		}
	});

})(jQuery);
;(function($) {

  //Make nodes selectable by expression
  $.extend($.expr[':'], { draggable: "(' '+a.className+' ').indexOf(' ui-draggable ')" });


  //Macros for external methods that support chaining
  var methods = "destroy,enable,disable".split(",");
  for(var i=0;i<methods.length;i++) {
    var cur = methods[i], f;
    eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-draggable")) jQuery.data(this, "ui-draggable")["'+cur+'"](a); }); }');
    $.fn["draggable"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;
  }

  //get instance method
  $.fn.draggableInstance = function() {
    if($(this[0]).is(".ui-draggable")) return $.data(this[0], "ui-draggable");
    return false;
  };

  $.fn.draggable = function(o) {
    return this.each(function() {
      new $.ui.draggable(this, o);
    });
  };

  $.ui.ddmanager = {
    current: null,
    droppables: [],
    prepareOffsets: function(t, e) {
      var dropTop = $.ui.ddmanager.dropTop = [];
      var dropLeft = $.ui.ddmanager.dropLeft;
      var m = $.ui.ddmanager.droppables;
      for (var i = 0; i < m.length; i++) {
        if(m[i].item.disabled) continue;
        m[i].offset = $(m[i].item.element).offset();
        if (t && m[i].item.options.accept(t.element)) //Activate the droppable if used directly from draggables
          m[i].item.activate.call(m[i].item, e);
      }
    },
    fire: function(oDrag, e) {

      var oDrops = $.ui.ddmanager.droppables;
      var oOvers = $.grep(oDrops, function(oDrop) {

        if (!oDrop.item.disabled && $.ui.intersect(oDrag, oDrop, oDrop.item.options.tolerance))
          oDrop.item.drop.call(oDrop.item, e);
      });
      $.each(oDrops, function(i, oDrop) {
        if (!oDrop.item.disabled && oDrop.item.options.accept(oDrag.element)) {
          oDrop.out = 1; oDrop.over = 0;
          oDrop.item.deactivate.call(oDrop.item, e);
        }
      });
    },
    update: function(oDrag, e) {

      if(oDrag.options.refreshPositions) $.ui.ddmanager.prepareOffsets();

      var oDrops = $.ui.ddmanager.droppables;
      var oOvers = $.grep(oDrops, function(oDrop) {
        if(oDrop.item.disabled) return false;
        var isOver = $.ui.intersect(oDrag, oDrop, oDrop.item.options.tolerance);
        if (!isOver && oDrop.over == 1) {
          oDrop.out = 1; oDrop.over = 0;
          oDrop.item.out.call(oDrop.item, e);
        }
        return isOver;
      });
      $.each(oOvers, function(i, oOver) {
        if (oOver.over == 0) {
          oOver.out = 0; oOver.over = 1;
          oOver.item.over.call(oOver.item, e);
        }
      });
    }
  };

  $.ui.draggable = function(el, o) {

    var options = {};
    $.extend(options, o);
    var self = this;
    $.extend(options, {
      _start: function(h, p, c, t, e) {
        self.start.apply(t, [self, e]); // Trigger the start callback
      },
      _beforeStop: function(h, p, c, t, e) {
        self.stop.apply(t, [self, e]); // Trigger the start callback
      },
      _drag: function(h, p, c, t, e) {
        self.drag.apply(t, [self, e]); // Trigger the start callback
      },
      startCondition: function(e) {
        return !(e.target.className.indexOf("ui-resizable-handle") != -1 || self.disabled);
      }
    });

    $.data(el, "ui-draggable", this);

    if (options.ghosting == true) options.helper = 'clone'; //legacy option check
    $(el).addClass("ui-draggable");
    this.interaction = new $.ui.mouseInteraction(el, options);

  };

  $.extend($.ui.draggable.prototype, {
    plugins: {},
    currentTarget: null,
    lastTarget: null,
    destroy: function() {
      $(this.interaction.element).removeClass("ui-draggable").removeClass("ui-draggable-disabled");
      this.interaction.destroy();
    },
    enable: function() {
      $(this.interaction.element).removeClass("ui-draggable-disabled");
      this.disabled = false;
    },
    disable: function() {
      $(this.interaction.element).addClass("ui-draggable-disabled");
      this.disabled = true;
    },
    prepareCallbackObj: function(self) {
      return {
        helper: self.helper,
        position: { left: self.pos[0], top: self.pos[1] },
        offset: self.options.cursorAt,
        draggable: self,
        options: self.options
      }
    },
    start: function(that, e) {

      var o = this.options;
      $.ui.ddmanager.current = this;

      $.ui.plugin.call(that, 'start', [e, that.prepareCallbackObj(this)]);
      $(this.element).triggerHandler("dragstart", [e, that.prepareCallbackObj(this)], o.start);

      if (this.slowMode && $.ui.droppable && !o.dropBehaviour)
        $.ui.ddmanager.prepareOffsets(this, e);

      return false;

    },
    stop: function(that, e) {

      var o = this.options;

      $.ui.plugin.call(that, 'stop', [e, that.prepareCallbackObj(this)]);
      $(this.element).triggerHandler("dragstop", [e, that.prepareCallbackObj(this)], o.stop);

      if (this.slowMode && $.ui.droppable && !o.dropBehaviour) //If cursorAt is within the helper, we must use our drop manager
        $.ui.ddmanager.fire(this, e);

      $.ui.ddmanager.current = null;
      $.ui.ddmanager.last = this;

      return false;

    },
    drag: function(that, e) {

      var o = this.options;

      $.ui.ddmanager.update(this, e);

      this.pos = [this.pos[0]-o.cursorAt.left, this.pos[1]-o.cursorAt.top];

      $.ui.plugin.call(that, 'drag', [e, that.prepareCallbackObj(this)]);
      var nv = $(this.element).triggerHandler("drag", [e, that.prepareCallbackObj(this)], o.drag);

      var nl = (nv && nv.left) ? nv.left : this.pos[0];
      var nt = (nv && nv.top) ? nv.top : this.pos[1];

      $(this.helper).css('left', nl+'px').css('top', nt+'px'); // Stick the helper to the cursor
      return false;

    }
  });

})($);
;/*
 * 'this' -> original element
 * 1. argument: browser event
 * 2.argument: ui object
 */

(function($) {

	$.ui.plugin.add("draggable", "stop", "effect", function(e,ui) {
		var t = ui.helper;
		if(ui.options.effect[1]) {
			if(t != this) {
				ui.options.beQuietAtEnd = true;
				switch(ui.options.effect[1]) {
					case 'fade':
						$(t).fadeOut(300, function() { $(this).remove(); });
						break;
					default:
						$(t).remove();
						break;	
				}
			}
		}
	});
	
	$.ui.plugin.add("draggable", "start", "effect", function(e,ui) {
		if(ui.options.effect[0]) {
			switch(ui.options.effect[0]) {
				case 'fade':
					$(ui.helper).hide().fadeIn(300);
					break;
			}
		}
	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "start", "cursor", function(e,ui) {
		var t = $('body');
		if (t.css("cursor")) ui.options.ocursor = t.css("cursor");
		t.css("cursor", ui.options.cursor);
	});

	$.ui.plugin.add("draggable", "stop", "cursor", function(e,ui) {
		if (ui.options.ocursor) $('body').css("cursor", ui.options.ocursor);
	});

//----------------------------------------------------------------
	
	$.ui.plugin.add("draggable", "start", "zIndex", function(e,ui) {
		var t = $(ui.helper);
		if(t.css("zIndex")) ui.options.ozIndex = t.css("zIndex");
		t.css('zIndex', ui.options.zIndex);
	});
	
	$.ui.plugin.add("draggable", "stop", "zIndex", function(e,ui) {
		if(ui.options.ozIndex) $(ui.helper).css('zIndex', ui.options.ozIndex);
	});


//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "start", "opacity", function(e,ui) {
		var t = $(ui.helper);
		if(t.css("opacity")) ui.options.oopacity = t.css("opacity");
		t.css('opacity', ui.options.opacity);
	});
	
	$.ui.plugin.add("draggable", "stop", "opacity", function(e,ui) {
		if(ui.options.oopacity) $(ui.helper).css('opacity', ui.options.oopacity);
	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "stop", "revert", function(e,ui) {
	
		var o = ui.options;
		var rpos = { left: 0, top: 0 };
		o.beQuietAtEnd = true;

		if(ui.helper != this) {

			rpos = $(ui.draggable.sorthelper || this).offset({ border: false });

			var nl = rpos.left-o.po.left-o.margins.left;
			var nt = rpos.top-o.po.top-o.margins.top;

		} else {
			var nl = o.co.left - (o.po ? o.po.left : 0);
			var nt = o.co.top - (o.po ? o.po.top : 0);
		}
		
		var self = ui.draggable;

		$(ui.helper).animate({
			left: nl,
			top: nt
		}, 500, function() {
			
			if(o.wasPositioned) $(self.element).css('position', o.wasPositioned);
			if(o.stop) o.stop.apply(self.element, [self.helper, self.pos, [o.co.left - o.po.left,o.co.top - o.po.top],self]);
			
			if(self.helper != self.element) window.setTimeout(function() { $(self.helper).remove(); }, 0); //Using setTimeout because of strange flickering in Firefox
			
		});
		
	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "start", "iframeFix", function(e,ui) {

		var o = ui.options;
		if(!ui.draggable.slowMode) { // Make clones on top of iframes (only if we are not in slowMode)
			if(o.iframeFix.constructor == Array) {
				for(var i=0;i<o.iframeFix.length;i++) {
					var co = $(o.iframeFix[i]).offset({ border: false });
					$("<div class='DragDropIframeFix' style='background: #fff;'></div>").css("width", $(o.iframeFix[i])[0].offsetWidth+"px").css("height", $(o.iframeFix[i])[0].offsetHeight+"px").css("position", "absolute").css("opacity", "0.001").css("z-index", "1000").css("top", co.top+"px").css("left", co.left+"px").appendTo("body");
				}		
			} else {
				$("iframe").each(function() {					
					var co = $(this).offset({ border: false });
					$("<div class='DragDropIframeFix' style='background: #fff;'></div>").css("width", this.offsetWidth+"px").css("height", this.offsetHeight+"px").css("position", "absolute").css("opacity", "0.001").css("z-index", "1000").css("top", co.top+"px").css("left", co.left+"px").appendTo("body");
				});							
			}		
		}

	});
	
	$.ui.plugin.add("draggable","stop", "iframeFix", function(e,ui) {
		if(ui.options.iframeFix) $("div.DragDropIframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers	
	});
		
//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "start", "containment", function(e,ui) {

		var o = ui.options;

		if(!o.cursorAtIgnore || o.containment.left != undefined || o.containment.constructor == Array) return;
		if(o.containment == 'parent') o.containment = this.parentNode;


		if(o.containment == 'document') {
			o.containment = [
				0-o.margins.left,
				0-o.margins.top,
				$(document).width()-o.margins.right,
				($(document).height() || document.body.parentNode.scrollHeight)-o.margins.bottom
			];
		} else { //I'm a node, so compute top/left/right/bottom
			var ce = $(o.containment)[0];
			var co = $(o.containment).offset({ border: false });

			o.containment = [
				co.left-o.margins.left,
				co.top-o.margins.top,
				co.left+(ce.offsetWidth || ce.scrollWidth)-o.margins.right,
				co.top+(ce.offsetHeight || ce.scrollHeight)-o.margins.bottom
			];
		}

	});
	
	$.ui.plugin.add("draggable", "drag", "containment", function(e,ui) {
		
		var o = ui.options;
		if(!o.cursorAtIgnore) return;
			
		var h = $(ui.helper);
		var c = o.containment;
		if(c.constructor == Array) {
			
			if((ui.draggable.pos[0] < c[0]-o.po.left)) ui.draggable.pos[0] = c[0]-o.po.left;
			if((ui.draggable.pos[1] < c[1]-o.po.top)) ui.draggable.pos[1] = c[1]-o.po.top;
			if(ui.draggable.pos[0]+h[0].offsetWidth > c[2]-o.po.left) ui.draggable.pos[0] = c[2]-o.po.left-h[0].offsetWidth;
			if(ui.draggable.pos[1]+h[0].offsetHeight > c[3]-o.po.top) ui.draggable.pos[1] = c[3]-o.po.top-h[0].offsetHeight;
			
		} else {

			if(c.left && (ui.draggable.pos[0] < c.left)) ui.draggable.pos[0] = c.left;
			if(c.top && (ui.draggable.pos[1] < c.top)) ui.draggable.pos[1] = c.top;

			var p = $(o.pp);
			if(c.right && ui.draggable.pos[0]+h[0].offsetWidth > p[0].offsetWidth-c.right) ui.draggable.pos[0] = (p[0].offsetWidth-c.right)-h[0].offsetWidth;
			if(c.bottom && ui.draggable.pos[1]+h[0].offsetHeight > p[0].offsetHeight-c.bottom) ui.draggable.pos[1] = (p[0].offsetHeight-c.bottom)-h[0].offsetHeight;
			
		}

		
	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "drag", "grid", function(e,ui) {
		var o = ui.options;
		if(!o.cursorAtIgnore) return;
		ui.draggable.pos[0] = o.co.left + o.margins.left - o.po.left + Math.round((ui.draggable.pos[0] - o.co.left - o.margins.left + o.po.left) / o.grid[0]) * o.grid[0];
		ui.draggable.pos[1] = o.co.top + o.margins.top - o.po.top + Math.round((ui.draggable.pos[1] - o.co.top - o.margins.top + o.po.top) / o.grid[1]) * o.grid[1];
	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "drag", "axis", function(e,ui) {
		var o = ui.options;
		if(!o.cursorAtIgnore) return;
		if(o.constraint) o.axis = o.constraint; //Legacy check
		o.axis ? ( o.axis == 'x' ? ui.draggable.pos[1] = o.co.top - o.margins.top - o.po.top : ui.draggable.pos[0] = o.co.left - o.margins.left - o.po.left ) : null;
	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "drag", "scroll", function(e,ui) {

		var o = ui.options;
		o.scrollSensitivity	= o.scrollSensitivity || 20;
		o.scrollSpeed		= o.scrollSpeed || 20;

		if(o.pp && o.ppOverflow) { // If we have a positioned parent, we only scroll in this one
			// TODO: Extremely strange issues are waiting here..handle with care
		} else {
			if((ui.draggable.rpos[1] - $(window).height()) - $(document).scrollTop() > -o.scrollSensitivity) window.scrollBy(0,o.scrollSpeed);
			if(ui.draggable.rpos[1] - $(document).scrollTop() < o.scrollSensitivity) window.scrollBy(0,-o.scrollSpeed);
			if((ui.draggable.rpos[0] - $(window).width()) - $(document).scrollLeft() > -o.scrollSensitivity) window.scrollBy(o.scrollSpeed,0);
			if(ui.draggable.rpos[0] - $(document).scrollLeft() < o.scrollSensitivity) window.scrollBy(-o.scrollSpeed,0);
		}

	});

//----------------------------------------------------------------

	$.ui.plugin.add("draggable", "drag", "wrapHelper", function(e,ui) {

		var o = ui.options;
		if(o.cursorAtIgnore) return;
		var t = ui.helper;

		if(!o.pp || !o.ppOverflow) {
			var wx = $(window).width() - ($.browser.mozilla ? 20 : 0);
			var sx = $(document).scrollLeft();
			
			var wy = $(window).height();
			var sy = $(document).scrollTop();	
		} else {
			var wx = o.pp.offsetWidth + o.po.left - 20;
			var sx = o.pp.scrollLeft;
			
			var wy = o.pp.offsetHeight + o.po.top - 20;
			var sy = o.pp.scrollTop;						
		}

		ui.draggable.pos[0] -= ((ui.draggable.rpos[0]-o.cursorAt.left - wx + t.offsetWidth+o.margins.right) - sx > 0 || (ui.draggable.rpos[0]-o.cursorAt.left+o.margins.left) - sx < 0) ? (t.offsetWidth+o.margins.left+o.margins.right - o.cursorAt.left * 2) : 0;
		
		ui.draggable.pos[1] -= ((ui.draggable.rpos[1]-o.cursorAt.top - wy + t.offsetHeight+o.margins.bottom) - sy > 0 || (ui.draggable.rpos[1]-o.cursorAt.top+o.margins.top) - sy < 0) ? (t.offsetHeight+o.margins.top+o.margins.bottom - o.cursorAt.top * 2) : 0;

	});

})(jQuery);

;(function($) {

  //Make nodes selectable by expression
  $.extend($.expr[':'], { droppable: "(' '+a.className+' ').indexOf(' ui-droppable ')" });

  //Macros for external methods that support chaining
  var methods = "destroy,enable,disable".split(",");
  for(var i=0;i<methods.length;i++) {
    var cur = methods[i], f;
    eval('f = function() { var a = arguments; return this.each(function() { if(jQuery(this).is(".ui-droppable")) jQuery.data(this, "ui-droppable")["'+cur+'"](a); }); };');
    $.fn["droppable"+cur.substr(0,1).toUpperCase()+cur.substr(1)] = f;
  }

  //get instance method
  $.fn.droppableInstance = function() {
    if($(this[0]).is(".ui-droppable")) return $.data(this[0], "ui-droppable");
    return false;
  };

  $.fn.droppable = function(o) {
    return this.each(function() {
      new $.ui.droppable(this,o);
    });
  };

  $.ui.droppable = function(el,o) {

    if(!o) var o = {};
    this.element = el; if($.browser.msie) el.droppable = 1;
    $.data(el, "ui-droppable", this);

    this.options = {};
    $.extend(this.options, o);

    var accept = o.accept;
    $.extend(this.options, {
      accept: o.accept && o.accept.constructor == Function ? o.accept : function(d) {
        return $(d).is(accept);
      },
      tolerance: o.tolerance || 'intersect'
    });
    o = this.options;
    var self = this;

    this.mouseBindings = [function(e) { return self.move.apply(self, [e]); },function(e) { return self.drop.apply(self, [e]); }];
    $(this.element).bind("mousemove", this.mouseBindings[0]);
    $(this.element).bind("mouseup", this.mouseBindings[1]);

    $.ui.ddmanager.droppables.push({ item: this, over: 0, out: 1 }); // Add the reference and positions to the manager
    $(this.element).addClass("ui-droppable");

  };

  $.extend($.ui.droppable.prototype, {
    plugins: {},
    prepareCallbackObj: function(c) {
      return {
        draggable: c,
        droppable: this,
        element: c.element,
        helper: c.helper,
        options: this.options
      };
    },
    destroy: function() {
      $(this.element).removeClass("ui-droppable").removeClass("ui-droppable-disabled");
      $(this.element).unbind("mousemove", this.mouseBindings[0]);
      $(this.element).unbind("mouseup", this.mouseBindings[1]);

      for(var i=0;i<$.ui.ddmanager.droppables.length;i++) {
        if($.ui.ddmanager.droppables[i].item == this) $.ui.ddmanager.droppables.splice(i,1);
      }
    },
    enable: function() {
      $(this.element).removeClass("ui-droppable-disabled");
      this.disabled = false;
    },
    disable: function() {
      $(this.element).addClass("ui-droppable-disabled");
      this.disabled = true;
    },
    move: function(e) {

      if(!$.ui.ddmanager.current) return;

      var o = this.options;
      var c = $.ui.ddmanager.current;

      /* Save current target, if no last target given */
      var findCurrentTarget = function(e) {
        if(e.currentTarget) return e.currentTarget;
        var el = e.srcElement;
        do { if(el.droppable) return el; el = el.parentNode; } while (el); //This is only used in IE! references in DOM are evil!
      };
      if(c && o.accept(c.element)) c.currentTarget = findCurrentTarget(e);

      c.drag.apply(c, [e]);
      e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;

    },
    over: function(e) {

      var c = $.ui.ddmanager.current;
      if (!c || c.element == this.element) return; // Bail if draggable and droppable are same element

      var o = this.options;
      if (o.accept(c.element)) {
        $.ui.plugin.call(this, 'over', [e, this.prepareCallbackObj(c)]);
        $(this.element).triggerHandler("dropover", [e, this.prepareCallbackObj(c)], o.over);
      }

    },
    out: function(e) {

      var c = $.ui.ddmanager.current;
      if (!c || c.element == this.element) return; // Bail if draggable and droppable are same element

      var o = this.options;
      if (o.accept(c.element)) {
        $.ui.plugin.call(this, 'out', [e, this.prepareCallbackObj(c)]);
        $(this.element).triggerHandler("dropout", [e, this.prepareCallbackObj(c)], o.out);
      }

    },
    drop: function(e) {

      var c = $.ui.ddmanager.current;
      if (!c || c.element == this.element) return; // Bail if draggable and droppable are same element

      var o = this.options;
      if(o.accept(c.element)) { // Fire callback
        if(o.greedy && !c.slowMode) {
          if(c.currentTarget == this.element) {
            $.ui.plugin.call(this, 'drop', [e, {
              draggable: c,
              droppable: this,
              element: c.element,
              helper: c.helper
            }]);
            $(this.element).triggerHandler("drop", [e, {
              draggable: c,
              droppable: this,
              element: c.element,
              helper: c.helper
            }], o.drop);
          }
        } else {
          $.ui.plugin.call(this, 'drop', [e, this.prepareCallbackObj(c)]);
          $(this.element).triggerHandler("drop", [e, this.prepareCallbackObj(c)], o.drop);
        }
      }

    },
    activate: function(e) {
      var c = $.ui.ddmanager.current;
      $.ui.plugin.call(this, 'activate', [e, this.prepareCallbackObj(c)]);
      if(c) $(this.element).triggerHandler("dropactivate", [e, this.prepareCallbackObj(c)], this.options.activate);
    },
    deactivate: function(e) {
      var c = $.ui.ddmanager.current;
      $.ui.plugin.call(this, 'deactivate', [e, this.prepareCallbackObj(c)]);
      if(c) $(this.element).triggerHandler("dropdeactivate", [e, this.prepareCallbackObj(c)], this.options.deactivate);
    }
  });

  $.ui.intersect = function(oDrag, oDrop, toleranceMode) {
    if (!oDrop.offset || !oDrag.helperSize)
      return false;
    var x1 = oDrag.rpos[0] - oDrag.options.cursorAt.left + oDrag.options.margins.left, x2 = x1 + oDrag.helperSize.width,
        y1 = oDrag.rpos[1] - oDrag.options.cursorAt.top + oDrag.options.margins.top, y2 = y1 + oDrag.helperSize.height;
    var l = oDrop.offset.left, r = l + oDrop.item.element.offsetWidth,
        t = oDrop.offset.top,  b = t + oDrop.item.element.offsetHeight;
    switch (toleranceMode) {
      case 'fit':
        return (   l < x1 && x2 < r
          && t < y1 && y2 < b);
        break;
      case 'intersect':
        return (   l < x1 + (oDrag.helperSize.width  / 2)        // Right Half
          &&     x2 - (oDrag.helperSize.width  / 2) < r    // Left Half
          && t < y1 + (oDrag.helperSize.height / 2)        // Bottom Half
          &&     y2 - (oDrag.helperSize.height / 2) < b ); // Top Half
        break;
      case 'pointer':
        return (   l < oDrag.rpos[0] && oDrag.rpos[0] < r
          && t < oDrag.rpos[1] && oDrag.rpos[1] < b);
        break;
      case 'touch':
        return (   (l < x1 && x1 < r && t < y1 && y1 < b)    // Top-Left Corner
          || (l < x1 && x1 < r && t < y2 && y2 < b)    // Bottom-Left Corner
          || (l < x2 && x2 < r && t < y1 && y1 < b)    // Top-Right Corner
          || (l < x2 && x2 < r && t < y2 && y2 < b) ); // Bottom-Right Corner
        break;
      default:
        return false;
        break;
    }
  };

})($);

;(function($) {
	
	// options.activeClass
	$.ui.plugin.add("droppable", "activate", "activeClass", function(e,ui) {
		$(this).addClass(ui.options.activeClass);
	});
	$.ui.plugin.add("droppable", "deactivate", "activeClass", function(e,ui) {
		$(this).removeClass(ui.options.activeClass);
	});
	$.ui.plugin.add("droppable", "drop", "activeClass", function(e,ui) {
		$(this).removeClass(ui.options.activeClass);
	});

	// options.hoverClass
	$.ui.plugin.add("droppable", "over", "hoverClass", function(e,ui) {
		$(this).addClass(ui.options.hoverClass);
	});
	$.ui.plugin.add("droppable", "out", "hoverClass", function(e,ui) {
		$(this).removeClass(ui.options.hoverClass);
	});
	$.ui.plugin.add("droppable", "drop", "hoverClass", function(e,ui) {
		$(this).removeClass(ui.options.hoverClass);
	});

})(jQuery);
;/*
 * Accordion 1.5 - jQuery menu widget
 *
 * Copyright (c) 2007 JÃ¶rn Zaefferer, Frank Marcia
 *
 * http://bassistance.de/jquery-plugins/jquery-plugin-accordion/
 *
 * 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: jquery.accordion.js 2951 2007-08-28 07:21:13Z joern.zaefferer $
 *
 */

(function($) {

$.ui = $.ui || {};

$.ui.accordion = {};
$.extend($.ui.accordion, {
  defaults: {
    selectedClass: "selected",
    alwaysOpen: true,
    animated: 'slide',
    event: "click",
    header: "a"
  },
  animations: {
    slide: function(settings, additions) {
      settings = $.extend({
        easing: "swing",
        duration: 300
      }, settings, additions);
      if ( !settings.toHide.size() ) {
        settings.toShow.animate({height: "show"}, {
          duration: settings.duration,
          easing: settings.easing,
          complete: settings.finished
        });
        return;
      }
      var hideHeight = settings.toHide.height(),
        showHeight = settings.toShow.height(),
        difference = showHeight / hideHeight;
      settings.toShow.css({ height: 0, overflow: 'hidden' }).show();
      settings.toHide.filter(":hidden").each(settings.finished).end().filter(":visible").animate({height:"hide"},{
        step: function(n){
          settings.toShow.height(Math.ceil( (hideHeight - (n)) * difference ));
        },
        duration: settings.duration,
        easing: settings.easing,
        complete: settings.finished
      });
    },
    bounceslide: function(settings) {
      this.slide(settings, {
        easing: settings.down ? "bounceout" : "swing",
        duration: settings.down ? 1000 : 200
      });
    },
    easeslide: function(settings) {
      this.slide(settings, {
        easing: "easeinout",
        duration: 700
      })
    }
  }
});

$.fn.extend({
  nextUntil: function(expr) {
      var match = [];

      // We need to figure out which elements to push onto the array
      this.each(function(){
          // Traverse through the sibling nodes
          for( var i = this.nextSibling; i; i = i.nextSibling ) {
              // Make sure that we're only dealing with elements
              if ( i.nodeType != 1 ) continue;

              // If we find a match then we need to stop
              if ( $.filter( expr, [i] ).r.length ) break;

              // Otherwise, add it on to the stack
              match.push( i );
          }
      });

      return this.pushStack( match );
  },
  // the plugin method itself
  accordion: function(settings) {
    if ( !this.length )
      return this;

    // setup configuration
    settings = $.extend({}, $.ui.accordion.defaults, settings);

    if ( settings.navigation ) {
      var current = this.find("a").filter(function() { return this.href == location.href; });
      if ( current.length ) {
        if ( current.filter(settings.header).length ) {
          settings.active = current;
        } else {
          settings.active = current.parent().parent().prev();
          current.addClass("current");
        }
      }
    }

    // calculate active if not specified, using the first header
    var container = this,
      headers = container.find(settings.header),
      active = findActive(settings.active),
      running = 0;

    if ( settings.fillSpace ) {
      var maxHeight = this.parent().height();
      headers.each(function() {
        maxHeight -= $(this).outerHeight();
      });
      var maxPadding = 0;
      headers.nextUntil(settings.header).each(function() {
        maxPadding = Math.max(maxPadding, $(this).innerHeight() - $(this).height());
      }).height(maxHeight - maxPadding);
    } else if ( settings.autoheight ) {
      var maxHeight = 0;
      headers.nextUntil(settings.header).each(function() {
        maxHeight = Math.max(maxHeight, $(this).height());
      }).height(maxHeight);
    }

    headers
      .not(active || "")
      .nextUntil(settings.header)
      .hide();
    active.parent().andSelf().addClass(settings.selectedClass);


    function findActive(selector) {
      return selector != undefined
        ? typeof selector == "number"
          ? headers.filter(":eq(" + selector + ")")
          : headers.not(headers.not(selector))
        : selector === false
          ? $("<div>")
          : headers.filter(":eq(0)");
    }

    function toggle(toShow, toHide, data, clickedActive, down) {
      var finished = function(cancel) {
        running = cancel ? 0 : --running;
        if ( running )
          return;
        // trigger custom change event
        container.trigger("change", data);
      };

      // count elements to animate
      running = toHide.size() == 0 ? toShow.size() : toHide.size();

      if ( settings.animated ) {
        if ( !settings.alwaysOpen && clickedActive ) {
          toShow.slideToggle(settings.animated);
          finished(true);
        } else {
          $.ui.accordion.animations[settings.animated]({
            toShow: toShow,
            toHide: toHide,
            finished: finished,
            down: down
          });
        }
      } else {
        if ( !settings.alwaysOpen && clickedActive ) {
          toShow.toggle();
        } else {
          toHide.hide();
          toShow.show();
        }
        finished(true);
      }
    }

    function clickHandler(event) {
      // called only when using activate(false) to close all parts programmatically
      if ( !event.target && !settings.alwaysOpen ) {
        active.toggleClass(settings.selectedClass);
        var toHide = active.nextUntil(settings.header);
        var toShow = active = $([]);
        toggle( toShow, toHide );
        return;
      }
      // get the click target
      var clicked = $(event.target);

      // due to the event delegation model, we have to check if one
      // of the parent elements is our actual header, and find that
      if ( clicked.parents(settings.header).length )
        while ( !clicked.is(settings.header) )
          clicked = clicked.parent();

      var clickedActive = clicked[0] == active[0];

      // if animations are still active, or the active header is the target, ignore click
      if(running || (settings.alwaysOpen && clickedActive) || !clicked.is(settings.header))
        return;

      // switch classes
      active.parent().andSelf().toggleClass(settings.selectedClass);
      if ( !clickedActive ) {
        clicked.parent().andSelf().addClass(settings.selectedClass);
      }

      // find elements to show and hide
      var toShow = clicked.nextUntil(settings.header),
        toHide = active.nextUntil(settings.header),
        data = [clicked, active, toShow, toHide],
        down = headers.index( active[0] ) > headers.index( clicked[0] );

      active = clickedActive ? $([]) : clicked;
      toggle( toShow, toHide, data, clickedActive, down );

      return !toShow.length;
    };
    function activateHandler(event, index) {
      // IE manages to call activateHandler on normal clicks
      if ( arguments.length == 1 )
        return;
      // call clickHandler with custom event
      clickHandler({
        target: findActive(index)[0]
      });
    };

    return container
      .bind(settings.event, clickHandler)
      .bind("activate", activateHandler);
  },
  activate: function(index) {
    return this.trigger('activate', [index]);
  }
});

})(jQuery);;/*
 * Tabs 3 - New Wave Tabs
 *
 * Copyright (c) 2007 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 */

(function($) {

    // if the UI scope is not availalable, add it
    $.ui = $.ui || {};

    // tabs initialization
    $.fn.tabs = function(initial, options) {
        if (initial && initial.constructor == Object) { // shift arguments
            options = initial;
            initial = null;
        }
        options = options || {};

        initial = initial && initial.constructor == Number && --initial || 0;

        return this.each(function() {
            new $.ui.tabs(this, $.extend(options, { initial: initial }));
        });
    };

    // other chainable tabs methods
    $.each(['Add', 'Remove', 'Enable', 'Disable', 'Click', 'Load'], function(i, method) {
        $.fn['tabs' + method] = function() {
            var args = arguments;
            return this.each(function() {
                var instance = $.ui.tabs.getInstance(this);
                instance[method.toLowerCase()].apply(instance, args);
            });
        };
    });
    $.fn.tabsSelected = function() {
        var selected = -1;
        if (this[0]) {
            var instance = $.ui.tabs.getInstance(this[0]),
                $lis = $('li', this);
            selected = $lis.index( $lis.filter('.' + instance.options.selectedClass)[0] );
        }
        return selected >= 0 ? ++selected : -1;
    };

    // tabs class
    $.ui.tabs = function(el, options) {

        this.source = el;

        this.options = $.extend({

            // basic setup
            initial: 0,
            event: 'click',
            disabled: [],
            // TODO bookmarkable: $.ajaxHistory ? true : false,
            unselected: false,
            unselect: options.unselected ? true : false,

            // Ajax
            spinner: 'Loading&#8230;',
            cache: false,
            idPrefix: 'tab-',

            // animations
            /*fxFade: null,
            fxSlide: null,
            fxShow: null,
            fxHide: null,*/
            fxSpeed: 'normal',
            /*fxShowSpeed: null,
            fxHideSpeed: null,*/

            // callbacks
            add: function() {},
            remove: function() {},
            enable: function() {},
            disable: function() {},
            click: function() {},
            hide: function() {},
            show: function() {},
            load: function() {},

            // CSS classes
            navClass: 'ui-tabs-nav',
            selectedClass: 'ui-tabs-selected',
            disabledClass: 'ui-tabs-disabled',
            containerClass: 'ui-tabs-container',
            hideClass: 'ui-tabs-hide',
            loadingClass: 'ui-tabs-loading'

        }, options);

        this.tabify(true);

        // save instance for later
        var uuid = 'tabs' + $.ui.tabs.prototype.count++;
        $.ui.tabs.instances[uuid] = this;
        $.data(el, 'tabsUUID', uuid);

    };

    // static
    $.ui.tabs.instances = {};
    $.ui.tabs.getInstance = function(el) {
        return $.ui.tabs.instances[$.data(el, 'tabsUUID')];
    };

    // instance methods
    $.extend($.ui.tabs.prototype, {
        count: 0,
        tabify: function(init) {

            this.$tabs = $('a:first-child', this.source);
            this.$containers = $([]);

            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.$containers = self.$containers.add(a.hash);
                }
                // remote tab
                else {
                    $.data(a, 'href', a.href);
                    var id = a.title && a.title.replace(/\s/g, '_') || o.idPrefix + (self.count + 1) + '-' + (i + 1);
                    a.href = '#' + id;
                    self.$containers = self.$containers.add(
                        $('#' + id)[0] || $('<div id="' + id + '" class="' + o.containerClass + '"></div>')
                            .insertAfter( self.$containers[i - 1] || self.source )
                    );
                }
            });

            if (init) {

                // Try to retrieve initial tab from fragment identifier in url if present,
                // otherwise try to find selected class attribute on <li>.
                this.$tabs.each(function(i, a) {
                    if (location.hash) {
                        if (a.hash == location.hash) {
                            o.initial = i;
                            // prevent page scroll to fragment
                            //if (($.browser.msie || $.browser.opera) && !o.remote) {
                            if ($.browser.msie || $.browser.opera) {
                                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 ( $(a).parents('li:eq(0)').is('li.' + o.selectedClass) ) {
                        o.initial = i;
                        return false; // break
                    }
                });

                // attach necessary classes for styling if not present
                $(this.source).is('.' + o.navClass) || $(this.source).addClass(o.navClass);
                this.$containers.each(function() {
                    var $this = $(this);
                    $this.is('.' + o.containerClass) || $this.addClass(o.containerClass);
                });

                // highlight tab
                var $lis = $('li', this.source);
                this.$containers.addClass(o.hideClass);
                $lis.removeClass(o.selectedClass);
                if (!o.unselected) {
                    this.$containers.slice(o.initial, o.initial + 1).show();
                    $lis.slice(o.initial, o.initial + 1).addClass(o.selectedClass);
                }

                // load if remote tab
                if ($.data(this.$tabs[o.initial], 'href')) {
                    this.load(o.initial + 1, $.data(this.$tabs[o.initial], 'href'));
                    if (o.cache) {
                        $.removeData(this.$tabs[o.initial], 'href'); // if loaded once do not load them again
                    }
                }

                // disabled tabs
                for (var i = 0, position; position = o.disabled[i]; i++) {
                    this.disable(position);
                }

            }

            // setup animations
            var showAnim = {}, showSpeed = o.fxShowSpeed || o.fxSpeed,
                hideAnim = {}, hideSpeed = o.fxHideSpeed || o.fxSpeed;
            if (o.fxSlide || o.fxFade) {
                if (o.fxSlide) {
                    showAnim['height'] = 'show';
                    hideAnim['height'] = 'hide';
                }
                if (o.fxFade) {
                    showAnim['opacity'] = 'show';
                    hideAnim['opacity'] = 'hide';
                }
            } else {
                if (o.fxShow) {
                    showAnim = o.fxShow;
                } else { // use some kind of animation to prevent browser scrolling to the tab
                    showAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
                    showSpeed = 1; // as little as 1 is sufficient
                }
                if (o.fxHide) {
                    hideAnim = o.fxHide;
                } else { // use some kind of animation to prevent browser scrolling to the tab
                    hideAnim['min-width'] = 0; // avoid opacity, causes flicker in Firefox
                    hideSpeed = 1; // as little as 1 is sufficient
                }
            }

            // 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(hideAnim, hideSpeed, function() { //
                    $hide.addClass(o.hideClass).css(resetCSS); // maintain flexible height and accessibility in print etc.
                    if ($.browser.msie) {
                        $hide[0].style.filter = '';
                    }
                    o.hide(clicked, $hide[0], $show && $show[0] || null);
                    if ($show) {
                        showTab(clicked, $show, $hide);
                    }
                });
            }

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

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

            // tab click handler
            function tabClick(e) {

                //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.$containers.filter(':visible'),
                    $show = $(this.hash);

                // If tab is already selected and not unselectable or tab disabled or click callback returns false stop here.
                // Check if click handler returns false last so that it is not executed for a disabled tab!
                if (($li.is('.' + o.selectedClass) && !o.unselect) || $li.is('.' + o.disabledClass)
                    || o.click(this, $show[0], $hide[0]) === false) {
                    this.blur();
                    return false;
                }
                    
                // if tab may be closed
                if (o.unselect) {
                    if ($li.is('.' + o.selectedClass)) {
                        $li.removeClass(o.selectedClass);
                        self.$containers.stop();
                        hideTab(this, $hide);
                        this.blur();
                        return false;
                    } else if (!$hide.length) {
                        $li.addClass(o.selectedClass);
                        self.$containers.stop();
                        showTab(this, $show);
                        this.blur();
                        return false;
                    }
                }

                // stop possibly running animations
                self.$containers.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);
                    }*/

                    if ($.data(this, 'href')) { // remote tab
                        var a = this;
                        self.load(self.$tabs.index(this) + 1, $.data(this, 'href'), function() {
                            switchTab(a, $hide, $show);
                        });
                        if (o.cache) {
                            $.removeData(this, 'href'); // if loaded once do not load them again
                        }
                    } else {
                        switchTab(this, $hide, $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.';
                }

                this.blur(); // prevent IE from keeping other link focussed when using the back button

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

            }

            // attach click event, avoid duplicates from former tabifying
            this.$tabs.unbind(o.event, tabClick).bind(o.event, tabClick);

        },
        add: function(url, text, position) {
            if (url && text) {
                var o = this.options;
                position = position || this.$tabs.length; // append by default
                if (position >= this.$tabs.length) {
                    var method = 'insertAfter';
                    position = this.$tabs.length;
                } else {
                    var method = 'insertBefore';
                }
                if (url.indexOf('#') == 0) { // ajax container is created by tabify automatically
                    var $container = $(url);
                    // try to find an existing element before creating a new one
                    ($container.length && $container || $('<div id="' + url.replace('#', '') + '" class="' + o.containerClass + ' ' + o.hideClass + '"></div>'))
                        [method](this.$containers[position - 1]);
                }
                $('<li><a href="' + url + '"><span>' + text + '</span></a></li>')
                    [method](this.$tabs.slice(position - 1, position).parents('li:eq(0)'));
                this.tabify();
                o.add(this.$tabs[position - 1], this.$containers[position - 1]); // callback
            } else {
                throw 'jQuery UI Tabs: Not enough arguments to add tab.';
            }
        },
        remove: function(position) {
            if (position && position.constructor == Number) {
                var $removedTab = this.$tabs.slice(position - 1, position).parents('li:eq(0)').remove();
                var $removedContainer = this.$containers.slice(position - 1, position).remove();
                this.tabify();
                this.options.remove($removedTab[0], $removedContainer[0]); // callback
            }
        },
        enable: function(position) {
            var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
            $li.removeClass(o.disabledClass);
            if ($.browser.safari) { // fix disappearing tab after enabling in Safari... TODO check Safari 3
                $li.animate({ opacity: 1 }, 1, function() {
                    $li.css({ opacity: '' });
                });
            }
            o.enable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
        },
        disable: function(position) {
            var $li = this.$tabs.slice(position - 1, position).parents('li:eq(0)'), o = this.options;
            if ($.browser.safari) { // fix opacity of tab after disabling in Safari... TODO check Safari 3
                $li.animate({ opacity: 0 }, 1, function() {
                   $li.css({ opacity: '' });
                });
            }
            $li.addClass(this.options.disabledClass);
            o.disable(this.$tabs[position - 1], this.$containers[position - 1]); // callback
        },
        click: function(position) {
            this.$tabs.slice(position - 1, position).trigger('click');
        },
        load: function(position, url, callback) {
            var self = this,
                o = this.options,
                $a = this.$tabs.slice(position - 1, position).addClass(o.loadingClass),
                $span = $('span', $a),
                text = $span.html();

            // shift arguments
            if (url && url.constructor == Function) {
                callback = url;
            }

            // set new URL
            if (url) {
                $.data($a[0], 'href', url);
            }

            // load
            if (o.spinner) {
                $span.html('<em>' + o.spinner + '</em>');
            }
            setTimeout(function() { // timeout is again required in IE, "wait" for id being restored
                $($a[0].hash).load(url, function() {
                    if (o.spinner) {
                        $span.html(text);
                    }
                    $a.removeClass(o.loadingClass);
                    // This callback is required because the switch has to take place after loading
                    // has completed.
                    if (callback && callback.constructor == Function) {
                        callback();
                    }
                    o.load(self.$tabs[position - 1], self.$containers[position - 1]); // callback
                });
            }, 0);
        }
    });

})(jQuery);
;/*
 * jQuery ifixpng plugin
 * renamed from pngfix to ifixpng due to naming conflict 
 * with another plugin
 * Version 1.7  (18/09/2007)
 * @requires jQuery v1.1.3 or above
 *
 * Examples at: http://jquery.khurshid.com
 * Copyright (c) 2007 Kush M.
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 */
 
 /**
  *
  * @example
  *
  * optional if location of pixel.gif if different to default which is images/pixel.gif
  * $.ifixpng('media/pixel.gif');
  *
  * $('img[@src$=.png], #panel').ifixpng();
  *
  * @apply hack to all png images and #panel which icluded png img in its css
  *
  * @name ifixpng
  * @type jQuery
  * @cat Plugins/Image
  * @return jQuery
  * @author jQuery Community
  */
 
(function($) {
	
	/**
	 * helper variables and function
	 */
	$.ifixpng = function(customPixel) {
		$.ifixpng.pixel = customPixel;
	};
	
	$.ifixpng.getPixel = function() {
		return $.ifixpng.pixel || 'images/pixel.gif';
	};
	
	var hack = {
		ltie7  : $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),
		filter : function(src) {
			return "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,sizingMethod=crop,src='"+src+"')";
		}
	};
	
	/**
	 * Applies ie png hack to selected dom elements
	 *
	 * $('img[@src$=.png]').ifixpng();
	 * @desc apply hack to all images with png extensions
	 *
	 * $('#panel, img[@src$=.png]').ifixpng();
	 * @desc apply hack to element #panel and all images with png extensions
	 *
	 * @name ifixpng
	 */
	 
	$.fn.ifixpng = hack.ltie7 ? function() {
    	return this.each(function() {
			var $$ = $(this);
			var base = $('base').attr('href'); // need to use this in case you are using rewriting urls
			if ($$.is('img') || $$.is('input')) { // hack image tags present in dom
				if ($$.attr('src').match(/.*\.png([?].*)?$/i)) { // make sure it is png image
					// use source tag value if set 
					var source = (base && $$.attr('src').substring(0,1)!='/') ? base + $$.attr('src') : $$.attr('src');
					// apply filter
					$$.css({filter:hack.filter(source), width:$$.width(), height:$$.height()})
					  .attr({src:$.ifixpng.getPixel()})
					  .positionFix();
				}
			} else { // hack png css properties present inside css
				var image = $$.css('backgroundImage');
				if (image.match(/^url\(["']?(.*\.png([?].*)?)["']?\)$/i)) {
					image = RegExp.$1;
					$$.css({backgroundImage:'none', filter:hack.filter(image)})
					  .positionFix();
				}
			}
		});
	} : function() { return this; };
	
	/**
	 * Removes any png hack that may have been applied previously
	 *
	 * $('img[@src$=.png]').iunfixpng();
	 * @desc revert hack on all images with png extensions
	 *
	 * $('#panel, img[@src$=.png]').iunfixpng();
	 * @desc revert hack on element #panel and all images with png extensions
	 *
	 * @name iunfixpng
	 */
	 
	$.fn.iunfixpng = hack.ltie7 ? function() {
    	return this.each(function() {
			var $$ = $(this);
			var src = $$.css('filter');
			if (src.match(/src=["']?(.*\.png([?].*)?)["']?/i)) { // get img source from filter
				src = RegExp.$1;
				if ($$.is('img') || $$.is('input')) {
					$$.attr({src:src}).css({filter:''});
				} else {
					$$.css({filter:'', background:'url('+src+')'});
				}
			}
		});
	} : function() { return this; };
	
	/**
	 * positions selected item relatively
	 */
	 
	$.fn.positionFix = function() {
		return this.each(function() {
			var $$ = $(this);
			var position = $$.css('position');
			if (position != 'absolute' && position != 'relative') {
				$$.css({position:'relative'});
			}
		});
	};

})(jQuery);;$.fn.pager = function(selector, options) {

  var settings = {
    navId          : 'nav',
    navClass       : 'nav',
    navAttach      : 'append',
    highlightClass : 'highlight',
    prevText       : '&laquo;',
    nextText       : '&raquo;',
    linkText       : null,
    linkWrap       : null,
    height         : null,
    selectedIndex  : 0,
    pageSize       : 1,
    eventName      : 'click'
  }
  if (options) {
    $.extend(settings, options);
  }

  return this.each( function () {

    var $me = $(this);
    var size;
    var i = settings.selectedIndex - (settings.selectedIndex % settings.pageSize);
    var navid = '#' + settings.navId;

    function init () {
      size = $(selector, $me).not(navid).size();
      if (settings.height == null) {
        settings.height = getHighest();
      }
      if (size > settings.pageSize) {
        if (settings.navAttach != 'none') {
          makeNav();
        }
        show();
        highlight();
      }
      sizePanel();
      if (settings.linkWrap != null) {
        linkWrap();
      }
    }
    function makeNav () {
      var str = '<div id="'+settings.navId+'" class="'+settings.navClass+'">';
      str += '<a href="#" rel="prev">'+settings.prevText+'</a>';
      for (var i = 0; i < size; i = i + settings.pageSize) {
        var j = i + 1;
        str += '<a href="#" rel="' + j + '">';
        if (settings.linkText == null) {
          if (settings.pageSize > 1) {
            str += j + '-';
            if (j + settings.pageSize - 1 < size) {
              str += j + settings.pageSize - 1;
            }
            else {
              str += size;
            }
          }
          else {
            str += j + 1;
          }
        }
        else {
          str += settings.linkText[j - 1];
        }
        str += '</a>';
      }
      str += '<a href="#" rel="next">'+settings.nextText+'</a>';
      str += '</div>';
      switch (settings.navAttach) {
        case 'before':
          $me.before(str);
          break;
        case 'after':
          $me.after(str);
          break;
        case 'prepend':
          $me.prepend(str);
          break;
        default:
          $me.append(str);
          break;
      }
    }
    function show () {
      $me.find(selector).not(navid).hide()
        .slice(i, i + settings.pageSize).show();
    }
    function highlight () {
      $me.find(navid).find('a').removeClass(settings.highlightClass)
        .filter('a[rel=' + (i + 1) + ']').addClass(settings.highlightClass);
    }

    function sizePanel () {
      if($.browser.msie) {
        $me.find(selector).not(navid).css( {
          height: settings.height
        });
      } else {
        $me.find(selector).not(navid).css( {
          minHeight: settings.height
        });
      }
    }
    function getHighest () {
      var highest = 0;
      $me.find(selector).not(navid).each(function () {

        if(this.offsetHeight > highest) {
          highest = this.offsetHeight;
        }
      });
      highest = highest + "px";
      return highest;
    }
    function getNavHeight () {
      var nav = $(navid).get(0);
      return nav.offsetHeight;
    }
    function linkWrap () {
      $me.find(navid).find("a").wrap(settings.linkWrap);
    }

    init();
    $(navid).find("a").bind(settings.eventName, function () {
      if ($(this).attr('rel') == 'next') {
        if (i + settings.pageSize < size) {
          i = i + settings.pageSize;
        }
      } else if ($(this).attr('rel') == 'prev') {
        if (i - settings.pageSize >= 0) {
          i = i - settings.pageSize;
        }
      } else {
        var j = $(this).attr('rel');
        i = j - 1;
      }
      show();
      highlight();
      return false;
    });
  });
};;/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2007 Ariel Flesler - aflesler(at)gmail(dot)com
 * Licensed under GPL license (http://www.opensource.org/licenses/gpl-license.php).
 * Date: 11/16/2007
 * @author Ariel Flesler
 * @version 1.2.4
 * Compatible with jQuery 1.2.1, tested on Firefox 2.0.0.7, and IE 6, both on Windows.
 **/
(function($){$.scrollTo=function(a,b){return $('html,body').scrollTo(a,b)};$.scrollTo.defaults={axis:'y',speed:1};$.fn.scrollTo=function(d,e){e=$.extend({},$.scrollTo.defaults,e);e.queue=e.queue&&e.axis.length==2;if(e.queue)e.speed=Math.ceil(e.speed/2);if(typeof e.offset=='number')e.offset={left:e.offset,top:e.offset};return this.each(function(){var c=$(this),t=d,q,r={};switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t={top:t,left:t};break}t=$(t,this);case'object':if(t.is||t.style)q=(t=$(t)).offset()}$.each(e.axis.split(''),parse);animate(e.onAfter);function parse(i,b){var P=b=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,a=c[0][k];r[k]=q?q[p]+(c.is('html,body')?0:a-c.offset()[p]):t[p];if(e.margin&&t.css)r[k]-=parseInt(t.css('margin'+P),10)||0;if(e.offset&&e.offset[p])r[k]+=e.offset[p];if(!i&&e.queue){if(a!=r[k])animate(e.onAfterFirst);delete r[k]}};function animate(a){c.animate(r,e.speed,e.easing,function(){if(a)a.call(this,c,r,t)})}})}})(jQuery);;/*
 * Jeditable - jQuery in place edit plugin
 *
 * Copyright (c) 2006-2007 Mika Tuupola, Dylan Verheul
 *
 * Licensed under the MIT license:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Revision: $Id: jquery.jeditable.js 261 2007-10-18 14:19:09Z tuupola $
 *
 */

/**
  * Based on editable by Dylan Verheul <dylan@dyve.net>
  * http://www.dyve.net/jquery/?editable
  *
  * Version 1.5.0
  *
  * @name  Jeditable
  * @type  jQuery
  * @param String  target             POST URL or function name to send edited content
  * @param Hash    options            additional options
  * @param String  options[name]      POST parameter name of edited content
  * @param String  options[id]        POST parameter name of edited div id
  * @param Hash    options[submitdata] Extra parameters to send when submitting edited content.
  * @param String  options[type]      text, textarea or select
  * @param Integer options[rows]      number of rows if using textarea
  * @param Integer options[cols]      number of columns if using textarea
  * @param Mixed   options[height]    'auto', 'none' or height in pixels
  * @param Mixed   options[width]     'auto', 'none' or width in pixels
  * @param String  options[loadurl]   URL to fetch external content before editing
  * @param String  options[loadtype]  Request type for load url. Should be GET or POST.
  * @param String  options[loadtext]  Text to display while loading external content.
  * @param Hash    options[loaddata]  Extra parameters to pass when fetching content before editing.
  * @param String  options[data]      Or content given as paramameter.
  * @param String  options[indicator] indicator html to show when saving
  * @param String  options[tooltip]   optional tooltip text via title attribute
  * @param String  options[event]     jQuery event such as 'click', 'dblclick' or a custom event
  * @param String  options[focus]     true or false, when true the first form element is auto-focused
  * @param Mixed   options[onblur]    'cancel', 'submit', 'ignore' or a function to call on blur
  * @param Mixed   options[reset]     'true', 'false' or a function to determine if the form should become read-only after submit
  * @param String  options[submit]    submit button value, empty means no button
  * @param String  options[cancel]    cancel button value, empty means no button
  * @param String  options[cssclass]  CSS class to apply to input form. 'inherit' to copy from parent.
  * @param String  options[style]     Style to apply to input form 'inherit' to copy from parent.
  * @param String  options[select]    true or false, when true text is highlighted
  * @param String  options[placeholder] Placeholder text or html to insert when element is empty.
  *
  */

(function($) {

    $.fn.editable = function(target, options) {

        var settings = {
            target     : target,
            name       : 'value',
            id         : 'id',
            type       : 'text',
            width      : 'auto',
            height     : 'auto',
            event      : 'click',
            focus      : true,
            reset      : true,
            onblur     : 'cancel',
            onsubmit   : 'reset',
            oncancel   : 'cancel',
            loadtype   : 'GET',
            loadtext   : 'Loading...',
            placeholder: 'Click to edit',
            loaddata   : {},
            submitdata : {}
        };

        if (options) {
            $.extend(settings, options);
        }

        /* setup some functions */
        var plugin   = $.editable.types[settings.type].plugin || function() { };
        var submit   = $.editable.types[settings.type].submit || function() { };
        var buttons  = $.editable.types[settings.type].buttons
                    || $.editable.types['defaults'].buttons;
        var content  = $.editable.types[settings.type].content
                    || $.editable.types['defaults'].content;
        var element  = $.editable.types[settings.type].element
                    || $.editable.types['defaults'].element;
        var callback = settings.callback || function() { };

        $(this).attr('title', settings.tooltip);

        settings.autowidth  = 'auto' == settings.width;
        settings.autoheight = 'auto' == settings.height;

        return this.each(function() {

            /* if element is empty add something clickable (if requested) */
            if (!$.trim($(this).html())) {
                $(this).html(settings.placeholder);
            }

            $(this).bind(settings.event, function(e) {

                /* save this to self because this changes when scope changes */
                var self = this;

                /* prevent throwing an exeption if edit field is clicked again */
                if (self.editing) {
                    return;
                }

                /* figure out how wide and tall we are */
                if (settings.width != 'none') {
                    settings.width =
                        settings.autowidth ? $(self).width()  : settings.width;
                }
                if (settings.height != 'none') {
                    settings.height =
                        settings.autoheight ? $(self).height() : settings.height;
                }

                /* remove placeholder text, replace is here because of IE */
                if ($(this).html().toLowerCase().replace(/;/, '') ==
                    settings.placeholder.toLowerCase().replace(/;/, '')) {
                        $(this).html('');
                }

                self.editing    = true;
                self.revert     = $(self).html();
                $(self).html('');

                /* create the form object */
                var form = $('<form/>');

                /* add created form to self */
                $(self).append(form);

                /* apply css or style or both */
                if (settings.cssclass) {
                    if ('inherit' == settings.cssclass) {
                        form.attr('class', $(self).attr('class'));
                    } else {
                        form.attr('class', settings.cssclass);
                    }
                }

                if (settings.style) {
                    if ('inherit' == settings.style) {
                        form.attr('style', $(self).attr('style'));
                        /* IE needs the second line or display wont be inherited */
                        form.css('display', $(self).css('display'));
                    } else {
                        form.attr('style', settings.style);
                    }
                }

                /* add main input element to form and store it in input */
                var input = element.apply(form, [settings, self]);

                /* set input content via POST, GET, given data or existing value */
                var input_content;

                if (settings.loadurl) {
                    var t = setTimeout(function() {
                        input.disabled = true;
                        content.apply(form, [settings.loadtext, settings, self]);
                    }, 100);

                    var loaddata = {};
                    loaddata[settings.id] = self.id;
                    if ($.isFunction(settings.loaddata)) {
                        $.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings]));
                    } else {
                        $.extend(loaddata, settings.loaddata);
                    }
                    $.ajax({
                       type : settings.loadtype,
                       url  : settings.loadurl,
                       data : loaddata,
                       async : false,
                       success: function(result) {
                          window.clearTimeout(t);
                          input_content = result;
                          input.disabled = false;
                       }
                    });
                } else if (settings.data) {
                    input_content = settings.data;
                    if ($.isFunction(settings.data)) {
                        input_content = settings.data.apply(self, [self.revert, settings]);
                    }
                } else {
                    input_content = self.revert;
                }
                content.apply(form, [input_content, settings, self]);

                input.attr('name', settings.name);

                /* add buttons to the form */
                buttons.apply(form, [settings, self]);

                /* highlight input contents when requested */
                if (settings.select) {
                    input.select();
                }

                /* attach 3rd party plugin if requested */
                plugin.apply(form, [settings, self]);

                /* focus to first visible form element if requested */
                if (settings.focus) {
                  $(':input:visible:enabled:first', form).focus();
                }

                var cancelFunction;
                if ($.isFunction(settings.oncancel)) {
                    cancelFunction = settings.oncancel;
                } else {
                    cancelFunction = reset;
                }

                /* discard changes if pressing Esc */
                input.keydown(function(e) {
                    if (e.keyCode == 27) {
                        e.preventDefault();
                        cancelFunction.apply(self, [input.val(), settings, e]);
                    }
                });

                /* discard, submit or nothing with changes when clicking outside */
                /* do nothing is usable when navigating with tab */
                var t;
                if ($.isFunction(settings.onblur)) {
                    input.blur(function (e) {
                        settings.onblur.apply(self, [input.val(), settings, e]);
                    });
                } else if ('cancel' == settings.onblur) {
                    input.blur(function(e) {
                        t = setTimeout(reset, 500);
                    });
                } else if ('submit' == settings.onblur) {
                    input.blur(function(e) {
                        form.submit();
                    });
                } else {
                    input.blur(function(e) {
                      /* TODO: maybe something here */
                    });
                }

                form.submit(function(e) {

                    if (t) {
                        clearTimeout(t);
                    }

                    /* do no submit */
                    e.preventDefault();

                    /* if this input type has a call before submit hook, call it */
                    submit.apply(form, [settings, self]);

                    /* determine if we should reset form after submission */
                    var resetVal;
                    if ($.isFunction(settings.reset)) {
                        resetVal = settings.reset.apply(self, [input.val(), settings]);
                    }
                    else {
                        resetVal = settings.reset;
                    }

                    /* check if given target is function */
                    if ($.isFunction(settings.target)) {
                        var str = settings.target.apply(self, [input.val(), settings]);
                        if (resetVal) {
                            $(self).html(str);
                            self.editing = false;
                        }
                        callback.apply(self, [self.innerHTML, settings]);
                    } else {
                        /* add edited content and id of edited element to POST */
                        var submitdata = {};
                        submitdata[settings.name] = input.val();
                        submitdata[settings.id] = self.id;
                        /* add extra data to be POST:ed */
                        if ($.isFunction(settings.submitdata)) {
                            $.extend(submitdata, settings.submitdata.apply(self, [self.revert, settings]));
                        } else {
                            $.extend(submitdata, settings.submitdata);
                        }

                        /* show the saving indicator */
                        $(self).html(settings.indicator);
                        $.post(settings.target, submitdata, function(str) {
                            if (resetVal) {
                                $(self).html(str);
                                self.editing = false;
                            }
                            callback.apply(self, [self.innerHTML, settings]);
                            /* TODO: this is not dry */
                            if (!$.trim($(self).html())) {
                                $(self).html(settings.placeholder);
                            }
                        });
                    }

                    return false;
                });

                function reset() {
                    $(self).trigger('editableReset');
                }

            });

            /* make reset a custom event so we can trigger it externally */
            $(this).bind('editableReset', function(e) {

                /* save this to self because this changes when scope changes */
                var self = this;

                $(self).html(self.revert);
                self.editing = false;
                if (!$.trim($(self).html())) {
                    $(self).html(settings.placeholder);
                }
            });

        });

    };


    $.editable = {
        types: {
            defaults: {
                element : function(settings, original) {
                    var input = $('<input type="hidden">');
                    $(this).append(input);
                    return(input);
                },
                content : function(string, settings, original) {
                    $(':input:first', this).val(string);
                },
                buttons : function(settings, original) {
                    if (settings.submit) {
                        var submit = $('<input type="submit">');
                        submit.val(settings.submit);
                        $(this).append(submit);
                    }
                    if (settings.cancel) {
                        var cancel = $('<input type="button">');
                        cancel.val(settings.cancel);
                        $(this).append(cancel);

                        $(cancel).click(function() {
                            $(original).html(original.revert);
                            original.editing = false;
                        });
                    }
                }
            },
            text: {
                element : function(settings, original) {
                    var input = $('<input>');
                    if (settings.width  != 'none') { input.width(settings.width);  }
                    if (settings.height != 'none') { input.height(settings.height); }
                    /* https://bugzilla.mozilla.org/show_bug.cgi?id=236791 */
                    //input[0].setAttribute('autocomplete','off');
                    input.attr('autocomplete','off');
                    $(this).append(input);
                    return(input);
                }
            },
            textarea: {
                element : function(settings, original) {
                    var textarea = $('<textarea>');
                    if (settings.rows) {
                        textarea.attr('rows', settings.rows);
                    } else if (settings.height != 'none') {
                        textarea.height(settings.height);
                    }
                    if (settings.cols) {
                        textarea.attr('cols', settings.cols);
                    } else if (settings.width != 'none') {
                        textarea.width(settings.width);
                    }
                    $(this).append(textarea);
                    return(textarea);
                }
            },
            select: {
                element : function(settings, original) {
                    var select = $('<select>');
                    $(this).append(select);
                    return(select);
                },
                content : function(string, settings, original) {
                    if (String == string.constructor) {
                        eval ('var json = ' + string);
                        for (var key in json) {
                            if ('selected' == key) {
                                continue;
                            }
                            var option = $('<option>').val(key).append(json[key]);
                            $('select', this).append(option);
                        }
                    }
                    /* Loop option again to set selected. IE needed this... */
                    $('select', this).children().each(function() {
                        if ($(this).val() == json['selected']) {
                            $(this).attr('selected', 'selected');
                        };
                    });
                }
            }
        },

        /* Add new input type */
        addInputType: function(name, input) {
            $.editable.types[name] = input;
        }
    };

})(jQuery);
;$.editable.addInputType('decoded_text', {
  element : $.editable.types.text.element,
  content : function(string, settings, original) {
    string = string.replace(/&lt;/g, '<');
    string = string.replace(/&gt;/g, '>');
    string = string.replace(/&quot;/g, '"');
    string = string.replace(/&#039;/g, "'");
    string = string.replace(/&amp;/g, '&');
    $(':input:first', this).val(string);
  }
});
;/**
 * --------------------------------------------------------------------
 * jQuery-Plugin "pngFix"
 * Version: 1.2, 09.03.2009
 * by Andreas Eberhard, andreas.eberhard@gmail.com
 *                      http://jquery.andreaseberhard.de/
 *
 * Copyright (c) 2007 Andreas Eberhard
 * Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
 *
 * Changelog:
 *    09.03.2009 Version 1.2
 *    - Update for jQuery 1.3.x, removed @ from selectors
 *    11.09.2007 Version 1.1
 *    - removed noConflict
 *    - added png-support for input type=image
 *    - 01.08.2007 CSS background-image support extension added by Scott Jehl, scott@filamentgroup.com, http://www.filamentgroup.com
 *    31.05.2007 initial Version 1.0
 * --------------------------------------------------------------------
 * @example $(function(){$(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready
 *
 * jQuery(function(){jQuery(document).pngFix();});
 * @desc Fixes all PNG's in the document on document.ready when using noConflict
 *
 * @example $(function(){$('div.examples').pngFix();});
 * @desc Fixes all PNG's within div with class examples
 *
 * @example $(function(){$('div.examples').pngFix( { blankgif:'ext.gif' } );});
 * @desc Fixes all PNG's within div with class examples, provides blank gif for input with png
 * --------------------------------------------------------------------
 */

(function($) {

jQuery.fn.pngFix = function(settings) {

	// Settings
	settings = jQuery.extend({
		blankgif: 'blank.gif'
	}, settings);

	var ie55 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 5.5") != -1);
	var ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1);

	if (jQuery.browser.msie && (ie55 || ie6)) {

		//fix images with png-source
		jQuery(this).find("img[src*=.png]").each(function() {

			jQuery(this).attr('width',jQuery(this).width());
			jQuery(this).attr('height',jQuery(this).height());

			var prevStyle = '';
			var strNewHTML = '';
			var imgId = (jQuery(this).attr('id')) ? 'id="' + jQuery(this).attr('id') + '" ' : '';
			var imgClass = (jQuery(this).attr('class')) ? 'class="' + jQuery(this).attr('class') + '" ' : '';
			var imgTitle = (jQuery(this).attr('title')) ? 'title="' + jQuery(this).attr('title') + '" ' : '';
			var imgAlt = (jQuery(this).attr('alt')) ? 'alt="' + jQuery(this).attr('alt') + '" ' : '';
			var imgAlign = (jQuery(this).attr('align')) ? 'float:' + jQuery(this).attr('align') + ';' : '';
			var imgHand = (jQuery(this).parent().attr('href')) ? 'cursor:hand;' : '';
			if (this.style.border) {
				prevStyle += 'border:'+this.style.border+';';
				this.style.border = '';
			}
			if (this.style.padding) {
				prevStyle += 'padding:'+this.style.padding+';';
				this.style.padding = '';
			}
			if (this.style.margin) {
				prevStyle += 'margin:'+this.style.margin+';';
				this.style.margin = '';
			}
			var imgStyle = (this.style.cssText);

			strNewHTML += '<span '+imgId+imgClass+imgTitle+imgAlt;
			strNewHTML += 'style="position:relative;white-space:pre-line;display:inline-block;background:transparent;'+imgAlign+imgHand;
			strNewHTML += 'width:' + jQuery(this).width() + 'px;' + 'height:' + jQuery(this).height() + 'px;';
			strNewHTML += 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + jQuery(this).attr('src') + '\', sizingMethod=\'scale\');';
			strNewHTML += imgStyle+'"></span>';
			if (prevStyle != ''){
				strNewHTML = '<span style="position:relative;display:inline-block;'+prevStyle+imgHand+'width:' + jQuery(this).width() + 'px;' + 'height:' + jQuery(this).height() + 'px;'+'">' + strNewHTML + '</span>';
			}

			jQuery(this).hide();
			jQuery(this).after(strNewHTML);

		});

		// fix css background pngs
		jQuery(this).find("*").each(function(){
			var bgIMG = jQuery(this).css('background-image');
			if(bgIMG.indexOf(".png")!=-1){
				var iebg = bgIMG.split('url("')[1].split('")')[0];
				jQuery(this).css('background-image', 'none');
				jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + iebg + "',sizingMethod='scale')";
				jQuery(this).find("a").css('position', 'relative');
			}
		});
		
		//fix input with png-source
		jQuery(this).find("input[src*=.png]").each(function() {
			var bgIMG = jQuery(this).attr('src');
			jQuery(this).get(0).runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + bgIMG + '\', sizingMethod=\'scale\');';
   		jQuery(this).attr('src', settings.blankgif)
		});
	
	}
	
	return jQuery;

};

})(jQuery);
;// Need to preload the spinner image or it will not show in firefox on a form submit
spinner = new Image();
spinner.src = '/sites/all/modules/sprout/images/indicator_medium.gif';

// Messages for leaving an unsaved sprout.
var promptToSaveChanges = false;
var savePromptMessage = Drupal.t('If you leave this page you will lose any unsaved changes you have made to your sprout. To save any changes, press Cancel and then click the Save button in the top right corner of your screen.');
var fakeSavePromptMessage = Drupal.t('Are you sure you want to navigate away from this page?') + "\n\n"
  + savePromptMessage + "\n\n"
  + Drupal.t('Press OK to lose your unsaved changes, or Cancel to stay on the current sprout.');

var showingBrowserUpgrade = false;
var popupNewOpenDialog = false;

var inBuilder = false;

$(document).ready(function() {
  $('#logo-floater').pngFix();
  inBuilder = $('#sproutobject').length;
  browserNeedsUpgrade();
});

Drupal.behaviors.new_project = function (context) {
  $('#sprout-project-add-form #edit-canvas:not(.change-processed)').change(function() {
    var wh = this.value.split('x');
    $('#sprout-project-add-form #edit-width').val(wh[0]);
    $('#sprout-project-add-form #edit-height').val(wh[1]);
  }).addClass('change-processed');
  $('div#new-project.dialog-right .sprout-project-blank:not(.click-processed)').click(function() {
    tb_load_ajax('/ajax/project/new');
    return false;
  }).addClass('click-processed');
  $('div#new-project.dialog-right .sprout-project-template:not(.over-processed)').mouseover(function() {
    $('.sprout-project-operations', this).show();
  }).addClass('over-processed');
  $('div#new-project.dialog-right .sprout-project-template:not(.out-processed)').mouseout(function() {
    $('.sprout-project-operations', this).hide();
  }).addClass('out-processed');
  $('div#open-filter-left #edit-sort:not(.change-processed)').change(function() {
    tb_load_ajax('/ajax/project/new-open?sort='+ $(this).val());
    return false;
  }).addClass('change-processed');
  $('div#open-filter-right #edit-filter:not(.change-processed), div#open-filter-full #edit-filter:not(.change-processed)').change(function() {
    tb_load_ajax('/ajax/project/new-open?filter='+ $(this).val());
    return false;
  }).addClass('change-processed');
  $('#sprout-project-add-form:not(.submit-processed)').submit(function() {
    return validateForm('#sprout-project-add-form');
  }).addClass('submit-processed');
};

function browserNeedsUpgrade() {
  if ($.cookie("browserChecked") == null
  && (($.browser.msie && /MSIE\s(5\.5|6\.)/i.test(navigator.userAgent) && !/MSIE\s(7\.)/i.test(navigator.userAgent))
  || ($.browser.mozilla && /Firefox\/(0\.|1\.)/i.test(navigator.userAgent))
  || ($.browser.safari && (!/Version\/3\./i.test(navigator.userAgent) && !/Mozilla\/5./i.test(navigator.userAgent)))
  || ($.browser.opera))) {

    showingBrowserUpgrade = true;

    var currentBrowserString = 'an unsupported browser';
    var upgradeBrowserString = 'upgrade to ';
    if ($.browser.msie) {
      currentBrowserString = 'Internet Explorer 6 or earlier';
      upgradeBrowserString = '<a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">upgrade to Internet Explorer 7</a> or use ';
    }
    else if ($.browser.mozilla) {
      currentBrowserString = 'Firefox 1.5 or earlier';
      upgradeBrowserString = '<a href="http://www.mozilla.com/firefox">upgrade to Firefox 2</a> or use ';
    }
    else if ($.browser.safari) {
      currentBrowserString = 'Safari 2 or earlier';
      upgradeBrowserString = '<a href="http://www.apple.com/safari/download">upgrade to Safari 3</a> or use ';
    }

    $('body').append('<div id="upgradeBrowser" style="display: none"><div style="padding: 5px 10px; font-size: 1.2em; line-height: 1.3em;">'
      + '<p>We notice that you\'re using ' + currentBrowserString + '. So we can provide the best online experience to you, '
      + 'please ' + upgradeBrowserString + ' one of these more standards-compliant browsers:</p>'
      + '<ul><li><a href="http://www.mozilla.com/firefox">Firefox 2</a></li>'
      + (navigator.userAgent.toLowerCase().indexOf('windows') != -1 ? '<li><a href="http://www.microsoft.com/windows/products/winfamily/ie/default.mspx">Internet Explorer 7</a></li>' : '')
      + (navigator.userAgent.toLowerCase().indexOf('mac') != -1 ? '<li><a href="http://www.apple.com/safari/download">Safari 3</a></li>' : '')
      + '</ul><a href="#" onclick="return closeBrowserWindow();" style="display: block; text-align: center; font-weight: bold;">Close This Window</a>'
    + '</div></div>');
    tb_show("Please upgrade your browser!", '#TB_inline?height=250&width=450&modal=true&replace=true&inlineId=upgradeBrowser', false);

    $("#TB_window").unload(function () {
      showingBrowserUpgrade = false;
    });
  }
  //$.cookie("browserChecked", null, { path: '/' });
  $.cookie("browserChecked", 1, { expires : 1, path: '/' });
}

function closeBrowserWindow() {
  if (popupNewOpenDialog) {
    popupNewOpenDialog = false;
    showNewOpenDialog();
  }
  else {
    tb_remove();
  }
  return false;
}

function showPopupDialog(popup) {
  var func = 'show' + popup;
  if (eval('typeof ' + func) == 'function') {
    eval(func+'()');
  }
}

function showNewOpenDialog() {
  $('#header-button-new').trigger('mousedown');
}

function showRegisterDialog() {
  $('#register-button').trigger('click');
}

function validateFormNoSavePrompt(form_name, form) {
  return validateForm(form_name, form, false);
}

function validateForm(form_name, form, honorPromptToSaveChanges) {
  if (typeof honorPromptToSaveChanges == 'undefined') {
    honorPromptToSaveChanges = true;
  }

  // Setting the cursor here interferes with the builder cursor (SPROUT-5171)
  // document.body.style.cursor='wait';
  if (typeof(form_name) == 'string') {
    $form = $(form_name);
  } else {
    $form = $(form);
  }
  var error = '';
  $('.required', $form).each(function(i){
    if ($(this).val() == '') {
      title = $('label[@for='+$(this).attr('id')+']:first').text();
      title = title.replace(/\: \*/g,'');
      error += 'The "'+title+'" field is required.' + "\n";
    }
  });
  if (error.length) {
    document.body.style.cursor='auto';
    alert(error);
    return false;
  }
  else {
    // New project creation needs some hacking for the "prompt on save" behavior
    // as it would just spin forever if you hit Cancel. So we ask user to go
    // save changes first or else they will be lost and do not run the normal
    // onbeforeunload event.
    if (honorPromptToSaveChanges && promptToSaveChanges
    && typeof Drupal.settings.sproutBuilder != 'undefined'
    && Drupal.settings.sproutBuilder.sproutAccountVerified) {
      var saveChanges = confirm(fakeSavePromptMessage);
      if (!saveChanges) {
        document.body.style.cursor = 'auto';
        tb_remove();
        return false;
      }
      else {
        promptToSaveChanges = false;
      }
    }
    if ($('.sproutSubmitIndicator', form).length) {
      sproutSubmitIndicator('Creating new project...');
    }
    return true;
  }
}

function sproutSubmitIndicator(message) {
  $('#dialog-new-project').hide();
  tb_show(null, '#TB_inline?height=200&width=350&modal=true', false);
  $('#dialog-new-project').after('<div id="sproutThrobber" style="text-align: center; margin: 50px;"><h1>'+ message +'</h1><p/><img src="'+ spinner.src +'" /></div>');
}

Drupal.behaviors.settingsTab = function (context) {
  $('#sprout-personal-settings-form:not(.form-processed)').ajaxForm({
    dataType:  'json',
    beforeSubmit: validateFormNoSavePrompt,
    success: processTrayForm
  }).keydown(function() {
    $('#sprout-personal-settings-form #edit-cancel').show();
  }).addClass('form-processed');

  $('#tray #sprout-whitelabel-portal-settings-form:not(.form-processed)').ajaxForm({
    dataType:  'json',
    beforeSubmit: validateForm,
    success: processTrayForm
  }).addClass('form-processed');
};

function processTrayForm(data) {
  document.body.style.cursor='auto';
  if (typeof(data.fullname) != 'undefined') {
    $('#fullname').html(data.fullname);
  }
  alert(data.message);
  if (typeof data.url != 'undefined') {
    refreshTrayContent(data.url);
  }
}

Drupal.behaviors.userRegister = function (context) {
  $('#sprout-user-register-form:not(.form-processed)').ajaxForm({
    dataType:  'json',
    beforeSubmit: validateForm,
    success: processRegisterForm
  }).addClass('form-processed');
  $('#sprout-email-verify-form:not(.form-processed)').ajaxForm({
    dataType:  'json',
    beforeSubmit: validateForm,
    success: processEmailVerifyForm
  }).addClass('form-processed');
  $('.resend-confirmation:not(.click-processed)').click(function() {
    $.getJSON('/ajax/user/resend_confirmation', function (data) {
      alert(data.message);
    });
    return false;
  }).addClass('click-processed');
  $('#user-registration:not(.click-processed)').click(function() {
    tb_load_ajax('/ajax/user/register?force_register=1');
    return false;
  }).addClass('click-processed');
};

function processRegisterForm(data) {
  document.body.style.cursor='auto';
  if (checkError(data)) {
    if (data.header) {
      $('#header-login').empty().html(data.header);
    }
    $("#fullname").html(data.fullname);
    tb_load_ajax('/ajax/user/register');
  }
}

function processEmailVerifyForm(data) {
  document.body.style.cursor='auto';
  if (checkError(data)) {
    if (typeof Drupal.settings.sproutBuilder != 'undefined') {
      Drupal.settings.sproutBuilder.sproutAccountVerified=true;
    }
    if (data.header) {
      $('#header-login').empty().html(data.header);
      tb_init('a.thickbox, area.thickbox, input.thickbox');
    }
    tb_load_ajax('/ajax/user/register');
  }
}

function tb_load_ajax(href) {
  $.get(href, function (data) {
    $('#TB_ajaxContent').empty().html(data);
    Drupal.attachBehaviors($('#TB_ajaxContent'));
  });
}

// Operations for the projects tab
Drupal.behaviors.projectsTab = function (context) {

  $('#projects-tab .projects-tab-project .projects-tab-info .embed input.copy-embed-code:not(.op-processed)').click(function () {
    copyToClipboard($(this).prev().get(0));
  })
  .addClass('op-processed');
  $('#sprout-gallery-state-form #edit-state:not(.change-processed)').change(function() {
    refreshTrayContent('/projects?notheme=1&state='+ $(this).val());
    return false;
  }).addClass('change-processed');
  $('.sprout-view-assets:not(.click-processed)').click(function() {
    var nid = ($(this).attr('id'));
    nid = nid.replace(/view_assets_/,'');
    $('a[@href^="/assets?"]').attr({href: '/assets?notheme=1&nid='+ nid}).mousedown().attr({href: '/assets?notheme=1'});
    return false;
  }).addClass('click-processed');

  var projectsDiv = $('#projects-tab');
  var projectInfo = $('.projects-tab-project .projects-tab-info', projectsDiv);

  // Make current project title in projects tab editable
  if (typeof Drupal.settings.sproutBuilder != 'undefined') {
    var currentTitle = $('.page-edit #header-title h1').text();
    $('#project-' + Drupal.settings.sproutBuilder.currentProjectNID
      + ' .projects-tab-info .title h2:not(.processed)', projectsDiv)
    .addClass('current-title')
    .text(currentTitle)
    .bind('click', function () {
      var answer = prompt('Rename sprout as:', currentTitle);
      $(this).text(answer);
      setCurrentProjectTitle(answer, true);
    })
    .hover(
      function () {
        $('.status', $(this).parent()).html('Click project title to rename.');
      },
      function () {
        $('.status', $(this).parent()).empty();
      }
    ).addClass('processed');
  }

  // Make other project title in projects tab editable
  $('.title h2:not(.processed)', projectInfo)
  .hover(
    function () {
      $('.status', $(this).parent()).html('Open project and click on title to rename.');
    },
    function () {
      $('.status', $(this).parent()).empty();
    }
  ).addClass('processed');

  // Make project description in projects tab editable
  $('.description h4:not(.editable-processed)', projectInfo)
  .bind('click', function () {
    $(this).trigger('makeEditable').next('.rename-ops').show();
    $('.status', $(this).parent()).hide();
  })
  .editable(function(value, settings) {
    $.post('/ajax/project/set-description', {
      'project_nid' : $(this).parent().parent().parent().attr('id').split('-')[1],
      'description'       : value
    }, handleProjectEditInTab, 'json');
    return value;
  }, {
    event     : 'makeEditable',
    indicator : 'Saving...',
    tooltip   : "Click to change this project's description.",
    cssclass  : 'editable-project-description',
    width     : 'none',
    height    : 'none',
    select    : true,
    focus     : true,
    type      : 'textarea',
    onblur    : function (value, settings, e) {
      // Don't execute blur action if clicked on Save or Cancel link.
      if (typeof e.explicitOriginalTarget != 'undefined' && !$(e.explicitOriginalTarget).parent().parent().hasClass('rename-ops')) {
        $(this).siblings('.rename-ops').children('a.save').trigger('click');
      }
    },
    oncancel  : function (value, settings, e) {
      // Trigger Cancel link if user hits ESC.
      $(this).siblings('.rename-ops').children('a.cancel').trigger('click');
    }
  })
  .hover(
    function () {
      $('.status', $(this).parent()).html('Click project description to change.');
    },
    function () {
      $('.status', $(this).parent()).empty();
    }
  ).addClass('editable-processed');

  $('.rename-ops a.save:not(.editable-processed)', projectInfo).bind('click', function () {
    this.blur();
    current = $(this).parent().parent();
    $('h2, h4', current).children('form').trigger('submit');
    return false;
  })
  .addClass('editable-processed');

  $('.rename-ops a.cancel:not(.editable-processed)', projectInfo).bind('click', function () {
    this.blur();
    current = $(this).parent().parent();
    $('h2, h4', current).trigger('editableReset').next('.rename-ops').hide();
    $('.status', current).show();
    return false;
  })
  .addClass('editable-processed');

};

function handleProjectEditInTab(data) {
  nid = data.nid;
  where = $('#projects-tab #project-'+ data.nid +' .projects-tab-info .'+ data.type);
  if (data.type == 'title') {
    tag = 'h2';
  } else if (data.type == 'description') {
    tag = 'h4';
    if (!data.value) {
      data.value = 'Click to edit';
    }
  }
  $(tag, where).html(data.value);
  if (checkError(data)) {
    $('.rename-ops', where).hide();
    $('.status', where).show();
    if (typeof Drupal.settings.sproutBuilder != 'undefined' && data.nid == Drupal.settings.sproutBuilder.currentProjectNID && data.value && data.type == 'title') {
      setCurrentProjectTitle(data.value);
    }
  }
  else {
    $('h2', where).trigger('click');
  }
}

Drupal.behaviors.feedbackTab = function (context) {
  $('#sprout-feedback-form:not(.processed)').ajaxForm({
    dataType:  'json',
    beforeSubmit: validateFormNoSavePrompt,
    success: processTrayForm
  }).addClass('processed');
};

function hideBuilder() {
  $('#sprout-wrapper embed,object').attr('height','0').attr('width','0');
}

function showBuilder() {
  $('#sprout-wrapper embed,object').attr('height','100%').attr('width','100%');
}

function deleteSproutProject(nid, currentNID) {
  $('#delete-project').hide();
  tb_show(null, '#TB_inline?height=200&width=350&modal=true', false);
  $('#delete-project').after('<div id="sproutThrobber" style="text-align: center; margin: 50px;"><h1>Deleting project...</h1><p/><img src="'+ spinner.src +'" /></div>');
  $.post('/ajax/project/delete/'+ nid +'/confirmed', {nid: nid}, function(data) {
    if (checkError(data)) {
      if (nid == currentNID) {
        window.onbeforeunload = null;
        location.replace('/');
      } else {
        refreshTrayContent($('.tray-tabs .active-tab a').attr('href'));
        tb_remove();
      }
    }
  }, 'json');
}

function dialogVisible() {
  return $('#TB_window').length > 0;
}

/**
 * Suspends cursor management in Builder to avoid HTML overlay hiding cursor.
 */
function suspendCursorManagement() {
  if (!inBuilder || !applicationLoadComplete)
    return;

  sendMessage('APP:SUSPEND_CURSOR_MGMT', null);
}

/**
 * Resumes cursor management as long as tray and thickbox dialogs are closed.
 */
function resumeCursorManagement() {
  if (!inBuilder || !applicationLoadComplete || isTrayOpen() || dialogVisible())
    return;

  sendMessage('APP:RESUME_CURSOR_MGMT', null);
}
;// $Id$

var applicationLoadComplete = false;

Drupal.behaviors.sprout_buttons = function (context) {
  if (typeof Drupal.settings.sproutBuilder != 'undefined' && applicationLoadComplete) {
    enableButtons();
  }
  else {
    disableButtons();
  }
  $('ul#new-project-tabs:not(.tab-processed)')
  .tabs({
    cache : true
  })
  .addClass('tab-processed');

  $('#header-buttons #header-button-new:not(.tb-processed), a#add-project:not(.tb-processed), a.delete-project:not(.tb-processed)').disable('click').sproutThickbox().addClass('tb-processed');

  $('a#header-button-reports:not(.click-processed)').bind('click', function () {
    $(this).focus();
    this.blur();
    hideBuilder();
    tb_show(null, '/reports?notheme=1&height=500&width=900&modal=true', false);
    return false;
  }).addClass('click-processed');
};

function enableButtons() {
  $('#header-buttons a#header-button-save.disabled').disable('click').bind('mousedown', function () {
    $(this).focus();
    $(this).blur();
    saveProject();
    return false;
  }).removeClass('disabled');

  $('#header-buttons a#header-button-saveas.disabled').disable('click').bind('mousedown', function () {
    $(this).focus();
    $(this).blur();
    saveasProject();
    return false;
  }).removeClass('disabled');

  $('#header-buttons a#header-button-preview.disabled').disable('click').bind('mousedown', function () {
    $(this).focus();
    $(this).blur();
    togglePreview();
    return false;
  }).removeClass('disabled');

  // Save project (async) and open publish screen.
  $('#header-buttons a#header-button-publish.disabled').disable('click').bind('mousedown', function () {
    $(this).focus();
    this.blur();
    startPublishFlow();
    return false;
  }).removeClass('disabled');
}

function disableButtons() {
  $('#header-buttons a.dependent:not(.disabled)').disable('click').disable('mousedown').addClass('disabled');
}
;// Global flag indicating the user has dropped an asset on "New Folder"
// Folder we're renaming or deleting.
var modifyingFolderTID;
var modifyingAssetNID;

var minSliderValue = 0;
var maxSliderValue = 200;

var editableAssetHeightOffset = 30;

// Object to store asset information when dropping an asset on "New Folder"
var droppedAsset = {};

// Information about where we are trying to drop this asset.
var dropTarget = {};

/**
 * Attaches different behaviors to asset manager which is needed since we get asset content
 * over AJAX and need to reattach behaviors.
 */
Drupal.behaviors.sprout_assets = function (context) {
  var $galleryMenu = $('ul#gallery-menu');

  // If we've renamed a project and it's listed here, show the in-memory name.
  if (typeof Drupal.settings.sproutBuilder != 'undefined') {
    var currentTitle = $('.page-edit #header-title h1').text();
    $('li#project-header-' + Drupal.settings.sproutBuilder.currentProjectTID
      + ' a span.name:not(.title-processed)', $galleryMenu)
    .text(currentTitle)
    .addClass('current-title title-processed');
  }

  // Change any folder links to pull content into container panel
  // instead of actually taking browser to that href.
  $('a:not(.ajax-processed)', $galleryMenu).disable('click').bind('mousedown', function () {
    $(this).blur().parent('li').siblings().removeClass('selected').end().addClass('selected');
    $('#gallery-folders-pager a.fit-processed:first').scrollToActive();
    refreshAssets($(this).attr('href'));
    return false;
  })
  .addClass('ajax-processed');

  // Change any media type links to pull content into container panel
  // instead of actually taking browser to that href.
  $('ul#asset-type-tabs li a:not(.ajax-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();
    refreshAssets($(this).attr('href'));
    return false;
  })
  .addClass('ajax-processed');

  // Change any asset pager links to pull content into container panel
  // instead of actually taking browser to that href.
  $('#gallery-assets div.pager a:not(.ajax-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();

    var href = $(this).attr('href');

    // Silly pager hack for first page load to not try and AJAX get /assets/* but rather
    // the Ajax counterpart that just gets assets. Could have done it more elegantly.
    refreshAssets(href.replace(/^(http:\/\/.+)?\/assets?(.*)$/, "$1/ajax/gallery-assets$2"));
    return false;
  })
  .addClass('ajax-processed');


  // Enable the add asset link to open or close the add asset panel
  $('#gallery-toolbar a#add-asset:not(.add-asset-processed)').disable('click').bind('mousedown', function () {
    this.blur();

    var t = this.title || this.name || null;
    var g = this.rel || false;
    var uri = '/add/assets/' + Drupal.settings.sprout.currentFolder.tid + '?notheme=1&height=445&width=500&modal=true';
    if (typeof Drupal.settings.sproutBuilder != 'undefined') {
      uri = uri + '&current_project=' + Drupal.settings.sproutBuilder.currentProjectTID;
    }
    tb_show(t, uri, g);

    $('#TB_window:not(.refresh-processed)')
    .bind('unload', function () {
      // If last folder we uploaded to is different than current OR it is all assets (since you can never upload here), switch to that folder.
      if (typeof lastUploadedFolderTID != 'undefined' && (Drupal.settings.sprout.currentFolder.tid != lastUploadedFolderTID || Drupal.settings.sprout.currentFolder.isAllAssets)) {
        Drupal.settings.sprout.currentFolder.tid = lastUploadedFolderTID;
        Drupal.settings.sprout.currentFolder.isAllAssets = false;
        Drupal.settings.sprout.currentFolder.assetType = 'all';
      }
      refreshFoldersAndAssets();
    })
    .addClass('refresh-processed');

    // Switch to "All Types" tab if not there already.
    switchToAllTypesTab();

    return false;
  }).addClass('add-asset-processed');

  $('#gallery-assets .content a.activate-add-asset:not(.add-asset-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();
    var $addAssetButton = $('#gallery-toolbar a#add-asset');
    if (!$addAssetButton.hasClass('active')) {
      $addAssetButton.trigger('mousedown');
    }
    return false;
  }).addClass('add-asset-processed');

  // Give assets a hover craft... I mean class.
  $('#gallery-assets .asset:not(.hover-processed)')
  .hover(
    function() {
      $(this).addClass('hover');
    },
    function() {
      $(this).removeClass('hover');
    }
  )
  .addClass('hover-processed');

  // Make asset titles editable.
  $('#gallery-assets .asset .title:not(.editable-processed)').editable(function(value, settings) {
    modifyingAssetNID = $(this).parent('.operations').parent('.asset').attr('id').split('-')[1];

    var $assetDiv = $('#gallery-assets #asset-' + modifyingAssetNID + ' .operations').children('a.op').show().end().children('.rename-ops').hide().parent().parent();
    adjustAssetDiv('down', $assetDiv);

    $.post("/ajax/asset/rename", { asset_nid: modifyingAssetNID, title: value }, handleAssetRename, "json");
    return encodeSpecialChars(value);
  }, {
    type      : 'decoded_text',
    event     : 'makeEditable',
    indicator : "Saving...",
    id        : "asset_nid",
    name      : "title",
    tooltip   : 'Click to edit asset title.',
    cssclass  : 'editable-asset',
    width     : 'none',
    height    : 'none',
    select    : true,
    focus     : true,
    onblur    : function (value, settings, e) {
      // Don't execute blur action if clicked on Save or Cancel link.
      if (typeof e.explicitOriginalTarget != 'undefined' && !$(e.explicitOriginalTarget).parent().parent().hasClass('rename-ops')) {
        $(this).siblings('.rename-ops').children('a.save').trigger('mousedown');
      }
    },
    oncancel  : function (value, settings, e) {
      $(this).siblings('.rename-ops').children('a.cancel').trigger('mousedown');
    }
  })
  .bind('mousedown', function () {
    $(this).siblings('a.rename').trigger('mousedown');
  })
  .addClass('editable-processed');

  // And make rename links trigger click.
  $('#gallery-assets .rename:not(.rename-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();

    $(this).siblings('a.op').andSelf()
      .hide()
    .end()
    .siblings('.rename-ops')
      .show()
    .end()
    .siblings('div.title')
      .trigger('makeEditable')
    .end();

    var $assetDiv = $(this).parents('div.asset');
    adjustAssetDiv('up', $assetDiv);
    return false;
  })
  .addClass('rename-processed');

  // Allow a place asset in builder button.
  $('#gallery-assets .add-asset:not(.click-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();

    if (typeof assetDropToBuilder != 'undefined') {
      assetDropToBuilder($(this).parents('.asset').get(0), 0, 0);
    }

    return false;
  })
  .addClass('click-processed');

  // Delete asset button.
  $('#gallery-assets .delete:not(.click-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();
    var asset_nid = $(this).parent('.operations').parent('.asset').attr('id').split('-')[1];
    modifyingAssetNID = asset_nid;
    var title = $('div.title', $(this).parent('.operations').parent('.asset')).html();
    if (confirm('Are you sure you want to delete '+ title +'?')) {
      $.post('/ajax/asset/delete', {asset_nid: asset_nid, folder_tid: Drupal.settings.sprout.currentFolder.tid}, function (data) {
        if (checkError(data)) {
          $('#asset-'+ data.asset_nid).remove();
          refreshFoldersAndAssets()
        }
      }, 'json');
    }
    return false;
  })
  .addClass('click-processed');

  // Supplied toggle button.
  $('#gallery-assets .group:not(.click-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();
      var asset_nid = $(this).parent('.operations').parent('.asset').attr('id').split('-')[1];
    modifyingAssetNID = asset_nid;
    $.post('/ajax/asset/toggle-supplied', {asset_nid: asset_nid, folder_tid: Drupal.settings.sprout.currentFolder.tid}, function (data) {
        if (checkError(data)) {
          refreshFoldersAndAssets()
        }
      }, 'json');
    return false;
  })
  .addClass('click-processed');

  // Make save link do stuff to editable box.
  $('#gallery-assets .rename-ops a.save:not(.op-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();
    var $field = $(this).parent().siblings('div.title');
    $field.children('form').trigger('submit');
    return false;
  })
  .addClass('op-processed');

  // Make cancel link do stuff to editable box.
  $('#gallery-assets .rename-ops a.cancel:not(.op-processed)').disable('click').bind('mousedown', function () {
    $(this).blur();
    $(this).parent().siblings('div.title').trigger('editableReset').siblings().toggle();

    var $assetDiv = $(this).parents('div.asset');
    adjustAssetDiv('down', $assetDiv);
    return false;
  })
  .addClass('op-processed');

  // Flipping images in albums.
  $("div.thumb:not(.flip-processed)").bind("mousemove", function(e) {

    if(!this.offset) this.offset = $(this).offset({ border: false });

    //Determine mouse position and stripe length
    var p = e.clientX-this.offset.left;
    if(p == 0) return; else p--;
    var length = (this.getAttribute("stripelength"));

    //Change background position
    var left = Math.floor((p/80) * length) * 80;
    $(this).css("background-position", (-left)+"px 0px");
  })
  .addClass('flip-processed');

  // Make asset draggable.
  $('div#gallery div#gallery-assets img.thumb:not(.drag-processed)')
  .bind('click', function() {
    overlay.prepare(this); // Fill the overlay and bind events.
  })
  .hover(
    function() {
      $(this).addClass("hover");
    },
    function() {
      $(this).removeClass("hover");
    }
  )
  .draggable({
    appendTo    : 'body',
    helper      : function () {
      return $("<div class='draggable'></div>").append($(this).clone())[0];
    },
    cursorAt    : { top: 10, left: 10 },
    containment : 'parent'
  })
  .addClass('drag-processed');

  // Make slider for thumbnails and let mousewheel change it too!
  var sliderElement = $('div#gallery-toolbar div.slider:first:not(.slider-processed)');
  var sliderUI = new $.ui.slider(sliderElement, {
    minValue   : minSliderValue,
    maxValue   : maxSliderValue,
    startValue : getSavedSliderValue(),
    slide      : resizeAssetsOnSlide,
    change     : function (e, ui) {
      $.cookie('sliderValue', ui.slider.curValue);
    }
  });

  sliderElement.mousewheel(function(event, delta) {
    if (delta > 0) {
      sliderUI.moveTo(sliderUI.interaction.curValue + 10, null, true);
    }
    else if (delta < 0) {
      sliderUI.moveTo(sliderUI.interaction.curValue - 10, null, true);
    }

    event.preventDefault();
  })
  .addClass('slider-processed');

  // Resize all images to slider size on page load.
  var dummyEvent = {};
  var dummyUI = {};
  dummyUI.value = getSavedSliderValue();
  resizeAssetsOnSlide(dummyEvent, dummyUI);

  // Fix slider handle PNG.
  $('div.handle:not(.png-processed)').ifixpng().addClass('png-processed');

  // Make folders accept drops from assets.
  $("#gallery-menu li:not(.folder-drop-processed)").addClass('folder-drop-processed').droppable({
    accept: ".thumb",
    tolerance: "pointer",
    over: function(ev, ui) {
      // Get info about the target folder's URL.
      var target = $(this).children("a:first").attr("href").split("/");
      dropTarget.folderTID = target[target.length - 1];
      dropTarget.projectTID = dropTarget.folderTID;
      dropTarget.folderIsUncategorized = true; //$(this).is("li.uncategorized");
      dropTarget.copy = isCopyingAsset(dropTarget, ev);

      // Add styles to <li>.
      var classStr = 'over';
      if (dropTarget.copy) {
        classStr = classStr + ' copy';
      }
      $(this).add(ui.helper).addClass(classStr);
    },
    out: function(ev, ui) {
      $(this).add(ui.helper).removeClass('over copy');
    },
    drop: function(ev, ui) {
      $(this).add(ui.helper).removeClass('over copy');

      var assetID = $(ui.draggable.element).parent('.asset').attr("id").split("-")[1];

      // If not trying to copy/move to same folder, go ahead.
      if (dropTarget.folderTID != Drupal.settings.sprout.currentFolder.tid || Drupal.settings.sprout.currentFolder.isUncategorized != dropTarget.folderIsUncategorized) {

        // (removed)If we're moving to Uncategorized (meaning it's in same project), then make sure the user
        // is okay with removing it from this project's folders.
        //if (dropTarget.folderIsUncategorized && !dropTarget.copy) {
        //  if (!confirm("This action will uncategorize this asset from the current project's folders. Are you sure you want to continue?")) {
        //    return;
        //  }
        //}

        // Recheck this as we could have hit the shift key late.
        dropTarget.copy = isCopyingAsset(dropTarget, ev);

        tagAsset(dropTarget.copy, assetID, dropTarget.folderTID, Drupal.settings.sprout.currentFolder.tid);

        // TODO: Should check success and only remove if successful, but fine for now.
        if (!dropTarget.copy) {
          $(ui.element.parentNode).remove();

          // If no assets left, show an empty message.
          if (!$("#gallery-assets div.asset").length) {
            $("#gallery-assets").append("<p>This folder no longer contains any assets.</p>");
          }
        }
      }

      // Reset dropTarget object.
      dropTarget = {};
    }
  })
  .hover(
    function() {
      $(this).addClass("hover");
    },
    function() {
      $(this).removeClass("hover");
    }
  );

  /*if ($('ul#gallery-menu li').length > 5) {
    $('ul#gallery-menu:not(.pager-processed)').pager('li', {
      pageSize      : 5,
      height        : 'auto',
      eventName     : 'mousedown',
      navAttach     : 'none',
      navId         : 'gallery-folders-pager',
      selectedIndex : typeof Drupal.settings.sprout != 'undefined' ? $('#gallery-menu li').index($('#gallery-menu li#project-header-' + Drupal.settings.sprout.currentFolder.tid).get(0)) : 0
    })
    .addClass('pager-processed');

    $('#gallery-folders-pager').show().find('a:not(.fit-processed)').disable('click').bind('mousedown', fitAssetPanelToFolders).addClass('fit-processed');
  }*/

  $('#gallery-folders-pager').show().find('a:not(.fit-processed)').disable('click').folderScroll().addClass('fit-processed');

  // Do this on load only as other functions call this when appropriate.
  var $gallery = $('#gallery');
  if (!$gallery.hasClass('fit-processed')) {
    fitAssetPanelToFolders();
    $gallery.addClass('fit-processed');
  }

  $('ul#add-asset-tabs:not(.tab-processed)')
  .tabs({
    cache : true
  })
  .addClass('tab-processed');
};

$(document).ready(function () {
  $('body').append('<div class="overlay-background"></div><div class="overlay"><div id="player"></div></div>');
  overlay.container = $("div.overlay");
});

function adjustAssetDiv(direction, $obj) {
  if (direction == 'up' && !$obj.hasClass('height-adjusted')) {
    $obj.css({
      paddingBottom : '5px',
      height       : Math.floor($obj.height() + editableAssetHeightOffset) + 'px'
    }).addClass('height-adjusted');
  }
  else if (direction != 'up' && $obj.hasClass('height-adjusted')) {
    $obj.css({
      paddingBottom : '35px',
      height       : Math.floor($obj.height() - editableAssetHeightOffset) + 'px'
    }).removeClass('height-adjusted');
  }
}

/**
 * Does an AJAX switch to the All Types tab if we're not already there.
 */
function switchToAllTypesTab() {
  // Switch to "All Types" tab if not there already.
  if (!$('#asset-tab-all').parent().hasClass('active')) {
    var uri = '/ajax/gallery-assets/' + Drupal.settings.sprout.currentFolder.tid + '/' + (Drupal.settings.sprout.currentFolder.isAllAssets ? 'all' : '0');
    refreshAssets(uri);
  }
}

function tagAsset(copy, nid, targetFolderTID, currentFolderTID) {
  if (copy) {
    sproutTrace("Copying node " + nid + " to " + targetFolderTID);
    $.post("/ajax/asset/copy", { asset_nid: nid, destination_tid: targetFolderTID }, refreshCounts, "json");
  } else {
    sproutTrace("Moving node " + nid + " to " + targetFolderTID + " deleting from (" + currentFolderTID + ")");
    $.post("/ajax/asset/move", { asset_nid: nid, destination_tid: targetFolderTID, current_tid: currentFolderTID }, refreshCounts, "json");
  }
}

/**
 * Helper function to determine if we're copying or moving since both over
 * and drop from droppable use it.
 */
function isCopyingAsset(dropTarget, ev) {
  // Force a move if
  // - moving from/to "Uncategorized" in same project
  var force_move = Drupal.settings.sprout.currentFolder.projectTID == dropTarget.projectTID && (Drupal.settings.sprout.currentFolder.isUncategorized || dropTarget.folderIsUncategorized);

  // It's a copy if not a move and one of the following:
  // - holding down ctrl/shift/alt/meta key
  // - we're currently viewing all assets
  // - moving between different projects (removed || Drupal.settings.sprout.currentFolder.projectTID != dropTarget.projectTID)
  return !force_move && (ev.ctrlKey || ev.shiftKey || ev.altKey || ev.metaKey
         || Drupal.settings.sprout.currentFolder.isAllAssets);
}

/**
 * Function that goes through data.counts and updates any element IDs
 * with new counts after a copy/move.
 */
var refreshCounts = function (data) {
  if (checkError(data)) {
    for (var id in data.counts) {
      $("#" + id).html("(" + data.counts[id] + ")");
    }
  }
};

var checkError = function (data) {
  if (!data.success) {
    alert(data.message);
  }
  return data.success;
};

function getCurrentAssetPath() {
  var uri = '/ajax/gallery/' + Drupal.settings.sprout.currentFolder.tid + '/';
  if (Drupal.settings.sprout.currentFolder.isAllAssets) {
    uri = uri + 'all/';
  }
  else {
    uri = uri + '0/';
  }
  uri = uri + Drupal.settings.sprout.currentFolder.assetType;
  if (typeof Drupal.settings.sproutBuilder != 'undefined') {
    uri = uri + '?current_project=' + Drupal.settings.sproutBuilder.currentProjectTID;
  }
  return uri;
}

function refreshFoldersAndAssets() {
  //submitRenamedAssetTitles();

  $.getJSON(getCurrentAssetPath(), function (data) {
    // Destroy droppables before loading in new ones.
    $("#gallery-menu li.folder-drop-processed").droppableDestroy();
    refreshSections(data);
  });
}

function refreshFolders() {
  // Just get folders panel HTML for now.
  $.getJSON('/ajax/gallery-folders', function (data) {
    // Destroy droppables before loading in new ones.
    $("#gallery-menu li.folder-drop-processed").droppableDestroy();

    refreshSections(data);
  });
}

function refreshAssets(uri) {
  //submitRenamedAssetTitles();
  document.body.style.cursor='wait';
  $.getJSON(uri, refreshSections);
}

/**
 * A helper function that does the actual replacing of content. Takes a JSON array
 * and puts each value in #gallery-<key>.
 */
function refreshSections(data) {
  document.body.style.cursor='auto';
  var id;
  var cssId;
  var selectors = '';

  for (id in data) {
    cssId = '#gallery-' + id;
    $(cssId).html(data[id]);
    selectors = selectors + (selectors != '' ? ', ' : '') + cssId;
  }

  if (selectors != '') {
    Drupal.attachBehaviors($(selectors));
  }

  fitAssetPanelToFolders();
}

var handleAssetRename = function (data) {
  if (checkError(data)) {
  }
  else {
    $('#gallery-assets #asset-' + modifyingAssetNID + ' a.rename').trigger('mousedown');
  }
};

var overlay = {
  lastAssetDisplayed: null,
  allAssets: null,
  container: null,
  speed: 500,
  isRunning: false,
  prepare: function(cur) {
    var asset = $(cur).parent();
    // Will hold the current folder's asset gallery without paging
    overlay.displayAsset(asset, true);
    // Adjust view asset window if the user scrolls or resizes
    $(window).resize(function() {
      if (overlay.container.hasClass('open')) overlay.displayAsset(null, true);
    })
    .scroll(function() {
      if (overlay.container.hasClass('open')) overlay.displayAsset(null, true);
    });

    $.getJSON($('#asset-type-tabs li.active a').attr('href') + '?paging=false', function (data) {
      overlay.allAssets = $(data.assets);
      overlay.displayAssetPrevNext(asset);
    });

    //Append header
    $("<div class='head'>close</div>").bind("click", function() { overlay.container.hide().removeClass('open'); $('.overlay-background').fadeOut(); }).appendTo(overlay.container);
  },
  next: function() {
    if(overlay.isRunning) return;
    overlay.isRunning = true;

    overlay.displayAsset($('#'+ $('.next', overlay.container).attr('path'), overlay.allAssets));
    overlay.displayAssetPrevNext($('#'+ $('.next', overlay.container).attr('path'), overlay.allAssets));
    overlay.isRunning = false;
    return;
  },
  prev: function() {
    if(overlay.isRunning) return;
    overlay.isRunning = true;
    overlay.displayAsset($('#'+ $('.prev', overlay.container).attr('path'), overlay.allAssets));
    overlay.displayAssetPrevNext($('#'+ $('.prev', overlay.container).attr('path'), overlay.allAssets));
    overlay.isRunning = false;
    return;
  },
  displayAsset: function(asset, openBox) {
    if (asset == null) {
      if (this.lastAssetDisplayed == null) {
        return;
      }
      else {
        asset = this.lastAssetDisplayed;
      }
    }
    else {
      this.lastAssetDisplayed = asset;
    }
    var pw = parseInt(player['width'], 10), ph = parseInt(player['height'], 10), par = pw / ph;
    var cw = pw + 200, ch = ph + 100;
    if (openBox) {
      $('.overlay-background').css({
        backgroundColor:  '#000',
        width:        $(document).width(),
        height:       $(document).height(),
        background:   'transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAPSURBVHjaYmJgYGgACDAAAI8Ag+R3NvwAAAAASUVORK5CYII=)'
      }).fadeIn();

      overlay.container.css({"left": ($(window).width() / 2) - (cw / 2), width: cw, height: ch, "top": $(document).scrollTop() + 25}).show().addClass('open');
    }
    //Position the picture in the middle
    if ($('.type', asset).html() == 'image') {
      var iw = $('.width', asset).html(), ih = $('.height', asset).html(), ar = iw / ih;
      var sizeStr, ml = 0;
      ih = ph;
      iw = ih * ar;
      if (iw > pw) {
        iw = pw;
        ih = iw / ar;
        sizeStr = 'width = "'+ iw +'"';
        var ml = -cw+190;
      } else {
        sizeStr = 'height = "'+ ph +'"';
        ml = 0-iw;
      }
      //Adjust image preview position for Safari browser
      if (jQuery.browser.safari) {
        ml = (cw + ml) / 2;
      }
      var pos_y = ((ch / 2) - (ih / 2 ));
      $('#player').empty().
      html('<img src="'+ $('.player', asset).html() +'" '+ sizeStr +'" />')
      .css({'margin-top': pos_y, 'margin-left': ml})
    } 
    else if ($('.type', asset).html() == 'sproutxml') {
      $('#player').empty()
      .css({'margin-top': ((ch / 2) - (ph / 2 )), 
          'margin-left': ((cw / 2) - (pw / 2 ))})
      .html('<div class="xmlsnippet"></div>');
      $('#player .xmlsnippet').html($('.element', asset)
          .text()
          .replace(/&/g,'&amp;')
          .replace(/</g,'&lt;')
          .replace(/>/g,'&gt;')
          .replace(/[\r\n]/g, '<br/>')).css({
        height: ph,
        width: pw
      });
    }
    else {
      var pos_y = ((ch / 2) - (ph / 2 ));
      var flashVars = [];
      if ($('.flashvars', asset).html() != 'null') {
        eval('var flashVars = '+ $('.flashvars', asset).html());
      }
      $('#player').empty()
      .css({'margin-top': pos_y, 'margin-left': 0})
      .flash(
        {
          src: $('.player', asset).html(),
          width: pw,
          height: ph,
          flashvars: flashVars
        },
        {
          expressInstall: true
        }
      )
    }
    $('#player').append(
        '<p class="asset-title">'
        + ($('.type', asset).html() == 'image' ? '' : $('.title', asset).html() + '<br/>') 
        + '<a class="url" target="_blank" href="'+$('.url', asset).attr('href')+'">'+$('.url', asset).attr('href')+'</a>'
        +'</p>'
    );
    if ($('.type', asset).html() == 'image' || $('.type', asset).html() == 'sproutxml')
      $('#player .asset-title').css({
        position: 'absolute',
        top: ((ch / 2) - (ph / 2 ) + ph + 10),
        left: ((cw / 2) - (pw / 2 )),
        width: pw
      });
  },
  displayAssetPrevNext: function(asset) {
    assetID = asset.attr('id');
    next = $('#' + assetID, overlay.allAssets).next();
    prev = $('#' + assetID, overlay.allAssets).prev();
    var cw = parseInt(player['width'], 10) + 200, ch = parseInt(player['height'], 10) + 100;
    $('.next', overlay.container).remove();
    $('.prev', overlay.container).remove();
    if (next.length) {
      var img_right = $("<img class='next' src='"+ $('.thumb', next).attr('src') +"' style='width: 50px;' path ='"+ next.attr('id') +"'/>").appendTo(overlay.container);
        $(img_right).css({ left: cw - $(img_right)[0].offsetWidth - 10 , top: (ch / 2) - ( $(img_right)[0].offsetHeight / 2 ) });
        $(img_right).bind('mousedown', overlay.next);
    }
    if (prev.length) {
      var img_left = $("<img class='prev' src='"+ $('.thumb', prev).attr('src') +"' style='width: 50px;' path ='"+ prev.attr('id') +"'/>").appendTo(overlay.container);
        $(img_left).css({ left: 10, top: (ch / 2) - ( $(img_left)[0].offsetHeight / 2 ) });
        $(img_left).bind('mousedown', overlay.prev);
    }
  }

};

/**
 * Get old slider val from cookie if it was set.
 */
function getSavedSliderValue() {
  var value = $.cookie('sliderValue');
  return value != null && !isNaN(value) && value >= minSliderValue && value <= maxSliderValue ? parseInt(value, 10) : minSliderValue;
}

/**
 * Helper function to resize assets according to slider value (or whatever ui.value is).
 */
var resizeAssetsOnSlide = function(e, ui) {
  var val = ui.value + 70;
  $('div#gallery div#gallery-assets .asset')
  .width(val + 10)
  .height(Math.floor((val + 50) * 0.75))
  .children('.thumb')
    .width(val)
    .height(Math.floor(val * 0.75));
};

/**
 * Make sure assets panel is just a little bit bigger than folders accordion.
 */
function fitAssetPanelToFolders(animate) {
  var $folders = $('#gallery-folders-wrapper');
  var foldersOuterHeight = $folders.outerHeight();

  var $wrapper = $('#gallery-assets-wrapper');
  var $squeeze = $('#gallery-assets-squeeze');
  var $panel   = $('#gallery-assets-panel');

  var galleryHeaderHeight = $('#gallery-header').outerHeight();

  var extraSpaceBottom = 13;
  var targetWrapperHeight = foldersOuterHeight - ($wrapper.outerHeight() - $wrapper.height()) - galleryHeaderHeight + extraSpaceBottom;
  var targetSqueezeHeight = foldersOuterHeight - ($squeeze.outerHeight() - $squeeze.height()) - galleryHeaderHeight + extraSpaceBottom;
  var targetPanelHeight = foldersOuterHeight - (50) - galleryHeaderHeight + extraSpaceBottom;
  // TODO: $squeeze.outerHeight() - $squeeze.height() == 50, but .height() flickers. WTF?

  animate = false;
  if (!animate) {
    $wrapper.css('min-height', targetWrapperHeight + 'px');
    $squeeze.css('min-height', targetSqueezeHeight + 'px');
    $panel.css('min-height', targetPanelHeight + 'px');
    if (typeof fitTray != 'undefined') {
      fitTray();
    }
  }
  else {
    $wrapper.animate({ minHeight: targetWrapperHeight }, 100);
    $squeeze.animate({ minHeight: targetSqueezeHeight }, 100);
  }
}

function detectMacXFF() {
  var userAgent = navigator.userAgent.toLowerCase();
  if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
    return true;
  }
  return false;
}



/**
 * sproutPA: Sprout Platform Accounts UI functions
 */

function sproutPAClass() {
}

sproutPAClass.prototype = {
  edit: function(el, nid) {
    if (nid == Drupal.settings.sprout_default_pa) {
      if (!confirm("Editing this account will change the default platform account for ALL SPROUT USERS.  Are you sure?")) {
        return false;
      }
    }
    var row = this.getRow(el);
    $('label', row).show();
    $('input', row).show();
    $('select', row).show();
    this.refreshInputs(row);
    $('span', row).hide();
    $('td:last input', row).hide();
    row.addClass('sp-editing');
    return false;
  },
  getTid: function(row) {
    return $("select", row).get(0).options[$("select", row).get(0).selectedIndex].value;
  },
  refreshInputs: function(row) {
    var tid = this.getTid(row);
    if (tid && Drupal.settings.sprout_platforms[tid]) {
      if (Drupal.settings.sprout_platforms[tid].account_required == 1) {
        $('td.sp-pa-account .form-item', row).show();
      }
      else {
        $('td.sp-pa-account .form-item', row).hide();
      }
      if (Drupal.settings.sprout_platforms[tid].password_required == 1) {
        $('td.sp-pa-password .form-item', row).show();
      }
      else {
        $('td.sp-pa-password .form-item', row).hide();
      }
    }
  },
  save: function(el, nid) {
    var row = this.getRow(el);
    var postdata = {
      title: $('input[name=title]', row).get(0).value,
      accountid: $('input[name=accountid]', row).get(0).value
    };
    if ($('input[name=password].changed', row).length ||
        $('input[name=password]', row).get(0).value.search(/[^*]/) != -1)
      postdata.password = $('input[name=password]', row).get(0).value
    var vid = Drupal.settings.sprout_platforms_vid;
    if (!vid)
      spUtils.logError('Drupal.settings.sprout_platforms_vid is not set');
    var txKey = 'taxonomy[' + vid + ']';
    var tid = $("select[name='"+txKey+"']", row).get(0).options[$("select[name='"+txKey+"']", row).get(0).selectedIndex].value;
    if (Drupal.settings.sprout_platforms[tid].name == 'Gigya' && !postdata.accountid.match(/^\d+$/)) {
      alert('Gigya Account ID must be numeric (e.g. 120731)');
      return;
    }
    postdata[txKey] = tid;
    var pa = this;
    if (this.check(nid, this.getTid(row), postdata)) {
      $.ajax({
        url: '/ajax/pa/save/' + nid,
        type: 'POST',
        data: postdata,
        dataType: 'json',
        timeout: 10000,
        error: function(){
          alert('An error occurred contacting the server.  Please try again later.')
        },
        success: function(data){
          if (!data.success) {
            alert('An error occurred, please try again later: ' + data.message);
          }
          else {
            pa.load(el, data.nid);
            row.removeClass('sp-editing').removeClass('new-row');
          }
        }
      });
    }
    return false;
  },
  check: function(nid, tid, postdata) {
    var ok = false;
    if (tid == null || tid < 1) {
      alert("Please select a platform");
    }
    else {
      var platform = Drupal.settings.sprout_platforms[tid];
      if (platform == null) {
        alert("Please select a platform");
      }
      else if (platform.account_required == 1 && (postdata.accountid == null || postdata.accountid.length < 1)) {
        alert("Please enter an account id");
      }
      else if (postdata.title == null || postdata.title.length < 1) {
        alert("Please enter a name for this account");
      }
      else {
        ok = true;
      }
    }
    return ok;
  },
  load: function(el, nid) {
    var row = this.getRow(el);
    var me = this;
    $.get('/ajax/pa/load/' + nid, {}, function(data, ts){
      row.html(data);
      me.bindSelect(row);
    });
  },
  del: function(el, nid) {
    if (nid == Drupal.settings.sprout_default_pa) {
      alert("This account is required for the proper operation of Sprout.  It cannot be deleted.");
      return false;
    }
    var table = this.getTable(el);
    $.ajax({
      url: '/ajax/pa/delete/'+nid,
      type: 'GET',
      dataType: 'json',
      timeout: 10000,
      error: function(){
        alert('An error occurred contacting the server.  Please try again later.')
      },
      success: function(data){
        if (data.success) {
          sproutPA.getRow(el).remove();
          sproutPA.updateTable(table);
        }
        else {
          alert('Unable to delete account: ' + data.message);
        }
      }
    });
    return false;
  },
  cancel: function(el, nid) {
    var row = this.getRow(el);
    var table = this.getTable(el);
    if (row.hasClass('new-row')) {
      row.remove();
      this.updateTable(table);
    }
    else {
      $('span', row).show();
      $('label', row).hide();
      $('input', row).hide();
      $('select', row).hide();
      $('td:last input', row).show();
      row.removeClass('sp-editing');
    }
    return false;
  },
  updateTable: function(table) {
    if ($('.sprout_pa', table).size()) {
      $('.no-accounts-created', table).hide();
    }
    else {
      $('.no-accounts-created', table).show().css('display', 'table-row');
    }
  },
  getTable: function(el) {
    var container = $(el).parents('.sp-content').find('.sp-panel:visible');
    return $('table', container);
  },
  getRow: function(el) {
    if ($(el).is('tr')) {
      return $(el);
    }
    else {
      return $(el).parents('tr:first');
    }
  },
  create: function(el) {
    var table = this.getTable(el);
    var pa = this;
    if (!$('.new-row', table).size()) {
      table.each(function() {
        $('.no-accounts-created', this).hide();
        var type = 'odd';
        if ($('tr:not(.sp-hidden)', this).filter(':last').hasClass('odd'))
          type = 'even';
        $(this).append($('tr.empty-row', this).clone()
                       .removeClass('even').removeClass('odd')
                       .addClass('new-row').addClass(type)
                       .removeClass('sp-hidden').removeClass('empty-row'));
        $('.new-row', this).each(function(){
          pa.edit(this);
          $('input[name=title]', this).attr('value', 'My great account');
          sproutPA.bindSelect(this);
        });
      });
    }
    return false;
  },
  platforms: null,
  tabClick: function(el) {
    if (el.tagName == 'A')
      el = el.parentNode;
    var panelId = $(el).attr('id').replace(/-tab$/,'');
    $('#settings-tabs .active').removeClass('active');
    $(el).parents('.sp-content').find('.sp-panel').hide();
    $(el).addClass('active');
    $('#'+panelId).show();
    return false;
  },
  bindSelect: function(row) {
    var me = this;
    $('select:not(.processed)', row).bind('change', function() {
      me.refreshInputs(row);
      return true;
    }).addClass('processed');
    $('input[type="password"]:not(.processed)', row).bind('change', function() {
      $(this).addClass('changed');
      return true;
    }).each(function(){
      var c = $(this).parents('td').attr('class');
      var s = '';
      if (c.match) {
        var m = c.match(/pl-(\d+)/);
        var d = 0;
        if (m != null)
          d = parseInt(m[1]);
        for (var i=0; i<d; i++)
          s += '*';
      }
      this.value = s;
    })
    .bind('focus', function() {
      if (!$(this).hasClass('changed'))
        this.value = '';
    })
    .addClass('processed');
  }
};

if (typeof sproutPA == 'undefined')
  var sproutPA = new sproutPAClass;

Drupal.behaviors.sprout_pa = function (context) {
  $('.add-account-link:not(.processed)').disable('click').bind('mousedown', function() {
    return sproutPA.create(this);
  }).addClass('processed');
  $('#distribution-and-tracking tr.sprout_pa').each(function(){
    sproutPA.bindSelect(this);
  });
}

/**
 * /sproutPA
 */

/**
 * Folder scroller plugin.
 *
 * @todo This is an awful, incomplete at making this a generic plugin. Will revisit and clean up.
 */
$.fn.extend({
  folderScroll : function () {

    var settings = {
      pageSize : 5
    };

    var maxIndex = Math.max(0, $('#gallery-menu li').length - settings.pageSize);
    var currentIndex = 0;

    return this.each(function () {

      $(this).bind('mousedown', function () {
        this.blur();

        if ($(this).attr('rel') == 'next') {
          currentIndex = Math.min(maxIndex, currentIndex + settings.pageSize);
        }
        else {
          currentIndex = Math.max(0, currentIndex - settings.pageSize);
        }

        scroll();
        return false;
      })
      .bind('scrollToActive', function () {
        scroll();
      });

      setSelected();
      scroll();

      function setSelected() {
        currentIndex = Math.max(0, Math.min(maxIndex, $('#gallery-menu li').index($('#gallery-menu li.selected').get(0))));
      }

      function resize() {
        var targetHeight = $('div#gallery #gallery-menu li:gt(' + (currentIndex - 1) + '):lt(' + settings.pageSize + ')').totalHeight();
        $('div#gallery #gallery-folders').animate({
          height : targetHeight
        }, {
          speed : 500,
          complete : fitAssetPanelToFolders
        });
      }

      function scroll() {
        $('#gallery-folders').stop().scrollTo('li:eq(' + currentIndex + ')', {
          speed   : 500,
          onAfter : function () {
            resize();
          }
        });
      }
    });
  },

  scrollToActive : function () {
    return this.trigger('scrollToActive');
  }
});

/**
 * Function to unbind an event and then bind a return false to it. Used for
 * changing links to work on mousedown.
 */
$.fn.disable = function (eventName) {
  return this.each(function() {
    $(this).unbind(eventName).bind(eventName, function () {
      return false;
    });
  });
};

/**
 * Bind thickbox to 'mousedown' event instead of click.
 */
$.fn.sproutThickbox = function () {
  return this.each(function () {
    $(this).bind('mousedown', function() {
      var t = this.title || this.name || null;
      var a = this.href || this.alt;
      var g = this.rel || false;
      tb_show(t,a,g);
      this.blur();
      return false;
    });
  });
};

/**
 * Finds the aggregate height of all the objects selected.
 */
$.fn.totalHeight = function () {
  var val = 0;
  this.each(function () {
    val += $(this).height();
  });
  return val;
};
;// $Id$

var trayError = false;
var $tray;

$(document).ready(function() {
  if (!$('#tray').length) {
    return;
  }

  // Preload active tab images.
  var activeImageL = new Image(4, 31);
  activeImageL.src = '/sites/all/themes/sprout_theme/images/header-tab-active-left.png';
  var activeImageR = new Image(86, 31);
  activeImageR.src = '/sites/all/themes/sprout_theme/images/header-tab-active-right.png';

  // Preload open tab images.
  var openImageL = new Image(4, 31);
  openImageL.src = '/sites/all/themes/sprout_theme/images/header-tab-left.png';
  var openImageR = new Image(86, 31);
  openImageR.src = '/sites/all/themes/sprout_theme/images/header-tab-right.png';
});

Drupal.behaviors.sprout_tray = function (context) {
  $tray = $('#tray');
  if (!$tray.length) {
    return;
  }

  $('.tray-tabs a:not(.tray-processed)', $tray).disable('click').bind('mousedown', function () {
    // Remove dotted outline around tab.
    $(this).focus();
    $(this).blur();

    // Workaround for slider needing to be visible on load.
    if ($tray.hasClass('initial')) {
      $tray.removeClass('initial').find('#tray-content').hide().css('left', '0');
    }

    var $parentListItem = $(this).parent();
    var trayIsClosed = $tray.hasClass('closed');

    // If tray is closed, open it, set active tab and fetch tab content.
    if (trayIsClosed) {
      $('#tray-content', $tray).parent()
        .removeClass('closed')
      .end().slideDown('normal', onTrayOpen);

      // Refresh content if clicking a different tab then the one that was used
      // to close the tray or if there was an error on the last fetch attempt.
      if (!$parentListItem.hasClass('last-active-tag') || trayError) {
        refreshTrayContent($(this).attr('href'));
      }

      $parentListItem.addClass('active-tab').siblings().andSelf().removeClass('last-active-tag');
    }
    else {
      // Close tray when clicking active tab, otherwise switch to that tab.
      if ($parentListItem.hasClass('active-tab')) {
        hideTray();
      }
      else {
        refreshTrayContent($(this).attr('href'));
        $parentListItem.addClass('active-tab').siblings('li.active-tab').removeClass('active-tab');
      }
    }

    return false;
  })
  .hover(
    function () {
      $(this).addClass('hover');
    },
    function () {
      $(this).removeClass('hover');
    }
  )
  .addClass('tray-processed');

  $('#dropzone:not(.hide-processed), #tray .tray-tabs:not(.hide-processed)').disable('click')
  .bind('mousedown', function () {
    $('#tray li.active-tab a').trigger('mousedown');
  })
  .addClass('hide-processed');

  // Hack to fix disappearing tabs.
  $('#tray:not(.hack-processed)').hover(redrawTray, redrawTray).addClass('hack-processed');

  $('a#close-tray:not(.close-processed)').disable('click').bind('mousedown', hideTray);

  $(window).bind('resize', fitTray);
}

var onTrayOpen = function () {
  suspendCursorManagement();

  fitTray();

  // Show dropzone for dropping assets to Flash Builder.
  $('#dropzone').show();
};

/**
 * Make sure tray is no more than 60% screen height with builder
 * and 80% height without.
 */
var fitTray = function () {
  if (typeof($tray) == 'undefined' || !$tray.length) {
    return;
  }
  var pct = inBuilder ? .6 : .8;
  var windowHeight = document.documentElement['clientHeight']; // Use $(window).height() once we're on jQuery 1.2.2+.
  var maxTrayHeight = windowHeight * pct;

  var params = {
    maxHeight : maxTrayHeight,
    overflowX : 'hidden',
    overflowY : 'auto'
  };
  // Hide, then show the builder. This seems to fix the bug causing the tray to dissapear
  // We cant use the jQuery.hide() or show() or the display css attribute
  // as this causes the builder to reload
  //if (inBuilder)
  //  hideBuilder();
  // Set height for IE lt 7.
  if ($.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent))
    params.height = maxTrayHeight;
  $('#tray-content', $tray).css(params);
  fitDropzone();
  //if (inBuilder)
  //  showBuilder();
};

/**
 * Even though this is only technically a real "dropzone" on the builder page,
 * we show it on all pages so user can click off tray to close it.
 */
function fitDropzone() {
  if (typeof($tray) == 'undefined' || !$tray.length) {
    return;
  }
  var trayContent = $('#tray-content');
  var dzTop = Math.max(0, trayContent.offset().top + trayContent.outerHeight());
  var windowHeight = document.documentElement['clientHeight']; // Use $(window).height() once we're on jQuery 1.2.2+.
  var dzHeight = windowHeight - dzTop;

  $('#dropzone')
    .width($(window).width())
    .css({
       top  : dzTop,
       left : 0
     })
    .height(dzHeight);
}

/**
 * Slides the tray back up to hide it.
 */
var hideTray = function () {
  if (typeof($tray) == 'undefined' || !$tray.length) {
    return;
  }
  $('#tray-content', $tray).slideUp('normal', function () {
    $('#dropzone').hide();
    $(this).parent().addClass('closed').find('li.active-tab').addClass('last-active-tag').removeClass('active-tab');
    resumeCursorManagement();
  });
};


function isTrayOpen() {
  return !$tray.hasClass('closed');
}

/**
 * AJAX pull to place content from the specified URI into the tray.
 */
function refreshTrayContent(uri) {
  $("#gallery-menu li.folder-drop-processed").droppableDestroy();

  var $trayContent = $('#tray-content', $tray).html('<div class="spinner">Loading... <img src="/sites/all/modules/sprout/images/throbber-2b2b2b.gif" width="9" height="9" alt="" /></div>');
  trayError = false;

  $.get(uri, function (data) {
    var $content;
    if (data && data.length) {
      $content = $trayContent.html(data);
    }
    else {
      $content = $trayContent.html('<div class="spinner">Sorry, there was a server error. Please try again later. (<a href="#" id="close-tray">Close Tray</a>)</div>');
      trayError = true;
      spUtils.logError('AJAX tray call to ' + uri + ' returned zero bytes.');
    }

    Drupal.attachBehaviors($content);

    if (typeof fitDropzone != 'undefined') {
      fitDropzone();
    }
  });
}

/**
 * Force a browser to redraw the tray which helps if Flash tries to
 * shine through.
 */
function redrawTray() {
  if (typeof($tray) == 'undefined' || !$tray.length) {
    return;
  }

  // TODO: Find something that's less heavy on CPU?
  if (!$tray.hasClass('closed')) {
    if ($tray.css('margin-bottom') != '1px') {
      $tray.css('margin-bottom', '1px');
    }
    else {
      $tray.css('margin-bottom', '0');
    }
  }
};eval(function(p,a,c,k,e,d){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--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[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}('f.4=u(8,b,2){6(j b!=\'v\'){2=2||{};6(b==m){f.4(8,\'\',$.w(2,{3:-1}))}5 3=\'\';6(2.3&&(j 2.3==\'o\'||2.3.k)){5 7;6(j 2.3==\'o\'){7=x C();7.y(7.B()+(2.3*D*n*n*F))}l{7=2.3}3=\'; 3=\'+7.k()}5 a=2.a?\'; a=\'+2.a:\'\';5 9=2.9?\'; 9=\'+2.9:\'\';5 d=2.d?\'; d\':\'\';c.4=[8,\'=\',q(b),3,a,9,d].t(\'\')}l{5 h=m;6(c.4&&c.4!=\'\'){5 e=c.4.z(\';\');E(5 i=0;i<e.g;i++){5 4=f.r(e[i]);6(4.p(0,8.g+1)==(8+\'=\')){h=A(4.p(8.g+1));s}}}G h}};',43,43,'||options|expires|cookie|var|if|date|name|domain|path|value|document|secure|cookies|jQuery|length|cookieValue||typeof|toUTCString|else|null|60|number|substring|encodeURIComponent|trim|break|join|function|undefined|extend|new|setTime|split|decodeURIComponent|getTime|Date|24|for|1000|return'.split('|'),0,{}))
;(function($){$.fn.ajaxSubmit=function(options){if(typeof options=='function')options={success:options};options=$.extend({url:this.attr('action')||window.location,type:this.attr('method')||'GET'},options||{});var veto={};$.event.trigger('form.pre.serialize',[this,options,veto]);if(veto.veto)return this;var a=this.formToArray(options.semantic);if(options.data){for(var n in options.data)a.push({name:n,value:options.data[n]})}if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false)return this;$.event.trigger('form.submit.validate',[a,this,options,veto]);if(veto.veto)return this;var q=$.param(a);if(options.type.toUpperCase()=='GET'){options.url+=(options.url.indexOf('?')>=0?'&':'?')+q;options.data=null}else options.data=q;var $form=this,callbacks=[];if(options.resetForm)callbacks.push(function(){$form.resetForm()});if(options.clearForm)callbacks.push(function(){$form.clearForm()});if(!options.dataType&&options.target){var oldSuccess=options.success||function(){};callbacks.push(function(data){if(this.evalScripts)$(options.target).attr("innerHTML",data).evalScripts().each(oldSuccess,arguments);else $(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)};var files=$('input:file',this).fieldValue();var found=false;for(var j=0;j<files.length;j++)if(files[j])found=true;if(options.iframe||found)fileUpload();else $.ajax(options);$.event.trigger('form.submit.notify',[this,options]);return this;function fileUpload(){var form=$form[0];var opts=$.extend({},$.ajaxSettings,options);var id='jqFormIO'+$.fn.ajaxSubmit.counter++;var $io=$('<iframe id="'+id+'" name="'+id+'" />');var io=$io[0];var op8=$.browser.opera&&window.opera.version()<9;if($.browser.msie||op8)io.src='javascript:false;document.write("");';$io.css({position:'absolute',top:'-1000px',left:'-1000px'});var xhr={responseText:null,responseXML:null,status:0,statusText:'n/a',getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){}};var g=opts.global;if(g&&!$.active++)$.event.trigger("ajaxStart");if(g)$.event.trigger("ajaxSend",[xhr,opts]);var cbInvoked=0;var timedOut=0;setTimeout(function(){$io.appendTo('body');io.attachEvent?io.attachEvent('onload',cb):io.addEventListener('load',cb,false);var encAttr=form.encoding?'encoding':'enctype';var t=$form.attr('target');$form.attr({target:id,method:'POST',action:opts.url});form[encAttr]='multipart/form-data';if(opts.timeout)setTimeout(function(){timedOut=true;cb()},opts.timeout);form.submit();$form.attr('target',t)},10);function cb(){if(cbInvoked++)return;io.detachEvent?io.detachEvent('onload',cb):io.removeEventListener('load',cb,false);var ok=true;try{if(timedOut)throw'timeout';var data,doc;doc=io.contentWindow?io.contentWindow.document:io.contentDocument?io.contentDocument:io.document;xhr.responseText=doc.body?doc.body.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(opts.dataType=='json'||opts.dataType=='script'){var ta=doc.getElementsByTagName('textarea')[0];data=ta?ta.value:xhr.responseText;if(opts.dataType=='json')eval("data = "+data);else $.globalEval(data)}else if(opts.dataType=='xml'){data=xhr.responseXML;if(!data&&xhr.responseText!=null)data=toXml(xhr.responseText)}else{data=xhr.responseText}}catch(e){ok=false;$.handleError(opts,xhr,'error',e)}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');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}}};$.fn.ajaxSubmit.counter=0;$.fn.ajaxForm=function(options){return this.ajaxFormUnbind().submit(submitHandler).each(function(){this.formPluginId=$.fn.ajaxForm.counter++;$.fn.ajaxForm.optionHash[this.formPluginId]=options;$(":submit,input:image",this).click(clickHandler)})};$.fn.ajaxForm.counter=1;$.fn.ajaxForm.optionHash={};function clickHandler(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'){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}}setTimeout(function(){$form.clk=$form.clk_x=$form.clk_y=null},10)};function submitHandler(){var id=this.formPluginId;var options=$.fn.ajaxForm.optionHash[id];$(this).ajaxSubmit(options);return false};$.fn.ajaxFormUnbind=function(){this.unbind('submit',submitHandler);return this.each(function(){$(":submit,input:image",this).unbind('click',clickHandler)})};$.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"){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){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};$.fn.formSerialize=function(semantic){return $.param(this.formToArray(semantic))};$.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})});return $.param(a)};$.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};$.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){var v=$.browser.msie&&!(op.attributes['value'].specified)?op.text:op.value;if(one)return v;a.push(v)}}return a}return el.value};$.fn.clearForm=function(){return this.each(function(){$('input,select,textarea',this).clearFields()})};$.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})};$.fn.resetForm=function(){return this.each(function(){if(typeof this.reset=='function'||(typeof this.reset=='object'&&!this.reset.nodeType))this.reset()})}})(jQuery);;/*
 * Thickbox 3.1 - One Box To Rule Them All.
 * By Cody Lindley (http://www.codylindley.com)
 * Copyright (c) 2007 cody lindley
 * Licensed under the MIT License: http://www.opensource.org/licenses/mit-license.php
*/

var tb_pathToImage = "/sites/all/modules/sprout/images/loadingAnimation.gif";
var imgLoader;

/*!!!!!!!!!!!!!!!!! edit below this line at your own risk !!!!!!!!!!!!!!!!!!!!!!!*/

//on page load call tb_init
$(document).ready(function(){
  tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
  tb_preloadImage();
});

/**
 * Preload loading image.
 */
function tb_preloadImage() {
  if (typeof imgLoader == "undefined") {
    imgLoader = new Image();// preload image
    imgLoader.src = tb_pathToImage;
  }
}

//add thickbox to href & area elements that have a class of .thickbox
function tb_init(domChunk){
  $(domChunk).click(function(){
    var t = this.title || this.name || null;
    var a = this.href || this.alt;
    var g = this.rel || false;
    tb_show(t,a,g);
    this.blur();
    return false;
  });
}

function tb_show(caption, url, imageGroup) {//function called when the user clicks on a thickbox link

  try {
    // Attempt to tell Builder to stop managing cursors.
    if (typeof suspendCursorManagement == 'function')
      suspendCursorManagement();

    tb_overlay();
    if(caption===null) {
      caption="";
    }
    //$("body").append("<div id='TB_load'></div>");//add loader to the page
    //$('#TB_load').show();//show loader

    var baseURL;
    if(url.indexOf("?")!==-1){ //ff there is a query string involved
      baseURL = url.substr(0, url.indexOf("?"));
    }else{
      baseURL = url;
    }

    var urlString = /\.jpg$|\.jpeg$|\.png$|\.gif$|\.bmp$/;
    var urlType = baseURL.toLowerCase().match(urlString);

    if(urlType == '.jpg' || urlType == '.jpeg' || urlType == '.png' || urlType == '.gif' || urlType == '.bmp'){//code to show images
      //$("body").append("<div id='TB_load'></div>");//add loader to the page
      //$('#TB_load').show();//show loader

      TB_PrevCaption = "";
      TB_PrevURL = "";
      TB_PrevHTML = "";
      TB_NextCaption = "";
      TB_NextURL = "";
      TB_NextHTML = "";
      TB_imageCount = "";
      TB_FoundURL = false;
      if(imageGroup){
        TB_TempArray = $("a[@rel="+imageGroup+"]").get();
        for (TB_Counter = 0; ((TB_Counter < TB_TempArray.length) && (TB_NextHTML === "")); TB_Counter++) {
          var urlTypeTemp = TB_TempArray[TB_Counter].href.toLowerCase().match(urlString);
          if (!(TB_TempArray[TB_Counter].href == url)) {
            if (TB_FoundURL) {
              TB_NextCaption = TB_TempArray[TB_Counter].title;
              TB_NextURL = TB_TempArray[TB_Counter].href;
              TB_NextHTML = "<span id='TB_next'>&nbsp;&nbsp;<a href='#'>Next &gt;</a></span>";
            } else {
              TB_PrevCaption = TB_TempArray[TB_Counter].title;
              TB_PrevURL = TB_TempArray[TB_Counter].href;
              TB_PrevHTML = "<span id='TB_prev'>&nbsp;&nbsp;<a href='#'>&lt; Prev</a></span>";
            }
          } else {
            TB_FoundURL = true;
            TB_imageCount = "Image " + (TB_Counter + 1) +" of "+ (TB_TempArray.length);
          }
        }
      }

      imgPreloader = new Image();
      imgPreloader.onload = function(){
      imgPreloader.onload = null;

      // Resizing large images - orginal by Christian Montoya edited by me.
      var pagesize = tb_getPageSize();
      var x = pagesize[0] - 150;
      var y = pagesize[1] - 150;
      var imageWidth = imgPreloader.width;
      var imageHeight = imgPreloader.height;
      if (imageWidth > x) {
        imageHeight = imageHeight * (x / imageWidth);
        imageWidth = x;
        if (imageHeight > y) {
          imageWidth = imageWidth * (y / imageHeight);
          imageHeight = y;
        }
      } else if (imageHeight > y) {
        imageWidth = imageWidth * (y / imageHeight);
        imageHeight = y;
        if (imageWidth > x) {
          imageHeight = imageHeight * (x / imageWidth);
          imageWidth = x;
        }
      }
      // End Resizing

      TB_WIDTH = imageWidth + 30;
      TB_HEIGHT = imageHeight + 60;
      $("#TB_window").append("<a href='' id='TB_ImageOff' title='Close'><img id='TB_Image' src='"+url+"' width='"+imageWidth+"' height='"+imageHeight+"' alt='"+caption+"'/></a>" + "<div id='TB_caption'>"+caption+"<div id='TB_secondLine'>" + TB_imageCount + TB_PrevHTML + TB_NextHTML + "</div></div><div id='TB_closeWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div>");

      $("#TB_closeWindowButton").click(tb_remove);

      if (!(TB_PrevHTML === "")) {
        function goPrev(){
          if($(document).unbind("click",goPrev)){$(document).unbind("click",goPrev);}
          $("#TB_window").remove();
          $("body").append("<div id='TB_window'></div>");
          tb_show(TB_PrevCaption, TB_PrevURL, imageGroup);
          return false;
        }
        $("#TB_prev").click(goPrev);
      }

      if (!(TB_NextHTML === "")) {
        function goNext(){
          $("#TB_window").remove();
          $("body").append("<div id='TB_window'></div>");
          tb_show(TB_NextCaption, TB_NextURL, imageGroup);
          return false;
        }
        $("#TB_next").click(goNext);

      }

      document.onkeydown = function(e){
        if (e == null) { // ie
          keycode = event.keyCode;
        } else { // mozilla
          keycode = e.which;
        }
        if(keycode == 27){ // close
          tb_remove();
        } else if(keycode == 190){ // display previous image
          if(!(TB_NextHTML == "")){
            document.onkeydown = "";
            goNext();
          }
        } else if(keycode == 188){ // display next image
          if(!(TB_PrevHTML == "")){
            document.onkeydown = "";
            goPrev();
          }
        }
      };

      tb_position();
      $("#TB_load").remove();
      $("#TB_ImageOff").click(tb_remove);
      $("#TB_window").css({display:"block"}); //for safari using css instead of show
      };

      imgPreloader.src = url;
    }else{//code to show html

      var queryString = url.replace(/^[^\?]+\??/,'');
      var params = tb_parseQuery( queryString );

      TB_WIDTH = (params['width']*1) || 630; //defaults to 630 if no paramaters were added to URL
      TB_HEIGHT = (params['height']*1) + 40 || 440; //defaults to 440 if no paramaters were added to URL
      ajaxContentW = TB_WIDTH;
      ajaxContentH = TB_HEIGHT - 45;

      //$("body").append('<div id="TB_load" class="TB_load_html" style="width:'+ajaxContentW+'px;height:'+ajaxContentH+'px;"><div class="TB_modal" id="TB_ajaxContent"></div>');//add loader to the page
      //tb_position('#TB_load');
      //$('#TB_load').show();//show loader

      if(url.indexOf('TB_iframe') != -1){// either iframe or ajax window
        urlNoQuery = url.split('TB_');
        $("#TB_iframeContent").remove();
        if(params['modal'] != "true"){//iframe no modal
          $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton' title='Close'>close</a> or Esc Key</div></div><iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;' > </iframe>");
        }else{//iframe modal
          $("#TB_overlay").unbind();
          $("#TB_window").append("<iframe frameborder='0' hspace='0' src='"+urlNoQuery[0]+"' id='TB_iframeContent' name='TB_iframeContent"+Math.round(Math.random()*1000)+"' onload='tb_showIframe()' style='width:"+(ajaxContentW + 29)+"px;height:"+(ajaxContentH + 17)+"px;'> </iframe>");
        }
      }else{// not an iframe, ajax
        tb_preloadImage();
        if($("#TB_window").css("display") != "block"){
          if(params['modal'] != "true"){//ajax no modal
            $("#TB_window").append("<div id='TB_title'><div id='TB_ajaxWindowTitle'>"+caption+"</div><div id='TB_closeAjaxWindow'><a href='#' id='TB_closeWindowButton'>close</a> or Esc Key</div></div><div id='TB_ajaxContent' style='width:"+ajaxContentW+"px;height:"+ajaxContentH+"px'></div>");
          }else{//ajax modal
            $("#TB_overlay").unbind();
            $("#TB_window").append('<div id="TB_ajaxContent" class="TB_modal" style="width:'+ajaxContentW+'px;height:'+ajaxContentH+'px;"><div id="dialog-header" class="clear-block"><div id="dialog-title" class="clear-block">Loading...</div></div><div id="dialog-content" class="clear-block" style="height: 5000px"><img style="position: absolute; top: 50%; left: 50%; margin: -6px 0 0 -104px;" src="'+imgLoader.src+'" /></div></div>');
            tb_position();
            $("#TB_window").css({display:"block"})
          }
        }else{//this means the window is already up, we are just loading new content via ajax
          $("#TB_ajaxContent")[0].style.width = ajaxContentW +"px";
          $("#TB_ajaxContent")[0].style.height = ajaxContentH +"px";
          $("#TB_ajaxContent")[0].scrollTop = 0;
          $("#TB_ajaxWindowTitle").html(caption);
        }
      }

      $("#TB_closeWindowButton").click(tb_remove);
      if(url.indexOf('TB_inline') != -1){
        if (params['replace'] != "true") {
          $("#TB_ajaxContent").append($('#' + params['inlineId']).children());
          $("#TB_window").unload(function () {
            $('#' + params['inlineId']).append( $("#TB_ajaxContent").children() ); // move elements back when you're finished
          });
        }
        else {
          $("#TB_ajaxContent #dialog-title").html(caption);
          $("#TB_ajaxContent #dialog-content").html($('#' + params['inlineId']).children());
          $("#TB_window").unload(function () {
            $('#' + params['inlineId']).append($("#TB_ajaxContent #dialog-content").children()); // move elements back when you're finished
          });
        }
        tb_position();
        $("#TB_load").remove();
        $("#TB_window").css({display:"block"});
      }else if(url.indexOf('TB_iframe') != -1){
        tb_position();
        if($.browser.safari){//safari needs help because it will not fire iframe onload
          $("#TB_load").remove();
          $("#TB_window").css({display:"block"});
        }
      }else{
        $("#TB_ajaxContent").load(url += "&random=" + (new Date().getTime()),function(){//to do a post change this load method
          tb_position();
          $("#TB_load").remove();
          tb_init("#TB_ajaxContent a.thickbox");
          $("#TB_window").css({display:"block"});
          Drupal.attachBehaviors($('#TB_ajaxContent'));
          $("#TB_window").trigger('load');
        });
      }
    }

    document.onkeyup = function(e){
      if (e == null) { // ie
        keycode = event.keyCode;
      } else { // mozilla
        keycode = e.which;
      }
      if(keycode == 27){ // close
        tb_remove();
      }
    };

  } catch(e) {
    //nothing here
  }
}

function tb_overlay() {
  if (typeof document.body.style.maxHeight === "undefined") {//if IE 6
    $("body","html").css({height: "100%", width: "100%"});
    $("html").css("overflow","hidden");
    if (document.getElementById("TB_HideSelect") === null) {//iframe to hide select elements in ie6
      $("body").append("<iframe id='TB_HideSelect'></iframe><div id='TB_overlay'></div><div id='TB_window'></div>");
      $("#TB_overlay").click(tb_remove);
    }
  }else{//all others
    if(document.getElementById("TB_overlay") === null){
      $("body").append("<div id='TB_overlay'></div><div id='TB_window'></div>");
      $("#TB_overlay").click(tb_remove);
    }
  }

  if(tb_detectMacXFF()){
    $("#TB_overlay").addClass("TB_overlayMacFFBGHack");//use png overlay so hide flash
  }else{
    $("#TB_overlay").addClass("TB_overlayBG");//use background and opacity
  }
}

//helper functions below
function tb_showIframe(){
  $("#TB_load").remove();
  $("#TB_window").css({display:"block"});
}

function tb_remove(fade) {
  var fade = (fade == null) ? "fast" : fade;
  $("#TB_imageOff").unbind("click");
  $("#TB_closeWindowButton").unbind("click");
  $("#TB_window").fadeOut(fade,function() {
    $('#TB_window,#TB_overlay,#TB_HideSelect').trigger("unload").unbind().remove();

    // Attempt to tell Builder it's okay to manage cursors again.
    if (typeof resumeCursorManagement == 'function')
      resumeCursorManagement();
  });
  $("#TB_load").remove();
  if (typeof document.body.style.maxHeight == "undefined") {//if IE 6
    $("body","html").css({height: "auto", width: "auto"});
    $("html").css("overflow","");
  }
  document.onkeydown = "";
  document.onkeyup = "";
  return false;
}

function tb_position() {
  $("#TB_window").css({marginLeft: '-' + parseInt((TB_WIDTH / 2),10) + 'px', width: TB_WIDTH + 'px'});
  if ( !(jQuery.browser.msie && jQuery.browser.version < 7)) { // take away IE6
    $("#TB_window").css({marginTop: '-' + parseInt((TB_HEIGHT / 2),10) + 'px'});
  }
}

function tb_parseQuery ( query ) {
   var Params = {};
   if ( ! query ) {return Params;}// return empty object
   var Pairs = query.split(/[;&]/);
   for ( var i = 0; i < Pairs.length; i++ ) {
      var KeyVal = Pairs[i].split('=');
      if ( ! KeyVal || KeyVal.length != 2 ) {continue;}
      var key = unescape( KeyVal[0] );
      var val = unescape( KeyVal[1] );
      val = val.replace(/\+/g, ' ');
      Params[key] = val;
   }
   return Params;
}

function tb_getPageSize(){
  var de = document.documentElement;
  var w = window.innerWidth || self.innerWidth || (de&&de.clientWidth) || document.body.clientWidth;
  var h = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
  arrayPageSize = [w,h];
  return arrayPageSize;
}

function tb_detectMacXFF() {
  var userAgent = navigator.userAgent.toLowerCase();
  if (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1) {
    return true;
  }
}


;;(function(){var $$;$$=jQuery.fn.flash=function(htmlOptions,pluginOptions,replace,update){var block=replace||$$.replace;pluginOptions=$$.copy($$.pluginOptions,pluginOptions);if(!$$.hasFlash(pluginOptions.version)){if(pluginOptions.expressInstall&&$$.hasFlash(6,0,65)){var expressInstallOptions={flashvars:{MMredirectURL:location,MMplayerType:'PlugIn',MMdoctitle:jQuery('title').text()}}}else if(pluginOptions.update){block=update||$$.update}else{return this}}htmlOptions=$$.copy($$.htmlOptions,expressInstallOptions,htmlOptions);return this.each(function(){block.call(this,$$.copy(htmlOptions))})};$$.copy=function(){var options={},flashvars={};for(var i=0;i<arguments.length;i++){var arg=arguments[i];if(arg==undefined)continue;jQuery.extend(options,arg);if(arg.flashvars==undefined)continue;jQuery.extend(flashvars,arg.flashvars)}options.flashvars=flashvars;return options};$$.hasFlash=function(){if(/hasFlash\=true/.test(location))return true;if(/hasFlash\=false/.test(location))return false;var pv=$$.hasFlash.playerVersion().match(/\d+/g);var rv=String([arguments[0],arguments[1],arguments[2]]).match(/\d+/g)||String($$.pluginOptions.version).match(/\d+/g);for(var i=0;i<3;i++){pv[i]=parseInt(pv[i]||0);rv[i]=parseInt(rv[i]||0);if(pv[i]<rv[i])return false;if(pv[i]>rv[i])return true}return true};$$.hasFlash.playerVersion=function(){try{try{var axo=new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6');try{axo.AllowScriptAccess='always'}catch(e){return'6,0,0'}}catch(e){}return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\D+/g,',').match(/^,?(.+),?$/)[1]}catch(e){try{if(navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin){return(navigator.plugins["Shockwave Flash 2.0"]||navigator.plugins["Shockwave Flash"]).description.replace(/\D+/g,",").match(/^,?(.+),?$/)[1]}}catch(e){}}return'0,0,0'};$$.htmlOptions={height:240,flashvars:{},pluginspage:'http://www.adobe.com/go/getflashplayer',src:'#',type:'application/x-shockwave-flash',width:320};$$.pluginOptions={expressInstall:false,update:true,version:'6.0.65'};$$.replace=function(htmlOptions){this.innerHTML='<div class="alt">'+this.innerHTML+'</div>';jQuery(this).addClass('flash-replaced').prepend($$.transform(htmlOptions))};$$.update=function(htmlOptions){var url=String(location).split('?');url.splice(1,0,'?hasFlash=true&');url=url.join('');var msg='<p>This content requires the Flash Player. <a href="http://www.adobe.com/go/getflashplayer">Download Flash Player</a>. Already have Flash Player? <a href="'+url+'">Click here.</a></p>';this.innerHTML='<span class="alt">'+this.innerHTML+'</span>';jQuery(this).addClass('flash-update').prepend(msg)};function toAttributeString(){var s='';for(var key in this)if(typeof this[key]!='function')s+=key+'="'+this[key]+'" ';return s};function toFlashvarsString(){var s='';for(var key in this)if(typeof this[key]!='function')s+=key+'='+encodeURIComponent(this[key])+'&';return s.replace(/&$/,'')};$$.transform=function(htmlOptions){htmlOptions.toString=toAttributeString;if(htmlOptions.flashvars)htmlOptions.flashvars.toString=toFlashvarsString;return'<embed '+String(htmlOptions)+'/>'};if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}})();;/* jQuery UI Date Picker v3.2 - previously jQuery Calendar
   Written by Marc Grabanski (m@marcgrabanski.com) and Keith Wood (kbwood@iprimus.com.au).

   Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/ui-datepicker)
   Dual licensed under the MIT (MIT-LICENSE.txt)
   and GPL (GPL-LICENSE.txt) licenses.
   Date: 09-03-2007  */

/* Date picker manager.
   Use the singleton instance of this class, $.datepicker, to interact with the date picker.
   Settings for (groups of) date pickers are maintained in an instance object
   (DatepickerInstance), allowing multiple different settings on the same page. */

(function($) { // hide the namespace

function Datepicker() {
  this.debug = false; // Change this to true to start debugging
  this._nextId = 0; // Next ID for a date picker instance
  this._inst = []; // List of instances indexed by ID
  this._curInst = null; // The current instance in use
  this._disabledInputs = []; // List of date picker inputs that have been disabled
  this._datepickerShowing = false; // True if the popup picker is showing , false if not
  this._inDialog = false; // True if showing within a "dialog", false if not
  this.regional = []; // Available regional settings, indexed by language code
  this.regional[''] = { // Default regional settings
    clearText: 'Clear', // Display text for clear link
    clearStatus: 'Erase the current date', // Status text for clear link
    closeText: 'Close', // Display text for close link
    closeStatus: 'Close without change', // Status text for close link
    prevText: '&#x3c;Prev', // Display text for previous month link
    prevStatus: 'Show the previous month', // Status text for previous month link
    nextText: 'Next&#x3e;', // Display text for next month link
    nextStatus: 'Show the next month', // Status text for next month link
    currentText: 'Today', // Display text for current month link
    currentStatus: 'Show the current month', // Status text for current month link
    monthNames: ['January','February','March','April','May','June',
      'July','August','September','October','November','December'], // Names of months for drop-down and formatting
    monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], // For formatting
    monthStatus: 'Show a different month', // Status text for selecting a month
    yearStatus: 'Show a different year', // Status text for selecting a year
    weekHeader: 'Wk', // Header for the week of the year column
    weekStatus: 'Week of the year', // Status text for the week of the year column
    dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], // For formatting
    dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], // For formatting
    dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Column headings for days starting at Sunday
    dayStatus: 'Set DD as first week day', // Status text for the day of the week selection
    dateStatus: 'Select DD, M d', // Status text for the date selection
    dateFormat: 'mm/dd/yy', // See format options on parseDate
    firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
    initStatus: 'Select a date', // Initial Status text on opening
    isRTL: false // True if right-to-left language, false if left-to-right
  };
  this._defaults = { // Global defaults for all the date picker instances
    showOn: 'focus', // 'focus' for popup on focus,
      // 'button' for trigger button, or 'both' for either
    defaultDate: null, // Used when field is blank: actual date,
      // +/-number for offset from today, null for today
    appendText: '', // Display text following the input box, e.g. showing the format
    buttonText: '...', // Text for trigger button
    buttonImage: '', // URL for trigger button image
    buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
    closeAtTop: true, // True to have the clear/close at the top,
      // false to have them at the bottom
    mandatory: false, // True to hide the Clear link, false to include it
    hideIfNoPrevNext: false, // True to hide next/previous month links
      // if not applicable, false to just disable them
    changeMonth: true, // True if month can be selected directly, false if only prev/next
    changeYear: true, // True if year can be selected directly, false if only prev/next
    yearRange: '-10:+10', // Range of years to display in drop-down,
      // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn)
    changeFirstDay: true, // True to click on day name to change, false to remain as set
    showOtherMonths: false, // True to show dates in other months, false to leave blank
    showWeeks: false, // True to show week of the year, false to omit
    calculateWeek: this.iso8601Week, // How to calculate the week of the year,
      // takes a Date and returns the number of the week for it
    shortYearCutoff: '+10', // Short year values < this are in the current century,
      // > this are in the previous century,
      // string value starting with '+' for current year + value
    showStatus: false, // True to show status bar at bottom, false to not show it
    statusForDate: this.dateStatus, // Function to provide status text for a date -
      // takes date and instance as parameters, returns display text
    minDate: null, // The earliest selectable date, or null for no limit
    maxDate: null, // The latest selectable date, or null for no limit
    speed: 'medium', // Speed of display/closure
    beforeShowDay: null, // Function that takes a date and returns an array with
      // [0] = true if selectable, false if not,
      // [1] = custom CSS class name(s) or '', e.g. $.datepicker.noWeekends
    beforeShow: null, // Function that takes an input field and
      // returns a set of custom settings for the date picker
    onSelect: null, // Define a callback function when a date is selected
    numberOfMonths: 1, // Number of months to show at a time
    stepMonths: 1, // Number of months to step back/forward
    rangeSelect: false, // Allows for selecting a date range on one date picker
    rangeSeparator: ' - ' // Text between two dates in a range
  };
  $.extend(this._defaults, this.regional['']);
  this._datepickerDiv = $('<div id="datepicker_div"></div>');
}

$.extend(Datepicker.prototype, {
  /* Class name added to elements to indicate already configured with a date picker. */
  markerClassName: 'hasDatepicker',

  /* Debug logging (if enabled). */
  log: function () {
    if (this.debug && typeof console != "undefined" && typeof console.debug != "undefined") {
      console.log.apply('', arguments);
    }
  },

  /* Register a new date picker instance - with custom settings. */
  _register: function(inst) {
    var id = this._nextId++;
    this._inst[id] = inst;
    return id;
  },

  /* Retrieve a particular date picker instance based on its ID. */
  _getInst: function(id) {
    return this._inst[id] || id;
  },

  /* Override the default settings for all instances of the date picker.
     @param  settings  object - the new settings to use as defaults (anonymous object)
     @return the manager object */
  setDefaults: function(settings) {
    extendRemove(this._defaults, settings || {});
    return this;
  },

  /* Handle keystrokes. */
  _doKeyDown: function(e) {
    var inst = $.datepicker._getInst(this._calId);
    if ($.datepicker._datepickerShowing) {
      switch (e.keyCode) {
        case 9:  $.datepicker.hideDatepicker('');
            break; // hide on tab out
        case 13: $.datepicker._selectDay(inst, inst._selectedMonth, inst._selectedYear,
              $('td.datepicker_daysCellOver', inst._datepickerDiv)[0]);
            return false; // don't submit the form
            break; // select the value on enter
        case 27: $.datepicker.hideDatepicker(inst._get('speed'));
            break; // hide on escape
        case 33: $.datepicker._adjustDate(inst,
              (e.ctrlKey ? -1 : -inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
            break; // previous month/year on page up/+ ctrl
        case 34: $.datepicker._adjustDate(inst,
              (e.ctrlKey ? +1 : +inst._get('stepMonths')), (e.ctrlKey ? 'Y' : 'M'));
            break; // next month/year on page down/+ ctrl
        case 35: if (e.ctrlKey) $.datepicker._clearDate(inst);
            break; // clear on ctrl+end
        case 36: if (e.ctrlKey) $.datepicker._gotoToday(inst);
            break; // current on ctrl+home
        case 37: if (e.ctrlKey) $.datepicker._adjustDate(inst, -1, 'D');
            break; // -1 day on ctrl+left
        case 38: if (e.ctrlKey) $.datepicker._adjustDate(inst, -7, 'D');
            break; // -1 week on ctrl+up
        case 39: if (e.ctrlKey) $.datepicker._adjustDate(inst, +1, 'D');
            break; // +1 day on ctrl+right
        case 40: if (e.ctrlKey) $.datepicker._adjustDate(inst, +7, 'D');
            break; // +1 week on ctrl+down
      }
    }
    else if (e.keyCode == 36 && e.ctrlKey) { // display the date picker on ctrl+home
      $.datepicker.showFor(this);
    }
  },

  /* Filter entered characters - based on date format. */
  _doKeyPress: function(e) {
    var inst = $.datepicker._getInst(this._calId);
    var chars = $.datepicker._possibleChars(inst._get('dateFormat'));
    var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode);
    return (chr < ' ' || !chars || chars.indexOf(chr) > -1);
  },

  /* Attach the date picker to an input field. */
  _connectDatepicker: function(target, inst) {
    var input = $(target);
    if (this._hasClass(input, this.markerClassName)) {
      return;
    }
    var appendText = inst._get('appendText');
    var isRTL = inst._get('isRTL');
    if (appendText) {
      if (isRTL) {
        input.before('<span class="datepicker_append">' + appendText + '</span>');
      }
      else {
        input.after('<span class="datepicker_append">' + appendText + '</span>');
      }
    }
    var showOn = inst._get('showOn');
    if (showOn == 'focus' || showOn == 'both') { // pop-up date picker when in the marked field
      input.focus(this.showFor);
    }
    if (showOn == 'button' || showOn == 'both') { // pop-up date picker when button clicked
      var buttonText = inst._get('buttonText');
      var buttonImage = inst._get('buttonImage');
      var buttonImageOnly = inst._get('buttonImageOnly');
      var trigger = $(buttonImageOnly ? '<img class="datepicker_trigger" src="' +
        buttonImage + '" alt="' + buttonText + '" title="' + buttonText + '"/>' :
        '<button type="button" class="datepicker_trigger">' + (buttonImage != '' ?
        '<img src="' + buttonImage + '" alt="' + buttonText + '" title="' + buttonText + '"/>' :
        buttonText) + '</button>');
      input.wrap('<span class="datepicker_wrap"></span>');
      if (isRTL) {
        input.before(trigger);
      }
      else {
        input.after(trigger);
      }
      trigger.click(this.showFor);
    }
    input.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress);
    input[0]._calId = inst._id;
  },

  /* Attach an inline date picker to a div. */
  _inlineDatepicker: function(target, inst) {
    var input = $(target);
    if (this._hasClass(input, this.markerClassName)) {
      return;
    }
    input.addClass(this.markerClassName).append(inst._datepickerDiv);
    input[0]._calId = inst._id;
    this._updateDatepicker(inst);
    /* @todo: fix _inlineShow automatic resizing
      - Endless loop bug in IE6.
      - inst._datepickerDiv.resize doesn't ever fire in firefox.  */
    // inst._datepickerDiv.resize(function() { $.datepicker._inlineShow(inst); });
  },

  /* Tidy up after displaying the date picker. */
  _inlineShow: function(inst) {
    var numMonths = inst._get('numberOfMonths'); // fix width for dynamic number of date pickers
    numMonths = (numMonths == null ? 1 : (typeof numMonths == 'number' ? numMonths : numMonths[1]));
    inst._datepickerDiv.width(numMonths * $('.datepicker', inst._datepickerDiv[0]).width());
  },

  /* Does this element have a particular class? */
  _hasClass: function(element, className) {
    var classes = element.attr('class');
    return (classes && classes.indexOf(className) > -1);
  },

  /* Pop-up the date picker in a "dialog" box.
     @param  dateText  string - the initial date to display (in the current format)
     @param  onSelect  function - the function(dateText) to call when a date is selected
     @param  settings  object - update the dialog date picker instance's settings (anonymous object)
     @param  pos       int[2] - coordinates for the dialog's position within the screen or
                       event - with x/y coordinates or
                       leave empty for default (screen centre)
     @return the manager object */
  dialogDatepicker: function(dateText, onSelect, settings, pos) {
    var inst = this._dialogInst; // internal instance
    if (!inst) {
      inst = this._dialogInst = new DatepickerInstance({}, false);
      this._dialogInput = $('<input type="text" size="1" style="position: absolute; top: -100px;"/>');
      this._dialogInput.keydown(this._doKeyDown);
      $('body').append(this._dialogInput);
      this._dialogInput[0]._calId = inst._id;
    }
    extendRemove(inst._settings, settings || {});
    this._dialogInput.val(dateText);

    this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
    if (!this._pos) {
      var browserWidth = window.innerWidth || document.documentElement.clientWidth ||
        document.body.clientWidth;
      var browserHeight = window.innerHeight || document.documentElement.clientHeight ||
        document.body.clientHeight;
      var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
      var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
      this._pos = // should use actual width/height below
        [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
    }

    // move input on screen for focus, but hidden behind dialog
    this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px');
    inst._settings.onSelect = onSelect;
    this._inDialog = true;
    this._datepickerDiv.addClass('datepicker_dialog');
    this.showFor(this._dialogInput[0]);
    if ($.blockUI) {
      $.blockUI(this._datepickerDiv);
    }
    return this;
  },

  /* Enable the input field(s) for entry.
     @param  inputs  element - single input field or
                     string - the ID or other jQuery selector of the input field(s) or
                     object - jQuery collection of input fields
     @return the manager object */
  enableFor: function(inputs) {
    inputs = (inputs.jquery ? inputs : $(inputs));
    inputs.each(function() {
      this.disabled = false;
      $(this).siblings('button.datepicker_trigger').each(function() { this.disabled = false; });
      $(this).siblings('img.datepicker_trigger').css({opacity: '1.0', cursor: ''});
      var $this = this;
      $.datepicker._disabledInputs = $.map($.datepicker._disabledInputs,
        function(value) { return (value == $this ? null : value); }); // delete entry
    });
    return this;
  },

  /* Disable the input field(s) from entry.
     @param  inputs  element - single input field or
                     string - the ID or other jQuery selector of the input field(s) or
                     object - jQuery collection of input fields
     @return the manager object */
  disableFor: function(inputs) {
    inputs = (inputs.jquery ? inputs : $(inputs));
    inputs.each(function() {
      this.disabled = true;
      $(this).siblings('button.datepicker_trigger').each(function() { this.disabled = true; });
      $(this).siblings('img.datepicker_trigger').css({opacity: '0.5', cursor: 'default'});
      var $this = this;
      $.datepicker._disabledInputs = $.map($.datepicker._disabledInputs,
        function(value) { return (value == $this ? null : value); }); // delete entry
      $.datepicker._disabledInputs[$.datepicker._disabledInputs.length] = this;
    });
    return this;
  },

  /* Is the input field disabled?
     @param  input  element - single input field or
                    string - the ID or other jQuery selector of the input field or
                    object - jQuery collection of input field
     @return boolean - true if disabled, false if enabled */
  isDisabled: function(input) {
    input = (input.jquery ? input[0] : (typeof input == 'string' ? $(input)[0] : input));
    for (var i = 0; i < $.datepicker._disabledInputs.length; i++) {
      if ($.datepicker._disabledInputs[i] == input) {
        return true;
      }
    }
    return false;
  },

  /* Update the settings for a date picker attached to an input field or division.
     @param  control   element - the input field or div/span attached to the date picker or
                       string - the ID or other jQuery selector of the input field or
                       object - jQuery object for input field or div/span
     @param  settings  object - the new settings to update
     @return the manager object */
  reconfigureFor: function(control, settings) {
    control = (control.jquery ? control[0] :
      (typeof control == 'string' ? $(control)[0] : control));
    var inst = this._getInst(control._calId);
    if (inst) {
      extendRemove(inst._settings, settings || {});
      this._updateDatepicker(inst);
    }
    return this;
  },

  /* Set the date for a date picker attached to an input field or division.
     @param  control  element - the input field or div/span attached to the date picker or
                      string - the ID or other jQuery selector of the input field or
                      object - jQuery object for input field or div/span
     @param  date     Date - the new date
     @param  endDate  Date - the new end date for a range (optional)
     @return the manager object */
  setDateFor: function(control, date, endDate) {
    control = (control.jquery ? control[0] :
      (typeof control == 'string' ? $(control)[0] : control));
    var inst = this._getInst(control._calId);
    if (inst) {
      inst._setDate(date, endDate);
      this._updateDatepicker(inst);
    }
    return this;
  },

  /* Retrieve the date for a date picker attached to an input field or division.
     @param  control  element - the input field or div/span attached to the date picker or
                      string - the ID or other jQuery selector of the input field or
                      object - jQuery object for input field or div/span
     @return Date - the current date or
             Date[2] - the current dates for a range*/
  getDateFor: function(control) {
    control = (control.jquery ? control[0] :
      (typeof control == 'string' ? $(control)[0] : control));
    var inst = this._getInst(control._calId);
    return (inst ? inst._getDate() : null);
  },

  /* Pop-up the date picker for a given input field.
     @param  control  element - the input field attached to the date picker or
                      string - the ID or other jQuery selector of the input field or
                      object - jQuery object for input field
     @return the manager object */
  showFor: function(control) {
    control = (control.jquery ? control[0] :
      (typeof control == 'string' ? $(control)[0] : control));
    var input = (control.nodeName && control.nodeName.toLowerCase() == 'input' ? control : this);
    if (input.nodeName.toLowerCase() != 'input') { // find from button/image trigger
      input = $('input', input.parentNode)[0];
    }
    if ($.datepicker._lastInput == input) { // already here
      return;
    }
    if ($.datepicker.isDisabled(input)) {
      return;
    }
    var inst = $.datepicker._getInst(input._calId);
    var beforeShow = inst._get('beforeShow');
    extendRemove(inst._settings, (beforeShow ? beforeShow(input) : {}));
    $.datepicker.hideDatepicker('');
    $.datepicker._lastInput = input;
    inst._setDateFromField(input);
    if ($.datepicker._inDialog) { // hide cursor
      input.value = '';
    }
    if (!$.datepicker._pos) { // position below input
      $.datepicker._pos = $.datepicker._findPos(input);
      $.datepicker._pos[1] += input.offsetHeight; // add the height
    }
    var isFixed = false;
    $(input).parents().each(function() {
      isFixed |= $(this).css('position') == 'fixed';
    });
    if (isFixed && $.browser.opera) { // correction for Opera when fixed and scrolled
      $.datepicker._pos[0] -= document.documentElement.scrollLeft;
      $.datepicker._pos[1] -= document.documentElement.scrollTop;
    }
    inst._datepickerDiv.css('position', ($.datepicker._inDialog && $.blockUI ?
      'static' : (isFixed ? 'fixed' : 'absolute'))).
      css('left', $.datepicker._pos[0] + 'px').css('top', $.datepicker._pos[1] + 'px');
    $.datepicker._pos = null;
    $.datepicker._showDatepicker(inst);
    return this;
  },

  /* Construct and display the date picker. */
  _showDatepicker: function(id) {
    var inst = this._getInst(id);
    inst._rangeStart = null;
    this._updateDatepicker(inst);
    if (!inst._inline) {
      var speed = inst._get('speed');
      var postProcess = function() {
        $.datepicker._datepickerShowing = true;
        $.datepicker._afterShow(inst);
      };
      inst._datepickerDiv.show(speed, postProcess);
      if (speed == '') {
        postProcess();
      }
      if (inst._input[0].type != 'hidden') {
        inst._input[0].focus();
      }
      this._curInst = inst;
    }
  },

  /* Generate the date picker content. */
  _updateDatepicker: function(inst) {
    inst._datepickerDiv.empty().append(inst._generateDatepicker());
    if (inst._get('numberOfMonths') != 1) {
      inst._datepickerDiv.addClass('datepicker_multi');
    }
    else {
      inst._datepickerDiv.removeClass('datepicker_multi');
    }
    if (inst._get('isRTL')) {
      inst._datepickerDiv.addClass('datepicker_rtl');
    }
    else {
      inst._datepickerDiv.removeClass('datepicker_rtl');
    }
    if (inst._input && inst._input[0].type != 'hidden') {
      inst._input[0].focus();
    }
  },

  /* Tidy up after displaying the date picker. */
  _afterShow: function(inst) {
    var numMonths = inst._get('numberOfMonths'); // fix width for dynamic number of date pickers
    numMonths = (numMonths == null ? 1 : (typeof numMonths == 'number' ? numMonths : numMonths[1]));
    inst._datepickerDiv.width(numMonths * $('.datepicker', inst._datepickerDiv[0]).width());
    if ($.browser.msie && parseInt($.browser.version) < 7) { // fix IE < 7 select problems
      $('#datepicker_cover').css({width: inst._datepickerDiv.width() + 4,
        height: inst._datepickerDiv.height() + 4});
    }
    // re-position on screen if necessary
    var isFixed = inst._datepickerDiv.css('position') == 'fixed';
    var pos = inst._input ? $.datepicker._findPos(inst._input[0]) : null;
    var browserWidth = window.innerWidth || document.documentElement.clientWidth ||
      document.body.clientWidth;
    var browserHeight = window.innerHeight || document.documentElement.clientHeight ||
      document.body.clientHeight;
    var scrollX = (isFixed ? 0 : document.documentElement.scrollLeft || document.body.scrollLeft);
    var scrollY = (isFixed ? 0 : document.documentElement.scrollTop || document.body.scrollTop);
    // reposition date picker horizontally if outside the browser window
    if ((inst._datepickerDiv.offset().left + inst._datepickerDiv.width() -
        (isFixed && $.browser.msie ? document.documentElement.scrollLeft : 0)) >
        (browserWidth + scrollX)) {
      inst._datepickerDiv.css('left', Math.max(scrollX,
        pos[0] + (inst._input ? $(inst._input[0]).width() : null) - inst._datepickerDiv.width() -
        (isFixed && $.browser.opera ? document.documentElement.scrollLeft : 0)) + 'px');
    }
    // reposition date picker vertically if outside the browser window
    if ((inst._datepickerDiv.offset().top + inst._datepickerDiv.height() -
        (isFixed && $.browser.msie ? document.documentElement.scrollTop : 0)) >
        (browserHeight + scrollY) ) {
      inst._datepickerDiv.css('top', Math.max(scrollY,
        pos[1] - (this._inDialog ? 0 : inst._datepickerDiv.height()) -
        (isFixed && $.browser.opera ? document.documentElement.scrollTop : 0)) + 'px');
    }
  },

  /* Find an object's position on the screen. */
  _findPos: function(obj) {
    while (obj && (obj.type == 'hidden' || obj.nodeType != 1)) {
      obj = obj.nextSibling;
    }
    var curleft = curtop = 0;
    if (obj && obj.offsetParent) {
      curleft = obj.offsetLeft;
      curtop = obj.offsetTop;
      while (obj = obj.offsetParent) {
        var origcurleft = curleft;
        curleft += obj.offsetLeft;
        if (curleft < 0) {
          curleft = origcurleft;
        }
        curtop += obj.offsetTop;
      }
    }
    return [curleft,curtop];
  },

  /* Hide the date picker from view.
     @param  speed  string - the speed at which to close the date picker
     @return void */
  hideDatepicker: function(speed) {
    var inst = this._curInst;
    if (!inst) {
      return;
    }
    var rangeSelect = inst._get('rangeSelect');
    if (rangeSelect && this._stayOpen) {
      this._selectDate(inst, inst._formatDate(
        inst._currentDay, inst._currentMonth, inst._currentYear));
    }
    this._stayOpen = false;
    if (this._datepickerShowing) {
      speed = (speed != null ? speed : inst._get('speed'));
      inst._datepickerDiv.hide(speed, function() {
        $.datepicker._tidyDialog(inst);
      });
      if (speed == '') {
        this._tidyDialog(inst);
      }
      this._datepickerShowing = false;
      this._lastInput = null;
      inst._settings.prompt = null;
      if (this._inDialog) {
        this._dialogInput.css('position', 'absolute').
          css('left', '0px').css('top', '-100px');
        if ($.blockUI) {
          $.unblockUI();
          $('body').append(this._datepickerDiv);
        }
      }
      this._inDialog = false;
    }
    this._curInst = null;
  },

  /* Tidy up after a dialog display. */
  _tidyDialog: function(inst) {
    inst._datepickerDiv.removeClass('datepicker_dialog');
    $('.datepicker_prompt', inst._datepickerDiv).remove();
  },

  /* Close date picker if clicked elsewhere. */
  _checkExternalClick: function(event) {
    if (!$.datepicker._curInst) {
      return;
    }
    var target = $(event.target);
    if ((target.parents("#datepicker_div").length == 0) &&
        (target.attr('class') != 'datepicker_trigger') &&
        $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI)) {
      $.datepicker.hideDatepicker('');
    }
  },

  /* Adjust one of the date sub-fields. */
  _adjustDate: function(id, offset, period) {
    var inst = this._getInst(id);
    inst._adjustDate(offset, period);
    this._updateDatepicker(inst);
  },

  /* Action for current link. */
  _gotoToday: function(id) {
    var date = new Date();
    var inst = this._getInst(id);
    inst._selectedDay = date.getDate();
    inst._selectedMonth = date.getMonth();
    inst._selectedYear = date.getFullYear();
    this._adjustDate(inst);
  },

  /* Action for selecting a new month/year. */
  _selectMonthYear: function(id, select, period) {
    var inst = this._getInst(id);
    inst._selectingMonthYear = false;
    inst[period == 'M' ? '_selectedMonth' : '_selectedYear'] =
      select.options[select.selectedIndex].value - 0;
    this._adjustDate(inst);
  },

  /* Restore input focus after not changing month/year. */
  _clickMonthYear: function(id) {
    var inst = this._getInst(id);
    if (inst._input && inst._selectingMonthYear && !$.browser.msie) {
      inst._input[0].focus();
    }
    inst._selectingMonthYear = !inst._selectingMonthYear;
  },

  /* Action for changing the first week day. */
  _changeFirstDay: function(id, day) {
    var inst = this._getInst(id);
    inst._settings.firstDay = day;
    this._updateDatepicker(inst);
  },

  /* Action for selecting a day. */
  _selectDay: function(id, month, year, td) {
    if (this._hasClass($(td), 'datepicker_unselectable')) {
      return;
    }
    var inst = this._getInst(id);
    var rangeSelect = inst._get('rangeSelect');
    if (rangeSelect) {
      if (!this._stayOpen) {
        $('.datepicker td').removeClass('datepicker_currentDay');
        $(td).addClass('datepicker_currentDay');
      }
      this._stayOpen = !this._stayOpen;
    }
    inst._currentDay = $('a', td).html();
    inst._currentMonth = month;
    inst._currentYear = year;
    this._selectDate(id, inst._formatDate(
      inst._currentDay, inst._currentMonth, inst._currentYear));
    if (this._stayOpen) {
      inst._endDay = inst._endMonth = inst._endYear = null;
      inst._rangeStart = new Date(inst._currentYear, inst._currentMonth, inst._currentDay);
      this._updateDatepicker(inst);
    }
    else if (rangeSelect) {
      inst._endDay = inst._currentDay;
      inst._endMonth = inst._currentMonth;
      inst._endYear = inst._currentYear;
      inst._selectedDay = inst._currentDay = inst._rangeStart.getDate();
      inst._selectedMonth = inst._currentMonth = inst._rangeStart.getMonth();
      inst._selectedYear = inst._currentYear = inst._rangeStart.getFullYear();
      inst._rangeStart = null;
      if (inst._inline) {
        this._updateDatepicker(inst);
      }
    }
  },

  /* Erase the input field and hide the date picker. */
  _clearDate: function(id) {
    var inst = this._getInst(id);
    this._stayOpen = false;
    inst._endDay = inst._endMonth = inst._endYear = inst._rangeStart = null;
    this._selectDate(inst, '');
  },

  /* Update the input field with the selected date. */
  _selectDate: function(id, dateStr) {
    var inst = this._getInst(id);
    dateStr = (dateStr != null ? dateStr : inst._formatDate());
    if (inst._rangeStart) {
      dateStr = inst._formatDate(inst._rangeStart) + inst._get('rangeSeparator') + dateStr;
    }
    if (inst._input) {
      inst._input.val(dateStr);
    }
    var onSelect = inst._get('onSelect');
    if (onSelect) {
      onSelect(dateStr, inst);  // trigger custom callback
    }
    else {
      if (inst._input) {
        inst._input.trigger('change'); // fire the change event
      }
    }
    if (inst._inline) {
      this._updateDatepicker(inst);
    }
    else {
      if (!this._stayOpen) {
        this.hideDatepicker(inst._get('speed'));
      }
    }
  },

  /* Set as beforeShowDay function to prevent selection of weekends.
     @param  date  Date - the date to customise
     @return [boolean, string] - is this date selectable?, what is its CSS class? */
  noWeekends: function(date) {
    var day = date.getDay();
    return [(day > 0 && day < 6), ''];
  },

  /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
     @param  date  Date - the date to get the week for
     @return  number - the number of the week within the year that contains this date */
  iso8601Week: function(date) {
    var checkDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
    var firstMon = new Date(checkDate.getFullYear(), 1 - 1, 4); // First week always contains 4 Jan
    var firstDay = firstMon.getDay() || 7; // Day of week: Mon = 1, ..., Sun = 7
    firstMon.setDate(firstMon.getDate() + 1 - firstDay); // Preceding Monday
    if (firstDay < 4 && checkDate < firstMon) { // Adjust first three days in year if necessary
      checkDate.setDate(checkDate.getDate() - 3); // Generate for previous year
      return $.datepicker.iso8601Week(checkDate);
    }
    else if (checkDate > new Date(checkDate.getFullYear(), 12 - 1, 28)) { // Check last three days in year
      firstDay = new Date(checkDate.getFullYear() + 1, 1 - 1, 4).getDay() || 7;
      if (firstDay > 4 && (checkDate.getDay() || 7) < firstDay - 3) { // Adjust if necessary
        checkDate.setDate(checkDate.getDate() + 3); // Generate for next year
        return $.datepicker.iso8601Week(checkDate);
      }
    }
    return Math.floor(((checkDate - firstMon) / 86400000) / 7) + 1; // Weeks to given date
  },

  /* Provide status text for a particular date.
     @param  date  the date to get the status for
     @param  inst  the current datepicker instance
     @return  the status display text for this date */
  dateStatus: function(date, inst) {
    return $.datepicker.formatDate(inst._get('dateStatus'), date, inst._get('dayNamesShort'),
      inst._get('dayNames'), inst._get('monthNamesShort'), inst._get('monthNames'));
  },

  /* Parse a string value into a date object.
     The format can be combinations of the following:
     d  - day of month (no leading zero)
     dd - day of month (two digit)
     D  - day name short
     DD - day name long
     m  - month of year (no leading zero)
     mm - month of year (two digit)
     M  - month name short
     MM - month name long
     y  - year (two digit)
     yy - year (four digit)
     '...' - literal text
     '' - single quote

     @param  format           String - the expected format of the date
     @param  value            String - the date in the above format
     @param  shortYearCutoff  Number - the cutoff year for determining the century (optional)
     @param  dayNamesShort    String[7] - abbreviated names of the days from Sunday (optional)
     @param  dayNames         String[7] - names of the days from Sunday (optional)
     @param  monthNamesShort  String[12] - abbreviated names of the months (optional)
     @param  monthNames       String[12] - names of the months (optional)
     @return  Date - the extracted date value or null if value is blank */
  parseDate: function (format, value, shortYearCutoff, dayNamesShort, dayNames, monthNamesShort, monthNames) {
    if (format == null || value == null) {
      throw 'Invalid arguments';
    }
//		format = dateFormats[format] || format;
    value = (typeof value == 'object' ? value.toString() : value + '');
    if (value == '') {
      return null;
    }
    dayNamesShort = dayNamesShort || this._defaults.dayNamesShort;
    dayNames = dayNames || this._defaults.dayNames;
    monthNamesShort = monthNamesShort || this._defaults.monthNamesShort;
    monthNames = monthNames || this._defaults.monthNames;
    var year = -1;
    var month = -1;
    var day = -1;
    var literal = false;
    // Check whether a format character is doubled
    var lookAhead = function(match) {
      var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
      if (matches) {
        iFormat++;
      }
      return matches;
    };
    // Extract a number from the string value
    var getNumber = function(match) {
      lookAhead(match);
      var size = (match == 'y' ? 4 : 2);
      var num = 0;
      while (size > 0 && iValue < value.length &&
          value.charAt(iValue) >= '0' && value.charAt(iValue) <= '9') {
        num = num * 10 + (value.charAt(iValue++) - 0);
        size--;
      }
      if (size == (match == 'y' ? 4 : 2)) {
        throw 'Missing number at position ' + iValue;
      }
      return num;
    };
    // Extract a name from the string value and convert to an index
    var getName = function(match, shortNames, longNames) {
      var names = (lookAhead(match) ? longNames : shortNames);
      var size = 0;
      for (var j = 0; j < names.length; j++) {
        size = Math.max(size, names[j].length);
      }
      var name = '';
      var iInit = iValue;
      while (size > 0 && iValue < value.length) {
        name += value.charAt(iValue++);
        for (var i = 0; i < names.length; i++) {
          if (name == names[i]) {
            return i + 1;
          }
        }
        size--;
      }
      throw 'Unknown name at position ' + iInit;
    };
    // Confirm that a literal character matches the string value
    var checkLiteral = function() {
      if (value.charAt(iValue) != format.charAt(iFormat)) {
        throw 'Unexpected literal at position ' + iValue;
      }
      iValue++;
    };
    var iValue = 0;
    for (var iFormat = 0; iFormat < format.length; iFormat++) {
      if (literal) {
        if (format.charAt(iFormat) == '\'' && !lookAhead('\'')) {
          literal = false;
        }
        else {
          checkLiteral();
        }
      }
      else {
        switch (format.charAt(iFormat)) {
          case 'd':
            day = getNumber('d');
            break;
          case 'D':
            getName('D', dayNamesShort, dayNames);
            break;
          case 'm':
            month = getNumber('m');
            break;
          case 'M':
            month = getName('M', monthNamesShort, monthNames);
            break;
          case 'y':
            year = getNumber('y');
            break;
          case '\'':
            if (lookAhead('\'')) {
              checkLiteral();
            }
            else {
              literal = true;
            }
            break;
          default:
            checkLiteral();
        }
      }
    }
    if (year < 100) {
      year += new Date().getFullYear() - new Date().getFullYear() % 100 +
        (year <= shortYearCutoff ? 0 : -100);
    }
    var date = new Date(year, month - 1, day);
    if (date.getFullYear() != year || date.getMonth() + 1 != month || date.getDate() != day) {
      throw 'Invalid date'; // E.g. 31/02/*
    }
    return date;
  },

  /* Format a date object into a string value.
     The format can be combinations of the following:
     d  - day of month (no leading zero)
     dd - day of month (two digit)
     D  - day name short
     DD - day name long
     m  - month of year (no leading zero)
     mm - month of year (two digit)
     M  - month name short
     MM - month name long
     y  - year (two digit)
     yy - year (four digit)
     '...' - literal text
     '' - single quote

     @param  format           String - the desired format of the date
     @param  date             Date - the date value to format
     @param  dayNamesShort    String[7] - abbreviated names of the days from Sunday (optional)
     @param  dayNames         String[7] - names of the days from Sunday (optional)
     @param  monthNamesShort  String[12] - abbreviated names of the months (optional)
     @param  monthNames       String[12] - names of the months (optional)
     @return  String - the date in the above format */
  formatDate: function (format, date, dayNamesShort, dayNames, monthNamesShort, monthNames) {
    if (!date) {
      return '';
    }
//		format = dateFormats[format] || format;
    dayNamesShort = dayNamesShort || this._defaults.dayNamesShort;
    dayNames = dayNames || this._defaults.dayNames;
    monthNamesShort = monthNamesShort || this._defaults.monthNamesShort;
    monthNames = monthNames || this._defaults.monthNames;
    // Check whether a format character is doubled
    var lookAhead = function(match) {
      var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) == match);
      if (matches) {
        iFormat++;
      }
      return matches;
    };
    // Format a number, with leading zero if necessary
    var formatNumber = function(match, value) {
      return (lookAhead(match) && value < 10 ? '0' : '') + value;
    };
    // Format a name, short or long as requested
    var formatName = function(match, value, shortNames, longNames) {
      return (lookAhead(match) ? longNames[value] : shortNames[value]);
    };
    var output = '';
    var literal = false;
    if (date) {
      for (var iFormat = 0; iFormat < format.length; iFormat++) {
        if (literal) {
          if (format.charAt(iFormat) == '\'' && !lookAhead('\'')) {
            literal = false;
          }
          else {
            output += format.charAt(iFormat);
          }
        }
        else {
          switch (format.charAt(iFormat)) {
            case 'd':
              output += formatNumber('d', date.getDate());
              break;
            case 'D':
              output += formatName('D', date.getDay(), dayNamesShort, dayNames);
              break;
            case 'm':
              output += formatNumber('m', date.getMonth() + 1);
              break;
            case 'M':
              output += formatName('M', date.getMonth(), monthNamesShort, monthNames);
              break;
            case 'y':
              output += (lookAhead('y') ? date.getFullYear() :
                (date.getYear() % 100 < 10 ? '0' : '') + date.getYear() % 100);
              break;
            case '\'':
              if (lookAhead('\'')) {
                output += '\'';
              }
              else {
                literal = true;
              }
              break;
            default:
              output += format.charAt(iFormat);
          }
        }
      }
    }
    return output;
  },

  /* Extract all possible characters from the date format. */
  _possibleChars: function (format) {
//		format = dateFormats[format] || format;
    var chars = '';
    var literal = false;
    for (var iFormat = 0; iFormat < format.length; iFormat++) {
      if (literal) {
        if (format.charAt(iFormat) == '\'' && !lookAhead('\'')) {
          literal = false;
        }
        else {
          chars += format.charAt(iFormat);
        }
      }
      else {
        switch (format.charAt(iFormat)) {
          case 'd':
          case 'm':
          case 'y':
            chars += '0123456789';
            break;
          case 'D':
          case 'M':
            return null; // Accept anything
          case '\'':
            if (lookAhead('\'')) {
              chars += '\'';
            }
            else {
              literal = true;
            }
            break;
          default:
            chars += format.charAt(iFormat);
        }
      }
    }
    return chars;
  }
});

/* Individualised settings for date picker functionality applied to one or more related inputs.
   Instances are managed and manipulated through the Datepicker manager. */
function DatepickerInstance(settings, inline) {
  this._id = $.datepicker._register(this);
  this._selectedDay = 0;
  this._selectedMonth = 0; // 0-11
  this._selectedYear = 0; // 4-digit year
  this._input = null; // The attached input field
  this._inline = inline; // True if showing inline, false if used in a popup
  this._datepickerDiv = (!inline ? $.datepicker._datepickerDiv :
    $('<div id="datepicker_div_' + this._id + '" class="datepicker_inline"></div>'));
  // customise the date picker object - uses manager defaults if not overridden
  this._settings = extendRemove({}, settings || {}); // clone
  if (inline) {
    this._setDate(this._getDefaultDate());
  }
}

$.extend(DatepickerInstance.prototype, {
  /* Get a setting value, defaulting if necessary. */
  _get: function(name) {
    return (this._settings[name] != null ? this._settings[name] : $.datepicker._defaults[name]);
  },

  /* Parse existing date and initialise date picker. */
  _setDateFromField: function(input) {
    this._input = $(input);
    var dateFormat = this._get('dateFormat');
    var dates = this._input ? this._input.val().split(this._get('rangeSeparator')) : null;
    this._endDay = this._endMonth = this._endYear = null;
    var shortYearCutoff = this._get('shortYearCutoff');
    shortYearCutoff = (typeof shortYearCutoff != 'string' ? shortYearCutoff :
      new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
    var date = this._getDefaultDate();
    if (dates.length > 0) {
      var dayNamesShort = this._get('dayNamesShort');
      var dayNames = this._get('dayNames');
      var monthNamesShort = this._get('monthNamesShort');
      var monthNames = this._get('monthNames');
      if (dates.length > 1) {
        date = $.datepicker.parseDate(dateFormat, dates[1], shortYearCutoff,
          dayNamesShort, dayNames, monthNamesShort, monthNames) ||
          this._getDefaultDate();
        this._endDay = date.getDate();
        this._endMonth = date.getMonth();
        this._endYear = date.getFullYear();
      }
      try {
        date = $.datepicker.parseDate(dateFormat, dates[0], shortYearCutoff,
          dayNamesShort, dayNames, monthNamesShort, monthNames) ||
          this._getDefaultDate();
      }
      catch (e) {
        $.datepicker.log(e);
        date = this._getDefaultDate();
      }
    }
    this._selectedDay = this._currentDay = date.getDate();
    this._selectedMonth = this._currentMonth = date.getMonth();
    this._selectedYear = this._currentYear = date.getFullYear();
    this._adjustDate();
  },

  /* Retrieve the default date shown on opening. */
  _getDefaultDate: function() {
    var offsetDate = function(offset) {
      var date = new Date();
      date.setDate(date.getDate() + offset);
      return date;
    };
    var defaultDate = this._get('defaultDate');
    return (defaultDate == null ? new Date() :
      (typeof defaultDate == 'number' ? offsetDate(defaultDate) : defaultDate));
  },

  /* Set the date(s) directly. */
  _setDate: function(date, endDate) {
    this._selectedDay = this._currentDay = date.getDate();
    this._selectedMonth = this._currentMonth = date.getMonth();
    this._selectedYear = this._currentYear = date.getFullYear();
    if (this._get('rangeSelect')) {
      if (endDate) {
        this._endDay = endDate.getDate();
        this._endMonth = endDate.getMonth();
        this._endYear = endDate.getFullYear();
      }
      else {
        this._endDay = this._currentDay;
        this._endMonth = this._currentMonth;
        this._endYear = this._currentYear;
      }
    }
    this._adjustDate();
  },

  /* Retrieve the date(s) directly. */
  _getDate: function() {
    var startDate = (!this._currentYear || (this._input && this._input.val() == '') ? null :
      new Date(this._currentYear, this._currentMonth, this._currentDay));
    if (this._get('rangeSelect')) {
      return [startDate, (!this._endYear ? null :
        new Date(this._endYear, this._endMonth, this._endDay))];
    }
    else {
      return startDate;
    }
  },

  /* Generate the HTML for the current state of the date picker. */
  _generateDatepicker: function() {
    var today = new Date();
    today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time
    var showStatus = this._get('showStatus');
    var isRTL = this._get('isRTL');
    // build the date picker HTML
    var clear = (this._get('mandatory') ? '' :
      '<div class="datepicker_clear"><a onclick="jQuery.datepicker._clearDate(' + this._id + ');"' +
      (showStatus ? this._addStatus(this._get('clearStatus') || '&#xa0;') : '') + '>' +
      this._get('clearText') + '</a></div>');
    var controls = '<div class="datepicker_control">' + (isRTL ? '' : clear) +
      '<div class="datepicker_close"><a onclick="jQuery.datepicker.hideDatepicker();"' +
      (showStatus ? this._addStatus(this._get('closeStatus') || '&#xa0;') : '') + '>' +
      this._get('closeText') + '</a></div>' + (isRTL ? clear : '')  + '</div>';
    var prompt = this._get('prompt');
    var closeAtTop = this._get('closeAtTop');
    var hideIfNoPrevNext = this._get('hideIfNoPrevNext');
    var numMonths = this._get('numberOfMonths');
    var stepMonths = this._get('stepMonths');
    var isMultiMonth = (numMonths != 1);
    numMonths = (numMonths == null ? [1, 1] : (typeof numMonths == 'number' ? [1, numMonths] : numMonths));
    // controls and links
    var prev = '<div class="datepicker_prev">' + (this._canAdjustMonth(-1) ?
      '<a onclick="jQuery.datepicker._adjustDate(' + this._id + ', -' + stepMonths + ', \'M\');"' +
      (showStatus ? this._addStatus(this._get('prevStatus') || '&#xa0;') : '') + '>' +
      this._get('prevText') + '</a>' :
      (hideIfNoPrevNext ? '' : '<label>' + this._get('prevText') + '</label>')) + '</div>';
    var next = '<div class="datepicker_next">' + (this._canAdjustMonth(+1) ?
      '<a onclick="jQuery.datepicker._adjustDate(' + this._id + ', +' + stepMonths + ', \'M\');"' +
      (showStatus ? this._addStatus(this._get('nextStatus') || '&#xa0;') : '') + '>' +
      this._get('nextText') + '</a>' :
      (hideIfNoPrevNext ? '>' : '<label>' + this._get('nextText') + '</label>')) + '</div>';
    var html = (prompt ? '<div class="datepicker_prompt">' + prompt + '</div>' : '') +
      (closeAtTop && !this._inline ? controls : '') +
      '<div class="datepicker_links">' + (isRTL ? next : prev) +
      (this._isInRange(today) ? '<div class="datepicker_current">' +
      '<a onclick="jQuery.datepicker._gotoToday(' + this._id + ');"' +
      (showStatus ? this._addStatus(this._get('currentStatus') || '&#xa0;') : '') + '>' +
      this._get('currentText') + '</a></div>' : '') + (isRTL ? prev : next) + '</div>';
    var minDate = this._getMinDate();
    var maxDate = this._get('maxDate');
    var drawMonth = this._selectedMonth;
    var drawYear = this._selectedYear;
    var showWeeks = this._get('showWeeks');
    for (var row = 0; row < numMonths[0]; row++) {
    for (var col = 0; col < numMonths[1]; col++) {
      var selectedDate = new Date(drawYear, drawMonth, this._selectedDay);
      html += '<div class="datepicker_oneMonth' + (col == 0 ? ' datepicker_newRow' : '') + '">' +
        this._generateMonthYearHeader(drawMonth, drawYear, minDate, maxDate,
        selectedDate, row > 0 || col > 0) + // draw month headers
        '<table class="datepicker" cellpadding="0" cellspacing="0"><thead>' +
        '<tr class="datepicker_titleRow">' +
        (showWeeks ? '<td>' + this._get('weekHeader') + '</td>' : '');
      var firstDay = this._get('firstDay');
      var changeFirstDay = this._get('changeFirstDay');
      var dayNames = this._get('dayNames');
      var dayNamesShort = this._get('dayNamesShort');
      var dayNamesMin = this._get('dayNamesMin');
      for (var dow = 0; dow < 7; dow++) { // days of the week
        var day = (dow + firstDay) % 7;
        var status = this._get('dayStatus') || '&#xa0;';
        status = (status.indexOf('DD') > -1 ? status.replace(/DD/, dayNames[day]) :
          status.replace(/D/, dayNamesShort[day]));
        html += '<td>' + (!changeFirstDay ? '<span' :
          '<a onclick="jQuery.datepicker._changeFirstDay(' + this._id + ', ' + day + ');"') +
          (showStatus ? this._addStatus(status) : '') + ' title="' + dayNames[day] + '">' +
          dayNamesMin[day] + (changeFirstDay ? '</a>' : '</span>') + '</td>';
      }
      html += '</tr></thead><tbody>';
      var daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
      this._selectedDay = Math.min(this._selectedDay, daysInMonth);
      var leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
      var currentDate = new Date(this._currentYear, this._currentMonth, this._currentDay);
      var endDate = this._endDay ? new Date(this._endYear, this._endMonth, this._endDay) : currentDate;
      var printDate = new Date(drawYear, drawMonth, 1 - leadDays);
      var numRows = (isMultiMonth ? 6 : Math.ceil((leadDays + daysInMonth) / 7)); // calculate the number of rows to generate
      var beforeShowDay = this._get('beforeShowDay');
      var showOtherMonths = this._get('showOtherMonths');
      var calculateWeek = this._get('calculateWeek') || $.datepicker.iso8601Week;
      var dateStatus = this._get('statusForDate') || $.datepicker.dateStatus;
      for (var dRow = 0; dRow < numRows; dRow++) { // create date picker rows
        html += '<tr class="datepicker_daysRow">' +
          (showWeeks ? '<td class="datepicker_weekCol">' + calculateWeek(printDate) + '</td>' : '');
        for (var dow = 0; dow < 7; dow++) { // create date picker days
          var daySettings = (beforeShowDay ? beforeShowDay(printDate) : [true, '']);
          var otherMonth = (printDate.getMonth() != drawMonth);
          var unselectable = otherMonth || !daySettings[0] ||
            (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
          html += '<td class="datepicker_daysCell' +
            ((dow + firstDay + 6) % 7 >= 5 ? ' datepicker_weekEndCell' : '') + // highlight weekends
            (otherMonth ? ' datepicker_otherMonth' : '') + // highlight days from other months
            (printDate.getTime() == selectedDate.getTime() && drawMonth == this._selectedMonth ?
            ' datepicker_daysCellOver' : '') + // highlight selected day
            (unselectable ? ' datepicker_unselectable' : '') +  // highlight unselectable days
            (otherMonth && !showOtherMonths ? '' : ' ' + daySettings[1] + // highlight custom dates
            (printDate.getTime() >= currentDate.getTime() && printDate.getTime() <= endDate.getTime() ?  // in current range
            ' datepicker_currentDay' : // highlight selected day
            (printDate.getTime() == today.getTime() ? ' datepicker_today' : ''))) + '"' + // highlight today (if different)
            (unselectable ? '' : ' onmouseover="jQuery(this).addClass(\'datepicker_daysCellOver\');' +
            (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#datepicker_status_' +
            this._id + '\').html(\'' + (dateStatus(printDate, this) || '&#xa0;') +'\');') + '"' +
            ' onmouseout="jQuery(this).removeClass(\'datepicker_daysCellOver\');' +
            (!showStatus || (otherMonth && !showOtherMonths) ? '' : 'jQuery(\'#datepicker_status_' +
            this._id + '\').html(\'&#xa0;\');') + '" onclick="jQuery.datepicker._selectDay(' +
            this._id + ',' + drawMonth + ',' + drawYear + ', this);"') + '>' + // actions
            (otherMonth ? (showOtherMonths ? printDate.getDate() : '&#xa0;') : // display for other months
            (unselectable ? printDate.getDate() : '<a>' + printDate.getDate() + '</a>')) + '</td>'; // display for this month
          printDate.setDate(printDate.getDate() + 1);
        }
        html += '</tr>';
      }
      drawMonth++;
      if (drawMonth > 11) {
        drawMonth = 0;
        drawYear++;
      }
      html += '</tbody></table></div>';
    }
    }
    html += (showStatus ? '<div id="datepicker_status_' + this._id +
      '" class="datepicker_status">' + (this._get('initStatus') || '&#xa0;') + '</div>' : '') +
      (!closeAtTop && !this._inline ? controls : '') +
      '<div style="clear: both;"></div>' +
      ($.browser.msie && parseInt($.browser.version) < 7 && !this._inline ?
      '<iframe src="javascript:false;" class="datepicker_cover"></iframe>' : '');
    return html;
  },

  /* Generate the month and year header. */
  _generateMonthYearHeader: function(drawMonth, drawYear, minDate, maxDate, selectedDate, secondary) {
    minDate = (this._rangeStart && minDate && selectedDate < minDate ? selectedDate : minDate);
    var showStatus = this._get('showStatus');
    var html = '<div class="datepicker_header">';
    // month selection
    var monthNames = this._get('monthNames');
    if (secondary || !this._get('changeMonth')) {
      html += monthNames[drawMonth] + '&#xa0;';
    }
    else {
      var inMinYear = (minDate && minDate.getFullYear() == drawYear);
      var inMaxYear = (maxDate && maxDate.getFullYear() == drawYear);
      html += '<select class="datepicker_newMonth" ' +
        'onchange="jQuery.datepicker._selectMonthYear(' + this._id + ', this, \'M\');" ' +
        'onclick="jQuery.datepicker._clickMonthYear(' + this._id + ');"' +
        (showStatus ? this._addStatus(this._get('monthStatus') || '&#xa0;') : '') + '>';
      for (var month = 0; month < 12; month++) {
        if ((!inMinYear || month >= minDate.getMonth()) &&
            (!inMaxYear || month <= maxDate.getMonth())) {
          html += '<option value="' + month + '"' +
            (month == drawMonth ? ' selected="selected"' : '') +
            '>' + monthNames[month] + '</option>';
        }
      }
      html += '</select>';
    }
    // year selection
    if (secondary || !this._get('changeYear')) {
      html += drawYear;
    }
    else {
      // determine range of years to display
      var years = this._get('yearRange').split(':');
      var year = 0;
      var endYear = 0;
      if (years.length != 2) {
        year = drawYear - 10;
        endYear = drawYear + 10;
      }
      else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') {
        year = drawYear + parseInt(years[0], 10);
        endYear = drawYear + parseInt(years[1], 10);
      }
      else {
        year = parseInt(years[0], 10);
        endYear = parseInt(years[1], 10);
      }
      year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
      endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
      html += '<select class="datepicker_newYear" ' +
        'onchange="jQuery.datepicker._selectMonthYear(' + this._id + ', this, \'Y\');" ' +
        'onclick="jQuery.datepicker._clickMonthYear(' + this._id + ');"' +
        (showStatus ? this._addStatus(this._get('yearStatus') || '&#xa0;') : '') + '>';
      for (; year <= endYear; year++) {
        html += '<option value="' + year + '"' +
          (year == drawYear ? ' selected="selected"' : '') +
          '>' + year + '</option>';
      }
      html += '</select>';
    }
    html += '</div>'; // Close datepicker_header
    return html;
  },

  /* Provide code to set and clear the status panel. */
  _addStatus: function(text) {
    return ' onmouseover="jQuery(\'#datepicker_status_' + this._id + '\').html(\'' + text + '\');" ' +
      'onmouseout="jQuery(\'#datepicker_status_' + this._id + '\').html(\'&#xa0;\');"';
  },

  /* Adjust one of the date sub-fields. */
  _adjustDate: function(offset, period) {
    var year = this._selectedYear + (period == 'Y' ? offset : 0);
    var month = this._selectedMonth + (period == 'M' ? offset : 0);
    var day = Math.min(this._selectedDay, this._getDaysInMonth(year, month)) +
      (period == 'D' ? offset : 0);
    var date = new Date(year, month, day);
    // ensure it is within the bounds set
    var minDate = this._getMinDate();
    var maxDate = this._get('maxDate');
    date = (minDate && date < minDate ? minDate : date);
    date = (maxDate && date > maxDate ? maxDate : date);
    this._selectedDay = date.getDate();
    this._selectedMonth = date.getMonth();
    this._selectedYear = date.getFullYear();
  },

  /* Determine the current minimum date - may be overridden for a range. */
  _getMinDate: function() {
    return this._get('minDate') || this._rangeStart;
  },

  /* Find the number of days in a given month. */
  _getDaysInMonth: function(year, month) {
    return 32 - new Date(year, month, 32).getDate();
  },

  /* Find the day of the week of the first of a month. */
  _getFirstDayOfMonth: function(year, month) {
    return new Date(year, month, 1).getDay();
  },

  /* Determines if we should allow a "next/prev" month display change. */
  _canAdjustMonth: function(offset) {
    var date = new Date(this._selectedYear, this._selectedMonth + offset, 1);
    if (offset < 0) {
      date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
    }
    return this._isInRange(date);
  },

  /* Is the given date in the accepted range? */
  _isInRange: function(date) {
    // during range selection, use minimum of selected date and range start
    var newMinDate = (!this._rangeStart ? null :
      new Date(this._selectedYear, this._selectedMonth, this._selectedDay));
    newMinDate = (newMinDate && this._rangeStart < newMinDate ? this._rangeStart : newMinDate);
    var minDate = newMinDate || this._get('minDate');
    var maxDate = this._get('maxDate');
    return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate));
  },

  /* Format the given date for display. */
  _formatDate: function(day, month, year) {
    if (!day) {
      this._currentDay = this._selectedDay;
      this._currentMonth = this._selectedMonth;
      this._currentYear = this._selectedYear;
    }
    var date = (day ? (typeof day == 'object' ? day : new Date(year, month, day)) :
      new Date(this._currentYear, this._currentMonth, this._currentDay));
    return $.datepicker.formatDate(this._get('dateFormat'), date,
      this._get('dayNamesShort'), this._get('dayNames'),
      this._get('monthNamesShort'), this._get('monthNames'));
  }
});

/* jQuery extend now ignores nulls! */
function extendRemove(target, props) {
  $.extend(target, props);
  for (var name in props) {
    if (props[name] == null) {
      target[name] = null;
    }
  }
  return target;
};

/* Attach the date picker to a jQuery selection.
   @param  settings  object - the new settings to use for this date picker instance (anonymous)
   @return jQuery object - for chaining further calls */
$.fn.datepicker = function(settings) {
  return this.each(function() {
    // check for settings on the control itself - in namespace 'date:'
    var inlineSettings = null;
    for (attrName in $.datepicker._defaults) {
      var attrValue = this.getAttribute('date:' + attrName);
      if (attrValue) {
        inlineSettings = inlineSettings || {};
        try {
          inlineSettings[attrName] = eval(attrValue);
        }
        catch (err) {
          inlineSettings[attrName] = attrValue;
        }
      }
    }
    var nodeName = this.nodeName.toLowerCase();
    if (nodeName == 'input') {
      var instSettings = (inlineSettings ? $.extend($.extend({}, settings || {}),
        inlineSettings || {}) : settings); // clone and customise
      var inst = (inst && !inlineSettings ? inst :
        new DatepickerInstance(instSettings, false));
      $.datepicker._connectDatepicker(this, inst);
    }
    else if (nodeName == 'div' || nodeName == 'span') {
      var instSettings = $.extend($.extend({}, settings || {}),
        inlineSettings || {}); // clone and customise
      var inst = new DatepickerInstance(instSettings, true);
      $.datepicker._inlineDatepicker(this, inst);
    }
  });
};

/* Initialise the date picker. */
$(document).ready(function() {
  $.datepicker = new Datepicker(); // singleton instance
  $(document.body).append($.datepicker._datepickerDiv).
    mousedown($.datepicker._checkExternalClick);
});

})(jQuery);
;/**
 * This file contains helper code for the SWFUpload add assets form.
 */

var swfu;
var linkQueue = [];
var lastUploadedFolderTID;
var defaultLinkURL;
var $uploadProgressList;
var swfuploadLoadComplete = false;
var message = false;

function getPostParams() {
  return {
    'PHPSESSID'  : Drupal.settings.session.sessionID,
    'folder_tid' : $('#edit-folder-tid').val()
  };
}

function swfuploadLoaded() {
  swfuploadLoadComplete = true;
}

function createUploader() {
  try {
	this.message = false;
    swfuploadLoadComplete = false;
    swfu = new SWFUpload({
      // Button Settings
      button_image_url : '/sites/all/modules/sprout/images/button-browse-all-states.png',
      button_width : 77,
      button_height : 21,
      button_placeholder_id : 'asset-browse',
      prevent_swf_caching : true,

      // Backend Settings
      upload_url: '/ajax/asset/insert',  // Relative to the SWF file (or you can use absolute paths)
      post_params: getPostParams(),

      // File Upload Settings
      file_size_limit : '18mb',
      file_types : '*.mp3;*.swf;*.jpe;*.jpg;*.jpeg;*.gif;*.png;*.flv;*.spc;*.xml;*.svg',
      file_types_description : 'Asset Files',
      file_upload_limit : '0',
      file_queue_limit : '0',

      // Event Handler Settings (all my handlers are in the Handler.js file)
      swfupload_loaded_handler : swfuploadLoaded,
      file_dialog_start_handler : fileDialogStart,
      file_queued_handler : fileQueued,
      file_queue_error_handler : fileQueueError,
      file_dialog_complete_handler : fileDialogComplete,
      upload_start_handler : uploadStart,
      upload_progress_handler : uploadProgress,
      upload_error_handler : uploadError,
      upload_complete_handler : uploadComplete,
      upload_success_handler: uploadSuccess,

      // Flash Settings
      flash_url : '/sites/all/modules/sprout/swfupload/swfupload_f9.swf' + Drupal.settings.sprout_cache_suffix, // Relative to this file (or you can use absolute paths)

      // Debug Settings
      debug: true,
      debug_handler : spUtils.storeError
    });

    spUtils.clearStoredErrors();
  }
  catch (ex) {
    spUtils.logError('createUploader(): ' + ex);
  }
}

Drupal.behaviors.sproutUpload = function (context) {
  $uploadProgressList = $('#upload-progress');

  $('#start-upload:not(.start-processed)').bind('click', function () {
    $(this).blur();

    if (!swfuploadLoadComplete)
      return false;

    // Update post params before we upload.
    swfu.setPostParams(getPostParams());

    lastUploadedFolderTID = $('select#edit-folder-tid').val();

    // If there is an unqueued URL, then add it to the links queue.
    var linkURL = $('#edit-link').val();
    if (linkURL != '' && linkURL != defaultLinkURL) {
      addLink();
    }

    numAssetsQueued = linksQueued() + swfu.getStats().files_queued;
    numAssetsAdded = 0;

    // Upload any files.
    swfu.startUpload();
    $('li.error, li.complete', $uploadProgressList).fadeAndRemoveUploadItem();
    $('li a.cancel', $uploadProgressList).hide();
    $('li:not(.system):not(.complete):not(.error) span.status', $uploadProgressList).html('Processing...');

    // Add any links.
    // TODO: Turn into one multi-call?
    numLinksQueued = linksQueued();
    numLinksAttempted = 0;
    for (var id in linkQueue) {
      $.post('/ajax/asset/insert', {
        'folder_tid' : lastUploadedFolderTID,
        'link'       : linkQueue[id],
        'css_id'     : 'link-' + id
      }, handleAddLinkComplete, 'json');

      delete linkQueue[id];
      numLinksAttempted++;
    }

    linksFinished = true;

    // If no files are waiting to be uploaded and only uploading links, close dialog at this point.
    if (swfu.getStats().files_queued === 0 && numLinksAttempted > 0) {
      //closeDialog();
    }

    return false;
  }).addClass('start-processed');

  $('#cancel-upload:not(.cancel-processed)').bind('click', function () {
    $(this).blur();

    if (swfuploadLoadComplete)
      cancelQueue(swfu);

    closeUploader();
    return false;
  }).addClass('cancel-processed');


  $('#asset-browse:not(.swfu-processed)').bind('mousedown', redrawWindow)
  .bind('click', function () {
    $(this).blur();
    redrawWindow();
    if (swfuploadLoadComplete) {
      swfu.selectFiles();
      redrawWindow();
    }
    return false;
  }).addClass('swfu-processed');

  $('#add-url:not(.add-processed)').bind('mousedown', redrawWindow)
  .bind('click', function () {
    $(this).blur();
    addLink();
    return false;
  }).addClass('add-processed');

  if (defaultLinkURL == null && $('#edit-link').length) {
    defaultLinkURL = $('#edit-link').val();
  }

  $('#edit-link:not(.upload-processed)').bind('keypress', function (e) {
    if (e.which == 13) {
      addLink();
      $(this).blur();
      return false;
    }
  })
  .bind('focus', function () {
    if ($(this).hasClass('default')) {
      $(this).removeClass('default').val('');
    }
    redrawWindow();
  })
  .bind('blur', function () {
    if ($(this).val() == '') {
      $(this).addClass('default').val(defaultLinkURL);
    }
    redrawWindow();
  })
  .addClass('upload-processed');

  $('.toggle-asset-help:not(.help-processed)').bind('mousedown', redrawWindow)
  .bind('click', function () {
    $(this).blur();
    $($(this).attr('rel')).toggle();
    return false;
  }).addClass('help-processed');
};

function handleAddLinkComplete(data) {
  // TODO: This will be accurate once we have a multi-call.
  if (data.success) {
    $('li#' + data.css_id + '.link', $uploadProgressList).addClass('complete').find('span.status').html('100% complete').next('a.cancel').show();
  }
  else {
    $('li#' + data.css_id + '.link', $uploadProgressList).addClass('error').find('span.status').html('Error adding web link').next('a.cancel').show();
  }
  incrementAssetsAdded(1);
}

function incrementAssetsAdded(val) {
  numAssetsAdded = numAssetsAdded + val;
  var percent = Math.floor((numAssetsAdded / numAssetsQueued) * 100);
  //$('#sprout-add-assets-form').append(percent);
  //sproutTrace('upload total percent', percent, numAssetsAdded, numAssetsQueued);
  if (percent == 100 && $('li.error', $uploadProgressList).length == 0) {
    closeDialog();
  }
}

function addErrorToList(message) {
  var $item = $('<li class="file error"><strong>Error:</strong> ' + message + ' <a class="cancel" href="#" title="Remove this file from upload list."></a></li>').children('a.cancel').bind('click', function () { removeItemFromList($(this)); }).end();
  $uploadProgressList
    .children('li.system').remove().end()
    .append($item);
}

function addLink() {
  var linkURL = $('#edit-link').val();

  redrawWindow();

  // Let user add link as long as not blank and not default.
  if (linkURL != '' && linkURL != defaultLinkURL) {
    addLinkToQueue(linkURL);
    $('#edit-link').val(defaultLinkURL).addClass('default');
  }
  else {
    // If user clicked Add expecting a popup box, give it to em.
    var answer = prompt(Drupal.t('Please enter the web link you would like to add:'), 'http://');
    if (answer != null) {
      addLinkToQueue(answer);
    }
  }

  redrawWindow();
}

function addLinkToQueue(linkURL) {
  var linkID = linkQueue.length;
  linkQueue[linkQueue.length] = linkURL;

  var $item = $('<li class="link" id="link-' + linkID + '">' + linkURL + ' <span class="status"></span> <a class="cancel" href="#" title="Remove this link from upload list."></a></li>').children('a.cancel').bind('click', cancelLink).end();
  $uploadProgressList
    .children('li.system').remove().end()
    .append($item);
}

/**
 * Checks how many links are still queued to be added since the linkQueue
 * array keeps added links keys, but sets value to undefined.
 */
function linksQueued() {
  var count = 0;
  for (var key in linkQueue) {
    if (typeof linkQueue[key] != 'undefined') {
      count++;
    }
  }
  return count;
}

function getTrueObjectLength(obj) {
  var count = 0;
  for (var key in obj) {
    if (typeof obj[key] != 'undefined') {
      count++;
    }
  }
  return count;
}

function closeDialog() {
  $('#dialog-close').trigger('click');
}


function removeItemFromList($linkObj) {
  var $item = $linkObj.parent().fadeAndRemoveUploadItem();

  if (typeof $item.attr('id') != 'undefined') {
    return $item.attr('id').substring(5); // link- or file-
  }
  else {
    return null;
  }
}

function cancelLink() {
  var linkID = parseInt(removeItemFromList($(this)));
  delete linkQueue[linkID];
  return false;
}

function cancelFile() {
  var fileID = removeItemFromList($(this));
  swfu.cancelUpload(fileID);
  return false;
}

function updateUploadStatus(fileObj, msg, status) {
  var $item = $('li#file-' + fileObj.id, $uploadProgressList).find('span.status').html(msg);
  if (typeof status != 'undefined' && status) {
    // Fake timer based on file size if moving to CDN. Otherwise, just set the
    // completed status (complete or error) and show the cancel link.
    if (status == 'begin-cdn') {
      //fileObj.size
      fakeProgressQueue[fileObj.id] = {
        'fileObj' : fileObj,
        'percent' : 50
      };

      if (!timeoutsRunning) {
        updateFakeProgress();
        timeoutsRunning = true;
      }
    }
    else {
      $item.next('a.cancel').show().parent().addClass(status);
    }
  }
}

/**
 * Since moving to S3 takes some time, we have to fake the progress for that
 * part. Also, since we have multiple files we need a queue to work with the
 * anonymous function used by setTimeout(). Very tricky!
 */
var fakeProgressQueue = {};
var timeoutsRunning = false;
var fakeTimeout;

var updateFakeProgress = function () {
  for (var id in fakeProgressQueue) {
    if (fakeProgressQueue[id].percent <= 98) {
      fakeProgressQueue[id].percent++;
      updateUploadStatus(fakeProgressQueue[id].fileObj, fakeProgressQueue[id].percent + '% complete');
    }

    if (fakeProgressQueue[id].percent >= 99) {
      delete fakeProgressQueue[id];
    }
  }

  if (getTrueObjectLength(fakeProgressQueue) > 0) {
    fakeTimeout = setTimeout(updateFakeProgress, 100);
  }
  else {
    timeoutsRunning = false;
  }
};

/* This is an example of how to cancel all the files queued up.  It's made somewhat generic.  Just pass your SWFUpload
object in to this method and it loops through cancelling the uploads. */
function cancelQueue(instance) {
  //document.getElementById(instance.customSettings.cancelButtonId).disabled = true;
  instance.stopUpload();
  var stats;

  do {
    stats = instance.getStats();
    instance.cancelUpload();
  } while (stats.files_queued !== 0);

}

/* **********************
   Event Handlers
   These are my custom event handlers to make my
   web application behave the way I went when SWFUpload
   completes different tasks.  These aren't part of the SWFUpload
   package.  They are part of my application.  Without these none
   of the actions SWFUpload makes will show up in my application.
   ********************** */
function fileDialogStart() {
	message = "Upload Canceled"
}

function getFileExtension(name) {
  var pos = name.lastIndexOf('.') + 1;
  return name.substring(pos).toLowerCase();
}

function fileIsTooBig(fileObj) {
  var ext = getFileExtension(fileObj.name);
  var limits = {
    'jpeg' : 1024000,
    'jpg'  : 1024000,
    'jpe'  : 1024000,
    'gif'  : 1024000,
    'png'  : 1024000
    //'flv'  : ,
    //'swf'  : ,
    //'mp3'  :
  };

  // If we have a self-imposed limit, check here. If not return false since this
  // will hit SWFUpload's global limit that is set at the beginning of this file.
  if (typeof limits[ext] != 'undefined') {
    return fileObj.size > limits[ext];
  }
  return false;
}

function fileQueued(fileObj) {
  try {
    if (fileIsTooBig(fileObj)) {
      swfu.cancelUpload(fileObj.id);
      addErrorToList(fileObj.name + " is too big.");
    }
    else {
      var $item = $('<li class="file" id="file-' + fileObj.id + '">' + fileObj.name + ' <span class="status"></span> <a class="cancel" href="#" title="Remove this file from upload list."></a></li>').children('a.cancel').bind('click', cancelFile).end();
      $uploadProgressList
        .children('li.system').remove().end()
        .append($item);
    }
  }
  catch (ex) {
    this.debug('fileQueued(): ' + ex);
    spUtils.logError('fileQueued(): ' + ex);
  }

}

function fileQueueError(fileObj, error_code, message) {
  try {
    switch (error_code) {
      case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
        addErrorToList(fileObj.name + " is too big.");
        this.debug("Error Code: File too big, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message);
        break;
      case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
        addErrorToList(fileObj.name + " is an empty file.");
        this.debug("Error Code: Zero byte file, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message);
        break;
      case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
        addErrorToList(fileObj.name + " is an invalid file type.");
        this.debug("Error Code: Invalid File Type, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message);
        break;
      case SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED:
        alert("You have attempted to queue too many files.\n" + (message === 0 ? "You have reached the upload limit." : "You may select " + (message > 1 ? "up to " + message + " files." : "one file.")));
        break;
      default:
        if (fileObj !== null) {
          addErrorToList(fileObj.name + " (unknown error)");
          this.debug("Error Code: " + error_code + ", File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message);
        }
        break;
    }
  }
  catch (ex) {
    this.debug('fileQueueError(): ' + ex);
    spUtils.logError('fileQueueError(): ' + ex);
  }
}

function fileDialogComplete(num_files_queued) { }

function uploadStart(fileObj) {
  try {
    updateUploadStatus(fileObj, '0% complete');
  }
  catch (ex) {
    this.debug('uploadStart(): ' + ex);
    spUtils.logError('uploadStart(): ' + ex);
  }

  return true;
}

function uploadProgress(fileObj, bytesLoaded, bytesTotal) {
  try {
    var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
    updateUploadStatus(fileObj, parseInt(percent / 2, 10) + '% complete', (percent == 100 ? 'begin-cdn' : null));
    redrawWindow();
  }
  catch (ex) {
    this.debug('uploadProgress(): ' + ex);
    spUtils.logError('uploadProgress(): ' + ex);
  }
}

function uploadComplete(fileObj) {
  try {
    incrementAssetsAdded(1);

    if (!(this.getStats().files_queued === 0 && linksQueued() === 0)) {
      this.startUpload();
    }
  }
  catch (ex) {
    this.debug('uploadComplete(): ' + ex);
    spUtils.logError('uploadComplete(): ' + ex);
  }

}

function uploadSuccess(fileObj, data) {
  message = "Upload Successful";
  try {
    data=eval('(' + data + ')');
    delete fakeProgressQueue[fileObj.id];
    if (checkError(data)) {
      updateUploadStatus(fileObj, '100% complete', 'complete');
    }
  }
  catch (ex) {
    this.debug('uploadSuccess(): ' + ex);
    spUtils.logError('uploadSuccess(): ' + ex);
  }
}

function uploadError(fileObj, error_code, message) {
  message = "Upload Error";
  try {
    delete fakeProgressQueue[fileObj.id];

    switch(error_code) {
      case SWFUpload.UPLOAD_ERROR.HTTP_ERROR:
        updateUploadStatus(fileObj, "Error: Upload Failed", 'error');
        errorMessage = "Error Code: HTTP Error, File name: " + fileObj.name + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.MISSING_UPLOAD_URL:
        updateUploadStatus(fileObj, "Error: Configuration Error", 'error');
        errorMessage = "Error Code: No backend file, File name: " + fileObj.name + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.UPLOAD_FAILED:
        updateUploadStatus(fileObj, "Error: Upload Failed", 'error');
        errorMessage = "Error Code: Upload Failed, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.IO_ERROR:
        updateUploadStatus(fileObj, "Error: File not readable", 'error');
        errorMessage = "Error Code: IO Error, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.SECURITY_ERROR:
        updateUploadStatus(fileObj, "Error: Security Error", 'error');
        errorMessage = "Error Code: Security Error, File name: " + fileObj.name + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.UPLOAD_LIMIT_EXCEEDED:
        updateUploadStatus(fileObj, "Error: Upload Limit Exceeded", 'error');
        errorMessage = "Error Code: Upload Limit Exceeded, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.SPECIFIED_FILE_ID_NOT_FOUND:
        updateUploadStatus(fileObj, "Error: File Not Found", 'error');
        errorMessage = "Error Code: The file was not found, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.FILE_VALIDATION_FAILED:
        updateUploadStatus(fileObj, "Error: Failed Validation", 'error');
        errorMessage = "Error Code: File Validation Failed, File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message;
        break;
      case SWFUpload.UPLOAD_ERROR.FILE_CANCELLED:
        // We fade out instead. updateUploadStatus(fileObj, "Cancelled");
        break;
      case SWFUpload.UPLOAD_ERROR.UPLOAD_STOPPED:
        updateUploadStatus(fileObj, "Stopped", 'error');
        break;
      default:
        updateUploadStatus(fileObj, "Unhandled Error: " + error_code, 'error');
        errorMessage = "Error Code: " + error_code + ", File name: " + fileObj.name + ", File size: " + fileObj.size + ", Message: " + message;
        break;
    }

    if (typeof errorMessage != 'undefined') {
      this.debug(errorMessage);
      spUtils.logError("Error: " + errorMessage + "<br/>\nLog: " + spUtils.getStoredErrors());
    }
  }
  catch (ex) {
    this.debug('uploadError(): ' + ex);
    spUtils.logError('uploadError(): ' + ex);
  }
}

//Horrible workaround for SPROUT-5504
function showDialog(message)
{
	var BrowserDetect = {
			init: function () {
				this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
				this.version = this.searchVersion(navigator.userAgent)
					|| this.searchVersion(navigator.appVersion)
					|| "an unknown version";
				this.OS = this.searchString(this.dataOS) || "an unknown OS";
			},
			searchString: function (data) {
				for (var i=0;i<data.length;i++)	{
					var dataString = data[i].string;
					var dataProp = data[i].prop;
					this.versionSearchString = data[i].versionSearch || data[i].identity;
					if (dataString) {
						if (dataString.indexOf(data[i].subString) != -1)
							return data[i].identity;
					}
					else if (dataProp)
						return data[i].identity;
				}
			},
			searchVersion: function (dataString) {
				var index = dataString.indexOf(this.versionSearchString);
				if (index == -1) return;
				return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
			},
			dataBrowser: [
				{
					string: navigator.userAgent,
					subString: "Chrome",
					identity: "Chrome"
				},
				{ 	string: navigator.userAgent,
					subString: "OmniWeb",
					versionSearch: "OmniWeb/",
					identity: "OmniWeb"
				},
				{
					string: navigator.vendor,
					subString: "Apple",
					identity: "Safari",
					versionSearch: "Version"
				},
				{
					prop: window.opera,
					identity: "Opera"
				},
				{
					string: navigator.vendor,
					subString: "iCab",
					identity: "iCab"
				},
				{
					string: navigator.vendor,
					subString: "KDE",
					identity: "Konqueror"
				},
				{
					string: navigator.userAgent,
					subString: "Firefox",
					identity: "Firefox"
				},
				{
					string: navigator.vendor,
					subString: "Camino",
					identity: "Camino"
				},
				{		// for newer Netscapes (6+)
					string: navigator.userAgent,
					subString: "Netscape",
					identity: "Netscape"
				},
				{
					string: navigator.userAgent,
					subString: "MSIE",
					identity: "Explorer",
					versionSearch: "MSIE"
				},
				{
					string: navigator.userAgent,
					subString: "Gecko",
					identity: "Mozilla",
					versionSearch: "rv"
				},
				{ 		// for older Netscapes (4-)
					string: navigator.userAgent,
					subString: "Mozilla",
					identity: "Netscape",
					versionSearch: "Mozilla"
				}
			],
			dataOS : [
				{
					string: navigator.platform,
					subString: "Win",
					identity: "Windows"
				},
				{
					string: navigator.platform,
					subString: "Mac",
					identity: "Mac"
				},
				{
					   string: navigator.userAgent,
					   subString: "iPhone",
					   identity: "iPhone/iPod"
			    },
				{
					string: navigator.platform,
					subString: "Linux",
					identity: "Linux"
				}
			]

		};
		BrowserDetect.init();
		if (BrowserDetect.OS == "Mac")
			if (BrowserDetect.browser == "Safari") {
				win = window.open("");
				if (win && win.top)
					win.close();
				else
					alert(message);
			} else
				alert(message);
}

/**
 * jQuery function that fades and removes an upload list item, then shows the
 * help text if no other list items are there.
 */
$.fn.fadeAndRemoveUploadItem = function () {
  return this.fadeOut('normal', function () {
    if ($(this).siblings().length == 0) {
      $(this).parent().append('<li class="system">' + $('#add-asset-help').html() + '</li>');
    }
    $(this).remove();
  });
};

;/**
 * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
 *
 * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/,  http://www.vinterwebb.se/
 *
 * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzén and Mammon Media and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */


/* ******************* */
/* Constructor & Init  */
/* ******************* */

var SWFUpload = function (settings) {
  this.initSWFUpload(settings);
};

SWFUpload.prototype.initSWFUpload = function (settings) {
  try {
    this.customSettings = {};	// A container where developers can place their own settings associated with this instance.
    this.settings = settings;
    this.eventQueue = [];
    this.movieName = "SWFUpload_" + SWFUpload.movieCount++;
    this.movieElement = null;

    // Setup global control tracking
    SWFUpload.instances[this.movieName] = this;

    // Load the settings.  Load the Flash movie.
    this.initSettings();
    this.loadFlash();
    this.displayDebugInfo();
  } catch (ex) {
    delete SWFUpload.instances[this.movieName];
    throw ex;
  }
};

/* *************** */
/* Static Members  */
/* *************** */
SWFUpload.instances = {};
SWFUpload.movieCount = 0;
SWFUpload.version = "2.2.0 Alpha";
SWFUpload.QUEUE_ERROR = {
  QUEUE_LIMIT_EXCEEDED	  		: -100,
  FILE_EXCEEDS_SIZE_LIMIT  		: -110,
  ZERO_BYTE_FILE			  		: -120,
  INVALID_FILETYPE		  		: -130
};
SWFUpload.UPLOAD_ERROR = {
  HTTP_ERROR				  		: -200,
  MISSING_UPLOAD_URL	      		: -210,
  IO_ERROR				  		: -220,
  SECURITY_ERROR			  		: -230,
  UPLOAD_LIMIT_EXCEEDED	  		: -240,
  UPLOAD_FAILED			  		: -250,
  SPECIFIED_FILE_ID_NOT_FOUND		: -260,
  FILE_VALIDATION_FAILED	  		: -270,
  FILE_CANCELLED			  		: -280,
  UPLOAD_STOPPED					: -290
};
SWFUpload.FILE_STATUS = {
  QUEUED		 : -1,
  IN_PROGRESS	 : -2,
  ERROR		 : -3,
  COMPLETE	 : -4,
  CANCELLED	 : -5
};
SWFUpload.BUTTON_ACTION = {
  SELECT_FILE  : -100,
  SELECT_FILES : -110,
  START_UPLOAD : -120
};


/* ******************** */
/* Instance Members  */
/* ******************** */

// Private: initSettings ensures that all the
// settings are set, getting a default value if one was not assigned.
SWFUpload.prototype.initSettings = function () {
  this.ensureDefault = function (settingName, defaultValue) {
    this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
  };

  // Upload backend settings
  this.ensureDefault("upload_url", "");
  this.ensureDefault("file_post_name", "Filedata");
  this.ensureDefault("post_params", {});
  this.ensureDefault("use_query_string", false);
  this.ensureDefault("requeue_on_error", false);

  // File Settings
  this.ensureDefault("file_types", "*.*");
  this.ensureDefault("file_types_description", "All Files");
  this.ensureDefault("file_size_limit", 0);	// Default zero means "unlimited"
  this.ensureDefault("file_upload_limit", 0);
  this.ensureDefault("file_queue_limit", 0);

  // Flash Settings
  this.ensureDefault("flash_url", "swfupload_f9.swf");
  this.ensureDefault("prevent_swf_caching", false);

  // Button Settings
  this.ensureDefault("button_image_url", 0);
  this.ensureDefault("button_width", 1);
  this.ensureDefault("button_height", 1);
  this.ensureDefault("button_text", "");
  this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;");
  this.ensureDefault("button_text_top_padding", 0);
  this.ensureDefault("button_text_left_padding", 0);
  this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES);
  this.ensureDefault("button_disabled", false);
  this.ensureDefault("button_placeholder_id", null);

  // Debug Settings
  this.ensureDefault("debug", false);
  this.settings.debug_enabled = this.settings.debug;	// Here to maintain v2 API

  // Event Handlers
  this.settings.return_upload_start_handler = this.returnUploadStart;
  this.ensureDefault("swfupload_loaded_handler", null);
  this.ensureDefault("file_dialog_start_handler", null);
  this.ensureDefault("file_queued_handler", null);
  this.ensureDefault("file_queue_error_handler", null);
  this.ensureDefault("file_dialog_complete_handler", null);

  this.ensureDefault("upload_start_handler", null);
  this.ensureDefault("upload_progress_handler", null);
  this.ensureDefault("upload_error_handler", null);
  this.ensureDefault("upload_success_handler", null);
  this.ensureDefault("upload_complete_handler", null);

  this.ensureDefault("debug_handler", this.debugMessage);

  this.ensureDefault("custom_settings", {});

  // Other settings
  this.customSettings = this.settings.custom_settings;

  delete this.ensureDefault;
};

SWFUpload.prototype.loadFlash = function () {
  if (this.settings.button_placeholder_id !== "") {
    this.replaceWithFlash();
  } else {
    this.appendFlash();
  }
};

// Private: appendFlash gets the HTML tag for the Flash
// It then appends the flash to the body
SWFUpload.prototype.appendFlash = function () {
  var targetElement, container;

  // Make sure an element with the ID we are going to use doesn't already exist
  if (document.getElementById(this.movieName) !== null) {
    throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
  }

  // Get the body tag where we will be adding the flash movie
  targetElement = document.getElementsByTagName("body")[0];

  if (targetElement == undefined) {
    throw "Could not find the 'body' element.";
  }

  // Append the container and load the flash
  container = document.createElement("div");
  container.style.width = "1px";
  container.style.height = "1px";
  container.style.overflow = "hidden";

  targetElement.appendChild(container);
  container.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
};

// Private: replaceWithFlash replaces the button_placeholder element with the flash movie.
SWFUpload.prototype.replaceWithFlash = function () {
  var targetElement, tempParent;

  // Make sure an element with the ID we are going to use doesn't already exist
  if (document.getElementById(this.movieName) !== null) {
    throw "ID " + this.movieName + " is already in use. The Flash Object could not be added";
  }

  // Get the element where we will be placing the flash movie
  targetElement = document.getElementById(this.settings.button_placeholder_id);

  if (targetElement == undefined) {
    throw "Could not find the placeholder element.";
  }

  // Append the container and load the flash
  tempParent = document.createElement("div");
  tempParent.innerHTML = this.getFlashHTML();	// Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
  targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
  //targetElement.innerHTML = this.getFlashHTML();

  // Fix IE Flash/Form bug
  if (window[this.movieName] == undefined) {
    window[this.movieName] = this.getMovieElement();
  }

};

// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
SWFUpload.prototype.getFlashHTML = function () {
  var flash_url = this.settings.flash_url + (this.settings.prevent_swf_caching ? ("&swfuploadrnd=" + Math.random() * 999999999) : "");

  // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
  return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
        '<param name="movie" value="', this.settings.flash_url, '" />',
        '<param name="quality" value="high" />',
        '<param name="menu" value="false" />',
        '<param name="allowScriptAccess" value="always" />',
        '<param name="flashvars" value="' + this.getFlashVars() + '" />',
        '</object>'].join("");
};

// Private: getFlashVars builds the parameter string that will be passed
// to flash in the flashvars param.
SWFUpload.prototype.getFlashVars = function () {
  // Build a string from the post param object
  var paramString = this.buildParamString();

  // Build the parameter string
  return ["movieName=", encodeURIComponent(this.movieName),
      "&amp;uploadURL=", encodeURIComponent(this.settings.upload_url),
      "&amp;useQueryString=", encodeURIComponent(this.settings.use_query_string),
      "&amp;requeueOnError=", encodeURIComponent(this.settings.requeue_on_error),
      "&amp;params=", encodeURIComponent(paramString),
      "&amp;filePostName=", encodeURIComponent(this.settings.file_post_name),
      "&amp;fileTypes=", encodeURIComponent(this.settings.file_types),
      "&amp;fileTypesDescription=", encodeURIComponent(this.settings.file_types_description),
      "&amp;fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit),
      "&amp;fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit),
      "&amp;fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit),
      "&amp;debugEnabled=", encodeURIComponent(this.settings.debug_enabled),
      "&amp;buttonImageURL=", encodeURIComponent(this.settings.button_image_url),
      "&amp;buttonWidth=", encodeURIComponent(this.settings.button_width),
      "&amp;buttonHeight=", encodeURIComponent(this.settings.button_height),
      "&amp;buttonText=", encodeURIComponent(this.settings.button_text),
      "&amp;buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding),
      "&amp;buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding),
      "&amp;buttonTextStyle=", encodeURIComponent(this.settings.button_text_style),
      "&amp;buttonAction=", encodeURIComponent(this.settings.button_action),
      "&amp;buttonDisabled=", encodeURIComponent(this.settings.button_disabled)
    ].join("");
};

// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
// The element is cached after the first lookup
SWFUpload.prototype.getMovieElement = function () {
  if (this.movieElement == undefined) {
    this.movieElement = document.getElementById(this.movieName);
  }

  if (this.movieElement === null) {
    throw "Could not find Flash element";
  }

  return this.movieElement;
};

// Private: buildParamString takes the name/value pairs in the post_params setting object
// and joins them up in to a string formatted "name=value&amp;name=value"
SWFUpload.prototype.buildParamString = function () {
  var postParams = this.settings.post_params;
  var paramStringPairs = [];

  if (typeof(postParams) === "object") {
    for (var name in postParams) {
      if (postParams.hasOwnProperty(name)) {
        paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString()));
      }
    }
  }

  return paramStringPairs.join("&amp;");
};

// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
// all references to the SWF, and other objects so memory is properly freed.
// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
SWFUpload.prototype.destroy = function () {
  try {
    // Make sure Flash is done before we try to remove it
    this.stopUpload();

    // Remove the SWFUpload DOM nodes
    var movieElement = null;
    try {
      movieElement = this.getMovieElement();
    } catch (ex) {
    }

    if (movieElement != undefined && movieElement.parentNode != undefined && typeof(movieElement.parentNode.removeChild) === "function") {
      var container = movieElement.parentNode;
      if (container != undefined) {
        container.removeChild(movieElement);
        if (container.parentNode != undefined && typeof(container.parentNode.removeChild) === "function") {
          container.parentNode.removeChild(container);
        }
      }
    }

    // Destroy references
    SWFUpload.instances[this.movieName] = null;
    delete SWFUpload.instances[this.movieName];

    delete this.movieElement;
    delete this.settings;
    delete this.customSettings;
    delete this.eventQueue;
    delete this.movieName;

    delete window[this.movieName];

    return true;
  } catch (ex1) {
    return false;
  }
};

// Public: displayDebugInfo prints out settings and configuration
// information about this SWFUpload instance.
// This function (and any references to it) can be deleted when placing
// SWFUpload in production.
SWFUpload.prototype.displayDebugInfo = function () {
  this.debug(
    [
      "---SWFUpload Instance Info---\n",
      "Version: ", SWFUpload.version, "\n",
      "Movie Name: ", this.movieName, "\n",
      "Settings:\n",
      "\t", "upload_url:             ", this.settings.upload_url, "\n",
      "\t", "flash_url:                ", this.settings.flash_url, "\n",
      "\t", "use_query_string:       ", this.settings.use_query_string.toString(), "\n",
      "\t", "file_post_name:         ", this.settings.file_post_name, "\n",
      "\t", "post_params:            ", this.settings.post_params.toString(), "\n",
      "\t", "file_types:             ", this.settings.file_types, "\n",
      "\t", "file_types_description: ", this.settings.file_types_description, "\n",
      "\t", "file_size_limit:        ", this.settings.file_size_limit, "\n",
      "\t", "file_upload_limit:      ", this.settings.file_upload_limit, "\n",
      "\t", "file_queue_limit:       ", this.settings.file_queue_limit, "\n",
      "\t", "debug:                  ", this.settings.debug.toString(), "\n",

      "\t", "prevent_swf_caching:      ", this.settings.prevent_swf_caching.toString(), "\n",

      "\t", "button_placeholder_id:    ", this.settings.button_placeholder_id.toString(), "\n",
      "\t", "button_image_url:         ", this.settings.button_image_url.toString(), "\n",
      "\t", "button_width:             ", this.settings.button_width.toString(), "\n",
      "\t", "button_height:            ", this.settings.button_height.toString(), "\n",
      "\t", "button_text:              ", this.settings.button_text.toString(), "\n",
      "\t", "button_text_style:        ", this.settings.button_text_style.toString(), "\n",
      "\t", "button_text_top_padding:  ", this.settings.button_text_top_padding.toString(), "\n",
      "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n",
      "\t", "button_action:            ", this.settings.button_action.toString(), "\n",
      "\t", "button_disabled:          ", this.settings.button_disabled.toString(), "\n",

      "\t", "custom_settings:        ", this.settings.custom_settings.toString(), "\n",
      "Event Handlers:\n",
      "\t", "swfupload_loaded_handler assigned:  ", (typeof(this.settings.swfupload_loaded_handler) === "function").toString(), "\n",
      "\t", "file_dialog_start_handler assigned: ", (typeof(this.settings.file_dialog_start_handler) === "function").toString(), "\n",
      "\t", "file_queued_handler assigned:       ", (typeof(this.settings.file_queued_handler) === "function").toString(), "\n",
      "\t", "file_queue_error_handler assigned:  ", (typeof(this.settings.file_queue_error_handler) === "function").toString(), "\n",
      "\t", "upload_start_handler assigned:      ", (typeof(this.settings.upload_start_handler) === "function").toString(), "\n",
      "\t", "upload_progress_handler assigned:   ", (typeof(this.settings.upload_progress_handler) === "function").toString(), "\n",
      "\t", "upload_error_handler assigned:      ", (typeof(this.settings.upload_error_handler) === "function").toString(), "\n",
      "\t", "upload_success_handler assigned:    ", (typeof(this.settings.upload_success_handler) === "function").toString(), "\n",
      "\t", "upload_complete_handler assigned:   ", (typeof(this.settings.upload_complete_handler) === "function").toString(), "\n",
      "\t", "debug_handler assigned:             ", (typeof(this.settings.debug_handler) === "function").toString(), "\n"
    ].join("")
  );
};

/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
  the maintain v2 API compatibility
*/
// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
SWFUpload.prototype.addSetting = function (name, value, default_value) {
    if (value == undefined) {
        return (this.settings[name] = default_value);
    } else {
        return (this.settings[name] = value);
  }
};

// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
SWFUpload.prototype.getSetting = function (name) {
    if (this.settings[name] != undefined) {
        return this.settings[name];
  }

    return "";
};



// Private: callFlash handles function calls made to the Flash element.
// Calls are made with a setTimeout for some functions to work around
// bugs in the ExternalInterface library.
SWFUpload.prototype.callFlash = function (functionName, argumentArray) {
  argumentArray = argumentArray || [];

  var self = this;
  var callFunction = function () {
    var movieElement = self.getMovieElement();
    var returnValue;
    if (typeof(movieElement[functionName]) === "function") {
      // We have to go through all this if/else stuff because the Flash functions don't have apply() and only accept the exact number of arguments.
      if (argumentArray.length === 0) {
        returnValue = movieElement[functionName]();
      } else if (argumentArray.length === 1) {
        returnValue = movieElement[functionName](argumentArray[0]);
      } else if (argumentArray.length === 2) {
        returnValue = movieElement[functionName](argumentArray[0], argumentArray[1]);
      } else if (argumentArray.length === 3) {
        returnValue = movieElement[functionName](argumentArray[0], argumentArray[1], argumentArray[2]);
      } else {
        throw "Too many arguments";
      }

      // Unescape file post param values
      if (returnValue != undefined && typeof(returnValue.post) === "object") {
        returnValue = self.unescapeFilePostParams(returnValue);
      }

      return returnValue;
    } else {
      throw "Invalid function name: " + functionName;
    }
  };

  return callFunction();
};


/* *****************************
  -- Flash control methods --
  Your UI should use these
  to operate SWFUpload
   ***************************** */

// Public: selectFile causes a File Selection Dialog window to appear.  This
// dialog only allows 1 file to be selected. WARNING: this function does not work in Flash Player 10
SWFUpload.prototype.selectFile = function () {
  this.callFlash("SelectFile");
};

// Public: selectFiles causes a File Selection Dialog window to appear/ This
// dialog allows the user to select any number of files
// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
// If the selection name length is too long the dialog will fail in an unpredictable manner.  There is no work-around
// for this bug.  WARNING: this function does not work in Flash Player 10
SWFUpload.prototype.selectFiles = function () {
  this.callFlash("SelectFiles");
};


// Public: startUpload starts uploading the first file in the queue unless
// the optional parameter 'fileID' specifies the ID
SWFUpload.prototype.startUpload = function (fileID) {
  this.callFlash("StartUpload", [fileID]);
};

/* Cancels a the file upload.  You must specify a file_id */
// Public: cancelUpload cancels any queued file.  The fileID parameter
// must be specified.
SWFUpload.prototype.cancelUpload = function (fileID) {
  this.callFlash("CancelUpload", [fileID]);
};

// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
// If nothing is currently uploading then nothing happens.
SWFUpload.prototype.stopUpload = function () {
  this.callFlash("StopUpload");
};

/* ************************
 * Settings methods
 *   These methods change the SWFUpload settings.
 *   SWFUpload settings should not be changed directly on the settings object
 *   since many of the settings need to be passed to Flash in order to take
 *   effect.
 * *********************** */

// Public: getStats gets the file statistics object.
SWFUpload.prototype.getStats = function () {
  return this.callFlash("GetStats");
};

// Public: setStats changes the SWFUpload statistics.  You shouldn't need to
// change the statistics but you can.  Changing the statistics does not
// affect SWFUpload accept for the successful_uploads count which is used
// by the upload_limit setting to determine how many files the user may upload.
SWFUpload.prototype.setStats = function (statsObject) {
  this.callFlash("SetStats", [statsObject]);
};

// Public: getFile retrieves a File object by ID or Index.  If the file is
// not found then 'null' is returned.
SWFUpload.prototype.getFile = function (fileID) {
  if (typeof(fileID) === "number") {
    return this.callFlash("GetFileByIndex", [fileID]);
  } else {
    return this.callFlash("GetFile", [fileID]);
  }
};

// Public: addFileParam sets a name/value pair that will be posted with the
// file specified by the Files ID.  If the name already exists then the
// exiting value will be overwritten.
SWFUpload.prototype.addFileParam = function (fileID, name, value) {
  return this.callFlash("AddFileParam", [fileID, name, value]);
};

// Public: removeFileParam removes a previously set (by addFileParam) name/value
// pair from the specified file.
SWFUpload.prototype.removeFileParam = function (fileID, name) {
  this.callFlash("RemoveFileParam", [fileID, name]);
};

// Public: setUploadUrl changes the upload_url setting.
SWFUpload.prototype.setUploadURL = function (url) {
  this.settings.upload_url = url.toString();
  this.callFlash("SetUploadURL", [url]);
};

// Public: setPostParams changes the post_params setting
SWFUpload.prototype.setPostParams = function (paramsObject) {
  this.settings.post_params = paramsObject;
  this.callFlash("SetPostParams", [paramsObject]);
};

// Public: addPostParam adds post name/value pair.  Each name can have only one value.
SWFUpload.prototype.addPostParam = function (name, value) {
  this.settings.post_params[name] = value;
  this.callFlash("SetPostParams", [this.settings.post_params]);
};

// Public: removePostParam deletes post name/value pair.
SWFUpload.prototype.removePostParam = function (name) {
  delete this.settings.post_params[name];
  this.callFlash("SetPostParams", [this.settings.post_params]);
};

// Public: setFileTypes changes the file_types setting and the file_types_description setting
SWFUpload.prototype.setFileTypes = function (types, description) {
  this.settings.file_types = types;
  this.settings.file_types_description = description;
  this.callFlash("SetFileTypes", [types, description]);
};

// Public: setFileSizeLimit changes the file_size_limit setting
SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) {
  this.settings.file_size_limit = fileSizeLimit;
  this.callFlash("SetFileSizeLimit", [fileSizeLimit]);
};

// Public: setFileUploadLimit changes the file_upload_limit setting
SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) {
  this.settings.file_upload_limit = fileUploadLimit;
  this.callFlash("SetFileUploadLimit", [fileUploadLimit]);
};

// Public: setFileQueueLimit changes the file_queue_limit setting
SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) {
  this.settings.file_queue_limit = fileQueueLimit;
  this.callFlash("SetFileQueueLimit", [fileQueueLimit]);
};

// Public: setFilePostName changes the file_post_name setting
SWFUpload.prototype.setFilePostName = function (filePostName) {
  this.settings.file_post_name = filePostName;
  this.callFlash("SetFilePostName", [filePostName]);
};

// Public: setUseQueryString changes the use_query_string setting
SWFUpload.prototype.setUseQueryString = function (useQueryString) {
  this.settings.use_query_string = useQueryString;
  this.callFlash("SetUseQueryString", [useQueryString]);
};

// Public: setRequeueOnError changes the requeue_on_error setting
SWFUpload.prototype.setRequeueOnError = function (requeueOnError) {
  this.settings.requeue_on_error = requeueOnError;
  this.callFlash("SetRequeueOnError", [requeueOnError]);
};

// Public: setDebugEnabled changes the debug_enabled setting
SWFUpload.prototype.setDebugEnabled = function (debugEnabled) {
  this.settings.debug_enabled = debugEnabled;
  this.callFlash("SetDebugEnabled", [debugEnabled]);
};

// Public: setButtonImageURL loads a button image sprite
SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) {
  this.settings.button_image_url = buttonImageURL;
  this.callFlash("SetButtonImageURL", [buttonImageURL]);
};

// Public: setButtonDimensions resizes the Flash Movie and button
SWFUpload.prototype.setButtonDimensions = function (width, height) {
  this.settings.button_width = width;
  this.settings.button_height = height;

  var movie = this.getMovieElement();
  if (movie != undefined) {
    movie.style.width = width + "px";
    movie.style.height = (Math.floor(height / 4)) + "px";
  }

  this.callFlash("SetButtonDimensions", [width, height]);
};
// Public: setButtonText Changes the text overlaid on the button
SWFUpload.prototype.setButtonText = function (html) {
  this.settings.button_text = html;
  this.callFlash("SetButtonText", [html]);
};
// Public: setButtonTextPadding changes the top and left padding of the text overlay
SWFUpload.prototype.setButtonTextPadding = function (left, top) {
  this.settings.button_text_top_padding = top;
  this.settings.button_text_left_padding = left;
  this.callFlash("SetButtonTextPadding", [left, top]);
};

// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
SWFUpload.prototype.setButtonTextStyle = function (css) {
  this.settings.button_text_style = css;
  this.callFlash("SetButtonTextStyle", [css]);
};
// Public: setButtonDisabled disables/enables the button
SWFUpload.prototype.setButtonDisabled = function (isDisabled) {
  this.settings.button_disabled = isDisabled;
  this.callFlash("SetButtonDisabled", [isDisabled]);
};
// Public: setButtonAction sets the action that occurs when the button is clicked
SWFUpload.prototype.setButtonAction = function (buttonAction) {
  this.settings.button_action = buttonAction;
  this.callFlash("SetButtonAction", [buttonAction]);
};

/* *******************************
  Flash Event Interfaces
  These functions are used by Flash to trigger the various
  events.

  All these functions a Private.

  Because the ExternalInterface library is buggy the event calls
  are added to a queue and the queue then executed by a setTimeout.
  This ensures that events are executed in a determinate order and that
  the ExternalInterface bugs are avoided.
******************************* */

SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) {
  // Warning: Don't call this.debug inside here or you'll create an infinite loop

  if (argumentArray == undefined) {
    argumentArray = [];
  } else if (!(argumentArray instanceof Array)) {
    argumentArray = [argumentArray];
  }

  var self = this;
  if (typeof(this.settings[handlerName]) === "function") {
    // Queue the event
    this.eventQueue.push(function () {
      this.settings[handlerName].apply(this, argumentArray);
    });

    // Execute the next queued event
    setTimeout(function () {
      self.executeNextEvent();
    }, 0);

  } else if (this.settings[handlerName] !== null) {
    throw "Event handler " + handlerName + " is unknown or is not a function";
  }
};

// Private: Causes the next event in the queue to be executed.  Since events are queued using a setTimeout
// we must queue them in order to garentee that they are executed in order.
SWFUpload.prototype.executeNextEvent = function () {
  // Warning: Don't call this.debug inside here or you'll create an infinite loop

  var  f = this.eventQueue ? this.eventQueue.shift() : null;
  if (typeof(f) === "function") {
    f.apply(this);
  }
};

// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
// properties that contain characters that are not valid for JavaScript identifiers. To work around this
// the Flash Component escapes the parameter names and we must unescape again before passing them along.
SWFUpload.prototype.unescapeFilePostParams = function (file) {
  var reg = /[$]([0-9a-f]{4})/i;
  var unescapedPost = {};
  var uk;

  if (file != undefined) {
    for (var k in file.post) {
      if (file.post.hasOwnProperty(k)) {
        uk = k;
        var match;
        while ((match = reg.exec(uk)) !== null) {
          uk = uk.replace(match[0], String.fromCharCode(parseInt("0x"+match[1], 16)));
        }
        unescapedPost[uk] = file.post[k];
      }
    }

    file.post = unescapedPost;
  }

  return file;
};

SWFUpload.prototype.flashReady = function () {
  // Check that the movie element is loaded correctly with its ExternalInterface methods defined
  var movieElement = this.getMovieElement();
  if (typeof(movieElement.StartUpload) !== "function") {
    throw "ExternalInterface methods failed to initialize.";
  }

  this.queueEvent("swfupload_loaded_handler");
};


/* This is a chance to do something before the browse window opens */
SWFUpload.prototype.fileDialogStart = function () {
  this.queueEvent("file_dialog_start_handler");
};


/* Called when a file is successfully added to the queue. */
SWFUpload.prototype.fileQueued = function (file) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("file_queued_handler", file);
};


/* Handle errors that occur when an attempt to queue a file fails. */
SWFUpload.prototype.fileQueueError = function (file, errorCode, message) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("file_queue_error_handler", [file, errorCode, message]);
};

/* Called after the file dialog has closed and the selected files have been queued.
  You could call startUpload here if you want the queued files to begin uploading immediately. */
SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued) {
  this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued]);
};

SWFUpload.prototype.uploadStart = function (file) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("return_upload_start_handler", file);
};

SWFUpload.prototype.returnUploadStart = function (file) {
  var returnValue;
  if (typeof(this.settings.upload_start_handler) === "function") {
    file = this.unescapeFilePostParams(file);
    returnValue = this.settings.upload_start_handler.call(this, file);
  } else if (this.settings.upload_start_handler != undefined) {
    throw "upload_start_handler must be a function";
  }

  // Convert undefined to true so if nothing is returned from the upload_start_handler it is
  // interpretted as 'true'.
  if (returnValue === undefined) {
    returnValue = true;
  }

  returnValue = !!returnValue;

  this.callFlash("ReturnUploadStart", [returnValue]);
};



SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]);
};

SWFUpload.prototype.uploadError = function (file, errorCode, message) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("upload_error_handler", [file, errorCode, message]);
};

SWFUpload.prototype.uploadSuccess = function (file, serverData) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("upload_success_handler", [file, serverData]);
};

SWFUpload.prototype.uploadComplete = function (file) {
  file = this.unescapeFilePostParams(file);
  this.queueEvent("upload_complete_handler", file);
};

/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
   internal debug console.  You can override this event and have messages written where you want. */
SWFUpload.prototype.debug = function (message) {
  this.queueEvent("debug_handler", message);
};



/* **********************************
  Debug Console
  The debug console is a self contained, in page location
  for debug message to be sent.  The Debug Console adds
  itself to the body if necessary.

  The console is automatically scrolled as messages appear.

  If you are using your own debug handler or when you deploy to production and
  have debug disabled you can remove these functions to reduce the file size
  and complexity.
********************************** */

// Private: debugMessage is the default debug_handler.  If you want to print debug messages
// call the debug() function.  When overriding the function your own function should
// check to see if the debug setting is true before outputting debug information.
SWFUpload.prototype.debugMessage = function (message) {
  if (this.settings.debug) {
    var exceptionMessage, exceptionValues = [];

    // Check for an exception object and print it nicely
    if (typeof(message) === "object" && typeof(message.name) === "string" && typeof(message.message) === "string") {
      for (var key in message) {
        if (message.hasOwnProperty(key)) {
          exceptionValues.push(key + ": " + message[key]);
        }
      }
      exceptionMessage = exceptionValues.join("\n") || "";
      exceptionValues = exceptionMessage.split("\n");
      exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: ");
      SWFUpload.Console.writeLine(exceptionMessage);
    } else {
      SWFUpload.Console.writeLine(message);
    }
  }
};

SWFUpload.Console = {};
SWFUpload.Console.writeLine = function (message) {
  var console, documentForm;

  try {
    console = document.getElementById("SWFUpload_Console");

    if (!console) {
      documentForm = document.createElement("form");
      document.getElementsByTagName("body")[0].appendChild(documentForm);

      console = document.createElement("textarea");
      console.id = "SWFUpload_Console";
      console.style.fontFamily = "monospace";
      console.setAttribute("wrap", "off");
      console.wrap = "off";
      console.style.overflow = "auto";
      console.style.width = "700px";
      console.style.height = "350px";
      console.style.margin = "5px";
      documentForm.appendChild(console);
    }

    console.value += message + "\n";

    console.scrollTop = console.scrollHeight - console.clientHeight;
  } catch (ex) {
    alert("Exception: " + ex.name + " Message: " + ex.message);
  }
};
;var Wildfire = {};
Wildfire.LinkedLoading = true;
Wildfire._pixeIframeCreated = false;

Wildfire.Flash={

isIE  : (navigator.appVersion.indexOf("MSIE") != -1) ? true : false,
isWin : (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false,
isOpera : (navigator.userAgent.indexOf("Opera") != -1) ? true : false,

AC_Generateobj:function(objAttrs, params, embedAttrs) { 
	var str = '';
	if (this.isIE && this.isWin && !this.isOpera)	{
		str += '<object ';
		for (var i in objAttrs) {str += i + '="' + objAttrs[i] + '" ';}
		str += '>';
		for (var i in params) {str += '<param name="' + i + '" value="' + params[i] + '" /> ';}
		str += '</object>';
	}
	else {
		str += '<embed ';
		for (var i in embedAttrs) {str += i + '="' + embedAttrs[i] + '" ';}
		str += '> </embed>';
	}
	return str;
},

AC_FL_GetContent:function(){
	var ret = this.AC_GetArgs(arguments);
	return this.AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
},

AC_GetArgs:function(args, classid, mimeType){
	var ret = {};
	ret.embedAttrs = {};
	ret.params = {};
	ret.objAttrs = {};
	for (var i=0; i < args.length; i=i+2){
		var currArg = args[i].toLowerCase();    
		switch (currArg){	
			case "movie":	
				ret.embedAttrs["src"] = args[i+1];
				ret.params["movie"] = args[i+1];
			break;
			case "id":  
			case "width":
			case "height":
			case "align":
			case "name":
				ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
			break;
			default:
				ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
		}
  }
  ret.objAttrs['codebase']='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0';
  ret.objAttrs["classid"] = "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000";
  ret.embedAttrs["type"] ="application/x-shockwave-flash";
  ret.embedAttrs['pluginspage']='http://www.macromedia.com/go/getflashplayer';
  
  return ret;
}

} // Wildfire.Flash

// Event handlers
Wildfire.onClose = Wildfire.onPostProfile = Wildfire.onPostComment = Wildfire.onSend = function(){};

Wildfire.modules = {};
Wildfire.modulesArray = [];


/*** PUBLIC METHODS ***/
	
Wildfire.initShare = function(partner, targetId, width, height, config)	{   
	return Wildfire._createJSModule("share",partner,targetId,width,height,config,
						'cssURL,cornerRoundness,initialMessageType,domainForCallback,partner,source,partnerData,width,height,emailTabHidden,customCheckboxVisible,customCheckboxChecked,customCheckboxText,' +
						'internalColor,frameColor,externalColor,tabTextColor,textColor,fontType,fontSize,' +
						'headerInternalColor,headerFrameColor'
						);
}

Wildfire.initPost = function(partner, targetId, width, height, config) {	
	return Wildfire._createFlashModule("post",partner,targetId,width,height,config);
}

//DEPRECATED, replaced by initShare */
Wildfire.init = Wildfire.initShare;

//DEPRECATED, replaced by module.applyConfig*/
Wildfire.applyConfig= function(config) {
	if (isnotnull(Wildfire.share)) Wildfire.share.applyConfig(config);
}

/*** Flash Interface ***/
//this is Called from the SWF
Wildfire._GetFlashModuleXMLConfig=function (targetId){
	//hide the js progress indicator -- this is a mac issue fix.;
	var pdiv = document.getElementById(targetId+"_progress");
	if (pdiv!=null) {
		pdiv.innerHTML='&nbsp;';
		pdiv.style.display = "none";
		pdiv.style.visibility = "hidden";
	}
	
	xs= ['config',[], [
			'display',['width','height','showCodeBox','rememberMeVisible','networksToShow','bulletinChecked','showEmail','showPost','showBookmark'],
			'body',['font=fontType','size=fontSize'],[
				'background',['frame-color=frameColor','background-color=internalColor','corner-roundness=cornerRoundness'],
				'controls',[], [
					'textboxes',[],	[
						'inputs',['color=textInputColor','background-color=textInputBackgroundColor','frame-color=textInputBorderColor']
						],
					'snbuttons',['color=tabTextColor|snButtonsTextColor','background-color=snButtonsBackgroundColor','frame-color=snButtonsFrameColor','over-color=tabTextColor|snButtonsOverTextColor','over-background-color=snButtonsOverBackgroundColor','over-frame-color=snButtonsOverFrameColor'],
					'buttons',['font=fontType|buttonFontType','color=buttonTextColor']
					],
				'texts background-color="transparent" ',['color=textColor'],[
					'messages',['color=messageTextColor'],
					'links',['font=linkFontType','color=linkTextColor'],
					'privacy',['color=privacyTextColor']
					]
				]
			]
		];

	var oConfig=Wildfire._GetFlashModuleConfig(targetId);
	var s=Wildfire._BuildXMLConfigFromJSON(oConfig,xs);
	
	return s;

}

Wildfire._GetFlashModuleConfigAttribute=function (targetId,configAttribute,canBeTextareaID){
	//hide the js progress indicator -- this is a mac issue fix.;
	var pdiv = document.getElementById(targetId+"_progress");
	if (pdiv!=null) {
		pdiv.innerHTML='&nbsp;';
		pdiv.style.display = "none";
		pdiv.style.visibility = "hidden";
	}

	var module=Wildfire.modules[targetId];
	if (module!=null) {
		var AttribValue=module.config[configAttribute];
		if (typeof AttribValue=='undefined') return null;
		if (canBeTextareaID==true) {
			if ( isnotnull(AttribValue) ) {
				try {
					var element=document.getElementById(AttribValue);
					
					if ( isnotnull(element) ) {
						return element.value;
					}
					else {
						return AttribValue;
					}
					
				} catch (e) {
					//GIGYAONLY:alert('Unable to get template for module:' + targetId + ', configAttribute :'+ configAttribute + '\n' + ex.description);
					return AttribValue;	
				}
			}
		}
		else {
			return AttribValue;
		}
	}
	else {
		return {error:'Modlue not found',MID:targetId};
	}
}

Wildfire._GetFlashModuleConfig=function (targetId){
	if (Wildfire.modules == null) {
		alert('Wildfire has no modules yet');
	}
	var module=Wildfire.modules[targetId];
	if (module!=null) {
	
		var res=module.config;
		return res;
	}
	else {
		return null;
	}
}
	

/*** PRIVATE METHODS ***/

Wildfire._BuildXMLConfigFromJSON=function (oConfig,xs) {

	var s=[];
	try{
	for(var i=0;i<xs.length;i+=2){

		s[s.length]='<'+xs[i]+' ';
		var atts=xs[i+1];

		for (var ia=0;ia<atts.length;ia++) {
		
			var attrAndKeys=atts[ia].split('=');
			var key=attrAndKeys[0];
			var valkeys;
			if (attrAndKeys.length>1) {
				valkeys=attrAndKeys[1]
			}
			else {
				valkeys=attrAndKeys[0];
			}
			
			var arrKeys=valkeys.split('|')
			for (var ikey=0;ikey<arrKeys.length;ikey++) {
				if (typeof oConfig[arrKeys[ikey]] != 'undefined') {
					s[s.length]=key+'="';
					s[s.length]=(''+oConfig[arrKeys[ikey]]).replace('&','&amp;').replace('"','&quot;').replace('<','&lt;').replace('>','&gt;') ;
					s[s.length]='" ';
					break;
				}
			}
		}
		if (i+2==xs.length) { // there are no more nodes
			s[s.length]='/>';						
		}
		else {
			if (typeof xs[i+2]!='string') {
			  s[s.length]='>';
			  s[s.length]=Wildfire._BuildXMLConfigFromJSON(oConfig,xs[i+2]);
			  s[s.length]='</'+xs[i].split(' ')[0]+'>';
			  i++; // skip the array node.
			}
			else {
				s[s.length]='/>';
			}
		}
		
	}
	}
	catch(e){
//			return ('***');
	}
	return s.join('');
}

Wildfire._createJSModule = function (moduleType, partner, targetId, width, height, config, getParams)	
{	
	try {
		config.location = document.location.href;
	} catch(err) {}
	
	config.partner = partner;
	config.width = width;
	config.height = height;

	// validate input params
	if ( undef(moduleType) || undef(partner) || undef(targetId) || undef(width) || undef(height)|| undef(config)) return;

	var module = this[targetId] = this.modules[targetId] = this.modulesArray[this.modulesArray.length] = new Wildfire._JSModule();
	module.copyConfig(config);
	module.ready = false;
	module.type = moduleType;
	module.id = targetId;
	module.partner = partner;
	module.width = width;
	module.height = height;
	module.container = document.getElementById(targetId);		  
	module.container.style.width  = width + "px";
	module.container.style.height = height + "px";

	module.qsParams = [];
	var getParamArray = getParams.split(',');
	for (var i=0; i<getParamArray.length ; i++)
		Wildfire._addQSParam(module,getParamArray[i]);
	
	module.init(true); // true means check ping for safe mode
	return module;
};

Wildfire._origOnLoad = null;
Wildfire._onLoad = function(evt)
{
	if (Wildfire._origOnLoad!=null && Wildfire._origOnLoad!=Wildfire._onLoad)
		Wildfire._origOnLoad(evt);
	
	if (evt.ModuleID == Wildfire.modulesArray[0].id)
	{
		for (var i=1;i<Wildfire.modulesArray.length; i++)
		{
			if (!Wildfire.modulesArray[i].ready) 
			{
				try {Wildfire.modulesArray[i].init(true);} catch(e) {}
			}
				
		}
	}
};

Wildfire._createFlashModule = function (moduleType, partner, targetId, width, height, config/*, getParams*/)	
{	
	// set bookmarkURL if not set
	
	try {
		if (typeof config['bookmarkURL'] == 'undefined')
			config['bookmarkURL'] = document.location.href;
	} catch (e) {}


	// hook onLoad 
	if (Wildfire.LinkedLoading) 
	{
		if (Wildfire._origOnLoad==null && typeof Wildfire.onLoad != 'undefined') 
			Wildfire._origOnLoad = Wildfire.onLoad;
	
		Wildfire.onLoad = Wildfire._onLoad;
		// safety valve - if first module never loads, load everything
	}

	var blnRecreate=false;
	var idxInArray;
	if (this.modules[targetId] != null) {
		blnRecreate=true;
		document.getElementById(targetId).innerHTML='&nbsp;';
		idxInArray=this.modules[targetId].idxInArray;
	}
	else {
		idxInArray=this.modulesArray.length;
	}
	try {
		config.location = document.location.href;
	} catch(err) {}
	
	config.partner = partner;
	config.width = width;
	config.height = height;

	// validate input params
	if ( undef(moduleType) || undef(partner) || undef(targetId) || undef(width) || undef(height)|| undef(config)) return;
	
	
	var module = new Wildfire._FlashModule();
	this.modulesArray[idxInArray] = this[targetId] = this.modules[targetId] = module;
	
	module.idxInArray=idxInArray;
	module.copyConfig(config);
	module.queued = false;
	module.ready = false;
	module.type = moduleType;
	module.id = targetId;
	module.partner = partner;
	module.width = width;
	module.height = height;
	module.container = document.getElementById(targetId);		  
	module.container.style.width  = width + "px";
	module.container.style.height = height + "px";
	
	/*
	module.qsParams = [];
	var getParamArray = getParams.split(',');
	for (var i=0; i<getParamArray.length ; i++)
		Wildfire._addQSParam(module,getParamArray[i]);
	*/
	if (!Wildfire.LinkedLoading || this.modulesArray.length==1 || this.modulesArray[0].ready)
	{
		module.init(true); // true means check ping for safe mode
	} else {
		module.queued = true;
	}
	return module;
};


Wildfire._raiseModulesUpdate = function() 
{
	var moduleList = "";
	for(var key in this.modules) moduleList += key + ",";
			
	var eventData = {'type':'modulesUpdate','modules':moduleList};

	this._raiseSysEvent(eventData);
}

Wildfire._raiseSysSignoutEvent = function() {
	this._raiseSysEvent({'type':'signout'});
}

Wildfire._raiseSysEvent = function(eventData) 
{
	if (this.modulesArray.length<=1) return;
	
	for(var key in this.modules) {
		var rse=this.modules[key].raiseSysEvent;
		if (rse!=null) {
			rse(eventData);
		}
	}
}

Wildfire._onFrameLoaded = function(moduleId) 
{
	var ui = document.getElementById(moduleId+"_UIFrame");
	if (ui!=null) ui.style.visibility="visible";	

	var pdiv = document.getElementById(moduleId+"_progress");
	if (pdiv!=null) pdiv.style.display = "none";

	this.modules[moduleId].UIFrame.style.visibility="visible";	
	this.modules[moduleId].applyConfig();
	this.modules[moduleId].ready = true;
	
	setTimeout("Wildfire._raiseModulesUpdate()",1500);
};

Wildfire._addQSParam = function(module,pName) {
	if ( def(typeof module.config) && def(module.config[pName]) ) {
		module.qsParams[module.qsParams.length] = pName+'='+Wildfire._URLEncode(module.config[pName]);
	}
};

Wildfire._URLEncode=function (s){
	if (encodeURIComponent) {
		return encodeURIComponent(s);
	}
	else {
		es=escape(s);
		return es.replace(/\+/g,'%2b').replace(/%20/g,'+').replace(/[/]/g,'%2f').replace(/%3D/g,'%3d');
	}
};

Wildfire._onCallback=Wildfire._raiseEvent = function(WFEvent) {
	try {
		switch(WFEvent.type)
		{
			case 'send':
				if (isnotnull(Wildfire.onSend))
					Wildfire.onSend(WFEvent);
				break;
			case 'postComment':
				if (isnotnull(Wildfire.onPostComment))
					Wildfire.onPostComment(WFEvent);
				break;
			case 'postProfile':
				if (isnotnull(Wildfire.onPostProfile))
					Wildfire.onPostProfile(WFEvent);
				break;
			case 'close':
				if (isnotnull(Wildfire.onClose))
					Wildfire.onClose(WFEvent);
				break;
			case 'load':
				
				if (isnotnull(Wildfire.onLoad))
				{
					Wildfire.modules[WFEvent.ModuleID].ready = true; 
					Wildfire.onLoad(WFEvent);
				}
				break;

		}
	} catch (err) {
		//GIGYAONLY:alert('exception in _onCallback: '+err.description);
	}
};

Wildfire._Module=function() {
	// for common functionality of Flash and JS modules
}


Wildfire._JSModule= function () {
	this.formsContainer = null;
	this.pingTimeout = null;
}
Wildfire._JSModule.prototype=new Wildfire._Module();


Wildfire._FlashModule=function(){}
Wildfire._FlashModule.prototype=new Wildfire._Module();


Wildfire._JSModule.prototype.pingOK = function(ok) {
	window.clearTimeout(this.pingTimeout);
	this.config.safeMode = !ok;
	this.init(false);
}


Wildfire._FlashModule.prototype.init = function(checkPing){
	var html='';
		if ((''+this.config.isApply)!='true') {
			html += '<div style="position:relative;top:50%;text-align:center;font-size:12px;z-index:50;" id="'+this.id+'_progress"><center><img  src="'+this.config.progressImageSrc+'"></center></div>';
		}
		html += Wildfire.Flash.AC_FL_GetContent(
		'id', 'wfmodule_'+this.id,
		'name', 'wfmodule_'+this.id,
		'width', this.config.width,
		'height', this.config.height,
		'movie', 'http://cdn.gigya.com/WildFire/swf/wildfire.swf',
		'quality', 'high',  
		'align', 'middle',
		'play', 'true',
		'loop', 'true',
		'scale', 'showall',
		'wmode', 'transparent', 
		'devicefont', 'false',
		'bgcolor', '#ffffff',
		'menu', 'true',
		'allowFullScreen', 'false',
		'allowScriptAccess','always',
		'salign', '',
		'flashvars','ModuleID='+ this.id+'&now='+(new Date()).getTime(),
		'swLiveConnect','true'
		)
	
	window['wfmodule_'+this.id] = null;
	//alert('html =' + html);
	if (!Wildfire._pixeIframeCreated) {
		html += "<iframe src='http://cdn.gigya.com/wildfire/do_not_delete.htm' style='width:0;height:0;visibility:hidden' />";
		Wildfire._pixeIframeCreated = true;
	}
		
	this._injectWFCode(html);
	//alert('Html Code  Injected');
	// ExternalInterface bug workaround - 
	window['wfmodule_'+this.id] = document.getElementById('wfmodule_'+this.id);
	//alert('window attribute set, invoking go()');
	//because the flash needs to do externalInterface calls as soon as it starts
	//we can not have it "autoExecute" or the line above this comment would not
	//be executed by the time it tries to call back.
	//window['wfmodule_'+this.id].SetVariable('_root.ready','1');
}

Wildfire._IsModuleReady=function(targetId) {
	return (window['wfmodule_'+targetId] != null)
}


Wildfire._JSModule.prototype.init = function(checkPing) 
{
	var wfroot='http://wildfire.gigya.com/wildfire';
	var id=this.id;
	var uifid=id+'_UIFrame';
	var cfg=this.config;
	
	if (!cfg.safeMode && checkPing && this.pingTimeout==null)
	{
		var script = document.createElement("script");
		script.src = wfroot+'/jsping.ashx?mid='+id + "&rand=" + Math.random() + Math.random();
		this.container.appendChild(script);
		this.pingTimeout = window.setTimeout("Wildfire.modules['"+id+"'].pingOK(false)",10000);
		return;
	}
	var qs = this.qsParams.join('&');
	qs += ("&mid="+id);
	
	var html = "";
	var formsHTML = "";
	var UIURL = wfroot+'/'+this.type + "Main.aspx?" + qs;
	if (cfg.safeMode){
		UIURL = this.getSafeModeURL();
		if (UIURL==null) {
			Wildfire[id] = Wildfire.modules[id] = Wildfire.modulesArray[Wildfire.modulesArray.length] = null;
			return null;
		}
		html += "<iframe allowtransparency='true' id="+uifid +" name="+uifid+" style='width:" + cfg.width + "px;height:" + cfg.height + "px;display:inherit;visibility:inherit' frameborder=0 scrolling=no></iframe>";
		formsHTML += "<form id='"+id+"_postForm' action='"+UIURL+"' method='POST' target="+uifid+" style='display:none'></form>";
	}
	else if (cfg.simple) {
		if (this.type=="share") UIURL = wfroot+'/shareSimple.aspx';
		if (UIURL==null) {
			Wildfire[id] = Wildfire.modules[id] = Wildfire.modulesArray[Wildfire.modulesArray.length] = null;
			return null;
		}
		html += "<iframe allowtransparency='true' id="+uifid +" name="+uifid+" style='width:" + cfg.width + "px;height:" + cfg.height + "px;display:inherit;visibility:inherit' frameborder=0 scrolling=no></iframe>";
		formsHTML += "<form id='"+id+"_postForm' action='"+UIURL+"' method='POST' target="+uifid+" style='display:none'></form>";
	} else {
		html += "<div style='position:relative;top:50%;text-align:center;font-size:12px;' id='"+id+"_progress'><center><img  src='"+cfg.progressImageSrc+"'></center></div>";
		html += "<iframe allowtransparency='true' onload='Wildfire._onFrameLoaded(\""+id+"\")' id="+uifid+" style='visibility:hidden;width:" + cfg.width + "px;height:" + cfg.height + "px;' src='"+ UIURL + "' frameborder=0 scrolling=no></iframe>";			
		html += '<iframe id="IFREndlessActivityBugFix" style="display:none;width:100px;height:10px"></iframe>';
		html += this._createCBFrame();

		formsHTML += "<form id='"+id+"_postForm' action='"+wfroot+"/WFHandler.ashx?cmd=config' method='POST' target='"+id+"_postTargetFrame' style='display:none'></form>";			
		formsHTML += "<form id='"+id+"_sysEventForm' action='"+wfroot+"/WFHandler.ashx?cmd=sysEvent' method='POST' target='"+id+"_sysEventFrame' style='display:none'></form>";
	}
	
	this._injectWFCode(html,formsHTML);	
	
	// if cant create callback frame, disable callbacks
	if (document.getElementById(id+"_wfCBFrame")==null)	{
		cfg.domainForCallback = null;
	}
		
	this.UIFrame = document.getElementById(id+"_UIFrame");
	this.postForm = document.getElementById(id+"_postForm");
	this.sysEventForm = document.getElementById(id+"_sysEventForm");
	
	if (cfg.simple || cfg.safeMode) this.applyConfig(); // normal modules get config on frame load
}

Wildfire._JSModule.prototype._createCBFrame = function() 
{
	if ( def(this.config.domainForCallback) && document.getElementById(this.id+'_wfCBDiv')==null ) 
	{
		try {
			document.domain = this.config.domainForCallback;	
			return "<iframe name='"+this.id+"_wfCBFrame' style='visibility:hidden;width:0px;height:0px;' src='http://wildfire."+this.config.domainForCallback+"/wildfire/WFHandler.ashx?domain="+escape(this.config.domainForCallback)+"'></iframe>";
			
		} catch(ex) {
			//GIGYAONLY:alert('Unable to create Iframe for callback: '+ex.description);
			return "";
		}
	} else {
		return "";
	}
}

Wildfire._FlashModule.prototype.copyConfig =  Wildfire._JSModule.prototype.copyConfig = function(config) 
{
	// clone config obj to module
	if (config!=null) {
		this.config = {};
		for(var key in config) this.config[key] = config[key];
	}

	// apply default values
	if ( undef(this.config.progressImageSrc) ) 	this.config.progressImageSrc = "http://cdn.gigya.com/WildFire/i/progress_ani.gif";
	//if ( undef(this.config.cornerRoundness) ) 	this.config.cornerRoundness=1;
	if ( undef(this.config.simple) ) this.config.simple = navigator.userAgent.toLowerCase().indexOf('safari')!=-1;
}

Wildfire._JSModule.prototype.getSafeModeURL = function(){
	if (this.type=="share") return "http://backup.gigya.com/WFSimple/share.aspx";
	return null;
}

// check if page already has 'form' tag, if yes, insert div to contain our forms, outside of it.
Wildfire._JSModule.prototype._injectWFCode= function(html,formsHTML){
	var el=this.container;
	for(;((el!=null) && ((''+el.tagName).toLowerCase() !='form'));el=el.parentNode);
	if (el!=null) { 
		this.container.innerHTML = html;
		this.formsContainer = document.createElement('div');
		this.formsContainer.style.display='none';
		el.parentNode.insertBefore(this.formsContainer,el);
		this.formsContainer.innerHTML = formsHTML;
		
	} else
	{
		this.container.innerHTML = html + formsHTML;
	}
};


Wildfire._FlashModule.prototype._injectWFCode= function(html){
	this.container.innerHTML = html;
};

Wildfire._JSModule.prototype.raiseSysEvent = function(eventData){
	if (this.sysEventForm==null || !this.ready)  return;
	
	var s = []; var i=0;
	for(var key in eventData) {
		if (typeof key != 'function' && eventData[key]!=null) {
			s[i++] = "<input type=hidden name='"+key+"'/>"
		}
	}
	
	this.sysEventForm.innerHTML = s.join('');

	//set value (using foo.value handles escaping of strings better...)
	for (var i=0;i<this.sysEventForm.length; i++) {
		this.sysEventForm[i].value = eventData[this.sysEventForm[i].name];
	}
	this.sysEventForm.submit();
};

Wildfire._FlashModule.prototype.applyConfig = function(conf){
	conf.isApply="true";
	return Wildfire._createFlashModule(this.type, this.partner, this.id, this.width, this.height, conf);
};

Wildfire._JSModule.prototype.applyConfig = function(conf){
	if (conf!=null) this.copyConfig(conf);
	var cfg=this.config;
	if (cfg==null) return;
	if (cfg.location==null || cfg.location=="")	{
		try { cfg.location = document.location.href;} catch(err) {}
	}

	cfg.partner = this.partner;
	cfg.width	= this.width;
	cfg.height	= this.height;

	// check if templates are IDs or actual values
	// For Post
	postContent=['default','myspace','hi5','friendster','xanga','livejournal','freewebs','facebook','bebo','blogger','tagged','typepad','blackplanet'];
	for (var pci=0;pci<postContent.length;pci++){
		this._getTemplate(postContent[pci] + 'Content');
	}
	//For Share
	shareTemplates=['default','comment','email','myspace','hi5','friendster','xanga','freewebs'];
	for (var sti=0;sti<shareTemplates.length;sti++){
		this._getTemplate(shareTemplates[sti]+ 'Template');
	}

	// build config fields
	var s = []; var i=0;
	for(var key in cfg) {
		if (typeof key != 'function' && cfg[key]!=null) {
			s[i++] = "<input type=hidden name='"+key+"'/>"
		}
	}

	this.postForm.innerHTML = s.join('');

	//set value (using formfield.value handles escaping of strings better...)
	for (var i=0;i<this.postForm.length; i++) {
		this.postForm[i].value = this.config[this.postForm[i].name];
	}
	this.postForm.submit();
	
	window.setTimeout('Wildfire._EndlessActivityBugFix();',1000);
};

Wildfire._EndlessActivityBugFix=function(){
	var ifr=document.getElementById('IFREndlessActivityBugFix');
	if (ifr!=null) {
		ifr.src='http://cdn.gigya.com/wildfire/i/n.gif';
	}
};

Wildfire._JSModule.prototype._getTemplate = function (key) {
	if ( isnotnull(this.config[key]) ) {
		try {
			if ( isnotnull(document.getElementById(this.config[key])) )
				this.config[key] = document.getElementById(this.config[key]).value;
		} catch (e) {
			//GIGYAONLY:alert('Unable to get template for key :'+ key + '\n' + ex.description);
		}
	}
};

Wildfire._CopyAtts=function(t,s,atts){ for(k in atts.split(',')){ t[atts[k]]=s[atts[k]]; }}
Wildfire._CopyAllAtts=function(t,s){for(k in s) {t[k]=s[k];}}

function undef(o) { return (typeof(o)=='undefined');}
function def(o) { return (typeof(o)!='undefined');}
function isnotnull(o) { return (def(o) && (o!=null));}

function WFQueue(){
  var queue=[];
  var queueSpace=0;
  this.count=function()
  {
	return queue.length;
  }
  this.enqueue=function(element){
    queue.push(element);
  }
  this.dequeue=function(){
    if (queue.length){
      var element=queue[queueSpace];
      if (++queueSpace*2 >= queue.length){
        for (var i=queueSpace;i<queue.length;i++) queue[i-queueSpace]=queue[i];
        queue.length-=queueSpace;
        queueSpace=0;
      }
      return element;
    }else{
      return undefined;
    }
  }
}
;// Flash Player Version Detection - Rev 1.6
// Detect Client Browser type
// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

function ControlVersion()
{
  var version;
  var axo;
  var e;

  // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

  try {
    // version will be set for 7.X or greater players
    axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
    version = axo.GetVariable("$version");
  } catch (e) {
  }

  if (!version)
  {
    try {
      // version will be set for 6.X players only
      axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");

      // installed player is some revision of 6.0
      // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
      // so we have to be careful.

      // default to the first public version
      version = "WIN 6,0,21,0";

      // throws if AllowScripAccess does not exist (introduced in 6.0r47)
      axo.AllowScriptAccess = "always";

      // safe to call for 6.0r47 or greater
      version = axo.GetVariable("$version");

    } catch (e) {
    }
  }

  if (!version)
  {
    try {
      // version will be set for 4.X or 5.X player
      axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
      version = axo.GetVariable("$version");
    } catch (e) {
    }
  }

  if (!version)
  {
    try {
      // version will be set for 3.X player
      axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
      version = "WIN 3,0,18,0";
    } catch (e) {
    }
  }

  if (!version)
  {
    try {
      // version will be set for 2.X player
      axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
      version = "WIN 2,0,0,11";
    } catch (e) {
      version = -1;
    }
  }

  return version;
}

// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
  // NS/Opera version >= 3 check for Flash plugin in plugin array
  var flashVer = -1;

  if (navigator.plugins != null && navigator.plugins.length > 0) {
    if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
      var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
      var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
      var descArray = flashDescription.split(" ");
      var tempArrayMajor = descArray[2].split(".");
      var versionMajor = tempArrayMajor[0];
      var versionMinor = tempArrayMajor[1];
      var versionRevision = descArray[3];
      if (versionRevision == "") {
        versionRevision = descArray[4];
      }
      if (versionRevision[0] == "d") {
        versionRevision = versionRevision.substring(1);
      } else if (versionRevision[0] == "r") {
        versionRevision = versionRevision.substring(1);
        if (versionRevision.indexOf("d") > 0) {
          versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
        }
      }
      var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
    }
  }
  // MSN/WebTV 2.6 supports Flash 4
  else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
  // WebTV 2.5 supports Flash 3
  else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
  // older WebTV supports Flash 2
  else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
  else if ( isIE && isWin && !isOpera ) {
    flashVer = ControlVersion();
  }
  return flashVer;
}

// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
  versionStr = GetSwfVer();
  if (versionStr == -1 ) {
    return false;
  } else if (versionStr != 0) {
    if(isIE && isWin && !isOpera) {
      // Given "WIN 2,0,0,11"
      tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
      tempString        = tempArray[1];			// "2,0,0,11"
      versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
    } else {
      versionArray      = versionStr.split(".");
    }
    var versionMajor      = versionArray[0];
    var versionMinor      = versionArray[1];
    var versionRevision   = versionArray[2];

    // Turning this off as EditorApplication does better Flash version reporting
    // if (typeof(sproutTrace) === 'function')
    //  sproutTrace("Detected Flash version ", versionMajor + "." + versionMinor + "." + versionRevision);

    // is the major.revision >= requested major.revision AND the minor version >= requested minor
    if (versionMajor > parseFloat(reqMajorVer)) {
      return true;
    } else if (versionMajor == parseFloat(reqMajorVer)) {
      if (versionMinor > parseFloat(reqMinorVer))
        return true;
      else if (versionMinor == parseFloat(reqMinorVer)) {
        if (versionRevision >= parseFloat(reqRevision))
          return true;
      }
    }
    return false;
  }
}

function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?');
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs)
{
    var str = '';
    if (isIE && isWin && !isOpera)
    {
      str += '<object ';
      for (var i in objAttrs)
        str += i + '="' + objAttrs[i] + '" ';
      str += '>';
      for (var i in params)
        str += '<param name="' + i + '" value="' + params[i] + '" /> ';
      str += '</object>';
    } else {
      str += '<embed ';
      for (var i in embedAttrs)
        str += i + '="' + embedAttrs[i] + '" ';
      str += '> </embed>';
    }

    document.write(str);
}

function AC_FL_RunContent(){
  var ret =
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = {};
  ret.embedAttrs = {};
  ret.params = {};
  ret.objAttrs = {};
  var no_add_ext = 0;
  var defeat_cache = 0;
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();

    switch (currArg){
      case "classid":
        break;
      case "no_add_ext":
        no_add_ext = args[i+1];
        break;
      case "defeat_cache":
        defeat_cache = args[i+1];
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":
        if (no_add_ext == 0)
          args[i+1] = AC_AddExtension(args[i+1], ext);
        if (defeat_cache == 1)
          args[i+1] += (args[i+1].indexOf('?') == -1 ? '?' : '&') + '_t=' + new Date().getTime();
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "id":
      case "width":
      case "height":
      case "align":
      case "vspace":
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}

/**
 * Flash Player 9 Fix (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)

if (window.attachEvent) {
  window.attachEvent("onbeforeunload", function(){
    __flash_unloadHandler = function() {};
    __flash_savedUnloadHandler = function() {};
  });
}*/
;$(document).ready(function() {
  if($('#share-panel.gigya').length) {
    var wfUI = '<config>'
      + ' <display showDesktop="false" showEmail="true" useTransitions="true" showBookmark="false" codeBoxHeight="auto" showCodeBox="true" showCloseButton="false" bulletinChecked="false" networksWithCodeBox="" networksToHide="wordpress, hi5, piczo, blackplanet" />'
      + ' <body corner-roundness="8">'
      + '   <background frame-color="Transparent" gradient-color-begin="#353535" gradient-color-end="#606060" corner-roundness="8;8;8;8"/>'
      + '   <controls size="11" bold="true">'
      + '     <snbuttons iconsOnly="false" type="textUnder" frame-color="#202020" background-color="#FFFFFF" over-background-color="#FFFFFF" color="#CACACA" corner-roundness="4;4;4;4" gradient-color-begin="#8A8A8A" gradient-color-end="#000000" font="Tahoma" size="11" bold="false" over-gradient-color-begin="#AAAAAA" over-gradient-color-end="#000000" over-color="#F4F4F4" down-color="#000000">'
      + '       <more frame-color="Transparent"/>'
      + '     </snbuttons>'
      + '     <textboxes frame-color="#000000" color="#AAAAAA" corner-roundness="0;0;0;0" gradient-color-begin="#202020" gradient-color-end="#0B0B0B" font="Arial" bold="false">'
      + '       <codeboxes color="#EAEAEA" frame-color="#8A8A8A" gradient-color-begin="#000000" font="Arial" bold="false"/>'
      + '       <inputs frame-color="#6D0000"/>'
      + '       <dropdowns frame-color="#6D0000" handle-gradient-color-begin="#B60000" handle-gradient-color-end="#6D0000" handle-over-gradient-color-begin="#FF0000" handle-over-gradient-color-end="#DA0000" handle-down-gradient-color-begin="#FF0000" handle-down-gradient-color-end="#6D0000" background-color="#6D0000" gradient-color-begin="#000000" font="Arial" bold="false"/>'
      + '     </textboxes>'
      + '     <buttons frame-color="#FF0000" gradient-color-begin="#FF2424" gradient-color-end="#6D0000" color="#F4F4F4" corner-roundness="0;8;8;8" font="Arial" size="10" bold="false" down-frame-color="#000000" over-gradient-color-begin="#DA0000" down-gradient-color-begin="#910000" over-gradient-color-end="#DA0000" down-gradient-color-end="#FF0000" over-color="#F4F4F4">'
      + '       <post-buttons gradient-color-begin="#FF4949" gradient-color-end="#6D0000"/>'
      + '     </buttons>'
      + '     <listboxes corner-roundness="5"/>'
      + '     <servicemarker gradient-color-begin="#DA0000" gradient-color-end="#DA0000"/>'
      + '   </controls>'
      + '   <texts color="#FFFFFF" font="Arial" size="10">'
      + '     <privacy color="#959595" size="11"/>'
      + '     <headers size="11" bold="true"/>'
      + '     <labels size="11" bold="true"/>'
      + '     <messages color="#D5D5D5" frame-thickness="0" corner-roundness="0;0;0;0" gradient-color-begin="#B60000" gradient-color-end="#000000" size="11" bold="true"/>'
      + '     <links color="#DFDFDF" underline="false" size="11" bold="true" over-color="#FFFFFF"/>'
      + '   </texts>'
      + ' </body>'
      + '</config>';
    var pconf={
      CID: Drupal.settings.sproutbl.id,
      widgetTitle: Drupal.settings.sproutbl.title,
      defaultPreviewURL: Drupal.settings.sproutbl.thumbnail,
      defaultContent: 'widget-embed-code',
      defaultBookmarkURL: Drupal.settings.sproutbl.profile_url,
      useMyspaceAPI: "false",
      UIConfig: wfUI,
      facebookURL: "http://www.facebook.com/sharer.php?u=" + encodeURIComponent(Drupal.settings.sproutbl.profile_url)
        + "&t=" + encodeURIComponent(Drupal.settings.sproutbl.title)
    };
    var wfUICustom = Drupal.settings.sproutbl.gigya_ui;
    if (wfUICustom && wfUICustom.length)
      pconf.UIConfig = wfUICustom;
    Wildfire.onPostComment = function(arg){
      sproutTrace(arg);
      parent.sendMessage('TR:install', arg.network);
    };
    Wildfire.onPostProfile = function(arg){
      sproutTrace(arg);
      parent.sendMessage('TR:install', arg.network);
    };
    Wildfire.initPost(Drupal.settings.sproutbl.account_id, 'share-panel',
      Drupal.settings.sproutbl.share_width || 400,
      Drupal.settings.sproutbl.share_height || 300, pconf);
  }
  else if($('#share-panel.clearspring').length) {
    var conf = {
      wid: Drupal.settings.sproutbl.platform_id,
      menuWidth: Drupal.settings.sproutbl.share_width || 400,
      menuHeight: Drupal.settings.sproutbl.share_height || 300,
      bookmarkUrl: Drupal.settings.sproutbl.profile_url,
      targetElement: 'share-panel',
      servicesExclude: ['hi5','blackplanet', 'desktop', 'bookmark', 'eons', 'webwag',
                        'typepadsidebar', 'bloggersidebar', 'perfspot', 'piczo', 'univision']
    };
    $Launchpad.ShowMenu(conf);
  }
  else {
    $('#widget-embed-code,#widget-embed-code-copy,#widget-embed-code-title').show();
  }
});

function sendMessage(topic, message) {
  sproutTrace('sendMessage('+topic+'): '+message);
  var player = $('#seedmovie').get(0);
  player.sendMessage(topic, message);
}

/**
 * Gets called from the oauth callback page which sets an error message
 * or the authorized request token via this function. This data will in
 * turn gets passed into Flash when the auth window is closed via
 * flashapp.authenticationComplete(token, verifier);
 */
function setOauthCallbackData(token, verifier) {
  var flashapp = document.getElementById('seedmovie');
  if (flashapp && flashapp.msAuthComplete)
    flashapp.msAuthComplete(token, verifier);
};