// Labels for Ajax javascripts
// $Id: labels.js 45176 2009-12-23 12:17:07Z arjan $
//

window.labels								= new Object();

window.labels["main"] 						= new Object();
window.labels["main"]["loading"]			= "loading...";

/* autocomplete */
window.labels["autocomplete"] 				= new Object();
window.labels["autocomplete"]["cancel"]		= "Cancel";

/* annotations */
window.labels["annotations"] 				= new Object();
window.labels["annotations"]["makeactor"]	= "Make a new person";
window.labels["annotations"]["popuptitle"]	= "Tag person";
window.labels["annotations"]["needtologin"]	= "You need to log in";
window.labels["annotations"]["addingactor"]	= "Adding person";
window.labels["annotations"]["actoralreadyadded"]	= "Person is already tagged.";
window.labels["annotations"]["wasaproblem"]	= "There was a problem, please try again";

/* sortable */
window.labels["sortable"]	 				= new Object();

/* lightbox */
window.labels["lightbox"]					= new Object();
window.labels["lightbox"]["cancel"]			= "Cancel";
window.labels["lightbox"]["save"]			= "OK";

/* editatonce */
window.labels["editatonce"] 				= new Object();
window.labels["editatonce"]["saving"]		= "saving ...";

/* editinplace */
window.labels["editinplace"] 				= new Object();
window.labels["editinplace"]["cancel"]		= "Cancel";
window.labels["editinplace"]["save"]		= "OK";
window.labels["editinplace"]["onempty"]		= "Add value";
window.labels["editinplace"]["saving"]		= "saving ...";
window.labels["editinplace"]["fetching"]	= "fetching ...";
window.labels["editinplace"]["validate"]			= new Object();
window.labels["editinplace"]["validate"]["msg"]		= "Please enter valid information";
window.labels["editinplace"]["validate"]["out"]		= "Value out of range";
window.labels["editinplace"]["validate"]["integer"]	= "Enter numbers between 0-9 only";
window.labels["editinplace"]["validate"]["float"]	= "Enter numbers between 0-9 only";

/* unlink */
window.labels["unlink"] 					= new Object();
window.labels["unlink"]["cancel"]			= "No";
window.labels["unlink"]["yes"]				= "Yes";
window.labels["unlink"]["confirm"]			= "Remove";
window.labels["unlink"]["title"]			= "Remove";

/* shoutbox */
window.labels['shoutbox'] 					= new Object();
window.labels['shoutbox']['away']	  		= "You seem to be away from this window. Shutting down shoutbox.";
window.labels['shoutbox']['changed']		= "The default conversation for this page has changed. Refreshing in a few seconds.";
window.labels['shoutbox']['noconv']			= "No conversation exists for this thing yet.";
window.labels['shoutbox']['emptytext']		= "Text is empty. You need to type something";
window.labels['shoutbox']['votedthis']		= "Voted this:";
window.labels['shoutbox']['showsms']		= "Show SMS";
window.labels['shoutbox']['hidesms']		= "Hide SMS";


/* wysiwyg */
window.labels['wysiwyg'] 					= new Object();
window.labels['wysiwyg']['add_link']		= "Add the link";
window.labels['wysiwyg']['add_youtube']		= "Add YouTube code";
window.labels['wysiwyg']['add_title']		= "Add the title of the link";
window.labels["wysiwyg"]['cancel']			= "Cancel";
window.labels["wysiwyg"]['ok']				= "OK";
window.labels["wysiwyg"]['youtube_expl']	= "You can find the YouTube code in the url on YouTube, for example http://www.youtube.com/watch?v=<strong>nogDHP0gl9M</strong>";

window.labels['wysiwyg']['buttons']				= new Object();
window.labels['wysiwyg']['buttons']['italic'] 	= "italic";
window.labels['wysiwyg']['buttons']['bold'] 	= "bold";
window.labels['wysiwyg']['buttons']['link']	 	= "link";
window.labels['wysiwyg']['buttons']['youtube']	= "youtube";
window.labels['wysiwyg']['buttons']['h1'] 		= "huge subhead";
window.labels['wysiwyg']['buttons']['h2'] 		= "medium subhead";
window.labels['wysiwyg']['buttons']['h3'] 		= "subhead";
window.labels['wysiwyg']['buttons']['h4'] 		= "small subhead";

window.labels['dialog']		 					= new Object();
window.labels['dialog']['loading']	  			= "Loadingâ€¦";


//
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}('(p($){c 2Q="f";p 4u(){b.71=F;b.3U=t;b.2k=[];b.3r=F;b.2O=F;b.5P="v-f-H";b.6b="v-f-1b";b.6l="v-f-3v";b.2u="v-f-3Z";b.5L="v-f-8t";b.5X="v-f-3H";b.68="v-f-47";b.5V="v-f-4n";b.4C="v-f-4U-I";b.5u=[];b.5u[""]={7H:"8u",7I:"8s 30 4U h",6G:"6Q",6B:"6Q 8r 7F",2H:"&#5U;8p",6s:"3q 30 6W E",2D:"&#5U;&#5U;",6p:"3q 30 6W B",2J:"8q&#64;",6o:"3q 30 3F E",2I:"&#64;&#64;",6Z:"3q 30 3F B",3f:"8v",6O:"3q 30 4U E",1k:["8w","8B","8A","8z","7o","8x","8y","8o","8n","8d","8e","8c"],2a:["8b","89","8a","8f","7o","8g","8l","8m","8k","8j","8h","8i"],7x:"3q a 7l E",7C:"3q a 7l B",6M:"8C",4l:"8D 8Y 30 B",1v:["8Z","8X","8W","8U","8V","90","91"],1B:["96","88","95","94","92","93","8T"],4M:["8S","8I","8J","8H","8G","8E","8F"],4L:"8K 45 8L 8Q 2G I",3j:"77 45, M d",3d:"53/3Q/3s",1C:0,Z:"77 a h",1H:F};b.1E={3g:"2W",1V:"5q",5t:{},2e:t,46:"",2S:"...",3I:"",6A:F,4s:1d,65:F,4d:F,2z:F,3i:F,6d:F,7s:1d,7j:1d,4p:F,7y:"-10:+10",43:1d,3z:F,2F:F,4m:F,58:b.4X,1O:"+10",16:F,6S:b.3j,R:t,T:t,1h:"8R",4k:t,4c:t,2N:t,6y:t,4a:t,6v:1,4G:0,2x:1,2l:12,1M:F,42:" - ",4g:"",3K:""};$.4w(b.1E,b.5u[""]);b.O=$(\'<H u="\'+b.5P+\'" 4v="5C: 6X;"></H>\')}$.4w(4u.6z,{23:"8P",6i:p(){k(b.71){8O.6i.2w("",5F)}},8M:p(z){3X(b.1E,z||{});r b},6K:p(n,z){c 3G=t;1l(54 6Y b.1E){c 4x=n.8N("h:"+54);k(4x){3G=3G||{};6e{3G[54]=97(4x)}6j(7c){3G[54]=4x}}}c 19=n.19.4f();c 1b=(19=="H"||19=="2U");k(!n.u){n.u="7u"+(++b.5K)}c 8=b.5R($(n),1b);8.z=$.4w({},z||{},3G||{});k(19=="q"){b.6u(n,8)}P{k(1b){b.7i(n,8)}}},5R:p(n,1b){c u=n[0].u.6m(/([:\\[\\]\\.])/g,"\\\\\\\\$1");r{u:u,q:n,1w:0,1n:0,1p:0,G:0,J:0,1b:1b,O:(!1b?b.O:$(\'<H 15="\'+b.6b+\'"></H>\'))}},6u:p(n,8){c q=$(n);k(q.2P(b.23)){r}c 46=b.l(8,"46");c 1H=b.l(8,"1H");k(46){q[1H?"7N":"7R"](\'<2U 15="\'+b.6l+\'">\'+46+"</2U>")}c 3g=b.l(8,"3g");k(3g=="2W"||3g=="56"){q.2W(b.3u)}k(3g=="3D"||3g=="56"){c 2S=b.l(8,"2S");c 3I=b.l(8,"3I");c 3Z=$(b.l(8,"6A")?$("<57/>").2t(b.2u).73({5O:3I,7D:2S,4i:2S}):$(\'<3D 49="3D"></3D>\').2t(b.2u).V(3I==""?2S:$("<57/>").73({5O:3I,7D:2S,4i:2S})));q[1H?"7N":"7R"](3Z);3Z.80(p(){k($.f.3r&&$.f.3J==n){$.f.2y()}P{$.f.3u(n)}r F})}q.2t(b.23).5W(b.4V).7k(b.5o).55("7b.f",p(3T,2T,K){8.z[2T]=K}).55("7d.f",p(3T,2T){r b.l(8,2T)});$.3a(n,2Q,8)},7i:p(n,8){c 5j=$(n);k(5j.2P(b.23)){r}5j.2t(b.23).3v(8.O).55("7b.f",p(3T,2T,K){8.z[2T]=K}).55("7d.f",p(3T,2T){r b.l(8,2T)});$.3a(n,2Q,8);b.6a(8,b.6k(8));b.1X(8)},84:p(8){c 1j=b.3W(8);8.O.1z(1j[1]*$(".v-f",8.O[0]).1z())},83:p(q,7w,2N,z,2r){c 8=b.7v;k(!8){c u="7u"+(++b.5K);b.2b=$(\'<q 49="5G" u="\'+u+\'" 2g="1" 4v="1R: 4E; 1t: -6r;"/>\');b.2b.5W(b.4V);$("2m").3v(b.2b);8=b.7v=b.5R(b.2b,F);8.z={};$.3a(b.2b[0],2Q,8)}3X(8.z,z||{});b.2b.2X(7w);b.1L=(2r?(2r.1g?2r:[2r.86,2r.7W]):t);k(!b.1L){c 4D=4F.6H||1f.1S.5y||1f.2m.5y;c 4W=4F.76||1f.1S.5x||1f.2m.5x;c 3e=1f.1S.3L||1f.2m.3L;c 3c=1f.1S.3R||1f.2m.3R;b.1L=[(4D/2)-2Y+3e,(4W/2)-81+3c]}b.2b.1Z("1J",b.1L[0]+"2R").1Z("1t",b.1L[1]+"2R");8.z.2N=2N;b.2O=1d;b.O.2t(b.5L);b.3u(b.2b[0]);k($.4b){$.4b(b.O)}$.3a(b.2b[0],2Q,8);r b},7Y:p(n){c $n=$(n);k(!$n.2P(b.23)){r}c 19=n.19.4f();$.85(n,2Q);k(19=="q"){$n.3w("."+b.6l).3Y().3B().3w("."+b.2u).3Y().3B().3k(b.23).4y("2W",b.3u).4y("5W",b.4V).4y("7k",b.5o)}P{k(19=="H"||19=="2U"){$n.3k(b.23).6P()}}},82:p(n){c $n=$(n);k(!$n.2P(b.23)){r}c 19=n.19.4f();k(19=="q"){n.47=F;$n.3w("3D."+b.2u).3V(p(){b.47=F}).3B().3w("57."+b.2u).1Z({6T:"1.0",6L:""})}P{k(19=="H"||19=="2U"){$n.75("."+b.68).3Y()}}b.2k=$.7e(b.2k,p(K){r(K==n?t:K)})},7X:p(n){c $n=$(n);k(!$n.2P(b.23)){r}c 19=n.19.4f();k(19=="q"){n.47=1d;$n.3w("3D."+b.2u).3V(p(){b.47=1d}).3B().3w("57."+b.2u).1Z({6T:"0.5",6L:"4h"})}P{k(19=="H"||19=="2U"){c 1b=$n.75("."+b.6b);c N=1b.N();c 4N={1J:0,1t:0};1b.5p().3V(p(){k($(b).1Z("1R")=="9d"){4N=$(b).N();r F}});$n.9W(\'<H 15="\'+b.68+\'" 4v="\'+($.2h.4S?"9V-9U: 9X; ":"")+"1z: "+1b.1z()+"2R; 2f: "+1b.2f()+"2R; 1J: "+(N.1J-4N.1J)+"2R; 1t: "+(N.1t-4N.1t)+\'2R;"></H>\')}}b.2k=$.7e(b.2k,p(K){r(K==n?t:K)});b.2k[b.2k.1g]=n},7J:p(n){k(!n){r F}1l(c i=0;i<b.2k.1g;i++){k(b.2k[i]==n){r 1d}}r F},1o:p(n){6e{r $.3a(n,2Q)}6j(7c){3C"7P 9Y 3a 1l b f"}},a0:p(n,1m,K){c z=1m||{};k(25 1m=="41"){z={};z[1m]=K}c 8=b.1o(n);k(8){k(b.3U==8){b.2y(t)}3X(8.z,z);c h=x A();3X(8,{1e:t,1P:t,1Y:t,1a:t,1w:h.S(),1n:h.X(),1p:h.Q(),1i:h.S(),1y:h.X(),1q:h.Q(),G:h.X(),J:h.Q()});b.1X(8)}},9Z:p(n){c 8=b.1o(n);k(8){b.1X(8)}},9T:p(n,h,29){c 8=b.1o(n);k(8){b.6a(8,h,29);b.1X(8);b.5I(8)}},9S:p(n){c 8=b.1o(n);k(8&&!8.1b){b.6h(8)}r(8?b.67(8):t)},4V:p(e){c 8=$.f.1o(e.n);c 2c=1d;k($.f.3r){48(e.5b){C 9:$.f.2y(t,"");L;C 13:$.f.63(e.n,8.1n,8.1p,$("1D.v-f-3y-3l-2C",8.O)[0]);r F;L;C 27:$.f.2y(t,$.f.l(8,"1h"));L;C 33:$.f.1K(e.n,(e.1s?-$.f.l(8,"2l"):-$.f.l(8,"2x")),"M");L;C 34:$.f.1K(e.n,(e.1s?+$.f.l(8,"2l"):+$.f.l(8,"2x")),"M");L;C 35:k(e.1s){$.f.66(e.n)}2c=e.1s;L;C 36:k(e.1s){$.f.5Z(e.n)}2c=e.1s;L;C 37:k(e.1s){$.f.1K(e.n,-1,"D")}2c=e.1s;L;C 38:k(e.1s){$.f.1K(e.n,-7,"D")}2c=e.1s;L;C 39:k(e.1s){$.f.1K(e.n,+1,"D")}2c=e.1s;L;C 40:k(e.1s){$.f.1K(e.n,+7,"D")}2c=e.1s;L;4h:2c=F}}P{k(e.5b==36&&e.1s){$.f.3u(b)}P{2c=F}}k(2c){e.a1();e.ad()}},5o:p(e){c 8=$.f.1o(e.n);c 2v=$.f.7p($.f.l(8,"3d"));c 5d=af.ae(e.7M==5z?e.5b:e.7M);r e.1s||(5d<" "||!2v||2v.6N(5d)>-1)},3u:p(q){q=q.n||q;k(q.19.4f()!="q"){q=$("q",q.a4)[0]}k($.f.7J(q)||$.f.3J==q){r}c 8=$.f.1o(q);c 4c=$.f.l(8,"4c");3X(8.z,(4c?4c.2w(q,[q,8]):{}));$.f.2y(t,"");$.f.3J=q;$.f.6h(8);k($.f.2O){q.K=""}k(!$.f.1L){$.f.1L=$.f.5v(q);$.f.1L[1]+=q.a3}c 1u=F;$(q).5p().3V(p(){1u|=$(b).1Z("1R")=="6D";r!1u});k(1u&&$.2h.5A){$.f.1L[0]-=1f.1S.3L;$.f.1L[1]-=1f.1S.3R}c N={1J:$.f.1L[0],1t:$.f.1L[1]};$.f.1L=t;8.1e=t;8.O.1Z({1R:"4E",5C:"a8",1t:"-ab"});$.f.1X(8);8.O.1z($.f.3W(8)[1]*$(".v-f",8.O[0])[0].aa);N=$.f.6E(8,N,1u);8.O.1Z({1R:($.f.2O&&$.4b?"a9":(1u?"6D":"4E")),5C:"6X",1J:N.1J+"2R",1t:N.1t+"2R"});k(!8.1b){c 1V=$.f.l(8,"1V")||"5q";c 1h=$.f.l(8,"1h");c 3t=p(){$.f.3r=1d;k($.2h.4S&&1N($.2h.7r,10)<7){$("4B.v-f-5l").1Z({1z:8.O.1z()+4,2f:8.O.2f()+4})}};k($.52&&$.52[1V]){8.O.5q(1V,$.f.l(8,"5t"),1h,3t)}P{8.O[1V](1h,3t)}k(1h==""){3t()}k(8.q[0].49!="5r"){8.q[0].2W()}$.f.3U=8}},1X:p(8){c 5g={1z:8.O.1z()+4,2f:8.O.2f()+4};8.O.6P().3v(b.78(8)).9Q("4B.v-f-5l").1Z({1z:5g.1z,2f:5g.2f});c 1j=b.3W(8);8.O[(1j[0]!=1||1j[1]!=1?"6C":"3Y")+"6F"]("v-f-9I");8.O[(b.l(8,"1H")?"6C":"3Y")+"6F"]("v-f-9l");k(8.q&&8.q[0].49!="5r"){$(8.q[0]).2W()}},6E:p(8,N,1u){c 2r=8.q?b.5v(8.q[0]):t;c 4D=4F.6H||1f.1S.5y;c 4W=4F.76||1f.1S.5x;c 3e=1f.1S.3L||1f.2m.3L;c 3c=1f.1S.3R||1f.2m.3R;k(b.l(8,"1H")||(N.1J+8.O.1z()-3e)>4D){N.1J=22.2V((1u?0:3e),2r[0]+(8.q?8.q.1z():0)-(1u?3e:0)-8.O.1z()-(1u&&$.2h.5A?1f.1S.3L:0))}P{N.1J-=(1u?3e:0)}k((N.1t+8.O.2f()-3c)>4W){N.1t=22.2V((1u?0:3c),2r[1]-(1u?3c:0)-(b.2O?0:8.O.2f())-(1u&&$.2h.5A?1f.1S.3R:0))}P{N.1t-=(1u?3c:0)}r N},5v:p(3b){2Z(3b&&(3b.49=="5r"||3b.9k!=1)){3b=3b.9j}c 1R=$(3b).N();r[1R.1J,1R.1t]},2y:p(q,1h){c 8=b.3U;k(!8||(q&&8!=$.3a(q,2Q))){r}c 1M=b.l(8,"1M");k(1M&&8.2j){b.4J("#"+8.u,b.3n(8,8.1i,8.1y,8.1q))}8.2j=F;k(b.3r){1h=(1h!=t?1h:b.l(8,"1h"));c 1V=b.l(8,"1V");c 3t=p(){$.f.5M(8)};k(1h!=""&&$.52&&$.52[1V]){8.O.5D(1V,$.f.l(8,"5t"),1h,3t)}P{8.O[(1h==""?"5D":(1V=="98"?"9J":(1V=="9n"?"9p":"5D")))](1h,3t)}k(1h==""){b.5M(8)}c 4a=b.l(8,"4a");k(4a){4a.2w((8.q?8.q[0]:t),[(8.q?8.q.2X():""),8])}b.3r=F;b.3J=t;8.z.3H=t;k(b.2O){b.2b.1Z({1R:"4E",1J:"0",1t:"-6r"});k($.4b){$.9a();$("2m").3v(b.O)}}b.2O=F}b.3U=t},5M:p(8){8.O.3k(b.5L).4y(".v-f");$("."+b.5X,8.O).3Y()},7a:p(3T){k(!$.f.3U){r}c $n=$(3T.n);k(($n.5p("#"+$.f.5P).1g==0)&&!$n.2P($.f.23)&&!$n.2P($.f.2u)&&$.f.3r&&!($.f.2O&&$.4b)){$.f.2y(t,"")}},1K:p(u,N,20){c n=$(u);c 8=b.1o(n[0]);b.4K(8,N,20);b.1X(8)},5Z:p(u){c n=$(u);c 8=b.1o(n[0]);k(b.l(8,"6d")&&8.1i){8.1w=8.1i;8.G=8.1n=8.1y;8.J=8.1p=8.1q}P{c h=x A();8.1w=h.S();8.G=8.1n=h.X();8.J=8.1p=h.Q()}b.4t(8);b.1K(n)},5f:p(u,3m,20){c n=$(u);c 8=b.1o(n[0]);8.4H=F;8["4q"+(20=="M"?"7g":"7G")]=8["99"+(20=="M"?"7g":"7G")]=1N(3m.2o[3m.9c].K,10);b.4t(8);b.1K(n)},5Q:p(u){c n=$(u);c 8=b.1o(n[0]);k(8.q&&8.4H&&!$.2h.4S){8.q[0].2W()}8.4H=!8.4H},6I:p(u,I){c n=$(u);c 8=b.1o(n[0]);8.z.1C=I;b.1X(8)},63:p(u,E,B,1D){k($(1D).2P(b.5V)){r}c n=$(u);c 8=b.1o(n[0]);c 1M=b.l(8,"1M");k(1M){8.2j=!8.2j;k(8.2j){$(".v-f 1D",8.O).3k(b.4C);$(1D).2t(b.4C)}}8.1w=8.1i=$("a",1D).V();8.1n=8.1y=E;8.1p=8.1q=B;k(8.2j){8.1P=8.1Y=8.1a=t}P{k(1M){8.1P=8.1i;8.1Y=8.1y;8.1a=8.1q}}b.4J(u,b.3n(8,8.1i,8.1y,8.1q));k(8.2j){8.1e=x A(8.1q,8.1y,8.1i);b.1X(8)}P{k(1M){8.1w=8.1i=8.1e.S();8.1n=8.1y=8.1e.X();8.1p=8.1q=8.1e.Q();8.1e=t;k(8.1b){b.1X(8)}}}},66:p(u){c n=$(u);c 8=b.1o(n[0]);k(b.l(8,"65")){r}8.2j=F;8.1P=8.1Y=8.1a=8.1e=t;b.4J(n,"")},4J:p(u,1T){c n=$(u);c 8=b.1o(n[0]);1T=(1T!=t?1T:b.3n(8));k(b.l(8,"1M")&&1T){1T=(8.1e?b.3n(8,8.1e):1T)+b.l(8,"42")+1T}k(8.q){8.q.2X(1T)}b.5I(8);c 2N=b.l(8,"2N");k(2N){2N.2w((8.q?8.q[0]:t),[1T,8])}P{k(8.q){8.q.3Z("7F")}}k(8.1b){b.1X(8)}P{k(!8.2j){b.2y(t,b.l(8,"1h"));b.3J=8.q[0];k(25(8.q[0])!="4I"){8.q[0].2W()}b.3J=t}}},5I:p(8){c 4g=b.l(8,"4g");k(4g){c 3K=b.l(8,"3K");c h=b.67(8);1T=(6U(h)?(!h[0]&&!h[1]?"":b.21(3K,h[0],b.1U(8))+b.l(8,"42")+b.21(3K,h[1]||h[0],b.1U(8))):b.21(3K,h,b.1U(8)));$(4g).3V(p(){$(b).2X(1T)})}},9g:p(h){c I=h.3A();r[(I>0&&I<6),""]},4X:p(h){c 24=x A(h.Q(),h.X(),h.S(),(h.9f()/-60));c 3O=x A(24.Q(),1-1,4);c 1C=3O.3A()||7;3O.4T(3O.S()+1-1C);k(1C<4&&24<3O){24.4T(24.S()-3);r $.f.4X(24)}P{k(24>x A(24.Q(),12-1,28)){1C=x A(24.Q()+1,1-1,4).3A()||7;k(1C>4&&(24.3A()||7)<1C-3){r 1}}}r 22.9e(((24-3O)/9q)/7)+1},3j:p(h,8){r $.f.21($.f.l(8,"3j"),h,$.f.1U(8))},6f:p(18,K,z){k(18==t||K==t){3C"69 5F"}K=(25 K=="4I"?K.5a():K+"");k(K==""){r t}c 1O=(z?z.1O:t)||b.1E.1O;c 1B=(z?z.1B:t)||b.1E.1B;c 1v=(z?z.1v:t)||b.1E.1v;c 2a=(z?z.2a:t)||b.1E.2a;c 1k=(z?z.1k:t)||b.1E.1k;c B=-1;c E=-1;c I=-1;c 3o=-1;c 1I=F;c 1F=p(1r){c 1A=(U+1<18.1g&&18.1c(U+1)==1r);k(1A){U++}r 1A};c 3x=p(1r){1F(1r);c 5c=(1r=="@"?14:(1r=="y"?4:(1r=="o"?3:2)));c 2g=5c;c 2s=0;2Z(2g>0&&1Q<K.1g&&K.1c(1Q)>="0"&&K.1c(1Q)<="9"){2s=2s*10+1N(K.1c(1Q++),10);2g--}k(2g==5c){3C"7P 5N 5m 1R "+1Q}r 2s};c 5k=p(1r,51,59){c 44=(1F(1r)?59:51);c 2g=0;1l(c j=0;j<44.1g;j++){2g=22.2V(2g,44[j].1g)}c 1m="";c 7z=1Q;2Z(2g>0&&1Q<K.1g){1m+=K.1c(1Q++);1l(c i=0;i<44.1g;i++){k(1m==44[i]){r i+1}}2g--}3C"9r 1m 5m 1R "+7z};c 4O=p(){k(K.1c(1Q)!=18.1c(U)){3C"9D 1I 5m 1R "+1Q}1Q++};c 1Q=0;1l(c U=0;U<18.1g;U++){k(1I){k(18.1c(U)=="\'"&&!1F("\'")){1I=F}P{4O()}}P{48(18.1c(U)){C"d":I=3x("d");L;C"D":5k("D",1B,1v);L;C"o":3o=3x("o");L;C"m":E=3x("m");L;C"M":E=5k("M",2a,1k);L;C"y":B=3x("y");L;C"@":c h=x A(3x("@"));B=h.Q();E=h.X()+1;I=h.S();L;C"\'":k(1F("\'")){4O()}P{1I=1d}L;4h:4O()}}}k(B<2Y){B+=x A().Q()-x A().Q()%2Y+(B<=1O?0:-2Y)}k(3o>-1){E=1;I=3o;9C{c 5e=b.31(B,E-1);k(I<=5e){L}E++;I-=5e}2Z(1d)}c h=x A(B,E-1,I);k(h.Q()!=B||h.X()+1!=E||h.S()!=I){3C"69 h"}r h},9B:"3s-53-3Q",9F:"D, 3Q M 3s",9H:"3s-53-3Q",9G:"D, d M y",9A:"45, 3Q-M-y",9z:"D, d M y",9u:"D, d M 3s",9t:"D, d M 3s",9s:"D, d M y",9v:"@",9w:"3s-53-3Q",21:p(18,h,z){k(!h){r""}c 1B=(z?z.1B:t)||b.1E.1B;c 1v=(z?z.1v:t)||b.1E.1v;c 2a=(z?z.2a:t)||b.1E.2a;c 1k=(z?z.1k:t)||b.1E.1k;c 1F=p(1r){c 1A=(U+1<18.1g&&18.1c(U+1)==1r);k(1A){U++}r 1A};c 4Y=p(1r,K,7t){c 2s=""+K;k(1F(1r)){2Z(2s.1g<7t){2s="0"+2s}}r 2s};c 5i=p(1r,K,51,59){r(1F(1r)?59[K]:51[K])};c 1W="";c 1I=F;k(h){1l(c U=0;U<18.1g;U++){k(1I){k(18.1c(U)=="\'"&&!1F("\'")){1I=F}P{1W+=18.1c(U)}}P{48(18.1c(U)){C"d":1W+=4Y("d",h.S(),2);L;C"D":1W+=5i("D",h.3A(),1B,1v);L;C"o":c 3o=h.S();1l(c m=h.X()-1;m>=0;m--){3o+=b.31(h.Q(),m)}1W+=4Y("o",3o,3);L;C"m":1W+=4Y("m",h.X()+1,2);L;C"M":1W+=5i("M",h.X(),2a,1k);L;C"y":1W+=(1F("y")?h.Q():(h.7n()%2Y<10?"0":"")+h.7n()%2Y);L;C"@":1W+=h.2d();L;C"\'":k(1F("\'")){1W+="\'"}P{1I=1d}L;4h:1W+=18.1c(U)}}}}r 1W},7p:p(18){c 2v="";c 1I=F;1l(c U=0;U<18.1g;U++){k(1I){k(18.1c(U)=="\'"&&!1F("\'")){1I=F}P{2v+=18.1c(U)}}P{48(18.1c(U)){C"d":C"m":C"y":C"@":2v+="9y";L;C"D":C"M":r t;C"\'":k(1F("\'")){2v+="\'"}P{1I=1d}L;4h:2v+=18.1c(U)}}}r 2v},l:p(8,1m){r 8.z[1m]!==5z?8.z[1m]:b.1E[1m]},6h:p(8){c 3d=b.l(8,"3d");c 2K=8.q?8.q.2X().7Q(b.l(8,"42")):t;8.1P=8.1Y=8.1a=t;c h=2e=b.6k(8);k(2K.1g>0){c z=b.1U(8);k(2K.1g>1){h=b.6f(3d,2K[1],z)||2e;8.1P=h.S();8.1Y=h.X();8.1a=h.Q()}6e{h=b.6f(3d,2K[0],z)||2e}6j(e){b.6i(e);h=2e}}8.1w=h.S();8.G=8.1n=h.X();8.J=8.1p=h.Q();8.1i=(2K[0]?h.S():0);8.1y=(2K[0]?h.X():0);8.1q=(2K[0]?h.Q():0);b.4K(8)},6k:p(8){c h=b.4o(b.l(8,"2e"),x A());c R=b.2q(8,"2p",1d);c T=b.2q(8,"2V");h=(R&&h<R?R:h);h=(T&&h>T?T:h);r h},4o:p(h,2e){c 7L=p(N){c h=x A();h.6n(h.6w()+N);r h};c 7U=p(N,5T){c h=x A();c B=h.Q();c E=h.X();c I=h.S();c 62=/([+-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g;c 1A=62.7O(N);2Z(1A){48(1A[2]||"d"){C"d":C"D":I+=1N(1A[1],10);L;C"w":C"W":I+=1N(1A[1],10)*7;L;C"m":C"M":E+=1N(1A[1],10);I=22.2p(I,5T(B,E));L;C"y":C"Y":B+=1N(1A[1],10);I=22.2p(I,5T(B,E));L}1A=62.7O(N)}r x A(B,E,I)};h=(h==t?2e:(25 h=="41"?7U(h,b.31):(25 h=="5N"?(9m(h)?2e:7L(h)):h)));r(h&&h.5a()=="69 A"?2e:h)},6a:p(8,h,29){c 2L=!(h);c 7A=8.1n;c 7E=8.1p;h=b.4o(h,x A());8.1w=8.1i=h.S();8.G=8.1n=8.1y=h.X();8.J=8.1p=8.1q=h.Q();k(b.l(8,"1M")){k(29){29=b.4o(29,t);8.1P=29.S();8.1Y=29.X();8.1a=29.Q()}P{8.1P=8.1i;8.1Y=8.1y;8.1a=8.1q}}k(7A!=8.1n||7E!=8.1p){b.4t(8)}b.4K(8);k(8.q){8.q.2X(2L?"":b.3n(8)+(!b.l(8,"1M")?"":b.l(8,"42")+b.3n(8,8.1P,8.1Y,8.1a)))}},67:p(8){c 4Q=(!8.1q||(8.q&&8.q.2X()=="")?t:x A(8.1q,8.1y,8.1i));k(b.l(8,"1M")){r[8.1e||4Q,(!8.1a?8.1e||4Q:x A(8.1a,8.1Y,8.1P))]}P{r 4Q}},78:p(8){c 2B=x A();2B=x A(2B.Q(),2B.X(),2B.S());c 16=b.l(8,"16");c Z=b.l(8,"Z")||"&#5h;";c 1H=b.l(8,"1H");c 2L=(b.l(8,"65")?"":\'<H 15="v-f-2L"><a 26="17.f.66(\\\'#\'+8.u+"\');\\""+b.1G(16,8.u,b.l(8,"7I"),Z)+">"+b.l(8,"7H")+"</a></H>");c 5S=\'<H 15="v-f-ac">\'+(1H?"":2L)+\'<H 15="v-f-a5"><a 26="17.f.2y();"\'+b.1G(16,8.u,b.l(8,"6B"),Z)+">"+b.l(8,"6G")+"</a></H>"+(1H?2L:"")+"</H>";c 3H=b.l(8,"3H");c 4s=b.l(8,"4s");c 4d=b.l(8,"4d");c 2z=b.l(8,"2z");c 3i=b.l(8,"3i");c 1j=b.3W(8);c 4G=b.l(8,"4G");c 2x=b.l(8,"2x");c 2l=b.l(8,"2l");c 6x=(1j[0]!=1||1j[1]!=1);c 4R=(!8.1i?x A(a2,9,9):x A(8.1q,8.1y,8.1i));c R=b.2q(8,"2p",1d);c T=b.2q(8,"2V");c G=8.G-4G;c J=8.J;k(G<0){G+=12;J--}k(T){c 4e=x A(T.Q(),T.X()-1j[1]+1,T.S());4e=(R&&4e<R?R:4e);2Z(x A(J,G,1)>4e){G--;k(G<0){G=11;J--}}}c 2H=b.l(8,"2H");2H=(!2z?2H:b.21(2H,x A(J,G-2x,1),b.1U(8)));c 2D=(3i?b.l(8,"2D"):"");2D=(!2z?2D:b.21(2D,x A(J,G-2l,1),b.1U(8)));c 4Z=\'<H 15="v-f-4Z">\'+(b.5s(8,-1,J,G)?(3i?"<a 26=\\"17.f.1K(\'#"+8.u+"\', -"+2l+", \'M\');\\""+b.1G(16,8.u,b.l(8,"6p"),Z)+">"+2D+"</a>":"")+"<a 26=\\"17.f.1K(\'#"+8.u+"\', -"+2x+", \'M\');\\""+b.1G(16,8.u,b.l(8,"6s"),Z)+">"+2H+"</a>":(4d?"":"<2M>"+2D+"</2M><2M>"+2H+"</2M>"))+"</H>";c 2J=b.l(8,"2J");2J=(!2z?2J:b.21(2J,x A(J,G+2x,1),b.1U(8)));c 2I=(3i?b.l(8,"2I"):"");2I=(!2z?2I:b.21(2I,x A(J,G+2l,1),b.1U(8)));c 3F=\'<H 15="v-f-3F">\'+(b.5s(8,+1,J,G)?"<a 26=\\"17.f.1K(\'#"+8.u+"\', +"+2x+", \'M\');\\""+b.1G(16,8.u,b.l(8,"6o"),Z)+">"+2J+"</a>"+(3i?"<a 26=\\"17.f.1K(\'#"+8.u+"\', +"+2l+", \'M\');\\""+b.1G(16,8.u,b.l(8,"6Z"),Z)+">"+2I+"</a>":""):(4d?"":"<2M>"+2J+"</2M><2M>"+2I+"</2M>"))+"</H>";c 3f=b.l(8,"3f");c 61=(b.l(8,"6d")&&8.1i?4R:2B);3f=(!2z?3f:b.21(3f,61,b.1U(8)));c V=(3H?\'<H 15="\'+b.5X+\'">\'+3H+"</H>":"")+(4s&&!8.1b?5S:"")+\'<H 15="v-f-9O">\'+(1H?3F:4Z)+(b.5w(8,61)?\'<H 15="v-f-4U"><a 26="17.f.5Z(\\\'#\'+8.u+"\');\\""+b.1G(16,8.u,b.l(8,"6O"),Z)+">"+3f+"</a></H>":"")+(1H?4Z:3F)+"</H>";c 1C=b.l(8,"1C");c 43=b.l(8,"43");c 1v=b.l(8,"1v");c 1B=b.l(8,"1B");c 4M=b.l(8,"4M");c 1k=b.l(8,"1k");c 4k=b.l(8,"4k");c 3z=b.l(8,"3z");c 2F=b.l(8,"2F");c 4m=b.l(8,"4m");c 58=b.l(8,"58")||b.4X;c 4l=b.l(8,"4l");c 2i=(16?b.l(8,"4L")||Z:"");c 3j=b.l(8,"6S")||b.3j;c 29=8.1P?x A(8.1a,8.1Y,8.1P):4R;1l(c 3h=0;3h<1j[0];3h++){1l(c 3E=0;3E<1j[1];3E++){c 3N=x A(J,G,8.1w);V+=\'<H 15="v-f-9N-E\'+(3E==0?" v-f-x-3h":"")+\'">\'+b.7q(8,G,J,R,T,3N,3h>0||3E>0,16,Z,1k)+\'<7h 15="v-f" 9K="0" 9L="0"><72><4P 15="v-f-4i-3h">\'+(4m?"<1D"+b.1G(16,8.u,4l,Z)+">"+b.l(8,"6M")+"</1D>":"");1l(c 2n=0;2n<7;2n++){c I=(2n+1C)%7;c 4L=(2i.6N("45")>-1?2i.6m(/45/,1v[I]):2i.6m(/D/,1B[I]));V+="<1D"+((2n+1C+6)%7>=5?\' 15="v-f-2G-3B-3l"\':"")+">"+(!43?"<2U":"<a 26=\\"17.f.6I(\'#"+8.u+"\', "+I+\');"\')+b.1G(16,8.u,4L,Z)+\' 4i="\'+1v[I]+\'">\'+4M[I]+(43?"</a>":"</2U>")+"</1D>"}V+="</4P></72><7B>";c 6c=b.31(J,G);k(J==8.1p&&G==8.1n){8.1w=22.2p(8.1w,6c)}c 4z=(b.74(J,G)-1C+7)%7;c 4r=x A(J,G,1-4z);c 3S=x A(J,G,1-4z);c 1x=3S;c 6R=(6x?6:22.9M((4z+6c)/7));1l(c 5Y=0;5Y<6R;5Y++){V+=\'<4P 15="v-f-3y-3h">\'+(4m?\'<1D 15="v-f-2G-3E"\'+b.1G(16,8.u,4l,Z)+">"+58(1x)+"</1D>":"");1l(c 2n=0;2n<7;2n++){c 4j=(4k?4k.2w((8.q?8.q[0]:t),[1x]):[1d,""]);c 2E=(1x.X()!=G);c 4n=2E||!4j[0]||(R&&1x<R)||(T&&1x>T);V+=\'<1D 15="v-f-3y-3l\'+((2n+1C+6)%7>=5?" v-f-2G-3B-3l":"")+(2E?" v-f-9R-E":"")+(1x.2d()==3N.2d()&&G==8.1n?" v-f-3y-3l-2C":"")+(4n?" "+b.5V:"")+(2E&&!2F?"":" "+4j[1]+(1x.2d()>=4R.2d()&&1x.2d()<=29.2d()?" "+b.4C:"")+(1x.2d()==2B.2d()?" v-f-2B":""))+\'"\'+((!2E||2F)&&4j[2]?\' 4i="\'+4j[2]+\'"\':"")+(4n?(3z?" 5H=\\"17(b).4A().2t(\'v-f-2G-2C\');\\" 5E=\\"17(b).4A().3k(\'v-f-2G-2C\');\\"":""):" 5H=\\"17(b).2t(\'v-f-3y-3l-2C\')"+(3z?".4A().2t(\'v-f-2G-2C\')":"")+";"+(!16||(2E&&!2F)?"":"17(\'#v-f-2i-"+8.u+"\').V(\'"+(3j.2w((8.q?8.q[0]:t),[1x,8])||Z)+"\');")+"\\" 5E=\\"17(b).3k(\'v-f-3y-3l-2C\')"+(3z?".4A().3k(\'v-f-2G-2C\')":"")+";"+(!16||(2E&&!2F)?"":"17(\'#v-f-2i-"+8.u+"\').V(\'"+Z+"\');")+\'" 26="17.f.63(\\\'#\'+8.u+"\',"+G+","+J+\', b);"\')+">"+(2E?(2F?1x.S():"&#5h;"):(4n?1x.S():"<a>"+1x.S()+"</a>"))+"</1D>";4r.4T(4r.S()+1);3S.6n(3S.6w()+1);1x=(4r>3S?4r:3S)}V+="</4P>"}G++;k(G>11){G=0;J++}V+="</7B></7h></H>"}}V+=(16?\'<H 4v="2L: 56;"></H><H u="v-f-2i-\'+8.u+\'" 15="v-f-2i">\'+Z+"</H>":"")+(!4s&&!8.1b?5S:"")+\'<H 4v="2L: 56;"></H>\'+($.2h.4S&&1N($.2h.7r,10)<7&&!8.1b?\'<4B 5O="9E:F;" 15="v-f-5l"></4B>\':"");r V},7q:p(8,G,J,R,T,3N,5n,16,Z,1k){R=(8.1e&&R&&3N<R?3N:R);c 4p=b.l(8,"4p");c V=\'<H 15="v-f-9x">\';c 3p="";k(5n||!b.l(8,"7s")){3p+=1k[G]+"&#5h;"}P{c 79=(R&&R.Q()==J);c 7f=(T&&T.Q()==J);3p+=\'<3m 15="v-f-x-E" 7S="17.f.5f(\\\'#\'+8.u+"\', b, \'M\');\\" 26=\\"17.f.5Q(\'#"+8.u+"\');\\""+b.1G(16,8.u,b.l(8,"7x"),Z)+">";1l(c E=0;E<12;E++){k((!79||E>=R.X())&&(!7f||E<=T.X())){3p+=\'<50 K="\'+E+\'"\'+(E==G?\' 4q="4q"\':"")+">"+1k[E]+"</50>"}}3p+="</3m>"}k(!4p){V+=3p}k(5n||!b.l(8,"7j")){V+=J}P{c 2A=b.l(8,"7y").7Q(":");c B=0;c 1a=0;k(2A.1g!=2){B=J-10;1a=J+10}P{k(2A[0].1c(0)=="+"||2A[0].1c(0)=="-"){B=1a=x A().Q();B+=1N(2A[0],10);1a+=1N(2A[1],10)}P{B=1N(2A[0],10);1a=1N(2A[1],10)}}B=(R?22.2V(B,R.Q()):B);1a=(T?22.2p(1a,T.Q()):1a);V+=\'<3m 15="v-f-x-B" 7S="17.f.5f(\\\'#\'+8.u+"\', b, \'Y\');\\" 26=\\"17.f.5Q(\'#"+8.u+"\');\\""+b.1G(16,8.u,b.l(8,"7C"),Z)+">";1l(;B<=1a;B++){V+=\'<50 K="\'+B+\'"\'+(B==J?\' 4q="4q"\':"")+">"+B+"</50>"}V+="</3m>"}k(4p){V+=3p}V+="</H>";r V},1G:p(16,u,5G,Z){r(16?" 5H=\\"17(\'#v-f-2i-"+u+"\').V(\'"+(5G||Z)+"\');\\" 5E=\\"17(\'#v-f-2i-"+u+"\').V(\'"+Z+"\');\\"":"")},4K:p(8,N,20){c B=8.J+(20=="Y"?N:0);c E=8.G+(20=="M"?N:0);c I=22.2p(8.1w,b.31(B,E))+(20=="D"?N:0);c h=x A(B,E,I);c R=b.2q(8,"2p",1d);c T=b.2q(8,"2V");h=(R&&h<R?R:h);h=(T&&h>T?T:h);8.1w=h.S();8.G=8.1n=h.X();8.J=8.1p=h.Q();k(20=="M"||20=="Y"){b.4t(8)}},4t:p(8){c 5J=b.l(8,"6y");k(5J){5J.2w((8.q?8.q[0]:t),[8.1p,8.1n+1,8])}},3W:p(8){c 1j=b.l(8,"6v");r(1j==t?[1,1]:(25 1j=="5N"?[1,1j]:1j))},2q:p(8,6q,70){c h=b.4o(b.l(8,6q+"A"),t);k(h){h.9b(0);h.9h(0);h.9i(0);h.9o(0)}r(!70||!8.1e?h:(!h||8.1e>h?8.1e:h))},31:p(B,E){r 32-x A(B,E,32).S()},74:p(B,E){r x A(B,E,1).3A()},5s:p(8,N,6V,6J){c 1j=b.3W(8);c h=x A(6V,6J+(N<0?N:1j[1]),1);k(N<0){h.4T(b.31(h.Q(),h.X()))}r b.5w(8,h)},5w:p(8,h){c 3P=(!8.1e?t:x A(8.1p,8.1n,8.1w));3P=(3P&&8.1e<3P?8.1e:3P);c R=3P||b.2q(8,"2p");c T=b.2q(8,"2V");r((!R||h>=R)&&(!T||h<=T))},1U:p(8){c 1O=b.l(8,"1O");1O=(25 1O!="41"?1O:x A().Q()%2Y+1N(1O,10));r{1O:1O,1B:b.l(8,"1B"),1v:b.l(8,"1v"),2a:b.l(8,"2a"),1k:b.l(8,"1k")}},3n:p(8,I,E,B){k(!I){8.1i=8.1w;8.1y=8.1n;8.1q=8.1p}c h=(I?(25 I=="4I"?I:x A(B,E,I)):x A(8.1q,8.1y,8.1i));r b.21(b.l(8,"3d"),h,b.1U(8))}});p 3X(n,3M){$.4w(n,3M);1l(c 1m 6Y 3M){k(3M[1m]==t||3M[1m]==5z){n[1m]=3M[1m]}}r n}p 6U(a){r(a&&(($.2h.a7&&25 a=="4I"&&a.1g)||(a.7K&&a.7K.5a().1r(/\\7T\\(\\)/))))}$.a6.f=p(2o){k(!$.f.5B){$(1f.2m).3v($.f.O).9P($.f.7a);$.f.5B=1d}c 6g=7T.6z.7V.7Z(5F,1);k(25 2o=="41"&&(2o=="87"||2o=="S")){r $.f["7m"+2o+"4u"].2w($.f,[b[0]].6t(6g))}r b.3V(p(){25 2o=="41"?$.f["7m"+2o+"4u"].2w($.f,[b].6t(6g)):$.f.6K(b,2o)})};$.f=x 4u();$.f.5B=F;$.f.5K=x A().2d()})(17);',62,636,'||||||||inst|||this|var|||datepicker||date|||if|_get||target||function|input|return||null|id|ui||new||settings|Date|year|case||month|false|drawMonth|div|day|drawYear|value|break||offset|dpDiv|else|getFullYear|minDate|getDate|maxDate|iFormat|html||getMonth||initStatus||||||class|showStatus|jQuery|format|nodeName|endYear|inline|charAt|true|rangeStart|document|length|duration|currentDay|numMonths|monthNames|for|name|selectedMonth|_getInst|selectedYear|currentYear|match|ctrlKey|top|isFixed|dayNames|selectedDay|printDate|currentMonth|width|matches|dayNamesShort|firstDay|td|_defaults|lookAhead|_addStatus|isRTL|literal|left|_adjustDate|_pos|rangeSelect|parseInt|shortYearCutoff|endDay|iValue|position|documentElement|dateStr|_getFormatConfig|showAnim|output|_updateDatepicker|endMonth|css|period|formatDate|Math|markerClassName|checkDate|typeof|onclick|||endDate|monthNamesShort|_dialogInput|handled|getTime|defaultDate|height|size|browser|status|stayOpen|_disabledInputs|stepBigMonths|body|dow|options|min|_getMinMaxDate|pos|num|addClass|_triggerClass|chars|apply|stepMonths|_hideDatepicker|navigationAsDateFormat|years|today|over|prevBigText|otherMonth|showOtherMonths|week|prevText|nextBigText|nextText|dates|clear|label|onSelect|_inDialog|hasClass|PROP_NAME|px|buttonText|key|span|max|focus|val|100|while|the|_getDaysInMonth|||||||||data|obj|scrollY|dateFormat|scrollX|currentText|showOn|row|showBigPrevNext|dateStatus|removeClass|cell|select|_formatDate|doy|monthHtml|Show|_datepickerShowing|yy|postProcess|_showDatepicker|append|siblings|getNumber|days|highlightWeek|getDay|end|throw|button|col|next|inlineSettings|prompt|buttonImage|_lastInput|altFormat|scrollLeft|props|selectedDate|firstMon|newMinDate|dd|scrollTop|utcDate|event|_curInst|each|_getNumberOfMonths|extendRemove|remove|trigger||string|rangeSeparator|changeFirstDay|names|DD|appendText|disabled|switch|type|onClose|blockUI|beforeShow|hideIfNoPrevNext|maxDraw|toLowerCase|altField|default|title|daySettings|beforeShowDay|weekStatus|showWeeks|unselectable|_determineDate|showMonthAfterYear|selected|tzDate|closeAtTop|_notifyChange|Datepicker|style|extend|attrValue|unbind|leadDays|parent|iframe|_currentClass|browserWidth|absolute|window|showCurrentAtPos|_selectingMonthYear|object|_selectDate|_adjustInstDate|dayStatus|dayNamesMin|relOffset|checkLiteral|tr|startDate|currentDate|msie|setDate|current|_doKeyDown|browserHeight|iso8601Week|formatNumber|prev|option|shortNames|effects|mm|attrName|bind|both|img|calculateWeek|longNames|toString|keyCode|origSize|chr|dim|_selectMonthYear|dims|xa0|formatName|divSpan|getName|cover|at|secondary|_doKeyPress|parents|show|hidden|_canAdjustMonth|showOptions|regional|_findPos|_isInRange|clientHeight|clientWidth|undefined|opera|initialized|display|hide|onmouseout|arguments|text|onmouseover|_updateAlternate|onChange|uuid|_dialogClass|_tidyDialog|number|src|_mainDivId|_clickMonthYear|_newInst|controls|getDaysInMonth|x3c|_unselectableClass|keydown|_promptClass|dRow|_gotoToday||gotoDate|pattern|_selectDay|x3e|mandatory|_clearDate|_getDate|_disableClass|Invalid|_setDate|_inlineClass|daysInMonth|gotoCurrent|try|parseDate|otherArgs|_setDateFromField|log|catch|_getDefaultDate|_appendClass|replace|setUTCDate|nextStatus|prevBigStatus|minMax|100px|prevStatus|concat|_connectDatepicker|numberOfMonths|getUTCDate|isMultiMonth|onChangeMonthYear|prototype|buttonImageOnly|closeStatus|add|fixed|_checkOffset|Class|closeText|innerWidth|_changeFirstDay|curMonth|_attachDatepicker|cursor|weekHeader|indexOf|currentStatus|empty|Close|numRows|statusForDate|opacity|isArray|curYear|previous|none|in|nextBigStatus|checkRange|debug|thead|attr|_getFirstDayOfMonth|children|innerHeight|Select|_generateHTML|inMinYear|_checkExternalClick|setData|err|getData|map|inMaxYear|Month|table|_inlineDatepicker|changeYear|keypress|different|_|getYear|May|_possibleChars|_generateMonthYearHeader|version|changeMonth|len|dp|_dialogInst|dateText|monthStatus|yearRange|iInit|origMonth|tbody|yearStatus|alt|origYear|change|Year|clearText|clearStatus|_isDisabledDatepicker|constructor|offsetNumeric|charCode|before|exec|Missing|split|after|onchange|Array|offsetString|slice|pageY|_disableDatepicker|_destroyDatepicker|call|click|150|_enableDatepicker|_dialogDatepicker|_inlineShow|removeData|pageX|isDisabled|Mon|Feb|Mar|Jan|December|October|November|Apr|Jun|Nov|Dec|Oct|Sep|Jul|Aug|September|August|Prev|Next|without|Erase|dialog|Clear|Today|January|June|July|April|March|February|Wk|Week|Fr|Sa|Th|We|Mo|Tu|Set|as|setDefaults|getAttribute|console|hasDatepicker|first|normal|Su|Sat|Wednesday|Thursday|Tuesday|Monday|of|Sunday|Friday|Saturday|Thu|Fri|Wed|Tue|Sun|eval|slideDown|draw|unblockUI|setHours|selectedIndex|relative|floor|getTimezoneOffset|noWeekends|setMinutes|setSeconds|nextSibling|nodeType|rtl|isNaN|fadeIn|setMilliseconds|fadeOut|86400000|Unknown|RSS|RFC_2822|RFC_1123|TIMESTAMP|W3C|header|0123456789|RFC_1036|RFC_850|ATOM|do|Unexpected|javascript|COOKIE|RFC_822|ISO_8601|multi|slideUp|cellpadding|cellspacing|ceil|one|links|mousedown|find|other|_getDateDatepicker|_setDateDatepicker|color|background|prepend|transparent|instance|_refreshDatepicker|_changeDatepicker|preventDefault|9999|offsetHeight|parentNode|close|fn|safari|block|static|offsetWidth|1000px|control|stopPropagation|fromCharCode|String'.split('|'),0,{}))
//
/**/

// class for status messages on user pages
// by Tim Benniks
var statusMessages = 
{

	// this function initializes all events for the status messages.
	// it needs the thg_id so we have that when we save a message.
	init: function(thg_id)
	{
		// make the keyboard trigger save and cancle events in the keypress.statusMessages namespace.		
		$(document)
			.unbind('keypress.statusMessages')
			.bind('keypress.statusMessages', function(e)
			{
				var key;
				if($.browser.msie) 	{ key = e.which } else { key = e.keyCode }
				if(key == 27) { $('.cancel-status-message').click(); }
				if(key == 13) { $('.save-status-message').click(); }
			});
		
		$('#add-status-massage, .status-editable').click(function()
		{
			statusMessages.addMsg($(this), $('.status-editable').text());
		});
				
		$('.save-status-message').click(function()
		{
			if(
				$('.add-status-message-wrapper input').val() != '' 
			 || $('.add-status-message-wrapper input').val() != 'is ' 
			 || $('.add-status-message-wrapper input').val() != 'is'
			)
			{
				statusMessages.saveMsg(thg_id, $('.add-status-message-wrapper input').val());
			}
			else
			{
				return false;
			}
		});
		
		$('.cancel-status-message').click(function()
		{
			statusMessages.cancelMsg();
		});
		
		statusMessages.applyStyle('h1', $('.add-status-message-wrapper input'));
	},
	
	// show the form, hide the button.
	addMsg: function(obj, value)
	{
		value = value || 'is ';
		
		obj.fadeOut(150, function()
		{
			$('.add-status-message-wrapper').fadeIn();
			$('.add-status-message-wrapper input')
				.focus()
				.val(value)
				.css({width: '100%'})
				.select();
		});	
	},

	// hide the form, show the old status message / new message button.
	cancelMsg: function()
	{
		$('.add-status-message-wrapper').fadeOut(function()
		{
			$('#the-status-msg').fadeIn();
		});
	},

	// apply the style from the header to the inputfield.
	applyStyle: function(from, to)
	{
		var inheritStyle = ['font-family', 'font-size', 'font-weight', 'color', 'line-height', 'font-style'];

		for(i in inheritStyle)
		{
			to.css(inheritStyle[i], $(from).css(inheritStyle[i]));
		}
	},

	// Save the status mesage.
	saveMsg: function(thg_id, msg)
	{
		$('.add-status-message-wrapper input').addClass('loading');
		
		anyRest.service('status.set', 
		{
			id: 		thg_id,
			message: 	msg
		},
		function(xml)
		{
			$('.add-status-message-wrapper input').removeClass('loading');
			
			// on error show the error div and add the status message in there.
			if(anyRest.aux.error(xml))
			{
				return false;
			}
			else
			{
				statusMessages.saveMsgCallBack(thg_id);
			}
		});
	},
	
	// after saving the message, reload the template with the right content
	saveMsgCallBack: function(thg_id)
	{
		anyRest.html.scomp(
		{
			'name':		'scomp_status_message_wrapper', 
			'thg_id':	thg_id
		}, 
		function(xml)
		{
			if(anyRest.aux.error(xml)) 
			{
				$.warn($('rsp msg', xml).attr('msg'), '');
			}
			else
			{
				var scompHtml 	= $('html', xml).text();
				var domID 		= $('#status-message-wrapper');

				if(scompHtml && domID)
				{
					$(domID).fadeOut(300, function()
					{
						$(domID).after(scompHtml).remove();
						return false;
					});
				}
				else
				{
					$.log('Internal error: did not get a template from the server or no dom id. Sorry...');
				}
			}
		});
	}
}
/* */
//
function init_imagehover(container, context)
{
	context = context || document.body;
	$(container, context).each(function() 
	{
		var opts = false;
		opts = jQuery.attrOptions(this, "imagehover");
		new Imagehover(this, opts);
	});
}

function docs_imagehover()
{
	var a = "An image hoverer.";
	var e = [ ['<div class="set-info-wrapper do_imagehover">', "Image zoomer"] ];
	var c = [];
	
	var o = 
	[
		[ "effectIn", 			{opacity: 'show', height: 'show'},		"The ineffect" ],
		[ "effectOut", 			{opacity: 'hide', height: 'hide'},		"The outeffect" ],
		[ "effectInDuration", 	300,									"The ineffect time in ms" ],
		[ "effectOutDuration", 	300,									"The outeffect time in ms" ],
		[ "effectInEasing", 	'easeInOutExpo',						"The ineffect easing" ],
		[ "effectOutEasing", 	'easeInOutExpo',						"The outeffect easing" ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}

function opts_imagehover(o)
{
	return apply_options(docs_imagehover().opts, o);
}

function Imagehover(container, opts)
{
	opts			= opts_imagehover( opts );
	this.container	= container;
	this.opts		= opts;
	
	$(container).imagehover(
	{
		effectIn: 			opts.effectIn,
		effectOut: 			opts.effectOut,
		effectInDuration: 	opts.effectInDuration,
		effectOutDuration: 	opts.effectOutDuration,
		effectInEasing: 	opts.effectInEasing,
		effectOutEasing: 	opts.effectOutEasing
	});	
}

;(function(jQuery) 
{
	jQuery.fn.imagehover = function(options)
	{
  		var options = jQuery.extend(jQuery.fn.imagehover.defaults, options);
  			
  		return this.each(function() 
		{
			// Remove all alt and title attributes because the hover event is fired again upon showing the alt or title attribute.
			// Crappy browser weirdness!
			$('img', $(this).parent()).removeAttr('alt');
			$('a', $(this).parent()).removeAttr('title');
	
			var self = $(this);
	
			// Hover the li (parent), for some reason it gives a smoother animation that way
			$(this)
				.parent()
				.hover(function()
				{
					if(self.data('_animating') == true) return;

					self.data('_animating', true);
					
					self.animate(options.effectIn, options.effectInDuration, options.effectInEasing, function() 
					{ 
						self.data('_animating', false);
					});
				},
				function()
				{
					self.animate(options.effectOut, options.effectOutDuration, options.effectOutEasing);
				});
		});
	}	

	jQuery.fn.imagehover.defaults = 
	{
		effectIn: 			{opacity: 'show', height: 'show'},
		effectOut: 			{opacity: 'hide', height: 'hide'},
		effectInDuration: 	300,
		effectOutDuration: 	300,
		effectInEasing: 	'easeInOutExpo',
		effectOutEasing: 	'easeInOutExpo'
	}

})(jQuery);

//
/*  */

// Main library file
// Contains all functions used by two or more widgets,
// Contains the main initialization and widget management code

/*  */

if (!$.any) $.any = {};

/* global notification code - Tim Benniks */
$.extend($.any,
{
	/**
	* Notification of messages resulting from interactions with AnyMeta.
	*/
	notification:
	{
		notice: function(msg, element)
		{
			$.any.notification._showNotice(msg, 'notice', element);
		},

		error: function(msg, element)
		{
			$.any.notification._showNotice(msg, 'error', element);
		},

		success: function(msg, element)
		{
			$.any.notification._showNotice(msg, 'success', element);
		},

        /**
         * Find the first element of class 'notification' that is
         * within the parents of the given element.
         */
        getNotificationElement: function(element)
        {
            var el = $(element).parents().prev('.notification:first');
            return el;
        },

		/**
		* Show the notice and calculate the timeout
		*/
		_showNotice: function(msg, kind, element)
		{
			$.any.notification.time  = 4000;
			$.any.notification.timer = null;

            if (element)
            {
                var notification = element;
            }
			else if($.any.dialog.opened())
			{
				var notification = $('.dialog .notification:first');
			}
			else
			{
				var notification = $('.notification:first');
			}

			if($('ul', notification).length)
			{
				$('ul', notification).append('<li class="'+ kind +'">'+ msg +'</li>');

				$('li', notification).each(function()
				{
					$.any.notification.time += 700;
				});

				$.any.notification._hideNotice(notification);
			}
			else
			{
				$('<ul></ul>').append('<li class="'+ kind +'">'+ msg +'</li>').appendTo(notification);

				setTimeout(function()
				{
					notification.animate({opacity: 'show', height: 'show'}, 300, function()
					{
						$('li', notification).each(function()
						{
							$.any.notification.time += 700;
						});

						$.any.notification._hideNotice(notification);
					});
				},

				10);
			}
		},

		/*
		* After the timeout, remove the notices
		*/
		_hideNotice: function(notification)
		{
			clearTimeout($.any.notification.timer);

			$.any.notification.timer = setTimeout(function()
			{
				notification.animate({opacity: 'hide', height: 'hide'}, 300, function()
				{
					$(this).empty().hide();
				});
			},

			$.any.notification.time);
		},

		/**
		* Ask Anymeta explicitly if there are any outstanding notifications which I should show in the interface.
		*/
		notifyCheck: function()
		{
			$.any.rest.get('anymeta.notifications.get', {}, function(data)
			{
				for(var i = 0; i < data.length; i++)
				{
					var n = data[i];

					if(typeof $.any.notification[n['class']] == 'function')
					{
						$.any.notification[n['class']](n['message']);
					}
					else
					{
						throw('wrong notification kind used.');
					}
				}
			});
		},

		loader:
		{
			options:
			{
				count: 0,
				time: null,
				dialogAnimation: false
			},

			start: function()
			{
				$.any.notification.loader.options.count += 1;
				$.any.notification.loader.options.time = (new Date()).getTime();

				if($.any.dialog.opened())
				{
					//return
					$('.dialog .dialog-loader').fadeIn(150);
				}

				var loader = $('<div class="ajax_notice" id="corner_notice"><img src="http://static.mediamatic.nl/f/cgcz/image/throbberdots.gif" /></div>').fadeIn(150);

				$(document.body)
					.addClass("wait")
					.append(loader);
			},

			stop: function()
			{
				$.any.notification.loader.options.count -= 1;

				if($.any.notification.loader.options.count > 0)
				{
					return;
				}
				else
				{
					$.any.notification.loader.options.count = 0;
				}

				var now = (new Date()).getTime();
				var diff = now - $.any.notification.loader.options.time;

				var remove = function()
				{
					$('#corner_notice').fadeOut(150, function()
					{
						$(this).remove();
						$(document.body).removeClass("wait");
						$('.dialog .dialog-loader').fadeOut(150);
					});
				};

				if(diff > 500)
				{
					remove();
				}
				else
				{
					setTimeout(remove, diff);
				}
			}
		}
	}
});

//
// START Global Initialization code
//

window.widget_manager = null;
$(function()
{
	window.widget_manager = new WidgetManager( window.widget_names );

	if ( window.widget_roots && window.widget_roots.length > 0 )
	{
		for ( var i in window.widget_roots )
		{
			// Initialize widgets at one or more specific root points
			// This option is here for perfomance reasons: it can make
			// a huge difference on a big page with few localized widgets,
			// e.g. admin interface
			init_widgets( window.widget_roots[i] );
		}
	}
	else
	{
		// Initialize the widgets starting from the root
		init_widgets( document.body );
	}

	$(window).unload(function()
	{
		// There might be things to save at
		// the moment a user clicks a link
		window.widget_manager.stopAll();
	});

	// check if modifier keys influence a link
	modifier_keys();

	// #4825: ready function for edit_required_fields template
	if ( window.required_fields )
	{
		validate_update();
	}
});

// check if modifier keys influence a link
function modifier_keys( url )
{
	if ($('#editpage'))
	{
		// check if editpage button is clicked
		// if shift key is clicked, use the admin page in new window
		$('#editpage').click(
			function(e)
			{
				if (e.shiftKey && $('#editpage').attr('rel'))
				{
					uri = $('#editpage').attr('rel');
					win = window.open('','_blank');
					win.location.href = uri;
					return false;
				}
			}
		);
	}
}

// External callback for the widget
function widget_save( submit_form )
{
	var n = window.widget_manager.stopAll();
	var t = n > 0 ? 2000 : 1;
	setTimeout(
		function ()
		{
			submit_form.submit();
		},
		t
	);
	return false;
}

// Start widgets inside a given element/css selector
function init_widgets( context )
{
	var x = $( context ).get(0);
	x && window.widget_manager.startWidgets( x );
}

// CLASS WidgetManager
// Handles the inter-widget communication
function WidgetManager( widget_names )
{
	this.widgetNames 	= widget_names;
	this.currentWidgets = {};
	this.allWidgets 	= {};
}

// Return all widgets of a given type
WidgetManager.prototype.widgets = function ( name )
{
	return this.allWidgets[name];
};

// Make the Widget Manager aware of a new widget instance
WidgetManager.prototype.add = function ( name, w )
{
	this.allWidgets[name] = this.allWidgets[name] || [];
	this.allWidgets[name].push( w );
};

// Select all the widget instances of types defined in ws
// that match predicate function f
WidgetManager.prototype.find_all = function ( f, ws )
{
	ws = ws || ['editinplace','editatonce'];
	var rt = [];
	for ( var i in ws )
	{
		var a = this.allWidgets[ws[i]] || [];

		for ( var j in a )
		{
			if ( f( a[j] ) )
			{
				rt.push( a[j] );
			}
		}
	}
	return rt;
};

// Finds the first element belonging to one of the types
// defined in ws that matches predicate function f
WidgetManager.prototype.find = function ( f, ws )
{
	ws = ws || ['editinplace','editatonce'];
	for ( var i in ws )
	{
		var a = this.allWidgets[ws[i]] || [];

		for ( var j in a )
		{
			if ( f( a[j] ) )
			{
				return a[j];
			}
		}
	}
	return null;
};

// Returns the current/active widget of type name
WidgetManager.prototype.current = function ( name )
{
	return this.currentWidgets[name];
};

// Stop (blur) all widgets. Used for e.g when the page is unloading
WidgetManager.prototype.stopAll = function ()
{
	var count = 0;
	for ( var name in this.currentWidgets )
	{
		var w = this.currentWidgets[name];
		if ( w )
		{
			if ( w.widgetBlur( name, null ) )
			{
				count += 1;
			}
		}
	}
	return count;
};

// Stop the current/active widget instance of type name
WidgetManager.prototype.stop = function ( name )
{
	var w = this.currentWidgets[name];
	w && w.widgetBlur( name, null );
};

// Defined a widget instance as the new current/active element
// fot the widget type name
WidgetManager.prototype.widgetFocus = function ( name, obj )
{
	for ( i in this.currentWidgets )
	{
		var w = this.currentWidgets[i];
		w.widgetBlur && w.widgetBlur( name, obj );
	}

	this.currentWidgets[name] = obj;
};

// Main widget initialization function
// Does a traversal of the tree that starts at root, checking
// the css classes of all elements for the do_<widgetname> pattern
// that matches one of the allowed types defined in window.widgetNames
WidgetManager.prototype.startWidgets = function ( root )
{
	var stack = [root];
	var names = this.widgetNames;
    var widgets = [];
	var names_do = {};
	for ( var i in names )
	{
		names_do['do_' + names[i]] = names[i];
	}

	while ( stack.length > 0 )
	{
        // Old-style widget

		var e = stack.pop();
		if ( e.className && e.className.match( /do_[a-z_]+/ ) )
		{
			// Note: IE6 does not recognize the \b escape char
			// (whitespace in js regexps)
			var clsss = e.className.match( /do_[a-z_]+/g );
			for ( var i = 0; i < clsss.length; i++ )
			{
				var w = names_do[clsss[i]];
				if ( w )
				{
					eval("init_" + w + "( e )");
				}
			}
        }

        // New-style widget ($.any.ui)

        var objectClass;
		if(e.className && (objectClass = new RegExp("ui_([\\w_]+)", "g").exec(e.className)))
		{
			var base = objectClass[1];
            widgets.push($.any.ui._instantiate(e, base));
        }

		if ( e.childNodes )
		{
			for ( var i = 0 ; i < e.childNodes.length ; i++ )
			{
				if ( e.childNodes[i].nodeType != 3 )
				{
					// Only process if not a text node
					stack.unshift( e.childNodes[i] );
				}
			}
		}
	}

	var ends = ['editinplace','editatonce'];
	for ( var i in ends )
	{
		if ( jQuery.inArray( ends[i], names ) > -1)
		{
			eval( 'end_' + ends[i] + '()' );
		}
	}

    $.each(widgets, function(i,w) { w._postInit(); });
};

// Convert the name of a validated field into a
// string usable as a dom id attribute
function validate_field2id ( name )
{
	name = name.replace( /\./g, "_" );
	return 'required_fields_li_' + name;
}

function validate_cmpfield ( l )
{
	return function ( x )
	{
		return jQuery.inArray( x.options.ajax.field, l ) > -1;
	}
}

// Scroll down/up the window to make visible the edit place of
// a given validate field that was incorrect or missing
function validate_goto ( i )
{
	var e = window.widget_manager.find( validate_cmpfield( [i] ) );
	if ( e )
	{
		var p = jQuery.getPosition( e.container );
		scroll( 0, p.y - 100 );
	}
}

// Update the validate fields error information
function validate_update ()
{
	if ( jQuery.isEmptyObject( window.required_fields ) )
	{
		$( "#required_fields_main"  ).hide();
		$( "#required_fields_other" ).show();
		return;
	}

	$( "#required_fields_main" ).show();
	$( "#required_fields_other" ).hide();

	var fs = window.required_fields;
	var ul = $( "#required_fields_list" ).get( 0 );
	ul.innerHTML = '';
	var bind_click = function ( li, i )
	{
		var fu = function ( x )
		{
			return x.options.ajax.field == i;
		};

		var e = window.widget_manager.find( fu );

		if ( e && e.options )
		{
			var c = e.options.callback;
			c = c || function () {};

			var fc = function ( d )
			{
				delete( window.required_fields[i] );
				validate_update();
				c && c( d );
			}

			e.options.callback = fc;

			$( li ).bind( "click",
				function ()
				{
					validate_goto( i );
					return false;
				}
			);
		}
	};

	var gs = jQuery.objKeys( fs );
	var fu = validate_cmpfield( gs );
	var ws = window.widget_manager.find_all( fu );
	for ( var i in ws )
	{
		ws[i].addRequiredClass();
	}

	for ( var i in fs )
	{
		var li = document.createElement( "li" );
		var an = document.createElement( "a" );
		li.id = validate_field2id( i );
		li.className = "required_field_title";
		an.href='#';
		$( an  ).html( fs[i] );
		$( li ).append( an );
		$( ul ).append( li );
		bind_click( an, i );
	}
}

// Used by all widgets. Override the default widget 'docs'
// options with those 'o' specific for this instance
function apply_options( docs, o )
{
	for ( var i in docs )
	{
		var d	= docs[i];
		var ds	= d[0].split('.');
		if ( ds.length > 1 )
		{
			o[ds[0]][ds[1]]	= (typeof o[ds[0]][ds[1]] != 'undefined') ? o[ds[0]][ds[1]]	: d[1];
		}
		else
		{
			o[d[0]]			= (typeof o[d[0]] != 'undefined') 		  ? o[d[0]] 		: d[1];
		}
	}
	return o;
}


//
// END Global Initialization code
//

// Identity function
function identity ( x )
{
	return x;
}

jQuery.fn.opacity = function ( v )
{
	this.css('opacity', v );
	if ( jQuery.browser.msie )
	{
		this.css('filter', 'alpha(opacity=' + v * 100 + ')');
	}
}

jQuery.extend(
{
	objKeys: function ( obj )
	{
		var ret = [];
		for ( var i in obj )
		{
			ret.push( i );
		}
		return ret;
	},

	label: function ( path, def )
	{
		var names 	= path.split('.');
		var tmp 	= window.labels;

		while ( names.length > 0 && tmp )
		{
			tmp = tmp[names.shift()];
		}

		return tmp || def;
	},

	// Create a new cookie
	// @param	name	string		name of the cookie
	// @param	value	string		value to be stored
	// @param	days	int			expiry time in days
	createCookie: function ( name, value, days )
	{
		if ( days )
		{
			var date = new Date();
			date.setTime( date.getTime() + ( days * 24 * 60 * 60 * 1000 ) );
			var expires = "; expires=" + date.toGMTString();
		}
		else
		{
			var expires = "";
		}
		document.cookie = name + "=" + value+expires + "; path=/";
	},

	// Read the value of a cookie
	readCookie: function ( name )
	{
		var nameEQ = name + "=";
		var ca = document.cookie.split( ';' );
		for ( var i = 0 ; i < ca.length ; i++ )
		{
			var c = ca[i];
			while ( c.charAt(0) == ' ' )
			{
				c = c.substring( 1, c.length );
			}

			if ( c.indexOf( nameEQ ) == 0 )
			{
				return c.substring( nameEQ.length, c.length );
			}
		}
		return null;
	},

	// Delete a cookie
	eraseCookie: function( name )
	{
		jQuery.createCookie( name, "", -1 );
	},

	// Use the log function of firebug without messing with other browsers
	log: function ()
	{
		if ( window.console && window.console.log && window.console.assert )
		{
			window.console.log( arguments );
		}
	},

	warn: function(where, what)
	{
		$.any.notification.notice(where);
	},

	error: function ( msg , url , line )
	{
		$.any.notification.error(msg + " @ " + url + " @ " + line);
	},

	// Encode object for get/post request: works with arbitrarily-leveled-nested
	// arrays and objects. Adapted from PHP (any_functions' http_build_query)
	//
	xparam: function (params)
	{
		var encoder_f = function (f, name, value, sep, uri)
		{
			if (value.constructor == Array)
			{
				for ( var i = 0 ; i < value.length ; i++ )
				{
					f(f, name + '[' + i + ']', value[i], sep, uri);
				}
			}
			else if ( value.constructor == Object )
			{
				for ( var i in value )
				{
					f(f, name + '[' + i + ']', value[i], sep, uri);
				}
			}
			else
			{
				uri.uri += sep.sep + name + '=' + encodeURIComponent(value);
				sep.sep = '&';
			}
		};

		// Hack for simulating call-by-reference in JavaScript
		var sep = {sep:''};
		var uri = {uri:''};

		for ( var i in params )
		{
			encoder_f(encoder_f, i, params[i], sep, uri);
		}

		return uri.uri;
	},

	// Get the window size
	windowSize: function ()
	{
		var p = { w: 0, h: 0 };
        var e = document.documentElement;
        var b = document.body;

		if ( typeof( window.innerWidth ) == 'number' )
		{
		  //Non-IE
		  p.w = window.innerWidth;
		  p.h = window.innerHeight;
		}
		else if( e && ( e.clientWidth || e.clientHeight ) )
		{
		  //IE 6+ in 'standards compliant mode'
		  p.w = e.clientWidth;
		  p.h = e.clientHeight;
		}
		else if( b && ( b.clientWidth || b.clientHeight ) )
		{
		  //IE 4 compatible
		  p.w = b.clientWidth;
		  p.h = b.clientHeight;
		}

		return p;
	},

	mousePosition: function ( ev )
	{
		ev = ev || window.event;

		var x = 0, y = 0;

		if ( ev.pageX || ev.pageY )
		{
			x = ev.pageX;
			y = ev.pageY;
		}
		else if ( ev.clientX || ev.clientY )
		{
			x = ev.clientX + document.body.scrollLeft;
			y = ev.clientY + jQuery.pageScrollTop(); //document.body.scrollTop;
		}

		return { "x": x, "y": y };
	},

	// Coordinates of mouse in relation to the window
	mouseInWindow: function ( e )
	{
		var ret = {};
		if ( !e )
		{
			var e = window.event;
		}

		if ( e.clientX || e.clientY )
		{
			ret.x = e.clientX - Math.max( 0 , document.body.scrollLeft );
			ret.y = e.clientY - Math.max( 0 , document.body.scrollTop ); // document.body.scrollTop*/  + document.documentElement.scrollTop;
		}
		return ret;
	},

	// Override r with properties from object a
	assocMergeInto: function ( r , a )
	{
		if ( a )
		{
			for( var i in a )
			{
				r[i] = a[i];
			}
		}
		return r;
	},

	// Merge two objects (properties of the second
	// argument override those of the first), result is a new
	// object in memory
	assocMerge: function ( a , b )
	{
	 	return jQuery.assocMergeInto( jQuery.assocMergeInto( {}, a ),  b );
	},

	// Output a datetime
	dateFormat: function ( format , date )
	{
		format = format.replace( /\%Y/ , date.getFullYear() );
		format = format.replace( /\%m/ , date.getMonth() + 1 );
		format = format.replace( /\%d/ , date.getDate() );
		format = format.replace( /\%H/ , date.getHours() );
		format = format.replace( /\%M/ , date.getMinutes() );
		return format;
	},

	// Remove a parameter from the url
	remFromQuery: function ( url , name )
	{
		var reg = new RegExp( '&?' + name + '=[^&]*' );
		url = url.replace( reg, '' );
		return url;
	},


	// Add some query data to a url
	addToQuery: function ( url , data )
	{
		return url + ( url.match( /\?/ ) ? '&' : '?' ) + data;
	},

	// Parse options given inside the attribute of an element
	attrOptions: function ( e , name )
	{
		return eval( "({" + ((e.getAttribute( name ) || '').replace( /,\s*$/ , '' )) + "})" );
	},

	// DEPRECATED: Vertical scroll offset in pixels
	pageScrollTop: function ()
	{
        var pos = jQuery.getScroll();
        return pos.y;
	},

    getScroll: function ()
    {
        var p = {x: 0, y: 0};
        var e = document.documentElement;
        var b = document.body;

        if ( e && ( e.scrollLeft || e.scrollTop ) )
        {
            p.x = e.scrollLeft;
            p.y = e.scrollTop;

        }
        else if ( b && ( b.scrollLeft || b.scrollTop ) )
        {
            p.x = b.scrollLeft;
            p.y = b.scrollTop;
        }
        else if ( window.pageXOffset || window.pageYOffset )
        {
            p.x = window.pageXOffset;
            p.y = window.pageYOffset;
        }
        else if( window.scrollX || window.scrollY )
        {
            p.x = window.scrollX;
            p.y = window.scrollY;
        }
        return p;
    },


	// Calculate x,y position of a given dom element
	getPosition: function ( obj, ignoreRelative )
	{
        ignoreRelative = ignoreRelative || false;

		var curleft = curtop = 0;

		// Hack for IE not needed ?
		// Not sure but this check for IE gave problems in the end
		// Keep the if in until we're sure that it is not needed
		if ( false && jQuery.browser.msie )
		{
			// Hack for IE, naturally
			var childImg = false;
			for ( var i in obj.childNodes )
			{
				childImg = childImg || obj.childNodes[i].tagName == 'IMG';
			}

			if ( childImg )
			{
				curleft -= obj.offsetLeft;
			}
		}

		while ( obj )
		{
			if ( !ignoreRelative || jQuery( obj ).css('position') != "relative" )
			{
				curleft += obj.offsetLeft;
				curtop  += obj.offsetTop;
			}
			obj = obj.offsetParent;
		}
		return { x: curleft, y: curtop };
	},

	// Calculate dimensions of a dom element
	getSize : function(e)
	{
		var w = jQuery.css(e,'width');
		var h = jQuery.css(e,'height');
		var wb = 0;
		var hb = 0;
		es = e.style;

		if ( jQuery(e).css('display') != 'none' )
		{
			wb = e.offsetWidth;
			hb = e.offsetHeight;
		}
		else
		{
			oldVisibility = es.visibility;
			oldPosition = es.position;
			es.visibility = 'hidden';
			es.display = 'block';
			es.position = 'absolute';
			wb = e.offsetWidth;
			hb = e.offsetHeight;
			es.display = 'none';
			es.position = oldPosition;
			es.visibility = oldVisibility;
		}
		return { w:w, h:h, wb:wb, hb:hb };
	},

	// Get an object position from the upper left viewport corner
	elemInWindow: function ( o )
	{
		// Get the positions from the parent object
		var oLeft = o.offsetLeft;
		var oTop  = o.offsetTop;

		// Parse the parent hierarchy up to the document element
		while( o.offsetParent != null )
		{
			oParent	 = 	o.offsetParent;		// Get parent object reference
			oLeft	+=	oParent.offsetLeft;	// Add parent left position
			oTop	+=	oParent.offsetTop;	// Add parent top position
			o = oParent;
		}

		return { l: oLeft , t: oTop };
	},

	validateForm: function ( frm , alrt )
	{
		if ( document.getElementById( frm ) )
		{
			var f = document.getElementById( frm );
		}
		else if ( document.forms[ frm ] )
		{
			var f = document.forms[ frm ];
		}
		else
		{
			f = frm;
		}

		if ( alrt == 'null' )
		{
			alrt = 'All fields are required';
		}

		var isValid		= true;
		var	vFormElems	= new Array();

		for ( i = 0 ; i < f.elements.length ; i++ )
		{
			elem  = f.elements[i];


			vCode = ( elem['alt'] ) ? elem['alt'] : elem.getAttribute('alt');

			if ( !( typeof vCode == 'undefined' || vCode == null || vCode == "" ) )
			{
				if ( jQuery.inArray( elem.name, vFormElems ) == -1)
				{
					v = jQuery.getValue( f.elements[elem.name] );

					if ( vCode == 'required' && v.length < 1 )
					{
						isValid = false;
					}
					vFormElems[i] = elem.name;
				}
			}
		}
		if (!isValid)
		{
			alert( alrt );
		}
		return isValid
	},

	// Returns value of a formfield
	getValue: function ( ffield , def )
	{
		v = '';
		t = ffield.type;

		if( !t )
		{
			t = ffield[0].type;
		}

		if( t == 'checkbox' )
		{
			if( ffield.length )
			{
				for( gv_i=0 ; gv_i < ffield.length ; gv_i++ )
				{
					if ( ffield[gv_i].checked )
					{
						v = ffield[gv_i].value;
					}
				}
			}
			else
			{
				if ( ffield.checked )
				{
					v = ffield.value;
				}
			}
		}
		else if ( t == 'file' )		v = ffield.value;
		else if ( t == 'hidden' )	v = ffield.value;
		else if ( t == 'password' ) v = ffield.value;
		else if ( t == 'radio' )
		{
			if ( ffield.length )
			{
				for ( gv_i=0 ; gv_i < ffield.length ; gv_i++)
				{
					if ( ffield[gv_i].checked ) v = ffield[gv_i].value;
				}
			}
			else
			{
				if ( ffield.checked ) v = ffield.value;
			}
		}
		else if (t == 'select-multiple' ) v = ffield.options[ffield.selectedIndex].value;
		else if (t == 'select-one' )	  v = ffield.options[ffield.selectedIndex].value;
		else if (t == 'text' )			  v = ffield.value;
		else if (t == 'textarea' )		  v = ffield.value;

		if (def != null && v == '')
		{
			return def;
		}
		return v;
	},

	byId: function ( id , doc )
	{
		if ( typeof id == "string" || id instanceof String )
		{
			if ( !doc )
			{
				doc = document;
			}
			return doc.getElementById ( id );
		}
		// assume it's a node
		return id;
	},

	textContent: function ( node )
	{
		var _result = "";
		if (node == null)
		{
			return _result;
		}

		for (var i = 0; i < node.childNodes.length; i++)
		{
			switch (node.childNodes[i].nodeType)
			{
				case 1: // ELEMENT_NODE
				case 5: // ENTITY_REFERENCE_NODE
					_result += jQuery.textContent(node.childNodes[i]);
					break;
				case 3: // TEXT_NODE
				case 2: // ATTRIBUTE_NODE
				case 4: // CDATA_SECTION_NODE
					_result += node.childNodes[i].nodeValue;
					break;
				default:
					break;
			}
		}
		return _result;
	},

	// used in form validator
	// maybe change in the future
	isEmailAddress: function ( v )
	{
		mailvalid = true;
		if ( v.indexOf ( '@' ) < 1 )
		{
			mailvalid = false;
		}
		else if ( v.lastIndexOf ( '.' ) < v.indexOf ( '@' ) )
		{
			isvalid = false;
		}
		aapje  = v.indexOf( '@' );
		puntje = v.indexOf( '.' );
		if ( puntje - aapje == 1 )
		{
			mailvalid = false;
		}
		return mailvalid;
	},

	// used in form validator
	// maybe change in the future
	isSizeSmaller: function ( v , size )
	{
		if ( v.length < size )
		{
			return true;
		}
		else
		{
			return false;
		}
	},

	// used in form validator
	// maybe change in the future
	isSizeGreater: function ( v , size )
	{
		if ( v.length > size )
		{
			return true;
		}
		else
		{
			return false;
		}
	},

	// showhide functions
	// used while rest call state is failed/ok/wait
	showHide: function (str)
	{
		a = str.split(',');
		for ( var i = 0 ; i < a.length ; i++ )
		{
			s = a[i];
			c = s.charAt(0);
			v = 'block';

			if (c == '-')
			{
				v = 'none';
				s = s.substr( 1 , s.length-1);
			}
			else if ( c == '+')
			{
				s = s.substr( 1 , s.length - 1 );
			}

			if ( $( "#" + s ) )
			{
				$("#" + s).css( 'display', v );
			}
		}
	},

	// Hide all obj in an array or string and optionally show obj b (can be an array)
	// Parameters:	a	which obj to hide (can be an array)
	//				b	which obj should openend afterwards (hide all but ...)(can be an array)
	//				s	if s = true search for objects starting with the string 'a'
	hideAllBut: function ( a, b )
	{
		if ( jQuery.isObject( a ) )
		{
			for ( var p in a )
			{
				$( "#" + a[p] ).hide();
			}
		}
		else if ( jQuery.isArray(a) )
		{
			for ( i = 0 ; i < a.length ; i++ )
			{
				$( "#" + a[i] ).hide();
			}
		}
		else if ( jQuery.isString( a ) )
		{
			var d = document.getElementsByTagName( 'div' );
			for( i = 0 ; i < d.length ; i++ )
			{
				var l = a.length;
				var id = d[i].id;
				if ( id.substring( 0 , l ) == a )
				{
					$( "#" + d[i].id ).hide();
				}
			}
		}

		if ( jQuery.isArray( b ) )
		{
			for ( i = 0 ; i < a.length ; i++)
			{
				$( "#" + b[i] ).show();
			}
		}
		else if ( jQuery.isString( b ) )
		{
			$( "#" + b ).show();
		}
	},


	popup: function ( thg_id, o, l, t, w, h )
	{
		if ( l == null ) l = 100;
		if ( t == null ) t = 100;
		if ( w == null ) w = 400;
		if ( h == null ) h = 400;

		var aPopupWin = window.open( '', 'PopupWin', 'scrollbars=yes,menubar=no,location=no,directories=no,statusbar=no,toolbar=no,resizable=yes,width=' + w + ',height=' + h + ',top=' + t + ',left=' + l );
		aPopupWin.document.open();
		aPopupWin.document.close();
		order = '';
		if ( o != null ) order = '&order='+o;
		var p = 'popup.php?id=' + thg_id + order;

		aPopupWin.document.location.href = p;
		if( aPopupWin && !aPopupWin.closed )
		{
			aPopupWin.focus();
		}
	},

	resizePopup: function()
	{
		var mw = 400;

		if ( parseInt( navigator.appVersion.charAt( 0 ) ) >= 4 )
		{
			NN = ( navigator.appName=="Netscape" ) ? 1 : 0;
		}

		if ( document.images[0] )
		{
			ww = ( screen.width  );
			wh = ( screen.height );

			if (NN)
			{
				rw = document.images[0].width + 80;
				rh = document.images[0].height;
				if ( ww < rw ) rw = ww;
				if ( rw < mw ) rw = mw;
				if ( wh < rh ) rh = wh;
				if ( rh < wh - 140 ) rh = rh + 160;
				window.top.innerWidth  = rw;
				window.top.innerHeight = rh;
			}
			else
			{
				rw = document.images[0].width + 80;
				rh = document.images[0].height;
				if ( ww < rw ) rw = ww;
				if ( rw < mw ) rw = mw;
				if ( wh < rh ) rh = wh;
				if ( rh < wh - 140 ) rh = rh + 160;
				window.top.resizeTo( rw, rh );
			}
			parent.window.moveTo( ( screen.width - rw ) / 2, ( screen.height - rh ) / 2 );
		}
	},

	// helper function
	isAlien: function ( a )
	{
		return jQuery.isObject(a) && typeof a.constructor != 'function';
	},

	isArray: function ( a )
	{
		return jQuery.isObject(a) && a.constructor == Array;
	},

	isBoolean: function ( a )
	{
		return typeof a == 'boolean';
	},

	isEmptyObject: function ( o )
	{
		for ( var i in o )
		{
			return false;
		}
		return true;
	},

	isEmpty: function(o)
	{
		var i, v;
		if (jQuery.isObject(o))
		{
			for (i in o)
			{
				v = o[i];
				if (jQuery.isUndefined(v) && jQuery.isFunction(v))
				{
					return false;
				}
			}
		}
		return true;
	},

	isFunction: function ( a )
	{
		return typeof a == 'function';
	},

	isNull: function ( a )
	{
		return typeof a == 'object' && !a;
	},

	isNumber: function ( a )
	{
		return typeof a == 'number' && isFinite(a);
	},

	isObject: function ( a )
	{
		return (a && typeof a == 'object') || jQuery.isFunction(a);
	},

	isString: function ( a )
	{
		return typeof a == 'string';
	},

	isUndefined: function ( a )
	{
		return typeof a == 'undefined';
	},

	isDomElement: function ( a )
	{
		return a && typeof a == 'object' && !jQuery.isUndefined(a.childNodes);
	},

	truncate: function(string, chars, after)
	{
		if (string.length <= chars)
		{
			return string;
		}

		if (typeof after == 'undefined')
		{
			after = '&hellip;';
		}

		string = string.substring(0, chars);
		string = string.replace(/\w+$/, '');

		var re  = new RegExp('[ 	\.\,\:\;\!\?]+$', 'g');
		string  = string.replace(re, '');
		string += ' ' + after;

		return string;
	}
});

// CLASS AjaxNotice
function AjaxNotice( sel )
{
	this.sel = sel;
}

// Start the notice
AjaxNotice.prototype.start = function ( text )
{
	if ( text == '...' )
	{
		text = '<img src="http://static.mediamatic.nl/f/cgcz/image/throbberdots.gif" />';
	}

	text && notice_corner_show( text );
	$( this.sel ).addClass( 'ajax_notice' );
}

// Stop the notice
AjaxNotice.prototype.stop = function ()
{
	notice_corner_hide();
	$( this.sel ).removeClass( 'ajax_notice' );
}

// Make corner notices have unique ids so that timeout events
// only act if the instance that triggered them is still active
window.notice_corner_count = 0;

// Show the notice in the corner of window
function notice_corner_show ( text )
{
	window.notice_corner_count += 1;
	var x = document.getElementById( 'corner_notice' );
	if ( !x )
	{
		x = document.createElement( 'div' );
		x.id = 'corner_notice';
		$( document.body ).append( x );
	}
	$( x ).html( text );
	$( x ).fadeIn(400);

	window.notice_corner_time = (new Date()).getTime();
}

// Hide the notice in the corner of window
function notice_corner_hide ()
{
	window.notice_corner_count -= 1
	if ( window.notice_corner_count > 0 )
	{
		return;
	}
	else
	{
		window.notice_corner_count = 0;
	}
	var now = (new Date()).getTime();
	var dif = now - window.notice_corner_time;
	if ( dif > 1000 )
	{
		$( '#corner_notice' ).fadeOut(400);
	}
	else
	{
		setTimeout(
			function ()
			{
				notice_corner_hide();
			},
			dif
		);
	}
}


// External callback for the documentation functions
function docs_validate()
{
	var lm = jQuery.label( 'editinplace.validate.msg'	, 'Please input a valid value' );
	var lo = jQuery.label( 'editinplace.validate.out'	, 'Value out of range'  );

	return { opts:
		[[ "validate",			{},			"Input format validation" ]
		,[ "validate.regexp",	null,		"Regular expression to validate format" ]
		,[ "validate.name",		null,		"Name of predefined regular expression [integer|float]" ]
		,[ "validate.msg",		lm,			"Alert message to be displayed in case of wrong format" ]
		,[ "validate.min",		null,		"Minimum allowed value" ]
		,[ "validate.max",		null,		"Maximum allowed value" ]
		,[ "validate.empty",	false,		"Input value is allowed to be empty" ]
		,[ "validate.blank",	false,		"Input value is allowed to be empty/whitespace" ]
		,[ "validate.out",		lo,			"Alert message to be displayed in case of out of range number" ]
		]
	};
}

// CLASS Validate
// Used by EditAtOnce and EditInPlace to validate
// the presence or format of some fields
function Validate( opts )
{
	this.opts = opts;
	if ( "integer" == this.opts.name )
	{
		this.opts.msg		= jQuery.label( 'editinplace.validate.integer'	, 'Please input an integer number' );
		this.opts.regexp	= /^\s*[-+]?\d+\s*$/;
	}
	else if ( "float" == this.opts.name )
	{
		this.opts.msg		= jQuery.label( 'editinplace.validate.float'	, 'Please input a number' );
		this.opts.regexp	= /^\s*[-+]?\d+(\.\d+)?\s*$/;
	}
}

// Is the value inside this range?
Validate.prototype.range = function ( value )
{
	var fs 	= {'integer': parseInt, 'float': parseFloat};
	var f 	= fs[this.opts.name] || identity;
	value = f( value );

	return 	!(	this.opts.min && this.opts.min > value
			||	this.opts.max && this.opts.max < value );
}

// Is the value not empty?
Validate.prototype.value = function ( value )
{
	return ( this.opts.blank && value.match( /^\s*$/ ) )
		|| ( this.opts.empty && value == '' )
		|| ( this.opts.regexp && this.opts.regexp.exec( value ) )
		|| ( !this.opts.regexp );
}


// Comment this line to stop server-side reporting of javascript errors
//window.onerror = anyOnError;

window.handlingOnError = false;
window.handledErrors   = [];

// Function used for server-side reporting of javascript errors
function anyOnError( msg , url , line )
{
	var exclude = [ "uncaught exception: Permission denied to get property HTMLInputElement.parentNode"
				  , "uncaught exception: Permission denied to get property HTMLDivElement.parentNode" ];

	// Don't report errors in black list
	for ( var i in exclude )
	{
		if ( exclude[i] == msg )
		{
			jQuery.log( "Error belongs to blacklist, won't report it." );

			// Stop browser from declaring this error
			return true;
		}
	}

	// Don't report same error twice
	for ( var i in window.handledErrors )
	{
		if ( window.handledErrors[i] == msg )
		{
			jQuery.log( "Error already reported once on this session" );

			// Stop browser from declaring same error twice
			return true;
		}
	}

	// Don't report errors that may have happened
	// during the error-processing phase
	// (danger of infinite recursivity)
	if ( window.handlingOnError )
	{
		jQuery.log( "Trying to report an error while already busy reporting another one" );

		// Pass error onto browser
		return false;
	}

	// Lock (informal mutex)
	window.handlingOnError = true;

	jQuery.log( "Reporting error: " + msg );

	// Remember this error
	window.handledErrors.push( msg );

	// Values to send to the server
	var params = {};
	params.msg			= msg;
	params.pageurl		= location.href;
	params.scripturl	= url;
	params.linenumber	= line;
	params.referrer		= document.referrer;

	// Send error report o server
	anyRest.error.log( params ,
		function ( xml )
		{
			jQuery.log( 'Error was reported!' );
			// Unlock (informal mutex)
			window.handlingOnError = false;
		}
	);

	// Pass error onto browser
	return false;
}

// rebuild a scomp ( file ) with a specific dom_id
function rebuild_scp ( ops, xml )
{
	var dom_id	= ops.dom_id;
	var file	= ops.file;
	var thg_id 	= ops.rebuild_scp_thg_id || self.options.id;

	if ( dom_id == null || file == null || thg_id == null )
	{
		jQuery.log('rebuild_scp - please use all parameters: dom_id, file, thg_id');
	}
	else
	{
		var scomp_options = jQuery.assocMerge(
			ops.extra,
			{ 	'name': 		file,
				'thg_id':		thg_id
			}
		);

		anyRest.html.scomp ( scomp_options ,
			function ( xml )
			{
				if (anyRest.aux.error(xml))
				{
					jQuery.log(anyRest.aux.errorMsg(xml));
				}
				else
				{
					var ts = xml.getElementsByTagName( 'html' )[0];
					x = document.getElementById( dom_id );

					if ( ts && x )
					{
						var v = anyRest.aux.concatChildNodes( ts );

						$( x ).after ( v ).remove();

						y = document.getElementById( dom_id );

						init_widgets( y );
					}
					else
					{
						jQuery.log('Internal error: did not get a template from the server or no dom id. Sorry...');
					}
				}
			}
		);
	}
}

// Get a css style attribute for a html node
function anyGetComputedStyle( node , cssSelector , inValue )
{
	var cssSelector = toSelectorCase( cssSelector );
	var property = toCamelCase( cssSelector );
	if( !node || !node.style )
	{
		return inValue;
	}

	else if ( document.defaultView &&
			// mozilla segfaults when margin-* and node is removed from doc
			// FIXME: need to figure out a if there is quicker workaround
			isDescendantOf( node, node.ownerDocument ) )
	{ // W3, gecko, KHTML
		try
		{
			var cs = document.defaultView.getComputedStyle( node , "" );
			if ( cs )
			{
				return cs.getPropertyValue( cssSelector );
			}
		}
		catch( e )
		{ // reports are that Safari can throw an exception above
			if ( node.style.getPropertyValue )
			{ // W3
				return node.style.getPropertyValue( cssSelector );
			}
			else
			{
				return inValue;
			}
		}
	}
	else if ( node.currentStyle )
	{ // IE
		return node.currentStyle[property];
	}
	if ( node.style.getPropertyValue )
	{ // W3
		return node.style.getPropertyValue( cssSelector );
	}
	else
	{
		return inValue;
	}
}



// Change from fontSize to font-size
function toSelectorCase( selector )
{
	return selector.replace(/([A-Z])/g, "-$1" ).toLowerCase();
}


// Change from font-size to fontSize
function toCamelCase ( selector ) {
	var arr = selector.split('-'), cc = arr[0];
	for ( var i = 1 ; i < arr.length ; i++ )
	{
		cc += arr[i].charAt( 0 ).toUpperCase() + arr[i].substring( 1 );
	}
	return cc;
}


// Test if node is descendant of a given ancestor
function isDescendantOf( node, ancestor, guaranteeDescendant )
{
	// guaranteeDescendant allows us to be a "true" isDescendantOf function
	if( guaranteeDescendant && node )
	{
		node = node.parentNode;
	}

	while( node )
	{
		if ( node == ancestor )
		{
			return true;
		}
		node = node.parentNode;
	}
	return false;
}

// Convert these strings '#abc', '#aabbcc', 'abc', etc
// into this string 'aabbcc'
// TODO: Find better name
function validate_hex( s )
{
	s = s.replace( /#/, '' );
	var h3 = s.match(/^[a-fA-F0-9]{3}$/);
	if ( h3 )
	{
		var a = "";
		for ( var i = 0; i < 3; i++ )
		{
			var c = s.slice(i,i+1);
			a += c + c;
		}
		s = a;
	}
	return s;
}

// Get the background color of a dom node and convert it
// into an array of decimal numbers [255,255,255]
// TODO: Find better name
function parse_dec_a( elem, stl )
{
	var stl = stl || 'background-color';
	var color = anyGetComputedStyle( elem, stl );

	if ( color == 'transparent' )
	{
		color = '';
	}
	else
	{
		var ff_fr = ffrgb_s2dec_a( color );

		if ( ff_fr || ff_fr == 'transparent' )
		{
			color = ff_fr;
		}
		else
		{
			color = validate_hex( color );
			color = hex_s2dec_a( color );
		}
	}
	return color;
}

// Convert from firefox-returned color format 'rgb(12,34,12)'
// into an array of decimal numbers [12,34,12]
// TODO: Find better name
function ffrgb_s2dec_a( x )
{
	var a = null;
	var m = x.match(/rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/);

	if ( m )
	{
		a = [];
		for ( var i = 1; i < 4 ; i++ )
		{
			a.push( parseInt( m[i] ) );
		}
	}
	return a;
}

// Make the node in the first argument throb its background color
// using the bkg color of the second argument as the intermediate
function throb( selector, color_example )
{
	var elem = $( selector      ).get( 0 );
	var exmp = $( color_example ).get( 0 );

	if ( !elem || !exmp )
	{
		jQuery.log( 'throb: did not receive the correct arguments' );
		return;
	}

	// Get the base color
	var frcolor = parse_dec_a( elem );
	var tocolor = parse_dec_a( exmp );

	if ( !frcolor || !tocolor )
	{
		jQuery.log( 'throb: color values not parseable' );
		return;
	}


	// Get the start time for animation
	var start = (new Date()).getTime();

	// Total duration of animation
	var total = 5000;

	var anim = function ()
	{
		var diff = (new Date()).getTime() - start;
		if ( diff > total )
		{
			elem.style.backgroundColor = '#' + dec_a2hex_s( frcolor );
		}
		else
		{
			var x = [];
			var f = diff / total;
			var g = ( Math.cos(6 * Math.PI * f + Math.PI) + 1 ) / 2;
			for ( var i = 0; i < 3; i++ )
			{
				x[i] = Math.floor( g * tocolor[i] + (1 - g) * frcolor[i] )
			}
			elem.style.backgroundColor = '#' + dec_a2hex_s( x );
		}
	};
	setInterval( anim, 20 );
}



// Parse a mysql datetime field
// @param	String		datetime	The string containing the datetime value "YYYY-MM-DD HH-MM-SS"
// @return	Date					The parsed value
function mysqlDatetimeToDate ( datetime )
{
   var regex = /^([0-9]{2,4})-([0-1][0-9])-([0-3][0-9]) (?:([0-2][0-9]):([0-5][0-9]):([0-5][0-9]))?$/;
   var parts = datetime.replace( regex, "$1 $2 $3 $4 $5 $6" ).split( ' ' );
   return new Date( parts[0], parts[1] - 1, parts[2], parts[3], parts[4], parts[5] );
}



// Show a date relative to a given moment
// @param	Date		date		The date to represent
// @param	Date		now			Optional, used as reference, default new Date()
// @return	String					The formatted string
function showDateRelative( date, now )
{
	now = now || new Date();
	var prefix = '';
	if ( date.getFullYear() != now.getFullYear() || date.getMonth() != now.getMonth() || date.getDay() != now.getDay() )
	{
		prefix = '' + date.getFullYear() + '/' + ( date.getMonth() + 1 ) + '/' + date.getDate() + ' ';
	}
	return prefix + lpad( date.getHours(), 2, '0' ) + ':' + lpad( date.getMinutes(), 2, '0' );
}



// Left-pad a string to a desired length
// @param	String		s		The string to pad
// @param	Number		n		Final length of resulting string
// @param	String		c 		The character to repeat
// @return	String				The padded string
function lpad( s, n, c )
{
	// Make sure it is a string
	s = '' + s;

	while ( s.length < n )
	{
		s = c + s;
	}
	return s
}

// Convert [255,255,255] into 'ffffff'
// TODO: Find better name
function dec_a2hex_s( a )
{
	var x = '';
	for ( var i in a )
	{
		x += lpad( dec2hex( a[i] ), 2, '0' );
	}
	return x;
}

// Convert 'ffffff' into [255,255,255]
// TODO: Find better name
function hex_s2dec_a( s )
{
	var r = [];
	for ( var i = 0; i <= 4; i += 2 )
	{
		r.push( hex2dec( s.slice( i, i + 2 ) ) );
	}
	return r;
}

// Convert a decimal number/string into a hex string
function dec2hex( x )
{
	x = parseInt( x );
	var m = 16;
	var s = '';
	while ( x > 0 )
	{
		r = x % m;
		r = r > 9 ? "abcdef".slice( r-10, r-9 ) : '' + r;
		s = r + s;
		x = Math.floor( x / m );
	}
	return s;
}

// Convert a hex string into a decimal number
function hex2dec( x )
{
	x = '' + x;
	x = x.toLowerCase();
	s = "0123456789abcdef";
	n = 0;
	for ( var i = 0; i < x.length; i++ )
	{
		n = n * 16 + s.indexOf( x.slice(i,i+1) );
	}
	return n;
}

// Convert an array to string using a separator in between
function implode( arr, sep )
{
    var ret = ''
    for ( var i = 0; i < arr.length; i++ )
    {
        ret += ( i > 0 ? sep : '' ) + arr[i];
    }
    return ret;
}

function strip( str )
{
	str = str || '';
	str = str.replace( /^\s+/g, "" );
	str = str.replace( /\s+$/g, "" );
	return str;
}

jQuery.fn.extend({
	everyTime: function(interval, label, fn, times, belay) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, times, belay);
		});
	},
	oneTime: function(interval, label, fn) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, 1);
		});
	},
	stopTime: function(label, fn) {
		return this.each(function() {
			jQuery.timer.remove(this, label, fn);
		});
	}
});

jQuery.extend({
	timer: {
		guid: 1,
		global: {},
		regex: /^([0-9]+)\s*(.*s)?$/,
		powers: {
			// Yeah this is major overkill...
			'ms': 1,
			'cs': 10,
			'ds': 100,
			's': 1000,
			'das': 10000,
			'hs': 100000,
			'ks': 1000000
		},
		timeParse: function(value) {
			if (value == undefined || value == null)
				return null;
			var result = this.regex.exec(jQuery.trim(value.toString()));
			if (result && result[2]) {
				var num = parseInt(result[1], 10);
				var mult = this.powers[result[2]] || 1;
				return num * mult;
			} else {
				return value;
			}
		},
		add: function(element, interval, label, fn, times, belay) {
			var counter = 0;

			if (jQuery.isFunction(label)) {
				if (!times)
					times = fn;
				fn = label;
				label = interval;
			}

			interval = jQuery.timer.timeParse(interval);

			if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
				return;

			if (times && times.constructor != Number) {
				belay = !!times;
				times = 0;
			}

			times = times || 0;
			belay = belay || false;

			if (!element.$timers)
				element.$timers = {};

			if (!element.$timers[label])
				element.$timers[label] = {};

			fn.$timerID = fn.$timerID || this.guid++;

			var handler = function() {
				if (belay && this.inProgress)
					return;
				this.inProgress = true;
				if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
					jQuery.timer.remove(element, label, fn);
				this.inProgress = false;
			};

			handler.$timerID = fn.$timerID;

			if (!element.$timers[label][fn.$timerID])
				element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);

			if ( !this.global[label] )
				this.global[label] = [];
			this.global[label].push( element );

		},
		remove: function(element, label, fn) {
			var timers = element.$timers, ret;

			if ( timers ) {

				if (!label) {
					for ( label in timers )
						this.remove(element, label, fn);
				} else if ( timers[label] ) {
					if ( fn ) {
						if ( fn.$timerID ) {
							window.clearInterval(timers[label][fn.$timerID]);
							delete timers[label][fn.$timerID];
						}
					} else {
						for ( var fn in timers[label] ) {
							window.clearInterval(timers[label][fn]);
							delete timers[label][fn];
						}
					}

					for ( ret in timers[label] ) break;
					if ( !ret ) {
						ret = null;
						delete timers[label];
					}
				}

				for ( ret in timers ) break;
				if ( !ret )
					element.$timers = null;
			}
		}
	}
});

if (jQuery.browser.msie)
	jQuery(window).one("unload", function() {
		var global = jQuery.timer.global;
		for ( var label in global ) {
			var els = global[label], i = els.length;
			while ( --i )
				jQuery.timer.remove(els[i], label);
		}
	});


// rounded corners

	// adds 4 spans to element, positions using css in utils.css
	/*  EXAMPLE

	if( $.browser.msie){
		// add rounded corners to these elements for IE
		$('.list-context li').rounded_corners();
	};
	// add rounded corners to these elements for all browsers
	$('.fig li').rounded_corners();

	*/

	$.fn.rounded_corners = function(){
		if (!$(this).length)
		return false;

		$(this)
			.css({position: 'relative'})
			.hover(function(){
				$(this).addClass('cnrs-hovered');
			},function(){
				$(this).removeClass('cnrs-hovered');
			});

		$('<span class="cnrs cnr_nw"></span><span class="cnrs cnr_ne"></span><span class="cnrs cnr_sw"></span><span class="cnrs cnr_se"></span>')
		.css({ // will only accept numeric border widths
	 		marginTop: 		'-'+(parseInt($(this).css('border-top-width'))||0),
	 		marginRight: 	'-'+(parseInt($(this).css('border-right-width'))||0),
	 		marginBottom: 	'-'+(parseInt($(this).css('border-bottom-width'))||0),
	 		marginLeft: 	'-'+(parseInt($(this).css('border-left-width'))||0)
	 	})
		.appendTo(this);
		// ie odd values bug fix
		if( $.browser.msie && $.browser.version < 7){
			$(this).each(function(){
				var h = $(this).height();
				if (h%2){ $('.cnr_sw',this).css({bottom: '-1px'});$('.cnr_se',this).css({bottom: '-1px'}); };
				var w = $(this).width();
				if (w%2){ $('.cnr_ne',this).css({right: '-1px'});$('.cnr_se',this).css({right: '-1px'}); };
			});
		};
	};

// hoverintent plugin
;(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};cfg=$.extend(cfg,g?{over:f,out:g}:f);var cX,cY,pX,pY;var track=function(ev){cX=ev.pageX;cY=ev.pageY;};var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);ob.hoverIntent_s=1;return cfg.over.apply(ob,[ev]);}else{pX=cX;pY=cY;ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}};var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);ob.hoverIntent_s=0;return cfg.out.apply(ob,[ev]);};var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;while(p&&p!=this){try{p=p.parentNode;}catch(e){p=this;}}if(p==this){return false;}var ev=jQuery.extend({},e);var ob=this;if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);}if(e.type=="mouseover"){pX=ev.pageX;pY=ev.pageY;$(ob).bind("mousemove",track);if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);},cfg.interval);}}else{$(ob).unbind("mousemove",track);if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);},cfg.timeout);}}};return this.mouseover(handleHover).mouseout(handleHover);};})(jQuery);

// caret plugin (http://cloudgen.w0ng.hk/jquery/caret.php)
;(function($){$.fn.caret=function(options,opt2){var start,end,t=this[0];if(typeof options==="object"&&typeof options.start==="number"&&typeof options.end==="number"){start=options.start;end=options.end}else if(typeof options==="number"&&typeof opt2==="number"){start=options;end=opt2}else if(typeof options==="string"){if((start=t.value.indexOf(options))>-1){end=start+options.length}else start=null}else if(Object.prototype.toString.call(options)==="[object RegExp]"){var re=options.exec(t.value);if(re!=null){start=re.index;end=start+re[0].length}};if(typeof start!="undefined"){if($.browser.msie){var selRange=this[0].createTextRange();selRange.collapse(true);selRange.moveStart('character',start);selRange.moveEnd('character',end-start);selRange.select()}else{this[0].selectionStart=start;this[0].selectionEnd=end};this[0].focus();return this}else{if($.browser.msie){var val=this.val();var range=document.selection.createRange().duplicate();range.moveEnd("character",val.length);var s=(range.text==""?val.length:val.lastIndexOf(range.text));range=document.selection.createRange().duplicate();range.moveStart("character",-val.length);var e=range.text.length}else var s=t.selectionStart,e=t.selectionEnd;var te=t.value.substring(s,e);return{start:s,end:e,text:te,replace:function(st){return t.value.substring(0,s)+st+t.value.substring(e,t.value.length)}}};return this}})(jQuery)

// no queue in animation plugin
;(function($)
{
	$.fn.animnoq = function(type, prop, speed, easing, callback)
	{
		if($.inArray(type, ['mouseover', 'mouseenter', 'mouseout', 'mouseleave']) == -1) { return this; }

		var opt = typeof speed === 'object' ? speed : { complete: callback || !callback && easing || $.isFunction(speed) && speed, duration: speed, easing: callback && easing || easing && !$.isFunction(easing) && easing }
		opt.queue = false;
		var origCallback = opt.complete;

		opt.complete = function()
		{
			$(this).dequeue();
			if($.isFunction(origCallback)) origCallback.call(this);
		}

		return this.each(function()
		{
			var $this = $(this);

			if(type == 'mouseover' || type == 'mouseenter')
			{
				$this.data('jQuery.animnoq', true);
			}
			else
			{
				$this.removeData('jQuery.animnoq');
			}

			$this.queue(function()
			{
				var condition = (type == 'mouseover' || type == 'mouseenter') ? $this.data('jQuery.animnoq') !== undefined : $this.data('jQuery.animnoq') === undefined;
				if(condition) { $this.animate(prop, opt); } else { $this.queue([]); }
			});
		});
	};
})(jQuery);

// Empty value on click
// Return value when blur and no value
(function($)
{
	$.fn.onEmptyValue = function(value)
	{
		$(this).each(function()
		{
			var $obj			= $(this);
			var defaultValue	= value   || $obj.val();
			
			$obj.data('defaultValue', defaultValue);

			var hasDefaultValue = function()
			{
				return $obj[0].value == defaultValue;
			}
			
			// Function: value changed
			var markValue = function()
			{
				if (hasDefaultValue())
				{
					$obj.addClass('text-default');
				} else
				{
					$obj.removeClass('text-default');
				}
			};
						
			// Function: Remove default value
			var removeDefaultValue = function()
			{
				if (hasDefaultValue())
				{
					$obj.val('');
					markValue();
				}
			};
			
			// Function: Restore default value when empty
			var restoreDefaultValue = function()
			{
				if ($obj.val() == '' || hasDefaultValue())
				{
					$obj.val(defaultValue);
					markValue();
				}
			};
			
			// Start by marking field correctly
			markValue();

			// Focus: delete if value is default value
			$obj.focus(removeDefaultValue);
			
			// Blur: restore default value
			$obj.blur(restoreDefaultValue);
			
			// Change: if value is using by javascript
			$obj.change(markValue);
			
			// Parent form submit: delete if value is default value
			$obj.parents('form:eq(0)').submit(removeDefaultValue);
		});
	};

	var originalVal = jQuery.fn.val;
	jQuery.fn.val = function(value)
	{
		var elem = this[0];
		
		if (typeof $(elem).data('defaultValue') != 'undefined') 
		{
			if (typeof value != 'undefined')
			{
				// setter
				elem.value = value;
				return this;
			} else
			{
				// getter
				if (jQuery(elem).data('defaultValue') == elem.value)
				{
					return '';
				}
				return elem.value;
			}
		}
		else
		{
			return originalVal.call(this, value);
		}
	};

})(jQuery);


/*  */
//
;(function($)
{
    /**
     * Anymeta Javascript User Interface elements.
     */
    if (!$.any) $.any = {};

    /**
     * Register a class for a new User Interface element. Anymeta user interface elements are regular jquery UI elements, but to prevent scoping issues their names are prefixed with any_.
     */
    $.any.ui = function ( base, ui_def, defaults )
    {
        var widget = "ui.any_" + base;

        /*
         * This is the prototype for every UI class.
         */
        var ui_prototype =
        {
            /**
             * Retrieve the parent UI element. Convenience function
             * when creating nested UI elements which have to
             * interact.
             */
            parent: function ()
            {
                return $.any.ui.getWidget(this.element[0].parentNode);
            },

            /**
             * Throw a certain event. This will fire the callback
             * function on every listener that matches this event.
             * Event "matching" works as follows: the event that is
             * broadcasted must contain every key in the event
             * pattern, and they should all match.
             *
             * The pattern: {id: 1} matches to the event {id: 1, foo: bar} but not to {id: 2}
             */
            publish: function ( event )
            {
                for (var i=0; i<$.any.ui._listeners.length; i++)
                {
                    var ev = $.any.ui._listeners[i];

                    if ($.any.ui._eventMatch(event, ev[0]) && this != ev[1])
                    {
                    	ev[2](event, this);
                    }
                }
            },

            /**
             * Listen for a certain event pattern. Events are simple
             * dicts containing values.
             */
            subscribe: function ( event_pattern, callback )
            {
                $.any.ui._listeners.push([event_pattern, this, callback]);
            },


            /**
             * Post-initialization function
             */
            _postInit: function ()
            {
            }
        };

        ui_def = $.extend(ui_prototype, ui_def);

        // Instantiate the jQuery UI widget
        $.widget(widget, ui_def);

        // This is the place where UI elements can put static data and functions.
        $.any.ui[base] = {};

        if (typeof defaults == "object")
        {
            $.any.ui.defaults[base] = defaults;
        }
    };


    $.extend($.any.ui,
    {
        defaults: {},

	    /**
         * Scan a context for UI widgets, and instantiate them.
         */
        scan: function(context)
	    {
            // FIXME: remove ALL old widgets and then remove these three lines.
            init_widgets(context);
            return;

		    context 	= context || document.body;
		    var stack 	= [context];
            var widgets = [];

		    while(stack.length > 0)
		    {
			    var objectClass, objectOptions, defaults, element = stack.pop();
			    if(element.className && (objectClass = new RegExp("ui_([\\w_]+)", "g").exec(element.className)))

			    {
				    var base = objectClass[1];
                    widgets.push($.any.ui._instantiate(element, base));
			    }

			    if(element.childNodes)
			    {
				    for(var i = 0; i< element.childNodes.length; i++)
				    {
					    if(element.childNodes[i].nodeType != 3)
					    {
						    stack.unshift(element.childNodes[i]);
					    }
				    }
			    }
		    }
            $.each(widgets, function(i,widget) { widget._postInit(); });
		},

        _instantiate: function ( element, base )
        {
            var widget = "any_" + base;

			if(typeof $(element)[widget] == "function")
			{
                var options = {};
				if(typeof $.any.ui.defaults[base] == "object")
				{
					options = $.any.ui.defaults[base];
				}

				options = $.extend({}, options, $(element).metadata());
                // Create the instance
				$(element)[widget](options);
                var ui = $(element).data(widget);
                // Set the "base" attribute so we know what kind of widget we are
                ui.base = base;
                // Tie the widget to the element, so we can look it up later.
                $(element).data("ui", ui);
                return ui;
			}
            else
            {
                // FIXME: should we also try to instantiate "regular" jQuery.UI widgets?
                throw('Programming error: unknown $.any.ui widget: ' + base);
            }
        },

        /**
         * This function lets you retrieve the first UI instance which
         * is a within the given DOM node.
         *
         * <button onclick="$.any.ui.getWidget(this).callBla()">Bla</button>
         */
        getWidget: function ( element )
        {
            while (element)
            {
                var ui = $(element).data("ui");
                if (ui)
                {
                    return ui;
                }
                element = element.parentNode;
            }
            return null;
        },


        _listeners: [],

        _eventMatch: function ( the_event, check_event )
        {
            if (typeof check_event == "string" && typeof the_event == "string")
            {
                return check_event == the_event;
            }
            else if (typeof check_event == "object" && typeof the_event == "object")
            {
                for (var k in check_event)
                {
                    if (typeof the_event[k] == "undefined"
                        || the_event[k] != check_event[k])
                    {
                        return false;
                    }
                }
            }
            else
            {
                // Mixing different event types..
                return false;
            }
            return true;
        }

    });


    /**
     * jQuery Metadata extension.
     */
    $.extend(
	{
		metadata:
		{
			defaults: {
				type: 'class',
				name: 'metadata',
				cre: /({.*})/,
				single: 'metadata'
			},

			setType: function(type, name)
			{
				this.defaults.type = type;
				this.defaults.name = name;
			},

			get: function(elem, opts)
			{
				var settings = $.extend({}, this.defaults, opts);

				// check for empty string in single property
				if(!settings.single.length)
				{
					settings.single = 'metadata';
				}

				var data = $.data(elem, settings.single);

				// returned cached data if it already exists
				if(data)
				{
					return data;
				}

				data = "{}";

				if(settings.type == "class")
				{
					var m = settings.cre.exec(elem.className);
					if(m)
					{
						data = m[1];
					}
				}
				else if(settings.type == "elem")
				{
					if(!elem.getElementsByTagName)
					{
						return;
					}

					var e = elem.getElementsByTagName(settings.name);

					if(e.length)
					{
						data = $.trim(e[0].innerHTML);
					}
				}
				else if(elem.getAttribute != undefined)
				{
					var attr = elem.getAttribute(settings.name);
					if(attr)
					{
						data = attr;
					}
				}

				if(data.indexOf( '{' ) < 0)
				data = "{" + data + "}";

				data = eval("(" + data + ")");

				$.data(elem, settings.single, data);
				return data;
			}
		}
	});

	$.fn.metadata = function(opts)
	{
		return $.metadata.get( this[0], opts );
	};

})(jQuery);

//
//
//
// any.rest

// Methods that do not fall inside the standard anyrest call style
var anyRest = {
	'aux':
	{
		'items': function ( xml )
		{
			var rsp = xml.getElementsByTagName( 'rsp' )[0];
			var rst = [];
			for ( var i = 0 ; i < rsp.childNodes.length ; i++ )
			{
				if ( rsp.childNodes[i].tagName == 'item' )
				{
					rst.push( rsp.childNodes[i] );
				}
			}
			return rst;
		},

		'status': function ( xml )
		{
			var rsp = xml.getElementsByTagName( 'rsp' );
			return rsp[0].getAttribute( 'stat' );
		},

		'error': function ( xml )
		{
			return ( anyRest.aux.status( xml ) != 'ok' );
		},

		'errorMsg': function ( xml )
		{
			var es = xml.getElementsByTagName( 'msg' );
			return es[0] ? es[0].getAttribute( 'msg' ) : '';
		},

		'skeleton': function ( type , params , callback )
		{
			params.format = params.format || "xml";
			callback = callback || function ( _ ) {};

			var no_notification_check = false;
			if (params.no_notification_check)
			{
				var no_notification_check = true;
				delete params.no_notification_check;
			}

			var opts = {
				"type": type,
				"url": 	"http://travel.mediamatic.net/services/rest/"
			};

			if ( type == 'GET' )
			{
				opts.url += '?' + $.any.rest.xparam( params );
			}

			if ( type == 'POST' )
			{
				opts.data = $.any.rest.xparam( params );
			}

			opts.success = function restSuccess ( data )
			{
			    if (type == 'POST' && !no_notification_check)
			    {
                    $.any.notification.notifyCheck();
			    }

			    callback( data );
			}
			opts.error = function restError ( request, text, errorThrown )
			{
				if (request.status == 401)
				{
					var loc = request.getResponseHeader('X-Authorize-Location');
					if (!loc)
					{
						return false;
					}

					$( "#throbberwait" ).remove();

					var target = document;
					if (LightboxHelper.isLightbox())
					{
						target = window.parent.document;
					}

					// Append return_to to callback URI
					if (loc.match(/\?/))
					{
						loc = loc + '&';
					}
					else
					{
						loc = loc + '?';
					}
					loc = loc + 'return_to=' + target.location.href;
					target.location = loc;

				}
			}

			jQuery.ajax( opts );
		}
	}
};

anyRest.aux.concatChildNodes = function ( xmldom )
{
	var str = '';
	for ( var i = 0; i < xmldom.childNodes.length ; i++ )
	{
		str += xmldom.childNodes[i].nodeValue;
	}
	return str;
};


// POST
// List of anymeta REST methods, indexed by their name prefix and http verbs
var batch = [
	['anymeta.','POST',
		['edge.attribute.get'
		,'edge.attribute.set'
		,'edge.add'
		,'edge.remove'
		,'edge.order'
		,'edge.addList'
		,'error.log'
		,'tags.add'
		,'predicates.get'
		,'predicates.set'
		,'messages.send'
		,'user.check'
		,'thing.insert'
		,'thing.update'
		,'thing.duplicate'
		]],
	['','POST',
		['contact.add'
		,'contact.change'
		,'contact.remove'
		]],
	['','POST',
		['jury.accuse'
		]],
	['anymeta.','GET',
		['html.template'
		,'html.scomp'
		,'search.live'
		]]]

for ( var i in batch )
{
	// For each of the REST methods, generate a javascript method with the same name.
	// Mostly here for backwards compatibility, this additional style freedom is not
	// particularly welcome
	var prefix = batch[i][0];
	var http_method = batch[i][1];
	var lis = batch[i][2];

	for ( var j in lis )
	{
		var words = lis[j].split('.');
		var tmp = anyRest;
		for ( var k = 0; k < words.length - 1; k++ )
		{
			if ( !tmp[words[k]] )
			{
				tmp[words[k]] = {};
			}
			tmp = tmp[words[k]];
		}

		tmp[words[words.length-1]] = makeRestMethod( http_method, prefix + lis[j] );

	}
}

// Produces a ajax method to communicate with anymeta REST services
function makeRestMethod( http_method, rest_method )
{
	return function ( params, callback )
	{
		params.method = rest_method;
		anyRest.aux.skeleton( http_method, params, callback );
	}
}

anyRest.service = function ( name, opts, callback )
{
	opts.method = name;
	anyRest.aux.skeleton( 'POST' , opts , callback );
};

anyRest.call = function ( opts, callback )
{
	anyRest.aux.skeleton( 'POST' , opts , callback );
};

anyRest.post = function ( name, opts, callback )
{
	opts.method = name;
	anyRest.aux.skeleton( 'POST' , opts , callback );
};

anyRest.get = function ( name, opts, callback )
{
	opts.method = name;
	anyRest.aux.skeleton( 'GET' , opts , callback );
};


/** Start of the newstyle rest functions */
;(function($)
{
    if (!$.any) $.any = {};
    $.extend($.any,
    {
        rest:
        {
            init: function (userId)
            {
                $.any.rest.userId = userId;

                $(window).bind('ajaxStart', $.any.notification.loader.start);
                $(window).bind('ajaxStop', $.any.notification.loader.stop);
            },


            /**
             * Require the user to be logged on. If this is not the case,
             * we redirect to the logon URI; appending the current URI as
             * the 'goto' uri + extra arguments that are passed into this
             * function.
             * @return true if we are redirecting, otherwise false.
             */
            requireLogon: function( ret_args )
            {
                if ($.any.rest.userId == 0)
                {
                    var uri = "/logon";
                    var go = document.location.href + '';
                    // Only keep the URL path part
                    go = go.replace(new RegExp('^.*?://.*?(/.*)$'), '$1');

				    go += go.match(/\?/) ? '&' : '?';
                    if (ret_args)
                    {
                        go += $.any.rest.xparam(ret_args);
                    }

                    uri += "?goto=" + escape(go);
                    $.any.rest.redirect(uri);
                    return true;
                }
                return false;
            },

            /**
             * Call the api using HTTP POST. The callback function gets a
             * JSON object with the result; or, when an (API or HTTP)
             * error has been detected, the errback function is called.
             */
            post: function (method, params, callback, errback, notifycallback)
            {
                $.any.rest._doMethod('POST', method, params, callback, errback, notifycallback);
            },


            /**
             * Call the api using HTTP GET. The callback function gets a
             * JSON object with the result; or, when an (API or HTTP)
             * error has been detected, the errback function is called.
             */
            get: function (method, params, callback, errback, notifycallback)
            {
                $.any.rest._doMethod('GET', method, params, callback, errback, notifycallback);
            },


            /**
             * Internal function for handling the API calls.
             */
          _doMethod: function(verb, api_method, params, callback, errback, notifycallback)
            {
			    var opts = {
				    "type": verb.toUpperCase(),
				    "url": 	"http://travel.mediamatic.net/services/rest/"
			    };

                params['format'] = 'json';
                params['method'] = api_method;
			    params['_n'] = '1'; // we want notifications

			    if ( opts.type == 'GET' )
			    {
				    opts.url += '?' + $.any.rest.xparam( params );
			    }

			    if ( opts.type == 'POST' )
			    {
				    opts.data = $.any.rest.xparam( params );
			    }

			    opts.success = function ( data )
			    {
                    data = eval('(' + data + ')');

                    if (data['_n'])
                    {
                        // We got notifications
                        for (var i=0; i<data['_n'].length; i++)
                        {
                            var notice = data['_n'][i];

                            if (typeof notifycallback == 'function')
                            {
                                notifycallback(notice);
                            }
                        }
                    }

                    if (data.err && data.err['-attrib-'])
                    {
                        var error = {code:    data.err['-attrib-'].code,
                                     message: data.err['-attrib-'].msg};
                        if (typeof errback == 'function')
                        {
                            errback(error);
                            return;
                        }

                        // No errback, shout out to the world this was not right.
                        $.any.rest.unhandledError(error);
			        }

                    if (typeof callback == 'function')
                    {
			            callback( data );
                    }
			    };

			    opts.error = function ( request, text, errorThrown )
			    {
				    if (request.status == 401)
				    {
					    var loc = request.getResponseHeader('X-Authorize-Location');
                        if (loc)
                        {
					        // Append return_to to callback URI
					        if (loc.match(/\?/))
					        {
						        loc = loc + '&';
					        }
					        else
					        {
						        loc = loc + '?';
					        }
					        loc = loc + 'return_to=' + document.location.href;
					        document.location = loc;
                            return;
                        }
				    }

                    var error = {'code': request.status, 'type': 'http', 'message': text};
                    if (typeof errback == 'function')
                    {
                        errback(error);
                        return;
                    }

                    $.any.rest.unhandledError(error);
			    };

			    $.ajax( opts );
            },

            /**
             * Redirect to a URL.
             */
            redirect: function ( url )
            {
                $.any.notification.loader.start();
                document.location.href = url;
            },


            /**
             * This function is called when a REST error has not been
             * handled by the caller (e.g., no error callback was
             * given).
             */
            unhandledError: function ( error )
            {
                $.any.notification.error(error.message);
                $.any.notification.loader.stop();
                throw error.code + ": " + error.message;
            },

	        /**
             * Encode object for get/post request: works with
             * arbitrarily-leveled-nested arrays and objects. Adapted
             * from PHP (any_functions' http_build_query)
             */
	        xparam: function (params)
	        {
		        var encoder_f = function (f, name, value, sep, uri)
		        {
                    if (value === null)
                    {
                        // Ignore value
                    }
			        else if (value.constructor == Array)
			        {
				        for ( var i = 0 ; i < value.length ; i++ )
				        {
					        f(f, name + '[' + i + ']', value[i], sep, uri);
				        }
			        }
			        else if ( value.constructor == Object )
			        {
				        for ( var i in value )
				        {
					        f(f, name + '[' + i + ']', value[i], sep, uri);
				        }
			        }
			        else
			        {
				        uri.uri += sep.sep + name + '=' + encodeURIComponent(value);
				        sep.sep = '&';
			        }
		        };

		        // Hack for simulating call-by-reference in JavaScript
		        var sep = {sep:''};
		        var uri = {uri:''};

		        for ( var i in params )
		        {
			        encoder_f(encoder_f, i, params[i], sep, uri);
		        }

		        return uri.uri;
	        }
	    }
    });
})(jQuery);
//
/*  */

/*  */

// Notes
// ULs and LIs margin values are set to 0
// LIs get display: block
// Style the menu and get it working first with CSS, then add this JS to make it nicer

// External callback to initialize the widget
// @param	mixed	container	jQuery selector for the object to be used
// @param	dom		context		DOM object used as jQuery context. Defaults to document.body
function init_menu( container, context )
{
	context = context || document.body;
	
	$( container, context ).each( 
		function () 
		{
			var opts = "";
			opts = jQuery.attrOptions( this , "menu" );
			new Menu( this, opts );
		}
	);
}

// External callback for the documentation functions
// @return  object Structure containing 'examples' of usage, 'about' message, default 'opts', and 'classes' (never used...)
function docs_menu()
{
	var a = "Dynamic cascading menu item. Notes: Get it working with CSS only first, then use this file to make it nice.";
	var e = [
		['<ul class="do_menu" menu="animationOver: {ldelim}height:\'show\',opacity: .9{rdelim}, speedOver: 400, dropShadows: true">\n<li>A.root\n\t<ul>\n\t<li>A.1</li>\n\t<li>A.2</li>\n\t</ul>\n</li>\n<li>B.root\n\t<ul>\n\t<li>B.1</li>\n\t</ul>\n</li>\n</ul>',
		"Superfish menu"]
	];
	var c = [];
	
	var o = 
	[[ "hoverClass", 	'sfHover', 		 				"the class applied to hovered list items" ]
	,[ "pathClass", 	'overideThisToUse',				"the class you have applied to list items that lead to the current page" ]
	,[ "pathLevels", 	1,								"the number of levels of submenus that remain open or are restored using pathClass" ]
	,[ "delay",  		400,							"the delay in milliseconds that the mouse can remain outside a submenu without it closing" ]
	,[ 'animationOver',	{height:'show'},				"exmp: {opacity:.85}, {height:'show'}, Animation on mouse over. See jQueryÍs .animate() method" ]
	,[ "speedOver",		300, 			 				"speed of the mouse over animation (in milliseconds). Equivalent to second parameter of jQueryÍs .animate() method" ]
	,[ 'animationOut',	{opacity:'hide',height:'hide'},	"{opacity:'hide'}, {height:'hide'}, Animation on mouse out" ]
	,[ "speedOut", 		200, 			 				"speed of the mouse out animation (in milliseconds). Equivalent to second parameter of jQueryÍs .animate() method" ]
	,[ "autoArrows",	false, 			 				"if true, arrow mark-up generated automatically. Will add .sf-with-ul to anchor of parent. " ]
	,[ "dropShadows",	false, 			 				"completely disable drop shadows by setting this to false" ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}


// Process the options for this widget (cached)
// @param   object  o   Widget options extracted from the html
// @return  object      Default options overriden by html options
function opts_menu( o )
{
	return apply_options( docs_menu().opts, o );
}



function Menu( container, opts )
{
	opts			= opts_menu( opts );
	this.container	= container;
	this.opts		= opts;
	
	
	$(container).superfish(
	{
		hoverClass: 	this.opts.hoverClass,
		pathClass: 		this.opts.pathClass,
		pathLevels: 	this.opts.pathLevels,
		delay: 			this.opts.delay,
		animationOver:	this.opts.animationOver,
		speedOver:		this.opts.speedOver,
		animationOut:	this.opts.animationOut,
		speedOut:		this.opts.speedOut,
		autoArrows: 	this.opts.autoArrows,
		dropShadows:	this.opts.dropShadows
	}	
	);	
	
}

;(function($){
	$.fn.superfish = function(op){

		var sf = $.fn.superfish,
			c = sf.c,
			$arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
			over = function(){
				var $$ = $(this), menu = getMenu($$);
				clearTimeout(menu.sfTimer);
				$$.showSuperfishUl().siblings().hideSuperfishUl();
			},
			out = function(){
				var $$ = $(this), menu = getMenu($$), o = sf.op;
				clearTimeout(menu.sfTimer);
				menu.sfTimer=setTimeout(function(){
					o.retainPath=($.inArray($$[0],o.$path)>-1);
					$$.hideSuperfishUl();
					if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
				},o.delay);	
			},
			getMenu = function($menu){
				var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
				sf.op = sf.o[menu.serial];
				return menu;
			},
			addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
			
		return this.each(function() {
			var s = this.serial = sf.o.length;
			var o = $.extend({},sf.defaults,op);
			o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
				$(this).addClass([o.hoverClass,c.bcClass].join(' '))
					.filter('li:has(ul)').removeClass(o.pathClass);
			});
			sf.o[s] = sf.op = o;
			
			$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
				if (o.autoArrows) addArrow( $('>a:first-child',this) );
			})
			.not('.'+c.bcClass)
				.hideSuperfishUl();
			
			var $a = $('a',this);
			$a.each(function(i){
				var $li = $a.eq(i).parents('li');
				$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
			});
			o.onInit.call(this);
			
		}).each(function() {
			menuClasses = [c.menuClass];
			if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
			$(this).addClass(menuClasses.join(' '));
		});
	};

	var sf = $.fn.superfish;
	sf.o = [];
	sf.op = {};
	sf.IE7fixAdd = function(){
		var o = sf.op;
		if ($.browser.msie && $.browser.version > 6 && o.dropShadows )
			this.addClass(sf.c.shadowClass+'-off');
		};
	sf.IE7fixRemove = function(){
		var o = sf.op;
		if ($.browser.msie && $.browser.version > 6 && o.dropShadows )
			this.removeClass(sf.c.shadowClass+'-off');
		};
	sf.c = {
		bcClass     : 'sf-breadcrumb',
		menuClass   : 'sf-js-enabled',
		anchorClass : 'sf-with-ul',
		arrowClass  : 'sf-sub-indicator',
		shadowClass : 'sf-shadow'
	};
	sf.defaults = {
		disableHI	: true,		// true disables hoverIntent detection
		onInit		: function(){}, // callback functions
		onBeforeShow: function(){},
		onShow		: function(){},
		onHide		: function(){}
	};
	$.fn.extend({
		hideSuperfishUl : function(){
			var o = sf.op,
			not = (o.retainPath===true) ? o.$path : '';
			o.retainPath = false;
			
			var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).find('>ul:visible')
			sf.IE7fixAdd.call($ul);		
			
			// important fix for ff2 opacity issues on a mac
			if (navigator.appVersion.indexOf("Mac")!=-1 && ($.browser.mozilla && $.browser.version.substr(0,3) == 1.8)) o.animationOut.opacity = 1;
			
			$ul.animate(o.animationOut,o.speedOut,function(){$(this).parent().removeClass(o.hoverClass); sf.IE7fixRemove.call($ul);});
			
			o.onHide.call($ul);
			return this;
		},
		showSuperfishUl : function(){
			var o = sf.op,
				sh = sf.c.shadowClass+'-off',
				$ul = this.addClass(o.hoverClass)
					.find('>ul:hidden').css('visibility','visible');
					
			sf.IE7fixAdd.call($ul);
			o.onBeforeShow.call($ul);
			
			// important fix for ff2 opacity issues on a mac
			if (navigator.appVersion.indexOf("Mac")!=-1 && ($.browser.mozilla && $.browser.version.substr(0,3) == 1.8)) o.animationOut.opacity = 1;
						
			$ul.animate(o.animationOver,o.speedOver,function(){ sf.IE7fixRemove.call($ul); o.onShow.call($ul); });
			return this;
		}
	});

})(jQuery);

/*  */
//
// External callback to initialize the widget
// @param	mixed	container	jQuery selector for the object to be used
// @param	dom		context		DOM object used as jQuery context. Defaults to document.body
function init_tooltip ( container, context )
{
	context = context || document.body;
	
	$(container, context).each(function()
	{
		var opts = jQuery.attrOptions( this , 'tooltip' );
		new Tooltip( this, opts );
	});
}

// External callback for the documentation functions
// @return  object      Structure containing 'examples' of usage, 'about' message, default 'opts', and 'classes' (never used...)
function docs_tooltip()
{
	var a = 'Mouse-pivoted tooltip that behaves intelligently against screen limits';
	var e = 
	[
		[ '<a class="do_tooltip" title="my tooltip text"', "simple popup using a custom div id" ],
	];
	
	var c = [];
	
	var o = 
	[ 
	 	[ 'timeover'			,50,				  					'Number of milliseconds before tooltip appears' ],
		[ 'effectover'			,{opacity: "show"}, 				 	'Action when hovering over. {opacity: \'toggle\', height: \'toggle\'}' ],
	 	[ 'effectover_duration'	,150,	  								'Duration of out effect' ],
	 	[ 'effectout' 			,{opacity: "hide"},  				  	'Action when hovering out. Other examples can be hide(), fadeOut(\'slow\')' ],
	 	[ 'effectout_duration'	,100,	  								'Duration of hover effect' ],
	 	[ 'offy'				,0, 				  					'Vertical distance from the mouse pointer' ],
	 	[ 'offx'				,5, 				  					'Horizontal distance from the mouse pointer' ],
	 	[ 'follow'				,true,	  								'Follow the mouse cursor' ],
		[ 'extra_image'			,'',									'Add an extra image to the ' ],
	 	[ 'inevent'				,'mouseover', 	  	  					'Bind this action when hovering over, choose mousemove when tooltip should move with mouse' ],
	 	[ 'outevent' 			,'mouseout', 		  					'Bind this action when hovering out' ],
	 	[ 'width'				,'auto', 			  					'Width of the tooltip' ],
	 	[ 'selectable'			,1, 	  	  	  					    'Set to true when it should be possible to select the text in the tooltip' ],
	 	[ 'cursor'				,'', 	  	  	  					    'tooltip parent cursor' ],
	 	[ 'maxwidth'			,'300px',								'the maximum width of the tooltip' ],
	 	[ 'type'				,'',									'is the type an input?' ],
	 	[ 'html'				,'',									'The html to be injected into the tooltip div' ],
	 	[ 'dom_id'				,'',									'what dom id to use for filling the tooltip' ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}

// Process the options for this widget
// @param   object  o   Widget options extracted from the html
// @return  object      Default options overriden by html options
function opts_tooltip( o )
{
	return apply_options( docs_tooltip().opts, o );
}

function Tooltip( container, options )
{
	options			= opts_tooltip( options );
	this.options	= options;
    this.container  = container;
        
	$(container).tooltip(
    {
    	timein: 			options.timeover,
    	ineffect: 			options.effectover,
    	ineffectduratrion: 	options.effectover_duration, 
    	outeffect: 			options.effectout,
    	outeffectduratrion: options.effectout_duration, 
    	offsetY:			options.offy,
    	offsetX: 			options.offx,
    	follow: 			options.follow,
    	extra_image: 		options.extra_image,
	   	inevent: 			options.inevent,
    	outevent: 			options.outevent,
    	width: 				options.width,
    	cursor:				options.cursor,
    	maxwidth:			options.maxwidth,
    	type:				options.type,
    	html:				options.html,
    	dom_id:				options.dom_id
    });
}

(function(jQuery) 
{
	jQuery.fn.tooltip = function(options)
	{
		var defaults = {
			timein: 			300, 
			ineffect: 			{opacity: 'show'},
			ineffectduration: 	200, 
			outeffect: 			{opacity: 'hide'},
			outeffectduration: 	300, 
			offsetY: 			-15,
			offsetX: 			15,
			follow: 			true,
			extra_image: 		'<span class="tooltip-arrow"></span>',
			inevent: 			'mouseover',
			outevent: 			'mouseout',
			width: 				'auto',
			cursor: 			'',
			maxwidth: 			'330px',
			type: 				'',
			html: 				'',
			dom_id:				''
  		};
  		
  		var options = jQuery.extend(defaults, options);
  			
  		return this.each(function() 
		{
			obj = jQuery(this);
		
			obj.css({cursor: options.cursor});			
			
			if(this.title == '' && !options.dom_id && !options.html)
			{
				obj.unbind(options.inevent, options.outevent);
				return false;
			}

			obj.bind(options.inevent, function(e) 
			{
				this.tip = this.title;
				
				if(options.html)
				{
					var tip_content = options.html;
				}
				else if(options.dom_id)
				{
					var tip_content = $('#' + options.dom_id).html();
				}
				else
				{
					var tip_content = this.tip;
				}
				
				this.title = "";
				
				tip = jQuery('<div></div>')
						.addClass('tooltip')
						.html(options.extra_image + tip_content)
						.css({top: e.pageY + options.offsetY, left: e.pageX + options.offsetX, width: options.width, maxWidth: options.maxwidth });
				
				jQuery(document.body).append(tip);
								
				if(options.follow)
				{
					jQuery(document).bind('mousemove', function(e)
					{ 
						tip.css({top: e.pageY + options.offsetY});
						
						if(e.pageX + tip.width() > jQuery.windowSize().w)
						{
							tip.css({left: e.pageX - options.offsetX - tip.width() - 30});
						}
						else if(e.pageX + tip.width() < jQuery.windowSize().w)
						{
							tip.css({left: e.pageX + options.offsetX });
						}
						else
						{
							tip.css({left: e.pageX + options.offsetX });
						}
					});
				}
				else
				{
					var left = jQuery.getPosition(this).x;
					var top  = jQuery.getPosition(this).y;
					
					tip.css({top: top - tip.height() - 10});
					
					if(left + tip.width() > jQuery.windowSize().w)
					{
						tip.css({left: left - (obj.width() / 2) - (tip.width() / 2 )});
					}
					else
					{
						tip.css({left: left + (obj.width() / 2) - (tip.width() / 2 )});
					}
									
					if(options.type == 'input')
					{
						tip.css({ left: left + obj.width() + 15, top: top});
					}
				}
								
				tip.oneTime(options.timein, function()
				{
					jQuery(this).stop().animate(options.ineffect, options.ineffectduration);
				});
			});
			
			obj.bind(options.outevent, function(e) 
			{
				tip.stop().animate(options.outeffect, options.outeffectduration, function()
				{
					jQuery(this).remove();
				});
				
				jQuery.fn.tooltip.destroy();
				this.title = this.tip;
			});
			
			jQuery.fn.tooltip.destroy = function()
			{
				obj.unbind(options.inevent, options.outevent);
				jQuery(document).unbind('mousemove');
			}
		});			
	}
})(jQuery);
//
// 
//function init_imgzoomer(container, context)
//{
//	context = context || document.body;
//
//	$(container, context).each(function() 
//	{
//		var opts = "";
//		opts = jQuery.attrOptions(this, "imgzoomer");
//		new Imgzoomer(this, opts);
//	});
//}
//
//function docs_imgzoomer()
//{
//	var a = "An image zoomer.";
//	var e = [ ['<img class="do_imgzoomer" src="" />', "Image zoomer"] ];
//	var c = [];
//	
//	var o = 
//	[
//		[ "showZoomer", 	'true',		"Show the zoomer in the bar" ],
//		[ "showMakeBig", 	'true',		"Show the button to make the image big" ]
//	];
//	
//	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
//}
//
//function opts_imgzoomer(o)
//{
//	return apply_options(docs_imgzoomer().opts, o);
//}
//
//function Imgzoomer(container, opts)
//{
//	opts			= opts_imgzoomer( opts );
//	this.container	= container;
//	this.opts		= opts;
//	
//	$(container).img_zoomer(
//	{
//		showZoomer: this.opts.showZoomer,
//		showMakeBig: this.opts.showMakeBig	
//	});	
//}

;(function($)
{
	$.fn.img_zoomer = function(options) 
	{
		//if($.browser.msie) 
		//{
		//	try { document.execCommand("BackgroundImageCache", false, true); } catch(err) { }
		//}
		
		var defaults = {
			showZoomer: false,
			showMakeBig: true
  		}
  		
  		var options = jQuery.extend({}, defaults, options);

		return this.each(function() 
		{
			var origImg 		= $(this);	
			var imgWidth 		= origImg.width();
			var imgHeight 		= origImg.height();
			var img_id 			= origImg.attr('usemap').replace('#',''); // find the <map> that belongs to this image
			
		
			var usemap, imgVars, imgSrc, originalWidth, originalHeight;
			
			if($('map[name='+ img_id +']').length)
			{
				usemap 			= $('map[name='+ img_id +']');
				imgVars 		= usemap.attr('title').split(",");
				imgSrc 			= imgVars[2];
				originalWidth 	= parseInt(imgVars[0]);
				originalHeight 	= parseInt(imgVars[1]);
			}
			
			var perc = 1;
		
			if(imgWidth != originalWidth)
			{			
				perc = (imgWidth / originalWidth);
			}
	
			// if image does not need zoomer, finish here, and skip to the next iteration
			if(!perc || perc > .85 || imgWidth < 220)
			{
				return true;
			}
			
			var a = false;
		
			// create wrapper div if it not in the template
			if(!origImg.parents('.img-wrapper').length) 
			{
				// wrap the image in a div for annotation positioning		
				wrapper = $('<div class="img-wrapper"></div>')
							.attr({rel: img_id})
							.css({width: imgWidth, height: imgHeight});
							
				if(origImg.parents('a').length)
				{
					a = origImg.parents('a');
					origImg.parents('a').wrap(wrapper);
				}
				else
				{
					origImg.wrap(wrapper);
				}
			}
			else
			{
	 			if(origImg.parents('a').length)
				{
					a = origImg.parents('a');
				}
			}
		
		
			var wrapper = origImg.parents('.img-wrapper');
		
			if($('.img-toolbar', wrapper).length)
			{
				var toolbar = $('.img-toolbar', wrapper);
			}
			else
			{
				// find toolbar div, add it to the wrapper
				var toolbar = wrapper.siblings('.img-toolbar').prependTo(wrapper);
			}
		
			// bind hovers
			wrapper
				.mouseover(function()
				{
					// load hi res image if present
					if(!$('.img-zoomer-hi-res',this).attr('src') && perc < .85)
					{
						imgViewerFunctions.loadBigImage($('.img-zoomer-hi-res', this));
					}
												
					$(this).addClass('img_hovered');			
					
					if($.browser.msie) 
					{
						toolbar.show();
						return false;
					}
					
					if(toolbar.length && toolbar.html() != '') 
					{
						toolbar.slideDown(200);
						
						if(toolbar.css('display') == 'none') 
						{
							toolbar.show();
						}
					}			
				})
				.mouseout(function()
				{	
					$(this).removeClass('img_hovered');
				
					if($.browser.msie) 
					{
						toolbar.animate({opacity: 1}, 800, function()
						{
							if(toolbar.length && !objParent.hasClass('img_hovered'))
							{
								toolbar.slideUp(200);
							}
						});
					
						return false;
					}
				
					$(this).animate({opacity: 1}, 800, function()
					{
						toolbar = $('.img-toolbar', this);
						if(!$(this).hasClass('img_hovered')) 
						{
							if(toolbar.length)
							{
								toolbar.slideUp(200);
							}
						}
					});
				});
		
			toolbar
				.prependTo(wrapper)
				.mouseover(function()
				{
					wrapper.addClass('img_hovered');
					if(options.showZoomer)
					{
						wrapper.addClass('zooming-img');
					}
				})
				.mouseout(function()
				{
					if(options.showZoomer)
					{
						if($('.ui-slider', this).slider('value') <= 1)
						{
							wrapper.removeClass('zooming-img');
						}
					}
				});

			toolbar = $(toolbar, wrapper);
		
			// add tags button, set binds and title	
			$('.edit-img-tags', toolbar).text($('.edit-img-tags', toolbar).text().split(',')[0]);
		
			var img 	= $('<img />').addClass('img-zoomer-hi-res').css({position: 'absolute'}).hide().insertAfter(origImg);	
			var loader 	= $('<span></span>', origImg).addClass('loading-toolbar').hide().prependTo(toolbar);
		
			// if zooming tools don't exist, add them to the toolbar
			if(!$('.img-zoomer-tools',toolbar).length)
			{
				var zoomer = $('<div></div>').addClass('img-zoomer-tools').hide().prependTo(toolbar);
			}
			else 
			{
				var zoomer = $('.img-zoomer-tools', toolbar);
			}
		
			// build zoom slider and add to zoomer
			if(options.showZoomer)
			{			
				$('<div></div>').slider({
					max: (perc * 100)+100,
					start: function()
					{
						origImg.hide();
						img.show();
								
						if(!wrapper.hasClass('zooming-img'))
						{
							wrapper.addClass('zooming-img');
						}
					},
					slide: function()
					{	
						if($('.ui-slider',toolbar).slider('value') > 1)
						{
							$('.img-zoomer-tool-reset', toolbar).animate({opacity: 1}, 200);
							$('.annotation', wrapper).hide();
						}
					
						var val 		= $(this).slider('value');
						var newPerc 	= (val / 100 ) + 1;			
						var percWidth 	= (imgWidth * newPerc);
						var percHeight 	= (imgHeight * newPerc);
						var left 		= (imgWidth - percWidth) / 2;
						var top 		= (imgHeight - percHeight) / 2;
					
						img.css({width: percWidth,height: percHeight,top: top,left: left});			
					},
					stop: function()
					{									
						if(a)
						{
							a.click(function()
							{ 
								return false 
							});
						}
					
						if($(this).slider('value') < 1)
						{
						 	imgViewerFunctions.resetImage($(this), img, origImg, toolbar, wrapper, a);
						}
					}		
				})
				.appendTo(zoomer);
			
				$('<span>+</span>').addClass('img-zoomer-tool-add').mousedown(function() { $(this).siblings('.ui-slider').slider("moveTo", "+=15"); }).appendTo(zoomer);
				$('<span>-</span>').addClass('img-zoomer-tool-less').mousedown(function() { if($(this).siblings('.ui-slider').slider('value') < 1) { imgViewerFunctions.resetImage($(this).siblings('.ui-slider'), img, origImg, toolbar, wrapper, a); } else { $(this).siblings('.ui-slider').slider("moveTo", "-=15"); } }).prependTo(zoomer);	
				$('<span>r</span>').addClass('img-zoomer-tool-reset').mouseup(function() { imgViewerFunctions.resetImage($(this).siblings('.ui-slider'), img, origImg, toolbar, wrapper, a); }).css({opacity: .4}).prependTo(zoomer);
			}
			
			if(options.showMakeBig)
			{
				$('<span></span>').addClass('img-zoomer-tool-fullscreen').click(function() { imgViewerFunctions.imageGoFullsize(img, wrapper, origImg, toolbar); }).prependTo(zoomer);
			}
		});
	}
})(jQuery);
	
imgViewerFunctions = 
{
	loadBigImage: function(img)
	{
		var wrapper = img.parents('div');
		var toolbar = $('.img-toolbar', wrapper);
		var zoomer 	= $('.img-zoomer-tools', wrapper).hide();
		var loader  = $('.loading-toolbar', wrapper).show();
		var imgVars	= $('map[name='+ wrapper.attr('rel') +']').attr('title').split(",");
		var imgSrc 	= imgVars[2];
		
		// load hi-res image	
		img
			.css({position:'absolute',left:-999999})
			.attr({src: imgSrc})
			.load(function()
			{
				loader.hide();
				zoomer.fadeIn(300);
			
				$(this)
					.attr({rel: $(this).width()+','+$(this).height()})
					.css({width: wrapper.width(),height: wrapper.height()})
					.unbind('load')
					.css({position:'static',left:'auto'});
			})
			.draggable(
			{
				start: function(e, ui)
				{
					uiWidth  = - (ui.helper.width() - wrapper.width());
					uiHeight = - (ui.helper.height() - wrapper.height());
				},
				
				drag: function(e, ui)
				{
					if(ui.position.left >= 0) 		ui.position.left = 1;
					if(ui.position.top >= 0) 		ui.position.top = 1;
					if(ui.position.left <= uiWidth) ui.position.left = (uiWidth + 1);
					if(ui.position.top <= uiHeight)	ui.position.top = (uiHeight + 1);
				}
			});
	},
	
	resetImage: function(slider, img, origImg, toolbar, wrapper, a)
	{
		a = a || false;
		
		if(slider.slider('value') > 1)
		{
			slider.slider("moveTo", "1");
		}
		
		img.hide()
	 	origImg.show()
	 	
	 	$('.img_zoomer_tool_reset', toolbar).css({opacity: .4});
		$('.annotation', wrapper).show().animate({opacity: 1},300,function()
		{
			wrapper.removeClass('zooming-img');
		});
		
		if(a)
		{
			a.unbind('click');
		}
	},
	
	imageGoFullsize: function(img, wrapper, origImg, toolbar)
	{
		var zoomDimen 		= img.attr('rel').split(',');
		var zoomImgWidth 	= zoomDimen[0];
		var zoomImgHeight 	= zoomDimen[1];
		var fullWidth 		= zoomImgWidth;
		var fullHeight 		= zoomImgHeight;

		// never wider than window
		if(zoomImgWidth > $(window).width())
		{
			fullWidth  = $(window).width() - 40;
			fullHeight = zoomImgHeight * (fullWidth / zoomImgWidth);	
		}		
		
		// re-position when window resizes
		$(window).resize(function()
		{
			if($(window).width() < zoomImgWidth)
			{
				$('.full-screen-img').animate({ 
					width: 	($(window).width() - 40),
					height: zoomImgHeight * (($(window).width() - 40) / zoomImgWidth),
					left: 	($(window).width() / 2) - (($(window).width() - 40) / 2)
				}, 200);
			} 
			else
			{
				$('.full-screen-img').animate({ 
					width: 	zoomImgWidth,
					height: zoomImgHeight,
					left: 	($(window).width() / 2) - (zoomImgWidth / 2)
				}, 200);
			}			
		});
 		
		leftPos = ($(window).width() / 2) - (fullWidth / 2);
		topPos  = $(window).scrollTop() + 10;
				
		// overlay
		$('<span class="popup-overlay"></span>')
			.css({opacity: .5, height: $(document).height(), backgroundColor: '#000000'})
			.click(function()
			{
				imgViewerFunctions.closeBigImage(toolbar, origImg, wrapper);	
			})
			.appendTo('body');
			
		// clone the large image, and animate to full screen
		img
			.clone()
			.show()
			.addClass('full-screen-img')
			.css({left: wrapper.offset().left, top: wrapper.offset().top})
			.appendTo('body')
			.animate({width: fullWidth, height: fullHeight, left: leftPos, top: topPos}, 300, 'easeOutCirc')
			.click(function()
			{
				imgViewerFunctions.closeBigImage(toolbar, origImg, wrapper);
			});
			
		$(document)
			.unbind('keypress.imageZoomer')
			.bind('keypress.imageZoomer', function(e)
			{
				var key;
				if($.browser.msie) 	{ key = e.which } else { key = e.keyCode }
				if(key == 27) { $('.popup-overlay').click(); }
			});	
	},
	
	closeBigImage: function(toolbar, origImg, wrapper)
	{
		$('.popup-overlay').fadeOut(300,function()
		{
			$(this).remove() 
		});
		
		$('.full-screen-img').animate({width: origImg.width(),height: origImg.height(), left: wrapper.offset().left,top: wrapper.offset().top}, 200, function()
		{ 
			$(this).remove(); 
			toolbar.show();
		})	
	}
}
// 
// 
//function init_imgannotations(container, context)
//{
//	context = context || document.body;
//
//	$(container, context).each(function() 
//	{
//		var opts = "";
//		opts = jQuery.attrOptions(this, "imgannotations");
//		new Imgannotations(this, opts);
//	});
//}
//
//function docs_imgannotations()
//{
//	var a = "An image annotator.";
//	var e = [ ['<img class="do_imgannotations" src="" />', "Image Annotator"] ];
//	var c = [];
//	var o = [];
//	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
//}
//
//function opts_imgannotations(o)
//{
//	return apply_options(docs_imgannotations().opts, o);
//}
//
//function Imgannotations(container, opts)
//{
//	opts			= opts_imgannotations( opts );
//	this.container	= container;
//	this.opts		= opts;
//	
//	$(container).img_annotations();
//}

;(function($)
{
	$.fn.img_annotations = function() 
	{
		return this.each(function() 
		{
			var obj	  	= $(this);
			var imgId 	= $(this).attr('usemap').replace("#","");
			objParent 	= obj.parent();
				
			// create label for future use
			if(!$('.annotation-label').length)
			{
				$('<span class="annotation-label"></span>').css({opacity: .9}).appendTo('body');
			}
	
			if($('map[name='+imgId+']').length)
			{
				// remove usemap
				var imgWidth 		= $(this).width();
				var imgHeight 		= $(this).height();
				var usemap 			= $('map[name='+imgId+']');			// find the <map> that belongs to this image
				var imgVars			= usemap.attr('title').split(",");
				var originalWidth	= parseInt(imgVars[0]);
				var originalHeight	= parseInt(imgVars[1]);
				var percWidth 		= 1;
				var percHeight 		= 1;
			}
			else
			{
				return;
			}
					
			if(imgWidth	 != originalWidth){ percWidth = (imgWidth / originalWidth) }
			if(imgHeight != originalHeight){ percHeight = (imgHeight / originalHeight) }
			
			// remove <a> from around image if in edit mode
			if(obj.parents('a:first').length) 
			{
				attachmentLink = obj.parents('a:first').clone();
			}
			
			// create wrapper div if it not in the template
			if(!obj.parents('.img-wrapper').length) 
			{
				// wrap the image in a div for annotation positioning		
				img_wrapper = $('<div class="img-wrapper '+imgId+'_wrap"></div>').addClass('img-with-annotations').attr({rel: imgId}).css({width: imgWidth,height: imgHeight});
				
				if(obj.parents('a:first').length)
				{
					obj.parents('a:first').wrap(img_wrapper);
				}
				else
				{
					obj.wrap(img_wrapper);
				}
			}
			else 
			{
				img_wrapper = obj.parents('.img-wrapper').addClass('img-with-annotations '+imgId+'_wrap').attr({rel: imgId});
			}
			
			objParent = obj.parents('.img-wrapper');
			
			// find and add toolbar
			if($('.img-toolbar',objParent).length)
			{
				toolbar = $('.img-toolbar',objParent);
			}
			else
			{
				// find toolbar div, add it to the wrapper
				toolbar = objParent.siblings('.img-toolbar:first').prependTo(objParent);
			}
			
			// Set up image 
			objParent.siblings('.help-text:first').slideUp();
			objParent.siblings('.temp-actor-list').remove()
			objParent.removeClass('in_edit');
			
			actorList = $('.list-actor ul');
			
			highlight_annotation_from_li(actorList, objParent, toolbar);
			
			// Create annotations from <map><area>'s
			if(obj.siblings('.annotation').length < 1)
			{
				$("area", usemap).each(function(i)
				{	
					// post ids = thing_id , edge_id, actor id
					var postIds 	= $(this).attr('rel').split(",");
					var thing_id 	= postIds[0];
					var actor_id 	= postIds[1];
					var edge_id 	= postIds[2];
					var coords 		= $(this).attr('coords').split(",");			
					var width 		= (coords[2] - coords[0]) * percWidth; // find the saved dimensions for the annotation
					var height 		= (coords[3] - coords[1]) * percHeight;
					var left 		= parseInt(coords[0]) * percHeight;
					var top 		= parseInt(coords[1]) * percHeight;
					var full_title  = $(this).attr("title").split(",");
			
					// create annotation
					annotation = $('<a id="annot'+actor_id+'" rel="'+postIds+'" href="'+$(this).attr("href")+'"><span class="drag">'+full_title+'</span></a>');
		
					$('span.drag',annotation).css({width: width, height: height, zIndex: ( 9998 - ( width + height ) ) });
					
					// IE fix
					if($.browser.msie) 
					{
						$('span.drag',annotation).css({backgroundColor: '#ccc',opacity: 0});
						$('body').addClass('isIE');
					}
					
					// make outer wrapper wider for border
					width = (width + 2);
							
					$(annotation)
						.addClass('annotation')
						.css({width: width, top: top, left: left, zIndex: ( 9998 - ( width + height ) ) })
						.prependTo('.'+imgId+'_wrap');
				});
			}
		
			// Bind image and annotation hover states
			annotations = $('.annotation', objParent);
			annotations.css({opacity: 1})
				// pause before fading
				.animate({opacity: 1},1500, function()
				{
					// fade annotations out
					$(this).animate({opacity: 0},500,function()
					{
						// if image has gone into edit, and show annotations
						if(img_wrapper.hasClass('in_edit'))
						{
							$(this).css({opacity: 1});
						}
					});
				})
				.each(function()
				{
					// show label on hover
					$(this).hover(function()
					{
						annotations.css({opacity: 1});
									
						if(!labelText) 
						{
							var labelText = $(this).text();
							$('span.annotation-label').text(labelText);
						}
				
						$(this).mousemove(function(e){
							$('span.annotation-label').css({ left: e.pageX, top: e.pageY, zIndex: 9999999 });
						});
						
						// underline li in actor list that matches annotation title
						var text = $('span:first',this).text().split(',');
				
						$('li:contains('+text[0]+') a',actorList).css({textDecoration: 'underline'});		
					},
					function()
					{
						hide_label();
						$('li a',actorList).css({textDecoration: 'none'});
					})
				});
			
			obj.removeAttr('alt');
			
			objParent
				.mouseover(function()
				{
					annotations = $('.annotation', this);
					toolbar 	= $('.img-toolbar', this);
					
					$(this).addClass('img_hovered');
					
					if(!objParent.hasClass('zooming-img'))
					{
						annotations.css({opacity: 1});
					}
					
					// load hi res image if present and has not been loaded yet
					if($('.img-zoomer-hi-res',this).length && !$('.img-zoomer-hi-res',this).attr('src'))
					{
						imgViewerFunctions.loadBigImage($('.img-zoomer-hi-res',this));
					}
					
					if($.browser.msie && !objParent.hasClass('zooming-img')) 
					{
						annotations.show();
						toolbar.show();
						return false;
					}
					
					if(toolbar.length && toolbar.html() != '') 
					{
						toolbar.slideDown(200);
						if(annotations.css('opacity') < 1 && toolbar.css('display') == 'none') 
						{
							toolbar.show();
						}
					}
				})
				.mouseout(function()
				{	
					annotations = $('.annotation',this);
					toolbar 	= $('.img-toolbar',this);
					
					$(this).removeClass('img_hovered');
					
					if($.browser.msie) 
					{
						annotations.hide();
						toolbar.animate({opacity: 1},800,function()
						{
							if(toolbar.length && !objParent.hasClass('img_hovered'))
							{
								toolbar.slideUp(200);
							}
						});
						
						return false;
					}
					
					$(this).animate({opacity: 1},800,function()
					{
						annotations = $('.annotation', this);
						toolbar 	= $('.img-toolbar', this);
	
						if(!$(this).hasClass('img_hovered')) 
						{
							annotations.animate({opacity: 0},200);	
							if(toolbar.length)
							{
								toolbar.slideUp(200);
							}
						}
					});
				});
					
			// remove areas for edit mode - needed for IE
			$("area", usemap).remove();
		});
	}
})(jQuery);

function hide_label()
{
	$('span.annotation-label').css({top: -99999});
}

// highlight annotation when actor li is hovered
function highlight_annotation_from_li(actorList, objParent, toolbar)
{
	$('li', actorList).unbind('mouseover', 'mouseout');
	
	$('li', actorList).hover(function()
	{
		if(!$(".annotation", objParent).length)
		{
			return false;
		}
		
		$('a', this).removeAttr('title');
		
		var li_text = $('span', this).text().replace('\n',' ').split(' ');
		
		if(li_text.length <= 1)
		{
			var search_text = li_text[0]
		}
		else
		{
			var search_text = li_text[0]+" "+li_text[1]
		}
		
		$(".annotation:contains("+search_text+")",objParent).addClass('hovered');
		objParent.trigger('mouseover');
		
		toolbar.css({top: -9999});	
	}, 
	function()
	{
		if( !$(".annotation",objParent).length )
		return false;
		
		$(".annotation",objParent).removeClass('hovered');
		objParent.trigger('mouseout');
		
		toolbar.hide().css({top: 0});
	});
}

//
/*  $Id: lightbox.js 43278 2009-08-24 09:34:49Z blaise $ */


// STATIC 

window.lightbox_pointer = null;


// Static hook to kill the currently active lightbox
// @return  undefined
function lightbox_remove()
{
	window.widget_manager.stop( 'lightbox' );
}


// Static hook to add an item to the top bar of the currently active lightbox
// @return  undefined
function lightbox_bar_add( x )
{
	$( "#lightbox-wrap-buttons" ).append( x );
}

// Static hook to add an button to the top bar of the currently active lightbox
// @return  undefined
function lightbox_bar_add_button( value, functionName )
{
	var str =  "<button onclick='lightbox_pointer." + functionName + "();'>" + value + "</button>";
	lightbox_bar_add( str );
}

// External callback to initialize the widget
// @param   mixed   container   jQuery selector for the object to be used
// @param   dom     context     DOM object used as jQuery context. Defaults to document.body
// @return  undefined
function init_lightbox( container, context )
{
	context = context || document;

	$( container, context ).each(
		function ()
		{
			var opts	= jQuery.attrOptions( this , 'lightbox' );
			var ajax	= jQuery.attrOptions( this , 'lightbox_ajax' );
			
			opts.ajax = ajax;
			
			new Lightbox( this, opts );
		}
	);
}


// External callback for the documentation functions
// @return  object      Structure containing 'examples' of usage, 'about' message, default 'opts', and 'classes' (never used...)
function docs_lightbox()
{
	var a = "A slightly too versatile lightbox implementation...";
	var e = [];
	var c = [];
	var s = jQuery.label( 'lightbox.cancel', 'Cancel' );
	var o = 
	[[ 'url', 			null, 	"Url to be loaded. Defaults to the href attribute in the element, and then to null" ]
	,[ 'lbl_cancel',	s, 		"Cancel button name" ]
	,[ 'width',			"60%", 	"Css width of the lightbox" ]
	,[ 'height',		"60%", 	"Css height of the lightbox" ]
	,[ 'freeze',		false, 	"Whether the lightbox size should be fixed instead of adapting to content"]
	,[ 'ajax',			{}, 	"Parameters to be added to lightbox url" ]
	,[ 'className',		"", 	"Class that will be added to the lightbox frame" ]
	];
	
	return { 'examples': e, 'about': a, 'opts': o, 'classes': c };
}


// Process the options for this widget (cached)
// // @param   object  o   Widget options extracted from the html
// // @return  object      Default options overriden by html options
function opts_lightbox( o )
{
	return apply_options( docs_lightbox().opts, o );	
}


function Lightbox( container, options )
{
	options			= opts_lightbox( options, container );
	options.url		= options.url || container.href || null;
	options.width	= ( "" + options.width  ).replace( 'px' , '' );
	options.height	= ( "" + options.height ).replace( 'px' , '' );

	this.options	= options;
	
	container = $( container ).get(0);
	container.obj_lightbox = this;

	var self = this;
	$( container ).click( 
		function (event)
		{
			window.lastEvent = event;
			self.show();
			return false;
		}
	);

	if ( options.showonload )
	{
		// bug#1732
		//
		// http://support.microsoft.com/default.aspx/kb/927917
		// http://clientside.cnet.com/code-snippets/manipulating-the-dom/ie-and-operation-aborted/
		//
		// The "operation is aborted" when we generate DOM content in the parent of a container of a script.
		// It is also aborted when we try to add DOM content to a container that is not yet ready.
		// We fix this IE problem by generating the lightbox inside the container that has the showonload parameter.
		//
		if ($.browser.msie)
		{
			this.show(container);
		}
		else
		{
			this.show();
		}
		container.blur();	
	}
}


// Callback for when the widget gets out of focus
// // @param   string  name    The name of the widget type
// // @param   object  obj     The object replacing this one in the widget focus
// // @return  bool            True if ajax request made, false otherwise
Lightbox.prototype.widgetBlur = function ( name, obj )
{
	if ( obj == null )
	{
		this.remove();
	}
	return false;
};



// Create the dom structure necessary to display lightbox
// @param container optional container where to create the lightbox
// @return  undefined
Lightbox.prototype.domCreate = function ( container )
{
	var self = this;
	
	var lo	= document.createElement( "div" );
	var lf	= document.createElement( "div" );
	var lw	= document.createElement( "div" );
	var lc	= document.createElement( "div" );
	var wb	= document.createElement( "div" );
	
	var cb	= $('<div></div>')
					.attr({id: 'lightbox-cancel', title: this.options.lbl_cancel})
					.click(function() 
					{ 
						self.remove();
					});
	
	lo.id	= "lightbox-overlay";
	lf.id	= "lightbox-frame";
	lw.id	= "lightbox-window";
	lc.id	= "lightbox-bar";
	wb.id	= "lightbox-wrap-buttons";
	
	lf.className = this.options.className;
	
	lf.style.position	= "absolute";
	lw.style.width		= "100%";
	lw.style.height		= "100%";
	
	if (container)
	{
		$( container ).append( lo );
		$( container ).append( lf );
	}
	else
	{
		$( "body" ).append( lo );
		$( "body" ).append( lf );
	}
		
	$( lf ).append( lc );
	$( lf ).append( lw );
	$( wb ).append( cb );
	$( lc ).append( wb );
	$( lc ).addClass('clearfix');
	
};


// Clear the timer used to resize the lightbox
// @return  undefined
Lightbox.prototype.clearResizeInterval = function()
{
	if ( window.lightbox_pointer && window.lightbox_pointer.interval )
	{
		clearInterval( window.lightbox_pointer.interval );
		window.lightbox_pointer.interval = null;
	}
};


// Remove this lightbox
// @return  undefined
Lightbox.prototype.remove = function ()
{
	this.clearResizeInterval();
	
	// $( document ).unkeyup();

	// Timeout is needed when this function is called from within the lightbox itself
	var self = this;
	setTimeout(
		function () 
		{
			$('#lightbox-window,#lightbox-frame,#lightbox-overlay').remove();
			self.showObjects();
		},
		500
	);
};


// Get the height of the page inside the lightbox 
// @return  undefined
Lightbox.prototype.size_of_content = function ()
{
	var fr = document.getElementById("lightbox-iframeContent").contentWindow;
	var h1 = 0;
	var h2 = 0;
	
	if ( fr && fr.document )
	{
		if ( fr.document.documentElement && fr.document.documentElement.scrollHeight )
		{
			h1 = fr.document.documentElement.scrollHeight;
		}

		if ( fr.document.body && fr.document.body.scrollHeight )
		{
			h2 = fr.document.body.scrollHeight;
		}
	}

	var h = Math.max( h1, h2 );
	var s = jQuery.getSize( document.getElementById( 'lightbox-frame'  ) );

	h = s.h < h ? h + 60 : 0;
	
	return h;
};


// Resize the lightbox in accordance to its contents
Lightbox.prototype.size = function ()
{
	if ( document.getElementById( "lightbox-iframeContent" ) )
	{
		var h = this.size_of_content();
		h > 0 && $( "#lightbox-frame" ).css( 'height', h + 'px' );
	}
};


// Convert a size in "%" into a value in "px"
// @param   string      x   Percentage value
// @param   integer     y   Absolute value
// @return  integer         Resulting pixel value
Lightbox.prototype.pixelizeSize = function ( x, y )
{
	x = parseInt( x.match( /\d+/ ) );
	x = Math.max( x , 0 );
	x = Math.min( x , 100 );
	x = Math.round( y * x / 100 );
	return x;
};


// Determine the width (horizontal position)
// @return  undefined
Lightbox.prototype.h_position = function ()
{
	var l = 0;
	var w = (typeof this.options != 'undefined') ? this.options.width : '60%';
	var d = jQuery.windowSize();

	if ( w.match( /\%/ ) )
	{
		w = this.pixelizeSize( w, d.w );
	}

	l = ( d.w - w ) / 2;

	$( "#lightbox-frame"  ).css( 'left',  l + 'px' );	
	$( "#lightbox-bar" ).css( 'width', w  - 2 + 'px' );
	$( "#lightbox-window" ).css( 'width', w + 'px' );
	
	this.overlaySize();	
};


// Determine the position  (vertical position)
// @return  undefined
Lightbox.prototype.v_position = function ()
{
	var pagesize   = jQuery.windowSize();	
	var pageScroll = jQuery.pageScrollTop();
	
	var t = 0;
	var h = (typeof this.options != 'undefined') ? this.options.height : '60%';
	var d = jQuery.windowSize();

	if ( h.match( /\%/ ) )
	{
		h = this.pixelizeSize( h, d.h );
	}

	t = ( d.h - h ) / 2;
	
	t = jQuery.pageScrollTop() + t;

	$( "#lightbox-frame" ).css({
		top:    t + 'px',
		height: h + 'px'
	});
};


// Determine size of dark mask 
// @return  undefined
Lightbox.prototype.overlaySize = function ()
{
	if ( window.innerHeight && window.scrollMaxY )
	{	
		yScroll = window.innerHeight + window.scrollMaxY;
	}
	else if ( document.body.scrollHeight > document.body.offsetHeight )
	{
		 // all but Explorer Mac
		yScroll = document.body.scrollHeight;
	}
	else
	{ 
		// Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		yScroll = document.body.offsetHeight;
  	}

	$( "#lightbox-overlay" ).css( {height: yScroll + "px", cursor: 'pointer' })
							.bind('click', function()
							{
								Lightbox.prototype.remove();
							});
};


// Update de size of the lightbox at a regular time interval
// @return  undefined
Lightbox.prototype.setRegularUpdate = function ()
{
	var self 	= this;
	var fr 		= document.getElementById("lightbox-iframeContent");
	fr.interval = setInterval( 
		function () 
		{ 
			self.size() 
		}, 
		800 
	);
};

Lightbox.prototype.hideObjects = function ()
{
	var self = this;
	$( 'embed,select' ).each(
		function ()
		{
			this.preLightboxVisibility = $( this ).css( 'visibility' );
			this.style.visibility = 'hidden';
		}
	);
};

Lightbox.prototype.showObjects = function ()
{
	var self = this;
	$( 'embed,select' ).each(
		function ()
		{
			this.style.visibility = this.preLightboxVisibility;
		}
	);
};


// Show the lightbox
// @param container, optional container where to generate the lightbox
// @return  undefined
Lightbox.prototype.show = function ( container )
{
	try 
	{
		window.widget_manager.widgetFocus( 'lightbox', this );
		
		$( "#lightbox-overlay" ).get( 0 ) || this.domCreate(container);
		
		var scroll = jQuery.pageScrollTop();

/*		window.scrollTo( 0, scroll );*/

		this.overlaySize();

		this.options.before_ajax && this.options.before_ajax( this.options );
		
		// Let the request know it is inside a lightbox
		this.options.ajax.in_lightbox = '1';
		
		var url		= jQuery.addToQuery( this.options.url , jQuery.param( this.options.ajax ) );
		var rand	= Math.floor( Math.random() * 100000 );
		
		if ( document.getElementById( "lightbox-iframeContent" ) == null )
		{
			$("#lightbox-window").append(
				"<iframe src='" + url + "' name='frame" + rand + "' id='lightbox-iframeContent' frameborder='0' border='0' style='width: 100%; height: 100%;'></iframe>" );
		}
		else
		{
			$( "#lightbox-iframeContent").get(0).src = url;
		}
		
		this.v_position();
		this.h_position();
		
 		$( "#lightbox-window,#lightbox-frame" ).css( 'display' , 'block' );

		this.options.freeze || this.setRegularUpdate();
		
		window.lightbox_pointer = window.frames['frame'+rand];
		
		var self = this;
		$( window ).resize(function () 
		{
			self.h_position();
			self.v_position();
		});	
		
		setTimeout(
			function ()
			{
				self.hideObjects();
			},
			20
		)
	}
	catch( e ) 
	{
		jQuery.warn( "Lightbox" , "An error occurred when opening the lightbox." , e );
	}
};

var LightboxHelper = 
{
	isLightbox: function(uri) 
	{
		if (!window.parent || window.parent.document.location.href == document.location.href)
		{
			return false;
		}
		if (!uri) uri = document.location.href;
		if (uri.match(/\bin_lightbox=1\b/))
		{
			return true;
		}
		
		return false;
	},

	openLightbox: function(url, container, options)
	{
		options['url'] = url;
		var lb = new Lightbox (container, options);
		lb.show();
	}
};

/**/
//
// any.dialog and any.dialogTrigger

;(function($)
{
    if (!$.any) $.any = {};

    $.extend($.any,
    {        
        dialog: 
        {
            /**
             * The defaults for the dialog.
             */
            defaults: 
            {
                /* options for the layout */
                width: '500px',                 // The width of the dialog'
                height: 'auto',                 // The height of the dialog
                ineffect: {opacity: 'show'},    // Animation when opening
                ineffectTime: 250,              // ... + duration
                outeffect: {opacity: 'hide'},   // Animation when closing
                outeffectTime: 100,             // ... + duration
                title: '',
                overlay: true,
                url: '',
                html: '',
                dom_id: '',                
                arrow: false,
                closeonmouseout: false,
                closeonmouseclick: true,
                callback: null,               // callback on close
                openCallback: null, // callback op open
                underObj: false
            },
            
            
            /**
             * This variable contains the options of the currently opened dialog.
             */
            currentOptions: {},
            
            
            /**
             * Open a dialog. By design, only one dialog can be opened
             * at the same time, so this function makes sure the
             * previous dialog closes.
             */
            open: function ( options, parent )
            {                
                if($.any.dialog.opened())
                {
                    // Remove the dialog.   
                    $.any.dialog.close( function () {
                                            $.any.dialog._showDialog(options, parent);
                                        });
                }
                else
                {
                    $.any.dialog._showDialog(options, parent);
                }
            },
            
            
            /**
             * Close the dialog, if there is one. Will call a callback
             * function afterwards. Returns TRUE if the dialog was
             * closed, or FALSE if none was open (so you can call the
             * callback yourself if you want).
             */
            close: function ( callback )
            {
            	var theBox = $('.dialog');
                
                if (!theBox.length)
                {
                    return false;
                }

                var opts = $.any.dialog.currentOptions;
                $.any.dialog.currentOptions = {};

            	theBox.animate(opts.outeffect, opts.outeffectTime, function()
            		           {
            		           	   // Remove autocompleter ( #5762 )
            		           	   // This should be removed when the new autocompleter ( #5472 ) is implemented
            		           	   if ($("#autocompleteHelper").length != 0)
            		           	   {
            		           	       $("#autocompleteHelper").remove();
            		           	   }
            		           	   
            			           $('.dialog-overlay').remove();
            			           theBox.remove();
            			           
            			           $('.dialog').unbind('mouseleave');
            			           
            			           if($.browser.msie && $.browser.version < 7) 
            			           {
            				           $('select').each(function()
            				                            {
            					                            $(this).css({visibility: 'visible'});
            				                            });
            			           }
            			           
            			           if(typeof callback == 'function') 
                                   {
                                       callback();
                                   }
            			           else if(typeof callback == 'string' && window[callback]) 
                                   {
                                       window[callback]();
                                   }
                                   
            			           if(typeof opts.callback == 'function') 
                                   { 
                                       opts.callback();
                                   }
                                   else if(typeof opts.callback == 'string' && window[opts.callback])
                                   {
                                       window[opts.callback]();
                                   }
            		           });
                return true;                
            },
            
            
            /**
             * Return whether a dialog is opened.
             */
            opened: function()
            {
                return $('.dialog').length > 0;                
            },

            
            /**
             * Return the container for the content area of the dialog.
             */
            contentArea: function()
            {
                return $('.dialog-content');
            },
            
            
            /**
             * Get the title of the current dialog
             */
            getTitle: function()
            {
                return $('.dialog-drag-handle-text').html();
            },


            /**
             * Set the title of the current dialog
             */
            setTitle: function(title)
            {
                $('.dialog-drag-handle-text').html(title);
            },


            /**
             * Add helptext to the current dialog
             */
            setHelpText: function(text)
            {
            	if(!$.any.dialog.opened()) return;
            	
            	if(!$('.action-help').length) 
            	{
            		$('<div></div>').addClass('action-help').appendTo($('.dialog-content'));
            	}
            	
            	$('.action-help').text(text);
    	    },
    	    
    	     /**
             * Remove helptext from the current dialog
             */
    	    removeHelpText: function()
    	    {
    	    	$('.action-help').remove();
    	    },

            /**
             * Private function for showing the dialog.
             */
            _showDialog: function ( options, parent )
            {
                options = $.extend({}, $.any.dialog.defaults, options);
                $.any.dialog.currentOptions = options;
            
                var theBox, closeButton, dialogContent, overlayDiv, dragHandle, dialogTop, dialogLeft, boxHeight, buttonText, loader;
                parent = $(parent || document.body);
                
                // The loader
   				loader	= $('<span></span>').addClass('dialog-loader').text(jQuery.label('dialog.loading', 'loading'));
                
                // The close button
				closeButton	= $('<span></span>').addClass('dialog-close').html('x');
				closeButton.click(function()
				{
					$.any.dialog.close();
				});

				if(options.overlay)
				{
					overlayDiv = $('<div></div>').addClass('dialog-overlay').css({zIndex: 35000, opacity: .30, height: $(document).height() });
				}
						
				if(typeof options.height == 'string')
				{
					boxHeight = 'auto';
				}
				else
				{
					boxHeight = options.height.replace('px', '') - 52;
				}

				if(parent[0] != document.body)
				{
					buttonText	= parent.text();
                    dialogTop   = parseInt(parent.offset().top);
					dialogLeft  = parseInt(parent.offset().left);
					
					if(options.underObj)
					{
						dialogTop += parseInt(parent.height());
						if(options.arrow)
						{
							dialogTop += 7;
						}
		            }
         		}
				else
				{
					dialogTop	= $(window).scrollTop() + Math.floor($(window).height() / 3);
					dialogLeft	= ($(window).width() / 2) - (parseInt(options.width) / 2);
				}

				if(options.title)
				{
					buttonText  = options.title;
				}

				theBox 			= $('<div></div>').addClass('dialog').css({position: "absolute", top: dialogTop, left: dialogLeft, width: options.width, height: boxHeight});
				dialogContent 	= $('<div></div>')
										.addClass('dialog-content')
										.appendTo(theBox);
				
				dragHandle	= $('<div></div>')
								.addClass('dialog-drag-handle')
								.html('<span class="dialog-drag-handle-text">'+buttonText+'</span>')
								.append(loader)
			                    .mousedown(function() { $(this).addClass('pressed'); })
								.mouseup(function() { $(this).removeClass('pressed'); })
								.prependTo(theBox);
				
				if(options.arrow) $('<div></div>').addClass('dialog-drag-handle-arrow').prependTo(theBox);
            	
            	// Remove opacity on IE browsers because it creates ugly edges
            	var removeOpacity = function()
            	{
            		if ($.browser.msie) 
            		{
            			theBox.css({ filter: '' });
            		}
            	};
            	
				theBox.draggable({ handle: dragHandle, start: removeOpacity, stop: removeOpacity});
				
				// No shadow on and hide all selects on ie6 
				if($.browser.msie) 
				{
					theBox.css({background: 'none', padding: 0});
					
					if($.browser.version < 7)
					{
						$('select').each(function()
						{
							$(this).css({visibility: 'hidden'});
						});
					}
				}
					
				if(options.overlay) $(document.body).append(overlayDiv);				
				
				// Destroy on escape
				$(document).keyup(function(e)
				{
					if(e.keyCode == $.ui.keyCode.ESCAPE)
					{
						$.any.dialog.close();
					}
				});
				
				// Destroy on outside click
				if(options.closeonmouseclick)
				{
					if(!options.overlay)
					{
						$(document).mousedown(function(e)
						{
							if(!$(e.target).hasClass('dialog') && !$(e.target).parents.hasClass('dialog') || !$(e.target).parents().attr('id') == 'ui-datepicker-div' || !$(e.target).parents().hasClass('unlink-confirm'))
							{
						        $.any.dialog.close();
							}
							else
							{
								return;
							}
						});
					}				
					else
					{
						overlayDiv.click(function()
						{
						    $.any.dialog.close();
						});
					}
				}
				
				// main content function
				var setContent = function(html)
				{
					$(document.body).append(theBox);
										
					dialogContent.html(html).prepend('<div class="notification"></div>');
					
					theBox.animate(options.ineffect, options.ineffectTime, function()
					{
						var left = $(this).offset().left;
						var top  = $(this).offset().top;
						
						if(top + $(this).height() + 20 - $(window).scrollTop() > $(window).height())
						{
                            top = Math.max(20 + $(window).scrollTop(), top - $(this).height());
						}
						
						if(left + $(this).width() > $(window).width())
						{
                            left = Math.max(20 + $(window).scrollLeft(), $(window).width() - $(this).width() - 20);
						}
                        
                        $(this).animate({left: left, top: top}, 150);
						
                        if (typeof options.openCallback == "function") options.openCallback();
						dragHandle.append(closeButton);
					});

					if(options.closeonmouseout)
					{
						// Destroy on mouse leave - This piece off code needs to be placed here for it to work. Weird
						$('.dialog').bind('mouseleave', function()
						{
							setTimeout(function()
							{ 
						        $.any.dialog.close();
							}, 1200);
						});
					}
				};
				
				// Call the content
				if(options.url)
				{
					$.ajax({
						type: 'GET',
						url: options.url,
						success: setContent
					});
				} 
				else if(options.dom_id)
				{
					setContent($(options.dom_id).clone(true));
				} 
				else if(options.html)
				{
                    setContent(options.html);
				} 
				else 
				{
					setContent('<p>Specify content using dom_id or url</p>');
				}
			}           
        }
    });
    
    /**
     * DialogTrigger ui element
     */
    $.any.ui("dialogtrigger",
    {
        _init: function()
        {
            var self = this;

            if(self.options.direct)
            {
            	$.any.dialog.open(self.options, self.element);
            }
            		
            if(self.options.hover)
            {
            	self.element.hoverIntent(
                {
            		//sensitivity threshold (must be 1 or higher)
            		sensitivity: 7,
            		
            		//milliseconds for onMouseOver polling interval
            		interval: 	 self.options.hoverTime,
            		
            		//milliseconds delay before onMouseOut			    
            		timeout: 	 500, 							 
            		
            		//onMouseOver callback
            		over: function()
            		{
            			$.any.dialog.open(self.options, self.element); 
            		}, 				    
            		
            		//onMouseOut callback
            		out: function() {}    
            	});
            }
            		
            if(self.options.click)
            {
                self.element.click(function(e) { self.open();});
            }			
        },
        
        open: function (callback) 
        {
            var opts = $.extend({}, this.options);
            if (callback) opts.openCallback = callback;
	        $.any.dialog.open(opts, this.element);
        }
    },
             
    /**
     * Defaults for dialogTrigger
     */             
    {
        /* options for the triggering of the dialog */                
        click: true,
        hover: false,
        hoverTime: 250,
        direct: false
    });

})(jQuery);
//
//

/**
 *
 * ActionManager Javascript API.
 *
 * - Open a scomp on the place where the button used to be
 * - Open a scomp which occupies the entire action dialog (hiding the other actions)
 * - Replace the current scomp with a next scomp (optionally going "full dialog")
 * - Close the current scomp (showing all the other actions again)
 * - Close the entire action dialog
 */

$.any.ui("action",
{
	_init: function ( )
	{
        var self = this;
        // see if there is an extra object registered for the current
        // action which can contain hooks and state.
        // if so, extend mythis with it.
        if (typeof $.any.ui.action.prototypes[self.options.action_name] !== "object")
        {
            throw('Programming error: action without programming logic: ' + self.options.action_name);
        }

        $.extend(self, $.any.ui.action.prototypes[self.options.action_name]);

        // call child init function if it's there
        if (typeof self['init'] == 'function')
        {
            self.init();
        }

        // Private data members.
        self.priv = {};
        self.priv.originalHTML = self.element.html();
        self.priv.full_dialog = false;   // flag whether the current stage is shown "full dialog"
        self.priv.my_dialog = false;    // flag whether I have opened the dialog (so I may close it).

        // The state variable.
        // everything you put in self.state will be posted to every stage that is rendered.
        self.state = {};

		self.priv.closePublishKey = {action: self.options.action, thg_id: self.options.thg_id};
        self.subscribe(self.priv.closePublishKey, function (e, twin) {
                           self.element.html(twin.element.html());
                           $.any.ui.scan(self.element[0]);
                           self.publish("action_reloaded");
                       });
    },

    /**
     * Reload the initial state of the action, only when used outside
      * the action dialog.
     */
    reload: function( callback )
    {
        var self = this;
        if (self._inActionDialog())
        {
            return;
        }

        var args = $.extend({}, self.state, self.options);
        args['stage']  = "close";
        delete args['action_name'];  // duplicate
        delete args['disabled'];     // set by jQuery UI
        delete args['require_logon'];

        // request the server with the arguments
        $.any.rest.get('action.render', args, function(data)
                      {
                          if (!data || typeof data != 'object' || !data.html)
                          {
                              throw('Programming error: The stage "' + stage + '" for action "' + self.options.action_name + '" returned no html.');
                          }

                          // Replace the container html!
                          self.element.html(data.html);
                          self.priv.originalHTML = self.element.html();

                          // when the result arrives, replace the target container with the contents.
                          $.any.ui.scan(self.element[0]);

                          if (typeof callback == 'function')
                          {
                              callback();
                          }

                          // Call stageReady handler
                          if (typeof self.stageReady == 'function')
                          {
                              self.stageReady("close", self.element);
                          }
                          self.publish("action_reloaded");
                      });
    },

    /**
     * Return the container element for the current stage of this
     * action. Can be used for jQuery selectors.
     */
    containerElement: function ()
    {
        var self = this;
        return self._inActionDialog() ? self.element : $.any.dialog.contentArea();
    },

    /**
      * Update the current action area with new content. This content
      * is fetched from the server from the template corresponding to
      * the action + stage.
      */
    renderStage: function( stage, callback, stage_opts )
    {
        var self = this;

        // Determine the target container.
        var target_container;

        var trigger_my_dialog = false;

        if (!self._inActionDialog() && stage != 'close')
        {
            // when we are on the page, we open a new dialog for the target container and remember where we came from.
            if (!$.any.dialog.opened())
            {
                trigger_my_dialog = true;
            }
            target_container = $.any.dialog.contentArea();
        }
        else
        {
            // the target container is "action area" of this action.
            target_container = self.element;
        }

        // gather all the required arguments
        var args = $.extend({}, self.state, self.options);
        if (typeof stage_opts == "object")
        {
            args = $.extend(args, stage_opts);
        }
        args['stage']  = stage;
        delete args['action_name'];  // duplicate
        delete args['disabled'];     // set by jQuery UI
        delete args['require_logon'];

        // request the server with the arguments
        $.any.rest.get('action.render', args, function(data)
                      {
                          if (!data || typeof data != 'object' || !data.html)
                          {
                              throw('Programming error: The stage "' + stage + '" for action "' + self.options.action_name + '" returned no html.');
                          }

                          if (trigger_my_dialog)
                          {
                              // A dialog should be opened.
                              self.priv.my_dialog = true;
                              var el = self.element;
                              $.any.dialog.open({
                                                    html:     data.html,
				                                    width:    '450px',
                                                    underObj: true,
                                                    arrow:    false,
				                                    title:    data.title
                                                }, el);
                              target_container = $.any.dialog.contentArea();
                              target_container.data("ui", self); // hook myself to this dialog for calculating the parent widget
                          }
                          else
                          {
                              if (self.priv.trigger_full_dialog && self._inActionDialog())
                              {
                                  self.element.parent('#action').children().each(
                                      function() {
                                          if(this != self.element[0])
                                          {
                                              $(this).hide();
                                          }
                                      }
                                  );
                              }

                              if (data.title && (self.priv.full_dialog || self.priv.my_dialog))
                              {
                                  if (self.priv.trigger_full_dialog)
                                  {
                                      self.priv.original_dialog_title = $.any.dialog.getTitle();
                                  }
                                  $.any.dialog.setTitle(data.title);
                              }


                              // Logic for the 'highlighted' class
                              if (self.priv.trigger_full_dialog && self._inActionDialog() || stage == "close")
                              {
                                  self.element.removeClass("highlighted");
                              }
                              else if (!self.priv.full_dialog && self._inActionDialog())
                              {
                                  self.element.addClass("highlighted");
                              }


                              // Replace the container html!
                              target_container.html(data.html);
								
                              if (stage == "close")
                              {
                                  self.priv.originalHTML = target_container.html();
                              }

                              if (self.priv.trigger_full_dialog)
                              {
                                  // Clean up
                                  delete self.priv.trigger_full_dialog;
                              }

                          }

                          // when the result arrives, replace the target container with the contents.
                          $.any.ui.scan(target_container[0]);
                          
                          if (typeof callback == 'function')
                          {
                              callback();
                          }

                          // Call stageReady handler
                          if (typeof self.stageReady == 'function')
                          {
                              self.stageReady(stage, target_container);
                          }

                      });
    },


    /**
     * Hide the other available actions in the action container,
     * giving the next stage all the available space.
     */
    goFullDialog: function( stage, callback, stage_opts )
    {
        var self = this;

        if (self._inActionDialog() && !self.priv.full_dialog)
        {
            self.priv.full_dialog = true;
            self.priv.trigger_full_dialog = true;
        }

        // We are not started in an action dialog, or already full_dialog.
        // Just open a stage. A dialog will be opened if it was not already open.
        self.renderStage(stage, callback, stage_opts);
    },

    /**
     *
     *
     *
     */

    rest: function(api_method, params, callback, errback, notifycallback)
    {
        var self = this;

        $.any.rest.post(
                   api_method,
                   params,
                   callback,
                   function (error)
                   {
                       //Call  default error handler and chain to given callback
                       if (typeof errback == 'function')
                       {
                           errback(error);
                       }
                       else
                       {
                           self.errback(error);
                       }
                   },
                   function (message)
                   {
                       self.notifycallback(message);

                       if (typeof notifycallback == 'function')
                       {
                           notifycallback(message);
                       }
                   });
    },

    errback: function( error )
    {
        var self = this;
        self.element.html('<div class="error action-stage-wrapper clearfix">' + error.message + '</div>');
    },

    notifycallback: function ( notice )
    {
        var self = this;
        $.any.notification.notice(notice.message, $.any.notification.getNotificationElement(self.element));
    },

    /**
     * Finishing the action flow: when we were in "full dialog" mode,
     * we show the other actions again, and reload the initial action
     * template.
     */
    close: function( callback )
    {
        var self = this;

        // If we opened a dialog, close it.
        if (self.priv.my_dialog)
        {
            $.any.dialog.close();
        }

        // refresh the action template where we came from.
        this.renderStage('close', function()
                         {
                             // If we were full_dialog in the action dialog, show the other actions again.
                             self._tryCloseFullDialog();

                             // Broadcast my own event
                             self.publish(self.priv.closePublishKey);
                             if (typeof callback == 'function')
                             {
                                 callback();
                             }
                         }
                        );
    },


    /**
     * call_close: wrapper function for <button class="do_action {call: 'close'}">
     */
    callClose: function ( vars )
    {
        this.close();
    },


    /**
     * Aborting the action flow. This shows the initial HTML again in
       the container div, without doing an ajax call to reload it.
     */
    cancel: function( )
    {
        var self = this;

        // If we opened a dialog, close it.
        if (self.priv.my_dialog)
        {
            $.any.dialog.close();
        }

        // If we were full_dialog in the action dialog, show the other actions again.
        self._tryCloseFullDialog();

        // Put original html back
        self.element.html(self.priv.originalHTML);
        self.element.removeClass("highlighted");
        $.any.ui.scan(self.element[0]);

        // Remove any help texts
        $.any.dialog.removeHelpText();
    },


    /**
     * callCancel: wrapper function for <button class="do_action {call: 'cancel'}">
     */
    callCancel: function ( vars )
    {
        this.cancel();
    },


    /**
     * Trigger the start of the action.
     */
    trigger: function ( )
    {
        var self = this;
        
        var b = $("button:first", this.element);
        if (b.length)
        {
            b.click();
        }
        else
        {
            throw("Trigger action: No button found.");
        }
    },


    /* Private functions */

    _tryCloseFullDialog: function ( )
    {
        var self = this;
        if (self._inActionDialog() && self.priv.full_dialog)
        {
            self.element.parent('#action').children().show();
            self.priv.full_dialog = false;
            $.any.dialog.setTitle(self.priv.original_dialog_title);
            delete self.priv.original_dialog_title;
        }
    },

    _inActionDialog: function ( )
    {
        if (this.element.parent('#action').length > 0)
        {
            return true;
        }
        var p = this.parent();
        while (p && p.base != 'action') p = p.parent();
        if (p)
        {
            return p._inActionDialog();
        }
        return false;
    }

},
/**
 *  The defaults
 */
{
    /** by default, require the user to authenticate before starting the action. */
    require_logon: true
}
);

/**
 * The container for the prototypes.
 */
$.any.ui.action.prototypes = {};

/**
 * Register application logic code for the named action.
 */
$.any.ui.action.js = function ( action_name, logic_code )
{
    if (typeof $.any.ui.action.prototypes[action_name] == "object")
    {
        // Already registered; just ignore.
        return;
    }
    $.any.ui.action.prototypes[action_name] = logic_code;
};


/**
 * Widget for triggering actions on the containing do_action.
 *
 * Constructed like this:
 * <button class="do_action {call: 'Foo'}">,
 * it will call the function 'callFoo' on the containing do_action widget, with as argument all the button's options.
 */
$.any.ui("actionbutton",
{
    _init: function ()
    {
        var self = this;

        // lookup the containing action
        self.containingAction = self.parent();
        if (!self.containingAction)
        {
            throw('Error: you should always use a do_actionbutton inside a do_action!');
        }
        if (self.containingAction.base != "action")
        {
            throw('Error: actionbutton should have "action" as direct UI parent');
        }
        self.element.click(function() { self.handleClick();});
    },

    handleClick: function ()
    {
        var self = this;

        // Check if we require a logged on user.
        if (this.containingAction.options.require_logon && $.any.rest.userId == 0)
        {
            var opts = $.extend({}, this.containingAction.options);
            opts['action'] = opts['action_name'];
            delete opts['action_name'];
            delete opts['disabled'];
            delete opts['require_logon'];
            $.any.rest.requireLogon(opts);
            return false;
        }

        self.containingAction.priv.last_actionbutton = this;

        self.element.attr("disabled", "disabled")
        			.oneTime(10000, function()
                    {
                    	$(this).removeAttr('disabled');
                    });
        
        if (self.containingAction._inActionDialog())
        {
            self.element.next('.action-expl').show().html('<img src="http://static.mediamatic.nl/f/cgcz/image/throbberwait.gif" />');
        }


        if (this.options.call)
        {
            var fn = 'call' + this.options.call.substr(0,1).toUpperCase() + this.options.call.substr(1);
            if (typeof this.containingAction[fn] == 'function')
            {
                this.containingAction[fn](this.options);
            }
            else
            {
                throw('Programming error: action function "' + fn + '" does not exist.');
            }
        }
        else if (this.options.stage)
        {
            if (this.options.fulldialog)
            {
                this.containingAction.goFullDialog(this.options.stage, null, this.options);
            }
            else
            {
                this.containingAction.renderStage(this.options.stage, null, this.options);
            }
        }
        else
        {
            throw('Programming error: actionbutton without "call" or "stage" option');
        }
        return false;
    }

});

//
/*
 * jQuery Form Plugin
 * version: 2.28 (10-MAY-2009)
 * @requires jQuery v1.2.2 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */

// 

;(function($) {

/*
    Usage Note:
    -----------
    Do not use both ajaxSubmit and ajaxForm on the same form.  These
    functions are intended to be exclusive.  Use ajaxSubmit if you want
    to bind your own submit handler to the form.  For example,

    $(document).ready(function() {
        $('#myForm').bind('submit', function() {
            $(this).ajaxSubmit({
                target: '#output'
            });
            return false; // <-- important!
        });
    });

    Use ajaxForm when you want the plugin to manage all the event binding
    for you.  For example,

    $(document).ready(function() {
        $('#myForm').ajaxForm({
            target: '#output'
        });
    });

    When using ajaxForm, the ajaxSubmit function will be invoked for you
    at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
    if (!this.length) {
        log('ajaxSubmit: skipping submit process - no element selected');
        return this;
    }

    if (typeof options == 'function')
        options = { success: options };

    var url = $.trim(this.attr('action'));
    if (url) {
	    // clean url (don't include hash vaue)
	    url = (url.match(/^([^#]+)/)||[])[1];
   	}
   	url = url || window.location.href || ''

    options = $.extend({
        url:  url,
        type: this.attr('method') || 'GET'
    }, options || {});

    // hook for manipulating the form data before it is extracted;
    // convenient for use with rich editors like tinyMCE or FCKEditor
    var veto = {};
    this.trigger('form-pre-serialize', [this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
        return this;
    }

    // provide opportunity to alter form data before it is serialized
    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSerialize callback');
        return this;
    }

    var a = this.formToArray(options.semantic);
    if (options.data) {
        options.extraData = options.data;
        for (var n in options.data) {
          if(options.data[n] instanceof Array) {
            for (var k in options.data[n])
              a.push( { name: n, value: options.data[n][k] } );
          }
          else
             a.push( { name: n, value: options.data[n] } );
        }
    }

    // give pre-submit callback an opportunity to abort the submit
    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
        log('ajaxSubmit: submit aborted via beforeSubmit callback');
        return this;
    }

    // fire vetoable 'validate' event
    this.trigger('form-submit-validate', [a, this, options, veto]);
    if (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
        return this;
    }

    var q = $.param(a);

    if (options.type.toUpperCase() == 'GET') {
        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
        options.data = null;  // data is null for 'get'
    }
    else
        options.data = q; // data is the query string for 'post'

    var $form = this, callbacks = [];
    if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
    if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

    // perform a load on the target only if dataType is not provided
    if (!options.dataType && options.target) {
        var oldSuccess = options.success || function(){};
        callbacks.push(function(data) {
            $(options.target).html(data).each(oldSuccess, arguments);
        });
    }
    else if (options.success)
        callbacks.push(options.success);

    options.success = function(data, status) {
        for (var i=0, max=callbacks.length; i < max; i++)
            callbacks[i].apply(options, [data, status, $form]);
    };

    // are there files to upload?
    var files = $('input:file', this).fieldValue();
    var found = false;
    for (var j=0; j < files.length; j++)
        if (files[j])
            found = true;

	var multipart = false;
//	var mp = 'multipart/form-data';
//	multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);

    // options.iframe allows user to force iframe mode
   if (options.iframe || found || multipart) {
       // hack to fix Safari hang (thanks to Tim Molendijk for this)
       // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
       if (options.closeKeepAlive)
           $.get(options.closeKeepAlive, fileUpload);
       else
           fileUpload();
       }
   else
       $.ajax(options);

    // fire 'notify' event
    this.trigger('form-submit-notify', [this, options]);
    return this;


    // private function for handling file uploads (hat tip to YAHOO!)
    function fileUpload() {
        var form = $form[0];

        if ($(':input[name=submit]', form).length) {
            alert('Error: Form elements must not be named "submit".');
            return;
        }

        var opts = $.extend({}, $.ajaxSettings, options);
		var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

        var id = 'jqFormIO' + (new Date().getTime());
        var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />');
        var io = $io[0];

        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

        var xhr = { // mock object
            aborted: 0,
            responseText: null,
            responseXML: null,
            status: 0,
            statusText: 'n/a',
            getAllResponseHeaders: function() {},
            getResponseHeader: function() {},
            setRequestHeader: function() {},
            abort: function() {
                this.aborted = 1;
                $io.attr('src','about:blank'); // abort op in progress
            }
        };

        var g = opts.global;
        // trigger ajax global events so that activity/block indicators work like normal
        if (g && ! $.active++) $.event.trigger("ajaxStart");
        if (g) $.event.trigger("ajaxSend", [xhr, opts]);

		if (s.beforeSend && s.beforeSend(xhr, s) === false) {
			s.global && $.active--;
			return;
        }
        if (xhr.aborted)
            return;

        var cbInvoked = 0;
        var timedOut = 0;

        // add submitting element to data if we know it
        var sub = form.clk;
        if (sub) {
            var n = sub.name;
            if (n && !sub.disabled) {
                options.extraData = options.extraData || {};
                options.extraData[n] = sub.value;
                if (sub.type == "image") {
                    options.extraData[name+'.x'] = form.clk_x;
                    options.extraData[name+'.y'] = form.clk_y;
                }
            }
        }

        // take a breath so that pending repaints get some cpu time before the upload starts
        setTimeout(function() {
            // make sure form attrs are set
            var t = $form.attr('target'), a = $form.attr('action');

			// update form attrs in IE friendly way
			form.setAttribute('target',id);
			if (form.getAttribute('method') != 'POST')
				form.setAttribute('method', 'POST');
			if (form.getAttribute('action') != opts.url)
				form.setAttribute('action', opts.url);

            // ie borks in some cases when setting encoding
            if (! options.skipEncodingOverride) {
                $form.attr({
                    encoding: 'multipart/form-data',
                    enctype:  'multipart/form-data'
                });
            }

            // support timout
            if (opts.timeout)
                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

            // add "extra" data to form if provided in options
            var extraInputs = [];
            try {
                if (options.extraData)
                    for (var n in options.extraData)
                        extraInputs.push(
                            $('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
                                .appendTo(form)[0]);

                // add iframe to doc and submit the form
                $io.appendTo('body');
                io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
                form.submit();
            }
            finally {
                // reset attrs and remove "extra" input elements
				form.setAttribute('action',a);
                t ? form.setAttribute('target', t) : $form.removeAttr('target');
                $(extraInputs).remove();
            }
        }, 10);

        var nullCheckFlag = 0;

        function cb() {
            if (cbInvoked++) return;

            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

            var ok = true;
            try {
                if (timedOut) throw 'timeout';
                // extract the server response from the iframe
                var data, doc;

                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;

                if ((doc.body == null || doc.body.innerHTML == '') && !nullCheckFlag) {
                    // in some browsers (cough, Opera 9.2.x) the iframe DOM is not always traversable when
                    // the onload callback fires, so we give them a 2nd chance
                    nullCheckFlag = 1;
                    cbInvoked--;
                    setTimeout(cb, 100);
                    return;
                }

                xhr.responseText = doc.body ? doc.body.innerHTML : null;
                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
                xhr.getResponseHeader = function(header){
                    var headers = {'content-type': opts.dataType};
                    return headers[header];
                };

                if (opts.dataType == 'json' || opts.dataType == 'script') {
                    var ta = doc.getElementsByTagName('textarea')[0];
                    xhr.responseText = ta ? ta.value : xhr.responseText;
                }
                else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
                    xhr.responseXML = toXml(xhr.responseText);
                }
                data = $.httpData(xhr, opts.dataType);
            }
            catch(e){
                ok = false;
                $.handleError(opts, xhr, 'error', e);
            }

            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
            if (ok) {
                opts.success(data, 'success');
                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
            }
            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
            if (g && ! --$.active) $.event.trigger("ajaxStop");
            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

            // clean up
            setTimeout(function() {
                $io.remove();
                xhr.responseXML = null;
            }, 100);
        };

        function toXml(s, doc) {
            if (window.ActiveXObject) {
                doc = new ActiveXObject('Microsoft.XMLDOM');
                doc.async = 'false';
                doc.loadXML(s);
            }
            else
                doc = (new DOMParser()).parseFromString(s, 'text/xml');
            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
        };
    };
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *    is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *    used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
    return this.ajaxFormUnbind().bind('submit.form-plugin',function() {
        $(this).ajaxSubmit(options);
        return false;
    }).each(function() {
        // store options in hash
        $(":submit,input:image", this).bind('click.form-plugin',function(e) {
            var form = this.form;
            form.clk = this;
            if (this.type == 'image') {
                if (e.offsetX != undefined) {
                    form.clk_x = e.offsetX;
                    form.clk_y = e.offsetY;
                } else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
                    var offset = $(this).offset();
                    form.clk_x = e.pageX - offset.left;
                    form.clk_y = e.pageY - offset.top;
                } else {
                    form.clk_x = e.pageX - this.offsetLeft;
                    form.clk_y = e.pageY - this.offsetTop;
                }
            }
            // clear form vars
            setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
        });
    });
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
    this.unbind('submit.form-plugin');
    return this.each(function() {
        $(":submit,input:image", this).unbind('click.form-plugin');
    });

};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
    var a = [];
    if (this.length == 0) return a;

    var form = this[0];
    var els = semantic ? form.getElementsByTagName('*') : form.elements;
    if (!els) return a;
    for(var i=0, max=els.length; i < max; i++) {
        var el = els[i];
        var n = el.name;
        if (!n) continue;

        if (semantic && form.clk && el.type == "image") {
            // handle image inputs on the fly when semantic == true
            if(!el.disabled && form.clk == el) {
            	a.push({name: n, value: $(el).val()});
                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
            }
            continue;
        }

        var v = $.fieldValue(el, true);
        if (v && v.constructor == Array) {
            for(var j=0, jmax=v.length; j < jmax; j++)
                a.push({name: n, value: v[j]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: n, value: v});
    }

    if (!semantic && form.clk) {
        // input type=='image' are not found in elements array! handle it here
        var $input = $(form.clk), input = $input[0], n = input.name;
        if (n && !input.disabled && input.type == 'image') {
        	a.push({name: n, value: $input.val()});
            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
        }
    }
    return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
    //hand off to jQuery.param for proper encoding
    return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
    var a = [];
    this.each(function() {
        var n = this.name;
        if (!n) return;
        var v = $.fieldValue(this, successful);
        if (v && v.constructor == Array) {
            for (var i=0,max=v.length; i < max; i++)
                a.push({name: n, value: v[i]});
        }
        else if (v !== null && typeof v != 'undefined')
            a.push({name: this.name, value: v});
    });
    //hand off to jQuery.param for proper encoding
    return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *      <input name="A" type="text" />
 *      <input name="A" type="text" />
 *      <input name="B" type="checkbox" value="B1" />
 *      <input name="B" type="checkbox" value="B2"/>
 *      <input name="C" type="radio" value="C1" />
 *      <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *       array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
    for (var val=[], i=0, max=this.length; i < max; i++) {
        var el = this[i];
        var v = $.fieldValue(el, successful);
        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
            continue;
        v.constructor == Array ? $.merge(val, v) : val.push(v);
    }
    return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
    if (typeof successful == 'undefined') successful = true;

    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
        (t == 'checkbox' || t == 'radio') && !el.checked ||
        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
        tag == 'select' && el.selectedIndex == -1))
            return null;

    if (tag == 'select') {
        var index = el.selectedIndex;
        if (index < 0) return null;
        var a = [], ops = el.options;
        var one = (t == 'select-one');
        var max = (one ? index+1 : ops.length);
        for(var i=(one ? index : 0); i < max; i++) {
            var op = ops[i];
            if (op.selected) {
				var v = op.value;
				if (!v) // extra pain for IE...
                	v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
                if (one) return v;
                a.push(v);
            }
        }
        return a;
    }
    return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
    return this.each(function() {
        $('input,select,textarea', this).clearFields();
    });
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
    return this.each(function() {
        var t = this.type, tag = this.tagName.toLowerCase();
        if (t == 'text' || t == 'password' || tag == 'textarea')
            this.value = '';
        else if (t == 'checkbox' || t == 'radio')
            this.checked = false;
        else if (tag == 'select')
            this.selectedIndex = -1;
    });
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
    return this.each(function() {
        // guard against an input with the name of 'reset'
        // note that IE reports the reset function as an 'object'
        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
            this.reset();
    });
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
    if (b == undefined) b = true;
    return this.each(function() {
        this.disabled = !b;
    });
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
    if (select == undefined) select = true;
    return this.each(function() {
        var t = this.type;
        if (t == 'checkbox' || t == 'radio')
            this.checked = select;
        else if (this.tagName.toLowerCase() == 'option') {
            var $sel = $(this).parent('select');
            if (select && $sel[0] && $sel[0].type == 'select-one') {
                // deselect all other options
                $sel.find('option').selected(false);
            }
            this.selected = select;
        }
    });
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
    if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
        window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);

// 