if (!("console" in window) || !("firebug" in console))
{
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml",
    "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];

    window.console = {};
    for (var i = 0; i < names.length; ++i) {
        window.console[names[i]] = function() {};
    }
}

var Prototype={Version:"1.6.0.2",Browser:{IE:!!(window.attachEvent&&!window.opera),Opera:!!window.opera,WebKit:navigator.userAgent.indexOf("AppleWebKit/")>-1,Gecko:navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")==-1,MobileSafari:!!navigator.userAgent.match(/Apple.*Mobile.*Safari/)},BrowserFeatures:{XPath:!!document.evaluate,ElementExtensions:!!window.HTMLElement,SpecificElementExtensions:document.createElement("div").__proto__&&document.createElement("div").__proto__!==document.createElement("form").__proto__},ScriptFragment:"<script[^>]*>([\\S\\s]*?)</script>",JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,emptyFunction:function(){
},K:function(x){
return x;
}};
if(Prototype.Browser.MobileSafari){
Prototype.BrowserFeatures.SpecificElementExtensions=false;
}
var Class={create:function(){
var _2=null,_3=$A(arguments);
if(Object.isFunction(_3[0])){
_2=_3.shift();
}
function _4(){
this.initialize.apply(this,arguments);
};
Object.extend(_4,Class.Methods);
_4.superclass=_2;
_4.subclasses=[];
if(_2){
var _5=function(){
};
_5.prototype=_2.prototype;
_4.prototype=new _5;
_2.subclasses.push(_4);
}
for(var i=0;i<_3.length;i++){
_4.addMethods(_3[i]);
}
if(!_4.prototype.initialize){
_4.prototype.initialize=Prototype.emptyFunction;
}
_4.prototype.constructor=_4;
return _4;
}};
Class.Methods={addMethods:function(_7){
var _8=this.superclass&&this.superclass.prototype;
var _9=Object.keys(_7);
if(!Object.keys({toString:true}).length){
_9.push("toString","valueOf");
}
for(var i=0,_b=_9.length;i<_b;i++){
var _c=_9[i],_d=_7[_c];
if(_8&&Object.isFunction(_d)&&_d.argumentNames().first()=="$super"){
var _e=_d,_d=Object.extend((function(m){
return function(){
return _8[m].apply(this,arguments);
};
})(_c).wrap(_e),{valueOf:function(){
return _e;
},toString:function(){
return _e.toString();
}});
}
this.prototype[_c]=_d;
}
return this;
}};
var Abstract={};
Object.extend=function(_10,_11){
for(var _12 in _11){
_10[_12]=_11[_12];
}
return _10;
};
Object.extend(Object,{inspect:function(_13){
try{
if(Object.isUndefined(_13)){
return "undefined";
}
if(_13===null){
return "null";
}
return _13.inspect?_13.inspect():String(_13);
}
catch(e){
if(e instanceof RangeError){
return "...";
}
throw e;
}
},toJSON:function(_14){
var _15=typeof _14;
switch(_15){
case "undefined":
case "function":
case "unknown":
return;
case "boolean":
return _14.toString();
}
if(_14===null){
return "null";
}
if(_14.toJSON){
return _14.toJSON();
}
if(Object.isElement(_14)){
return;
}
var _16=[];
for(var _17 in _14){
var _18=Object.toJSON(_14[_17]);
if(!Object.isUndefined(_18)){
_16.push(_17.toJSON()+": "+_18);
}
}
return "{"+_16.join(", ")+"}";
},toQueryString:function(_19){
return $H(_19).toQueryString();
},toHTML:function(_1a){
return _1a&&_1a.toHTML?_1a.toHTML():String.interpret(_1a);
},keys:function(_1b){
var _1c=[];
for(var _1d in _1b){
_1c.push(_1d);
}
return _1c;
},values:function(_1e){
var _1f=[];
for(var _20 in _1e){
_1f.push(_1e[_20]);
}
return _1f;
},clone:function(_21){
return Object.extend({},_21);
},isElement:function(_22){
return _22&&_22.nodeType==1;
},isArray:function(_23){
return _23!=null&&typeof _23=="object"&&"splice" in _23&&"join" in _23;
},isHash:function(_24){
return _24 instanceof Hash;
},isFunction:function(_25){
return typeof _25=="function";
},isString:function(_26){
return typeof _26=="string";
},isNumber:function(_27){
return typeof _27=="number";
},isUndefined:function(_28){
return typeof _28=="undefined";
}});
Object.extend(Function.prototype,{argumentNames:function(){
var _29=this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
return _29.length==1&&!_29[0]?[]:_29;
},bind:function(){
if(arguments.length<2&&Object.isUndefined(arguments[0])){
return this;
}
var _2a=this,_2b=$A(arguments),_2c=_2b.shift();
return function(){
return _2a.apply(_2c,_2b.concat($A(arguments)));
};
},bindAsEventListener:function(){
var _2d=this,_2e=$A(arguments),_2f=_2e.shift();
return function(_30){
return _2d.apply(_2f,[_30||window.event].concat(_2e));
};
},curry:function(){
if(!arguments.length){
return this;
}
var _31=this,_32=$A(arguments);
return function(){
return _31.apply(this,_32.concat($A(arguments)));
};
},delay:function(){
var _33=this,_34=$A(arguments),_35=_34.shift()*1000;
return window.setTimeout(function(){
return _33.apply(_33,_34);
},_35);
},wrap:function(_36){
var _37=this;
return function(){
return _36.apply(this,[_37.bind(this)].concat($A(arguments)));
};
},methodize:function(){
if(this._methodized){
return this._methodized;
}
var _38=this;
return this._methodized=function(){
return _38.apply(null,[this].concat($A(arguments)));
};
}});
Function.prototype.defer=Function.prototype.delay.curry(0.01);
Date.prototype.toJSON=function(){
return "\""+this.getUTCFullYear()+"-"+(this.getUTCMonth()+1).toPaddedString(2)+"-"+this.getUTCDate().toPaddedString(2)+"T"+this.getUTCHours().toPaddedString(2)+":"+this.getUTCMinutes().toPaddedString(2)+":"+this.getUTCSeconds().toPaddedString(2)+"Z\"";
};
var Try={these:function(){
var _39;
for(var i=0,_3b=arguments.length;i<_3b;i++){
var _3c=arguments[i];
try{
_39=_3c();
break;
}
catch(e){
}
}
return _39;
}};
RegExp.prototype.match=RegExp.prototype.test;
RegExp.escape=function(str){
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1");
};
var PeriodicalExecuter=Class.create({initialize:function(_3e,_3f){
this.callback=_3e;
this.frequency=_3f;
this.currentlyExecuting=false;
this.registerCallback();
},registerCallback:function(){
this.timer=setInterval(this.onTimerEvent.bind(this),this.frequency*1000);
},execute:function(){
this.callback(this);
},stop:function(){
if(!this.timer){
return;
}
clearInterval(this.timer);
this.timer=null;
},onTimerEvent:function(){
if(!this.currentlyExecuting){
try{
this.currentlyExecuting=true;
this.execute();
}
finally{
this.currentlyExecuting=false;
}
}
}});
Object.extend(String,{interpret:function(_40){
return _40==null?"":String(_40);
},specialChar:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\\":"\\\\"}});
Object.extend(String.prototype,{gsub:function(_41,_42){
var _43="",_44=this,_45;
_42=arguments.callee.prepareReplacement(_42);
while(_44.length>0){
if(_45=_44.match(_41)){
_43+=_44.slice(0,_45.index);
_43+=String.interpret(_42(_45));
_44=_44.slice(_45.index+_45[0].length);
}else{
_43+=_44,_44="";
}
}
return _43;
},sub:function(_46,_47,_48){
_47=this.gsub.prepareReplacement(_47);
_48=Object.isUndefined(_48)?1:_48;
return this.gsub(_46,function(_49){
if(--_48<0){
return _49[0];
}
return _47(_49);
});
},scan:function(_4a,_4b){
this.gsub(_4a,_4b);
return String(this);
},truncate:function(_4c,_4d){
_4c=_4c||30;
_4d=Object.isUndefined(_4d)?"...":_4d;
return this.length>_4c?this.slice(0,_4c-_4d.length)+_4d:String(this);
},strip:function(){
return this.replace(/^\s+/,"").replace(/\s+$/,"");
},stripTags:function(){
return this.replace(/<\/?[^>]+>/gi,"");
},stripScripts:function(){
return this.replace(new RegExp(Prototype.ScriptFragment,"img"),"");
},extractScripts:function(){
var _4e=new RegExp(Prototype.ScriptFragment,"img");
var _4f=new RegExp(Prototype.ScriptFragment,"im");
return (this.match(_4e)||[]).map(function(_50){
return (_50.match(_4f)||["",""])[1];
});
},evalScripts:function(){
return this.extractScripts().map(function(_51){
return eval(_51);
});
},escapeHTML:function(){
var _52=arguments.callee;
_52.text.data=this;
return _52.div.innerHTML;
},unescapeHTML:function(){
var div=new Element("div");
div.innerHTML=this.stripTags();
return div.childNodes[0]?(div.childNodes.length>1?$A(div.childNodes).inject("",function(_54,_55){
return _54+_55.nodeValue;
}):div.childNodes[0].nodeValue):"";
},toQueryParams:function(_56){
var _57=this.strip().match(/([^?#]*)(#.*)?$/);
if(!_57){
return {};
}
return _57[1].split(_56||"&").inject({},function(_58,_59){
if((_59=_59.split("="))[0]){
var key=decodeURIComponent(_59.shift());
var _5b=_59.length>1?_59.join("="):_59[0];
if(_5b!=undefined){
_5b=decodeURIComponent(_5b);
}
if(key in _58){
if(!Object.isArray(_58[key])){
_58[key]=[_58[key]];
}
_58[key].push(_5b);
}else{
_58[key]=_5b;
}
}
return _58;
});
},toArray:function(){
return this.split("");
},succ:function(){
return this.slice(0,this.length-1)+String.fromCharCode(this.charCodeAt(this.length-1)+1);
},times:function(_5c){
return _5c<1?"":new Array(_5c+1).join(this);
},camelize:function(){
var _5d=this.split("-"),len=_5d.length;
if(len==1){
return _5d[0];
}
var _5f=this.charAt(0)=="-"?_5d[0].charAt(0).toUpperCase()+_5d[0].substring(1):_5d[0];
for(var i=1;i<len;i++){
_5f+=_5d[i].charAt(0).toUpperCase()+_5d[i].substring(1);
}
return _5f;
},capitalize:function(){
return this.charAt(0).toUpperCase()+this.substring(1).toLowerCase();
},underscore:function(){
return this.gsub(/::/,"/").gsub(/([A-Z]+)([A-Z][a-z])/,"#{1}_#{2}").gsub(/([a-z\d])([A-Z])/,"#{1}_#{2}").gsub(/-/,"_").toLowerCase();
},dasherize:function(){
return this.gsub(/_/,"-");
},inspect:function(_61){
var _62=this.gsub(/[\x00-\x1f\\]/,function(_63){
var _64=String.specialChar[_63[0]];
return _64?_64:"\\u00"+_63[0].charCodeAt().toPaddedString(2,16);
});
if(_61){
return "\""+_62.replace(/"/g,"\\\"")+"\"";
}
return "'"+_62.replace(/'/g,"\\'")+"'";
},toJSON:function(){
return this.inspect(true);
},unfilterJSON:function(_65){
return this.sub(_65||Prototype.JSONFilter,"#{1}");
},isJSON:function(){
var str=this;
if(str.blank()){
return false;
}
str=this.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,"");
return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
},evalJSON:function(_67){
var _68=this.unfilterJSON();
try{
if(!_67||_68.isJSON()){
return eval("("+_68+")");
}
}
catch(e){
}
throw new SyntaxError("Badly formed JSON string: "+this.inspect());
},include:function(_69){
return this.indexOf(_69)>-1;
},startsWith:function(_6a){
return this.indexOf(_6a)===0;
},endsWith:function(_6b){
var d=this.length-_6b.length;
return d>=0&&this.lastIndexOf(_6b)===d;
},empty:function(){
return this=="";
},blank:function(){
return /^\s*$/.test(this);
},interpolate:function(_6d,_6e){
return new Template(this,_6e).evaluate(_6d);
}});
if(Prototype.Browser.WebKit||Prototype.Browser.IE){
Object.extend(String.prototype,{escapeHTML:function(){
return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
},unescapeHTML:function(){
return this.replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">");
}});
}
String.prototype.gsub.prepareReplacement=function(_6f){
if(Object.isFunction(_6f)){
return _6f;
}
var _70=new Template(_6f);
return function(_71){
return _70.evaluate(_71);
};
};
String.prototype.parseQuery=String.prototype.toQueryParams;
Object.extend(String.prototype.escapeHTML,{div:document.createElement("div"),text:document.createTextNode("")});
with(String.prototype.escapeHTML){
div.appendChild(text);
}
var Template=Class.create({initialize:function(_72,_73){
this.template=_72.toString();
this.pattern=_73||Template.Pattern;
},evaluate:function(_74){
if(Object.isFunction(_74.toTemplateReplacements)){
_74=_74.toTemplateReplacements();
}
return this.template.gsub(this.pattern,function(_75){
if(_74==null){
return "";
}
var _76=_75[1]||"";
if(_76=="\\"){
return _75[2];
}
var ctx=_74,_78=_75[3];
var _79=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
_75=_79.exec(_78);
if(_75==null){
return _76;
}
while(_75!=null){
var _7a=_75[1].startsWith("[")?_75[2].gsub("\\\\]","]"):_75[1];
ctx=ctx[_7a];
if(null==ctx||""==_75[3]){
break;
}
_78=_78.substring("["==_75[3]?_75[1].length:_75[0].length);
_75=_79.exec(_78);
}
return _76+String.interpret(ctx);
});
}});
Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;
var $break={};
var Enumerable={each:function(_7b,_7c){
var _7d=0;
_7b=_7b.bind(_7c);
try{
this._each(function(_7e){
_7b(_7e,_7d++);
});
}
catch(e){
if(e!=$break){
throw e;
}
}
return this;
},eachSlice:function(_7f,_80,_81){
_80=_80?_80.bind(_81):Prototype.K;
var _82=-_7f,_83=[],_84=this.toArray();
while((_82+=_7f)<_84.length){
_83.push(_84.slice(_82,_82+_7f));
}
return _83.collect(_80,_81);
},all:function(_85,_86){
_85=_85?_85.bind(_86):Prototype.K;
var _87=true;
this.each(function(_88,_89){
_87=_87&&!!_85(_88,_89);
if(!_87){
throw $break;
}
});
return _87;
},any:function(_8a,_8b){
_8a=_8a?_8a.bind(_8b):Prototype.K;
var _8c=false;
this.each(function(_8d,_8e){
if(_8c=!!_8a(_8d,_8e)){
throw $break;
}
});
return _8c;
},collect:function(_8f,_90){
_8f=_8f?_8f.bind(_90):Prototype.K;
var _91=[];
this.each(function(_92,_93){
_91.push(_8f(_92,_93));
});
return _91;
},detect:function(_94,_95){
_94=_94.bind(_95);
var _96;
this.each(function(_97,_98){
if(_94(_97,_98)){
_96=_97;
throw $break;
}
});
return _96;
},findAll:function(_99,_9a){
_99=_99.bind(_9a);
var _9b=[];
this.each(function(_9c,_9d){
if(_99(_9c,_9d)){
_9b.push(_9c);
}
});
return _9b;
},grep:function(_9e,_9f,_a0){
_9f=_9f?_9f.bind(_a0):Prototype.K;
var _a1=[];
if(Object.isString(_9e)){
_9e=new RegExp(_9e);
}
this.each(function(_a2,_a3){
if(_9e.match(_a2)){
_a1.push(_9f(_a2,_a3));
}
});
return _a1;
},include:function(_a4){
if(Object.isFunction(this.indexOf)){
if(this.indexOf(_a4)!=-1){
return true;
}
}
var _a5=false;
this.each(function(_a6){
if(_a6==_a4){
_a5=true;
throw $break;
}
});
return _a5;
},inGroupsOf:function(_a7,_a8){
_a8=Object.isUndefined(_a8)?null:_a8;
return this.eachSlice(_a7,function(_a9){
while(_a9.length<_a7){
_a9.push(_a8);
}
return _a9;
});
},inject:function(_aa,_ab,_ac){
_ab=_ab.bind(_ac);
this.each(function(_ad,_ae){
_aa=_ab(_aa,_ad,_ae);
});
return _aa;
},invoke:function(_af){
var _b0=$A(arguments).slice(1);
return this.map(function(_b1){
return _b1[_af].apply(_b1,_b0);
});
},max:function(_b2,_b3){
_b2=_b2?_b2.bind(_b3):Prototype.K;
var _b4;
this.each(function(_b5,_b6){
_b5=_b2(_b5,_b6);
if(_b4==null||_b5>=_b4){
_b4=_b5;
}
});
return _b4;
},min:function(_b7,_b8){
_b7=_b7?_b7.bind(_b8):Prototype.K;
var _b9;
this.each(function(_ba,_bb){
_ba=_b7(_ba,_bb);
if(_b9==null||_ba<_b9){
_b9=_ba;
}
});
return _b9;
},partition:function(_bc,_bd){
_bc=_bc?_bc.bind(_bd):Prototype.K;
var _be=[],_bf=[];
this.each(function(_c0,_c1){
(_bc(_c0,_c1)?_be:_bf).push(_c0);
});
return [_be,_bf];
},pluck:function(_c2){
var _c3=[];
this.each(function(_c4){
_c3.push(_c4[_c2]);
});
return _c3;
},reject:function(_c5,_c6){
_c5=_c5.bind(_c6);
var _c7=[];
this.each(function(_c8,_c9){
if(!_c5(_c8,_c9)){
_c7.push(_c8);
}
});
return _c7;
},sortBy:function(_ca,_cb){
_ca=_ca.bind(_cb);
return this.map(function(_cc,_cd){
return {value:_cc,criteria:_ca(_cc,_cd)};
}).sort(function(_ce,_cf){
var a=_ce.criteria,b=_cf.criteria;
return a<b?-1:a>b?1:0;
}).pluck("value");
},toArray:function(){
return this.map();
},zip:function(){
var _d2=Prototype.K,_d3=$A(arguments);
if(Object.isFunction(_d3.last())){
_d2=_d3.pop();
}
var _d4=[this].concat(_d3).map($A);
return this.map(function(_d5,_d6){
return _d2(_d4.pluck(_d6));
});
},size:function(){
return this.toArray().length;
},inspect:function(){
return "#<Enumerable:"+this.toArray().inspect()+">";
}};
Object.extend(Enumerable,{map:Enumerable.collect,find:Enumerable.detect,select:Enumerable.findAll,filter:Enumerable.findAll,member:Enumerable.include,entries:Enumerable.toArray,every:Enumerable.all,some:Enumerable.any});
function $A(_d7){
if(!_d7){
return [];
}
if(_d7.toArray){
return _d7.toArray();
}
var _d8=_d7.length||0,_d9=new Array(_d8);
while(_d8--){
_d9[_d8]=_d7[_d8];
}
return _d9;
};
if(Prototype.Browser.WebKit){
$A=function(_da){
if(!_da){
return [];
}
if(!(Object.isFunction(_da)&&_da=="[object NodeList]")&&_da.toArray){
return _da.toArray();
}
var _db=_da.length||0,_dc=new Array(_db);
while(_db--){
_dc[_db]=_da[_db];
}
return _dc;
};
}
Array.from=$A;
Object.extend(Array.prototype,Enumerable);
if(!Array.prototype._reverse){
Array.prototype._reverse=Array.prototype.reverse;
}
Object.extend(Array.prototype,{_each:function(_dd){
for(var i=0,_df=this.length;i<_df;i++){
_dd(this[i]);
}
},clear:function(){
this.length=0;
return this;
},first:function(){
return this[0];
},last:function(){
return this[this.length-1];
},compact:function(){
return this.select(function(_e0){
return _e0!=null;
});
},flatten:function(){
return this.inject([],function(_e1,_e2){
return _e1.concat(Object.isArray(_e2)?_e2.flatten():[_e2]);
});
},without:function(){
var _e3=$A(arguments);
return this.select(function(_e4){
return !_e3.include(_e4);
});
},reverse:function(_e5){
return (_e5!==false?this:this.toArray())._reverse();
},reduce:function(){
return this.length>1?this:this[0];
},uniq:function(_e6){
return this.inject([],function(_e7,_e8,_e9){
if(0==_e9||(_e6?_e7.last()!=_e8:!_e7.include(_e8))){
_e7.push(_e8);
}
return _e7;
});
},intersect:function(_ea){
return this.uniq().findAll(function(_eb){
return _ea.detect(function(_ec){
return _eb===_ec;
});
});
},clone:function(){
return [].concat(this);
},size:function(){
return this.length;
},inspect:function(){
return "["+this.map(Object.inspect).join(", ")+"]";
},toJSON:function(){
var _ed=[];
this.each(function(_ee){
var _ef=Object.toJSON(_ee);
if(!Object.isUndefined(_ef)){
_ed.push(_ef);
}
});
return "["+_ed.join(", ")+"]";
}});
if(Object.isFunction(Array.prototype.forEach)){
Array.prototype._each=Array.prototype.forEach;
}
if(!Array.prototype.indexOf){
Array.prototype.indexOf=function(_f0,i){
i||(i=0);
var _f2=this.length;
if(i<0){
i=_f2+i;
}
for(;i<_f2;i++){
if(this[i]===_f0){
return i;
}
}
return -1;
};
}
if(!Array.prototype.lastIndexOf){
Array.prototype.lastIndexOf=function(_f3,i){
i=isNaN(i)?this.length:(i<0?this.length+i:i)+1;
var n=this.slice(0,i).reverse().indexOf(_f3);
return (n<0)?n:i-n-1;
};
}
Array.prototype.toArray=Array.prototype.clone;
function $w(_f6){
if(!Object.isString(_f6)){
return [];
}
_f6=_f6.strip();
return _f6?_f6.split(/\s+/):[];
};
if(Prototype.Browser.Opera){
Array.prototype.concat=function(){
var _f7=[];
for(var i=0,_f9=this.length;i<_f9;i++){
_f7.push(this[i]);
}
for(var i=0,_f9=arguments.length;i<_f9;i++){
if(Object.isArray(arguments[i])){
for(var j=0,_fb=arguments[i].length;j<_fb;j++){
_f7.push(arguments[i][j]);
}
}else{
_f7.push(arguments[i]);
}
}
return _f7;
};
}
Object.extend(Number.prototype,{toColorPart:function(){
return this.toPaddedString(2,16);
},succ:function(){
return this+1;
},times:function(_fc){
$R(0,this,true).each(_fc);
return this;
},toPaddedString:function(_fd,_fe){
var _ff=this.toString(_fe||10);
return "0".times(_fd-_ff.length)+_ff;
},toJSON:function(){
return isFinite(this)?this.toString():"null";
}});
$w("abs round ceil floor").each(function(_100){
Number.prototype[_100]=Math[_100].methodize();
});
function $H(_101){
return new Hash(_101);
};
var Hash=Class.create(Enumerable,(function(){
function _102(key,_104){
if(Object.isUndefined(_104)){
return key;
}
return key+"="+encodeURIComponent(String.interpret(_104));
};
return {initialize:function(_105){
this._object=Object.isHash(_105)?_105.toObject():Object.clone(_105);
},_each:function(_106){
for(var key in this._object){
var _108=this._object[key],pair=[key,_108];
pair.key=key;
pair.value=_108;
_106(pair);
}
},set:function(key,_10b){
return this._object[key]=_10b;
},get:function(key){
return this._object[key];
},unset:function(key){
var _10e=this._object[key];
delete this._object[key];
return _10e;
},toObject:function(){
return Object.clone(this._object);
},keys:function(){
return this.pluck("key");
},values:function(){
return this.pluck("value");
},index:function(_10f){
var _110=this.detect(function(pair){
return pair.value===_10f;
});
return _110&&_110.key;
},merge:function(_112){
return this.clone().update(_112);
},update:function(_113){
return new Hash(_113).inject(this,function(_114,pair){
_114.set(pair.key,pair.value);
return _114;
});
},toQueryString:function(){
return this.map(function(pair){
var key=encodeURIComponent(pair.key),_118=pair.value;
if(_118&&typeof _118=="object"){
if(Object.isArray(_118)){
return _118.map(_102.curry(key)).join("&");
}
}
return _102(key,_118);
}).join("&");
},inspect:function(){
return "#<Hash:{"+this.map(function(pair){
return pair.map(Object.inspect).join(": ");
}).join(", ")+"}>";
},toJSON:function(){
return Object.toJSON(this.toObject());
},clone:function(){
return new Hash(this);
}};
})());
Hash.prototype.toTemplateReplacements=Hash.prototype.toObject;
Hash.from=$H;
var ObjectRange=Class.create(Enumerable,{initialize:function(_11a,end,_11c){
this.start=_11a;
this.end=end;
this.exclusive=_11c;
},_each:function(_11d){
var _11e=this.start;
while(this.include(_11e)){
_11d(_11e);
_11e=_11e.succ();
}
},include:function(_11f){
if(_11f<this.start){
return false;
}
if(this.exclusive){
return _11f<this.end;
}
return _11f<=this.end;
}});
var $R=function(_120,end,_122){
return new ObjectRange(_120,end,_122);
};
var Ajax={getTransport:function(){
return Try.these(function(){
return new XMLHttpRequest();
},function(){
return new ActiveXObject("Msxml2.XMLHTTP");
},function(){
return new ActiveXObject("Microsoft.XMLHTTP");
})||false;
},activeRequestCount:0};
Ajax.Responders={responders:[],_each:function(_123){
this.responders._each(_123);
},register:function(_124){
if(!this.include(_124)){
this.responders.push(_124);
}
},unregister:function(_125){
this.responders=this.responders.without(_125);
},dispatch:function(_126,_127,_128,json){
this.each(function(_12a){
if(Object.isFunction(_12a[_126])){
try{
_12a[_126].apply(_12a,[_127,_128,json]);
}
catch(e){
}
}
});
}};
Object.extend(Ajax.Responders,Enumerable);
Ajax.Responders.register({onCreate:function(){
Ajax.activeRequestCount++;
},onComplete:function(){
Ajax.activeRequestCount--;
}});
Ajax.Base=Class.create({initialize:function(_12b){
this.options={method:"post",asynchronous:true,contentType:"application/x-www-form-urlencoded",encoding:"UTF-8",parameters:"",evalJSON:true,evalJS:true};
Object.extend(this.options,_12b||{});
this.options.method=this.options.method.toLowerCase();
if(Object.isString(this.options.parameters)){
this.options.parameters=this.options.parameters.toQueryParams();
}else{
if(Object.isHash(this.options.parameters)){
this.options.parameters=this.options.parameters.toObject();
}
}
}});
Ajax.Request=Class.create(Ajax.Base,{_complete:false,initialize:function($super,url,_12e){
$super(_12e);
this.transport=Ajax.getTransport();
this.request(url);
},request:function(url){
this.url=url;
this.method=this.options.method;
var _130=Object.clone(this.options.parameters);
if(!["get","post"].include(this.method)){
_130["_method"]=this.method;
this.method="post";
}
this.parameters=_130;
if(_130=Object.toQueryString(_130)){
if(this.method=="get"){
this.url+=(this.url.include("?")?"&":"?")+_130;
}else{
if(/Konqueror|Safari|KHTML/.test(navigator.userAgent)){
_130+="&_=";
}
}
}
try{
var _131=new Ajax.Response(this);
if(this.options.onCreate){
this.options.onCreate(_131);
}
Ajax.Responders.dispatch("onCreate",this,_131);
this.transport.open(this.method.toUpperCase(),this.url,this.options.asynchronous);
if(this.options.asynchronous){
this.respondToReadyState.bind(this).defer(1);
}
this.transport.onreadystatechange=this.onStateChange.bind(this);
this.setRequestHeaders();
this.body=this.method=="post"?(this.options.postBody||_130):null;
this.transport.send(this.body);
if(!this.options.asynchronous&&this.transport.overrideMimeType){
this.onStateChange();
}
}
catch(e){
this.dispatchException(e);
}
},onStateChange:function(){
var _132=this.transport.readyState;
if(_132>1&&!((_132==4)&&this._complete)){
this.respondToReadyState(this.transport.readyState);
}
},setRequestHeaders:function(){
var _133={"X-Requested-With":"XMLHttpRequest","X-Prototype-Version":Prototype.Version,"Accept":"text/javascript, text/html, application/xml, text/xml, */*"};
if(this.method=="post"){
_133["Content-type"]=this.options.contentType+(this.options.encoding?"; charset="+this.options.encoding:"");
if(this.transport.overrideMimeType&&(navigator.userAgent.match(/Gecko\/(\d{4})/)||[0,2005])[1]<2005){
_133["Connection"]="close";
}
}
if(typeof this.options.requestHeaders=="object"){
var _134=this.options.requestHeaders;
if(Object.isFunction(_134.push)){
for(var i=0,_136=_134.length;i<_136;i+=2){
_133[_134[i]]=_134[i+1];
}
}else{
$H(_134).each(function(pair){
_133[pair.key]=pair.value;
});
}
}
for(var name in _133){
this.transport.setRequestHeader(name,_133[name]);
}
},success:function(){
var _139=this.getStatus();
return !_139||(_139>=200&&_139<300);
},getStatus:function(){
try{
return this.transport.status||0;
}
catch(e){
return 0;
}
},respondToReadyState:function(_13a){
var _13b=Ajax.Request.Events[_13a],_13c=new Ajax.Response(this);
if(_13b=="Complete"){
try{
this._complete=true;
(this.options["on"+_13c.status]||this.options["on"+(this.success()?"Success":"Failure")]||Prototype.emptyFunction)(_13c,_13c.headerJSON);
}
catch(e){
this.dispatchException(e);
}
var _13d=_13c.getHeader("Content-type");
if(this.options.evalJS=="force"||(this.options.evalJS&&this.isSameOrigin()&&_13d&&_13d.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i))){
this.evalResponse();
}
}
try{
(this.options["on"+_13b]||Prototype.emptyFunction)(_13c,_13c.headerJSON);
Ajax.Responders.dispatch("on"+_13b,this,_13c,_13c.headerJSON);
}
catch(e){
this.dispatchException(e);
}
if(_13b=="Complete"){
this.transport.onreadystatechange=Prototype.emptyFunction;
}
},isSameOrigin:function(){
var m=this.url.match(/^\s*https?:\/\/[^\/]*/);
return !m||(m[0]=="#{protocol}//#{domain}#{port}".interpolate({protocol:location.protocol,domain:document.domain,port:location.port?":"+location.port:""}));
},getHeader:function(name){
try{
return this.transport.getResponseHeader(name)||null;
}
catch(e){
return null;
}
},evalResponse:function(){
try{
return eval((this.transport.responseText||"").unfilterJSON());
}
catch(e){
this.dispatchException(e);
}
},dispatchException:function(_140){
(this.options.onException||Prototype.emptyFunction)(this,_140);
Ajax.Responders.dispatch("onException",this,_140);
}});
Ajax.Request.Events=["Uninitialized","Loading","Loaded","Interactive","Complete"];
Ajax.Response=Class.create({initialize:function(_141){
this.request=_141;
var _142=this.transport=_141.transport,_143=this.readyState=_142.readyState;
if((_143>2&&!Prototype.Browser.IE)||_143==4){
this.status=this.getStatus();
this.statusText=this.getStatusText();
this.responseText=String.interpret(_142.responseText);
this.headerJSON=this._getHeaderJSON();
}
if(_143==4){
var xml=_142.responseXML;
this.responseXML=Object.isUndefined(xml)?null:xml;
this.responseJSON=this._getResponseJSON();
}
},status:0,statusText:"",getStatus:Ajax.Request.prototype.getStatus,getStatusText:function(){
try{
return this.transport.statusText||"";
}
catch(e){
return "";
}
},getHeader:Ajax.Request.prototype.getHeader,getAllHeaders:function(){
try{
return this.getAllResponseHeaders();
}
catch(e){
return null;
}
},getResponseHeader:function(name){
return this.transport.getResponseHeader(name);
},getAllResponseHeaders:function(){
return this.transport.getAllResponseHeaders();
},_getHeaderJSON:function(){
var json=this.getHeader("X-JSON");
if(!json){
return null;
}
json=decodeURIComponent(escape(json));
try{
return json.evalJSON(this.request.options.sanitizeJSON||!this.request.isSameOrigin());
}
catch(e){
this.request.dispatchException(e);
}
},_getResponseJSON:function(){
var _147=this.request.options;
if(!_147.evalJSON||(_147.evalJSON!="force"&&!(this.getHeader("Content-type")||"").include("application/json"))||this.responseText.blank()){
return null;
}
try{
return this.responseText.evalJSON(_147.sanitizeJSON||!this.request.isSameOrigin());
}
catch(e){
this.request.dispatchException(e);
}
}});
Ajax.Updater=Class.create(Ajax.Request,{initialize:function(_148,_149,url,_14b){
this.container={success:(_149.success||_149),failure:(_149.failure||(_149.success?null:_149))};
_14b=Object.clone(_14b);
var _14c=_14b.onComplete;
_14b.onComplete=(function(_14d,json){
this.updateContent(_14d.responseText);
if(Object.isFunction(_14c)){
_14c(_14d,json);
}
}).bind(this);
_148(url,_14b);
},updateContent:function(_14f){
var _150=this.container[this.success()?"success":"failure"],_151=this.options;
if(!_151.evalScripts){
_14f=_14f.stripScripts();
}
if(_150=$(_150)){
if(_151.insertion){
if(Object.isString(_151.insertion)){
var _152={};
_152[_151.insertion]=_14f;
_150.insert(_152);
}else{
_151.insertion(_150,_14f);
}
}else{
_150.update(_14f);
}
}
}});
Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{initialize:function(_153,_154,url,_156){
_153(_156);
this.onComplete=this.options.onComplete;
this.frequency=(this.options.frequency||2);
this.decay=(this.options.decay||1);
this.updater={};
this.container=_154;
this.url=url;
this.start();
},start:function(){
this.options.onComplete=this.updateComplete.bind(this);
this.onTimerEvent();
},stop:function(){
this.updater.options.onComplete=undefined;
clearTimeout(this.timer);
(this.onComplete||Prototype.emptyFunction).apply(this,arguments);
},updateComplete:function(_157){
if(this.options.decay){
this.decay=(_157.responseText==this.lastText?this.decay*this.options.decay:1);
this.lastText=_157.responseText;
}
this.timer=this.onTimerEvent.bind(this).delay(this.decay*this.frequency);
},onTimerEvent:function(){
this.updater=new Ajax.Updater(this.container,this.url,this.options);
}});
function $(_158){
if(arguments.length>1){
for(var i=0,_15a=[],_15b=arguments.length;i<_15b;i++){
_15a.push($(arguments[i]));
}
return _15a;
}
if(Object.isString(_158)){
_158=document.getElementById(_158);
}
return Element.extend(_158);
};
if(Prototype.BrowserFeatures.XPath){
document._getElementsByXPath=function(_15c,_15d){
var _15e=[];
var _15f=document.evaluate(_15c,$(_15d)||document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
for(var i=0,_161=_15f.snapshotLength;i<_161;i++){
_15e.push(Element.extend(_15f.snapshotItem(i)));
}
return _15e;
};
}
if(!window.Node){
var Node={};
}
if(!Node.ELEMENT_NODE){
Object.extend(Node,{ELEMENT_NODE:1,ATTRIBUTE_NODE:2,TEXT_NODE:3,CDATA_SECTION_NODE:4,ENTITY_REFERENCE_NODE:5,ENTITY_NODE:6,PROCESSING_INSTRUCTION_NODE:7,COMMENT_NODE:8,DOCUMENT_NODE:9,DOCUMENT_TYPE_NODE:10,DOCUMENT_FRAGMENT_NODE:11,NOTATION_NODE:12});
}
(function(){
var _162=this.Element;
this.Element=function(_163,_164){
_164=_164||{};
_163=_163.toLowerCase();
var _165=Element.cache;
if(Prototype.Browser.IE&&_164.name){
_163="<"+_163+" name=\""+_164.name+"\">";
delete _164.name;
return Element.writeAttribute(document.createElement(_163),_164);
}
if(!_165[_163]){
_165[_163]=Element.extend(document.createElement(_163));
}
return Element.writeAttribute(_165[_163].cloneNode(false),_164);
};
Object.extend(this.Element,_162||{});
}).call(window);
Element.cache={};
Element.Methods={visible:function(_166){
return $(_166).style.display!="none";
},toggle:function(_167){
_167=$(_167);
Element[Element.visible(_167)?"hide":"show"](_167);
return _167;
},hide:function(_168){
$(_168).style.display="none";
return _168;
},show:function(_169){
$(_169).style.display="";
return _169;
},remove:function(_16a){
_16a=$(_16a);
_16a.parentNode.removeChild(_16a);
return _16a;
},update:function(_16b,_16c){
_16b=$(_16b);
if(_16c&&_16c.toElement){
_16c=_16c.toElement();
}
if(Object.isElement(_16c)){
return _16b.update().insert(_16c);
}
_16c=Object.toHTML(_16c);
_16b.innerHTML=_16c.stripScripts();
_16c.evalScripts.bind(_16c).defer();
return _16b;
},replace:function(_16d,_16e){
_16d=$(_16d);
if(_16e&&_16e.toElement){
_16e=_16e.toElement();
}else{
if(!Object.isElement(_16e)){
_16e=Object.toHTML(_16e);
var _16f=_16d.ownerDocument.createRange();
_16f.selectNode(_16d);
_16e.evalScripts.bind(_16e).defer();
_16e=_16f.createContextualFragment(_16e.stripScripts());
}
}
_16d.parentNode.replaceChild(_16e,_16d);
return _16d;
},insert:function(_170,_171){
_170=$(_170);
if(Object.isString(_171)||Object.isNumber(_171)||Object.isElement(_171)||(_171&&(_171.toElement||_171.toHTML))){
_171={bottom:_171};
}
var _172,_173,_174,_175;
for(var _176 in _171){
_172=_171[_176];
_176=_176.toLowerCase();
_173=Element._insertionTranslations[_176];
if(_172&&_172.toElement){
_172=_172.toElement();
}
if(Object.isElement(_172)){
_173(_170,_172);
continue;
}
_172=Object.toHTML(_172);
_174=((_176=="before"||_176=="after")?_170.parentNode:_170).tagName.toUpperCase();
_175=Element._getContentFromAnonymousElement(_174,_172.stripScripts());
if(_176=="top"||_176=="after"){
_175.reverse();
}
_175.each(_173.curry(_170));
_172.evalScripts.bind(_172).defer();
}
return _170;
},wrap:function(_177,_178,_179){
_177=$(_177);
if(Object.isElement(_178)){
$(_178).writeAttribute(_179||{});
}else{
if(Object.isString(_178)){
_178=new Element(_178,_179);
}else{
_178=new Element("div",_178);
}
}
if(_177.parentNode){
_177.parentNode.replaceChild(_178,_177);
}
_178.appendChild(_177);
return _178;
},inspect:function(_17a){
_17a=$(_17a);
var _17b="<"+_17a.tagName.toLowerCase();
$H({"id":"id","className":"class"}).each(function(pair){
var _17d=pair.first(),_17e=pair.last();
var _17f=(_17a[_17d]||"").toString();
if(_17f){
_17b+=" "+_17e+"="+_17f.inspect(true);
}
});
return _17b+">";
},recursivelyCollect:function(_180,_181){
_180=$(_180);
var _182=[];
while(_180=_180[_181]){
if(_180.nodeType==1){
_182.push(Element.extend(_180));
}
}
return _182;
},ancestors:function(_183){
return $(_183).recursivelyCollect("parentNode");
},descendants:function(_184){
return $(_184).select("*");
},firstDescendant:function(_185){
_185=$(_185).firstChild;
while(_185&&_185.nodeType!=1){
_185=_185.nextSibling;
}
return $(_185);
},immediateDescendants:function(_186){
if(!(_186=$(_186).firstChild)){
return [];
}
while(_186&&_186.nodeType!=1){
_186=_186.nextSibling;
}
if(_186){
return [_186].concat($(_186).nextSiblings());
}
return [];
},previousSiblings:function(_187){
return $(_187).recursivelyCollect("previousSibling");
},nextSiblings:function(_188){
return $(_188).recursivelyCollect("nextSibling");
},siblings:function(_189){
_189=$(_189);
return _189.previousSiblings().reverse().concat(_189.nextSiblings());
},match:function(_18a,_18b){
if(Object.isString(_18b)){
_18b=new Selector(_18b);
}
return _18b.match($(_18a));
},up:function(_18c,_18d,_18e){
_18c=$(_18c);
if(arguments.length==1){
return $(_18c.parentNode);
}
var _18f=_18c.ancestors();
return Object.isNumber(_18d)?_18f[_18d]:Selector.findElement(_18f,_18d,_18e);
},down:function(_190,_191,_192){
_190=$(_190);
if(arguments.length==1){
return _190.firstDescendant();
}
return Object.isNumber(_191)?_190.descendants()[_191]:_190.select(_191)[_192||0];
},previous:function(_193,_194,_195){
_193=$(_193);
if(arguments.length==1){
return $(Selector.handlers.previousElementSibling(_193));
}
var _196=_193.previousSiblings();
return Object.isNumber(_194)?_196[_194]:Selector.findElement(_196,_194,_195);
},next:function(_197,_198,_199){
_197=$(_197);
if(arguments.length==1){
return $(Selector.handlers.nextElementSibling(_197));
}
var _19a=_197.nextSiblings();
return Object.isNumber(_198)?_19a[_198]:Selector.findElement(_19a,_198,_199);
},select:function(){
var args=$A(arguments),_19c=$(args.shift());
return Selector.findChildElements(_19c,args);
},adjacent:function(){
var args=$A(arguments),_19e=$(args.shift());
return Selector.findChildElements(_19e.parentNode,args).without(_19e);
},identify:function(_19f){
_19f=$(_19f);
var id=_19f.readAttribute("id"),self=arguments.callee;
if(id){
return id;
}
do{
id="anonymous_element_"+self.counter++;
}while($(id));
_19f.writeAttribute("id",id);
return id;
},readAttribute:function(_1a2,name){
_1a2=$(_1a2);
if(Prototype.Browser.IE){
var t=Element._attributeTranslations.read;
if(t.values[name]){
return t.values[name](_1a2,name);
}
if(t.names[name]){
name=t.names[name];
}
if(name.include(":")){
return (!_1a2.attributes||!_1a2.attributes[name])?null:_1a2.attributes[name].value;
}
}
return _1a2.getAttribute(name);
},writeAttribute:function(_1a5,name,_1a7){
_1a5=$(_1a5);
var _1a8={},t=Element._attributeTranslations.write;
if(typeof name=="object"){
_1a8=name;
}else{
_1a8[name]=Object.isUndefined(_1a7)?true:_1a7;
}
for(var attr in _1a8){
name=t.names[attr]||attr;
_1a7=_1a8[attr];
if(t.values[attr]){
name=t.values[attr](_1a5,_1a7);
}
if(_1a7===false||_1a7===null){
_1a5.removeAttribute(name);
}else{
if(_1a7===true){
_1a5.setAttribute(name,name);
}else{
_1a5.setAttribute(name,_1a7);
}
}
}
return _1a5;
},getHeight:function(_1ab){
return $(_1ab).getDimensions().height;
},getWidth:function(_1ac){
return $(_1ac).getDimensions().width;
},classNames:function(_1ad){
return new Element.ClassNames(_1ad);
},hasClassName:function(_1ae,_1af){
if(!(_1ae=$(_1ae))){
return;
}
var _1b0=_1ae.className;
return (_1b0.length>0&&(_1b0==_1af||new RegExp("(^|\\s)"+_1af+"(\\s|$)").test(_1b0)));
},addClassName:function(_1b1,_1b2){
if(!(_1b1=$(_1b1))){
return;
}
if(!_1b1.hasClassName(_1b2)){
_1b1.className+=(_1b1.className?" ":"")+_1b2;
}
return _1b1;
},removeClassName:function(_1b3,_1b4){
if(!(_1b3=$(_1b3))){
return;
}
_1b3.className=_1b3.className.replace(new RegExp("(^|\\s+)"+_1b4+"(\\s+|$)")," ").strip();
return _1b3;
},toggleClassName:function(_1b5,_1b6){
if(!(_1b5=$(_1b5))){
return;
}
return _1b5[_1b5.hasClassName(_1b6)?"removeClassName":"addClassName"](_1b6);
},cleanWhitespace:function(_1b7){
_1b7=$(_1b7);
var node=_1b7.firstChild;
while(node){
var _1b9=node.nextSibling;
if(node.nodeType==3&&!/\S/.test(node.nodeValue)){
_1b7.removeChild(node);
}
node=_1b9;
}
return _1b7;
},empty:function(_1ba){
return $(_1ba).innerHTML.blank();
},descendantOf:function(_1bb,_1bc){
_1bb=$(_1bb),_1bc=$(_1bc);
var _1bd=_1bc;
if(_1bb.compareDocumentPosition){
return (_1bb.compareDocumentPosition(_1bc)&8)===8;
}
if(_1bb.sourceIndex&&!Prototype.Browser.Opera){
var e=_1bb.sourceIndex,a=_1bc.sourceIndex,_1c0=_1bc.nextSibling;
if(!_1c0){
do{
_1bc=_1bc.parentNode;
}while(!(_1c0=_1bc.nextSibling)&&_1bc.parentNode);
}
if(_1c0&&_1c0.sourceIndex){
return (e>a&&e<_1c0.sourceIndex);
}
}
while(_1bb=_1bb.parentNode){
if(_1bb==_1bd){
return true;
}
}
return false;
},scrollTo:function(_1c1){
_1c1=$(_1c1);
var pos=_1c1.cumulativeOffset();
window.scrollTo(pos[0],pos[1]);
return _1c1;
},getStyle:function(_1c3,_1c4){
_1c3=$(_1c3);
_1c4=_1c4=="float"?"cssFloat":_1c4.camelize();
var _1c5=_1c3.style[_1c4];
if(!_1c5){
var css=document.defaultView.getComputedStyle(_1c3,null);
_1c5=css?css[_1c4]:null;
}
if(_1c4=="opacity"){
return _1c5?parseFloat(_1c5):1;
}
return _1c5=="auto"?null:_1c5;
},getOpacity:function(_1c7){
return $(_1c7).getStyle("opacity");
},setStyle:function(_1c8,_1c9){
_1c8=$(_1c8);
var _1ca=_1c8.style,_1cb;
if(Object.isString(_1c9)){
_1c8.style.cssText+=";"+_1c9;
return _1c9.include("opacity")?_1c8.setOpacity(_1c9.match(/opacity:\s*(\d?\.?\d*)/)[1]):_1c8;
}
for(var _1cc in _1c9){
if(_1cc=="opacity"){
_1c8.setOpacity(_1c9[_1cc]);
}else{
_1ca[(_1cc=="float"||_1cc=="cssFloat")?(Object.isUndefined(_1ca.styleFloat)?"cssFloat":"styleFloat"):_1cc]=_1c9[_1cc];
}
}
return _1c8;
},setOpacity:function(_1cd,_1ce){
_1cd=$(_1cd);
_1cd.style.opacity=(_1ce==1||_1ce==="")?"":(_1ce<0.00001)?0:_1ce;
return _1cd;
},getDimensions:function(_1cf){
_1cf=$(_1cf);
var _1d0=$(_1cf).getStyle("display");
if(_1d0!="none"&&_1d0!=null){
return {width:_1cf.offsetWidth,height:_1cf.offsetHeight};
}
var els=_1cf.style;
var _1d2=els.visibility;
var _1d3=els.position;
var _1d4=els.display;
els.visibility="hidden";
els.position="absolute";
els.display="block";
var _1d5=_1cf.clientWidth;
var _1d6=_1cf.clientHeight;
els.display=_1d4;
els.position=_1d3;
els.visibility=_1d2;
return {width:_1d5,height:_1d6};
},makePositioned:function(_1d7){
_1d7=$(_1d7);
var pos=Element.getStyle(_1d7,"position");
if(pos=="static"||!pos){
_1d7._madePositioned=true;
_1d7.style.position="relative";
if(window.opera){
_1d7.style.top=0;
_1d7.style.left=0;
}
}
return _1d7;
},undoPositioned:function(_1d9){
_1d9=$(_1d9);
if(_1d9._madePositioned){
_1d9._madePositioned=undefined;
_1d9.style.position=_1d9.style.top=_1d9.style.left=_1d9.style.bottom=_1d9.style.right="";
}
return _1d9;
},makeClipping:function(_1da){
_1da=$(_1da);
if(_1da._overflow){
return _1da;
}
_1da._overflow=Element.getStyle(_1da,"overflow")||"auto";
if(_1da._overflow!=="hidden"){
_1da.style.overflow="hidden";
}
return _1da;
},undoClipping:function(_1db){
_1db=$(_1db);
if(!_1db._overflow){
return _1db;
}
_1db.style.overflow=_1db._overflow=="auto"?"":_1db._overflow;
_1db._overflow=null;
return _1db;
},cumulativeOffset:function(_1dc){
_1dc=$(_1dc);
var _1dd=0,_1de=0;
do{
_1dd+=_1dc.offsetTop||0;
_1de+=_1dc.offsetLeft||0;
_1dc=_1dc.offsetParent;
}while(_1dc);
return Element._returnOffset(_1de,_1dd);
},positionedOffset:function(_1df){
_1df=$(_1df);
var _1e0=0,_1e1=0;
do{
_1e0+=_1df.offsetTop||0;
_1e1+=_1df.offsetLeft||0;
_1df=_1df.offsetParent;
if(_1df){
if(_1df.tagName=="BODY"){
break;
}
var p=Element.getStyle(_1df,"position");
if(p!=="static"){
break;
}
}
}while(_1df);
return Element._returnOffset(_1e1,_1e0);
},absolutize:function(_1e3){
_1e3=$(_1e3);
if(_1e3.getStyle("position")=="absolute"){
return;
}
var _1e4=_1e3.positionedOffset();
var top=_1e4[1];
var left=_1e4[0];
var _1e7=_1e3.clientWidth;
var _1e8=_1e3.clientHeight;
_1e3._originalLeft=left-parseFloat(_1e3.style.left||0);
_1e3._originalTop=top-parseFloat(_1e3.style.top||0);
_1e3._originalWidth=_1e3.style.width;
_1e3._originalHeight=_1e3.style.height;
_1e3.style.position="absolute";
_1e3.style.top=top+"px";
_1e3.style.left=left+"px";
_1e3.style.width=_1e7+"px";
_1e3.style.height=_1e8+"px";
return _1e3;
},relativize:function(_1e9){
_1e9=$(_1e9);
if(_1e9.getStyle("position")=="relative"){
return;
}
_1e9.style.position="relative";
var top=parseFloat(_1e9.style.top||0)-(_1e9._originalTop||0);
var left=parseFloat(_1e9.style.left||0)-(_1e9._originalLeft||0);
_1e9.style.top=top+"px";
_1e9.style.left=left+"px";
_1e9.style.height=_1e9._originalHeight;
_1e9.style.width=_1e9._originalWidth;
return _1e9;
},cumulativeScrollOffset:function(_1ec){
_1ec=$(_1ec);
var _1ed=0,_1ee=0;
do{
_1ed+=_1ec.scrollTop||0;
_1ee+=_1ec.scrollLeft||0;
_1ec=_1ec.parentNode;
}while(_1ec);
return Element._returnOffset(_1ee,_1ed);
},getOffsetParent:function(_1ef){
_1ef=$(_1ef);
if(_1ef.offsetParent){
return $(_1ef.offsetParent);
}
if(_1ef==document.body){
return $(_1ef);
}
while((_1ef=_1ef.parentNode)&&_1ef!=document.body&&_1ef!=document){
if(Element.getStyle(_1ef,"position")!="static"){
return $(_1ef);
}
}
return $(document.body);
},viewportOffset:function(_1f0){
_1f0=$(_1f0);
var _1f1=0,_1f2=0;
var _1f3=_1f0;
do{
_1f1+=_1f3.offsetTop||0;
_1f2+=_1f3.offsetLeft||0;
if(_1f3.offsetParent==document.body&&Element.getStyle(_1f3,"position")=="absolute"){
break;
}
}while(_1f3=_1f3.offsetParent);
_1f3=_1f0;
do{
if(!Prototype.Browser.Opera||_1f3.tagName=="BODY"){
_1f1-=_1f3.scrollTop||0;
_1f2-=_1f3.scrollLeft||0;
}
}while(_1f3=_1f3.parentNode);
return Element._returnOffset(_1f2,_1f1);
},clonePosition:function(_1f4,_1f5){
_1f4=$(_1f4);
var _1f6=Object.extend({setLeft:true,setTop:true,setWidth:true,setHeight:true,offsetTop:0,offsetLeft:0},arguments[2]||{});
_1f5=$(_1f5);
var p=_1f5.viewportOffset();
var _1f8=[0,0];
var _1f9=null;
if(Element.getStyle(_1f4,"position")=="absolute"){
_1f9=_1f4.getOffsetParent();
_1f8=_1f9.viewportOffset();
}
if(_1f9==document.body){
_1f8[0]-=document.body.offsetLeft;
_1f8[1]-=document.body.offsetTop;
}
if(_1f6.setLeft){
_1f4.style.left=(p[0]-_1f8[0]+_1f6.offsetLeft)+"px";
}
if(_1f6.setTop){
_1f4.style.top=(p[1]-_1f8[1]+_1f6.offsetTop)+"px";
}
if(_1f6.setWidth){
_1f4.style.width=_1f5.offsetWidth+"px";
}
if(_1f6.setHeight){
_1f4.style.height=_1f5.offsetHeight+"px";
}
return _1f4;
}};
Element.Methods.identify.counter=1;
Object.extend(Element.Methods,{getElementsBySelector:Element.Methods.select,childElements:Element.Methods.immediateDescendants});
Element._attributeTranslations={write:{names:{className:"class",htmlFor:"for"},values:{}}};
if(Prototype.Browser.Opera){
Element.Methods.getStyle=Element.Methods.getStyle.wrap(function(_1fa,_1fb,_1fc){
switch(_1fc){
case "left":
case "top":
case "right":
case "bottom":
if(_1fa(_1fb,"position")==="static"){
return null;
}
case "height":
case "width":
if(!Element.visible(_1fb)){
return null;
}
var dim=parseInt(_1fa(_1fb,_1fc),10);
if(dim!==_1fb["offset"+_1fc.capitalize()]){
return dim+"px";
}
var _1fe;
if(_1fc==="height"){
_1fe=["border-top-width","padding-top","padding-bottom","border-bottom-width"];
}else{
_1fe=["border-left-width","padding-left","padding-right","border-right-width"];
}
return _1fe.inject(dim,function(memo,_200){
var val=_1fa(_1fb,_200);
return val===null?memo:memo-parseInt(val,10);
})+"px";
default:
return _1fa(_1fb,_1fc);
}
});
Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(function(_202,_203,_204){
if(_204==="title"){
return $(_203).title;
}
return _202(_203,_204);
});
}else{
if(Prototype.Browser.IE){
Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(function(_205,_206){
_206=$(_206);
var _207=_206.getStyle("position");
if(_207!=="static"){
return _205(_206);
}
_206.setStyle({position:"relative"});
var _208=_205(_206);
_206.setStyle({position:_207});
return _208;
});
$w("positionedOffset viewportOffset").each(function(_209){
Element.Methods[_209]=Element.Methods[_209].wrap(function(_20a,_20b){
_20b=$(_20b);
var _20c=_20b.getStyle("position");
if(_20c!=="static"){
return _20a(_20b);
}
var _20d=_20b.getOffsetParent();
if(_20d&&_20d.getStyle("position")==="fixed"){
_20d.setStyle({zoom:1});
}
_20b.setStyle({position:"relative"});
var _20e=_20a(_20b);
_20b.setStyle({position:_20c});
return _20e;
});
});
Element.Methods.getStyle=function(_20f,_210){
_20f=$(_20f);
_210=(_210=="float"||_210=="cssFloat")?"styleFloat":_210.camelize();
var _211=_20f.style[_210];
if(!_211&&_20f.currentStyle){
_211=_20f.currentStyle[_210];
}
if(_210=="opacity"){
if(_211=(_20f.getStyle("filter")||"").match(/alpha\(opacity=(.*)\)/)){
if(_211[1]){
return parseFloat(_211[1])/100;
}
}
return 1;
}
if(_211=="auto"){
if((_210=="width"||_210=="height")&&(_20f.getStyle("display")!="none")){
return _20f["offset"+_210.capitalize()]+"px";
}
return null;
}
return _211;
};
Element.Methods.setOpacity=function(_212,_213){
function _214(_215){
return _215.replace(/alpha\([^\)]*\)/gi,"");
};
_212=$(_212);
var _216=_212.currentStyle;
if((_216&&!_216.hasLayout)||(!_216&&_212.style.zoom=="normal")){
_212.style.zoom=1;
}
var _217=_212.getStyle("filter"),_218=_212.style;
if(_213==1||_213===""){
(_217=_214(_217))?_218.filter=_217:_218.removeAttribute("filter");
return _212;
}else{
if(_213<0.00001){
_213=0;
}
}
_218.filter=_214(_217)+"alpha(opacity="+(_213*100)+")";
return _212;
};
Element._attributeTranslations={read:{names:{"class":"className","for":"htmlFor"},values:{_getAttr:function(_219,_21a){
return _219.getAttribute(_21a,2);
},_getAttrNode:function(_21b,_21c){
var node=_21b.getAttributeNode(_21c);
return node?node.value:"";
},_getEv:function(_21e,_21f){
_21f=_21e.getAttribute(_21f);
return _21f?_21f.toString().slice(23,-2):null;
},_flag:function(_220,_221){
return $(_220).hasAttribute(_221)?_221:null;
},style:function(_222){
return _222.style.cssText.toLowerCase();
},title:function(_223){
return _223.title;
}}}};
Element._attributeTranslations.write={names:Object.extend({cellpadding:"cellPadding",cellspacing:"cellSpacing"},Element._attributeTranslations.read.names),values:{checked:function(_224,_225){
_224.checked=!!_225;
},style:function(_226,_227){
_226.style.cssText=_227?_227:"";
}}};
Element._attributeTranslations.has={};
$w("colSpan rowSpan vAlign dateTime accessKey tabIndex "+"encType maxLength readOnly longDesc").each(function(attr){
Element._attributeTranslations.write.names[attr.toLowerCase()]=attr;
Element._attributeTranslations.has[attr.toLowerCase()]=attr;
});
(function(v){
Object.extend(v,{href:v._getAttr,src:v._getAttr,type:v._getAttr,action:v._getAttrNode,disabled:v._flag,checked:v._flag,readonly:v._flag,multiple:v._flag,onload:v._getEv,onunload:v._getEv,onclick:v._getEv,ondblclick:v._getEv,onmousedown:v._getEv,onmouseup:v._getEv,onmouseover:v._getEv,onmousemove:v._getEv,onmouseout:v._getEv,onfocus:v._getEv,onblur:v._getEv,onkeypress:v._getEv,onkeydown:v._getEv,onkeyup:v._getEv,onsubmit:v._getEv,onreset:v._getEv,onselect:v._getEv,onchange:v._getEv});
})(Element._attributeTranslations.read.values);
}else{
if(Prototype.Browser.Gecko&&/rv:1\.8\.0/.test(navigator.userAgent)){
Element.Methods.setOpacity=function(_22a,_22b){
_22a=$(_22a);
_22a.style.opacity=(_22b==1)?0.999999:(_22b==="")?"":(_22b<0.00001)?0:_22b;
return _22a;
};
}else{
if(Prototype.Browser.WebKit){
Element.Methods.setOpacity=function(_22c,_22d){
_22c=$(_22c);
_22c.style.opacity=(_22d==1||_22d==="")?"":(_22d<0.00001)?0:_22d;
if(_22d==1){
if(_22c.tagName=="IMG"&&_22c.width){
_22c.width++;
_22c.width--;
}else{
try{
var n=document.createTextNode(" ");
_22c.appendChild(n);
_22c.removeChild(n);
}
catch(e){
}
}
}
return _22c;
};
Element.Methods.cumulativeOffset=function(_22f){
_22f=$(_22f);
var _230=0,_231=0;
do{
_230+=_22f.offsetTop||0;
_231+=_22f.offsetLeft||0;
if(_22f.offsetParent==document.body){
if(Element.getStyle(_22f,"position")=="absolute"){
break;
}
}
_22f=_22f.offsetParent;
}while(_22f);
return Element._returnOffset(_231,_230);
};
}
}
}
}
if(Prototype.Browser.IE||Prototype.Browser.Opera){
Element.Methods.update=function(_232,_233){
_232=$(_232);
if(_233&&_233.toElement){
_233=_233.toElement();
}
if(Object.isElement(_233)){
return _232.update().insert(_233);
}
_233=Object.toHTML(_233);
var _234=_232.tagName.toUpperCase();
if(_234 in Element._insertionTranslations.tags){
$A(_232.childNodes).each(function(node){
_232.removeChild(node);
});
Element._getContentFromAnonymousElement(_234,_233.stripScripts()).each(function(node){
_232.appendChild(node);
});
}else{
_232.innerHTML=_233.stripScripts();
}
_233.evalScripts.bind(_233).defer();
return _232;
};
}
if("outerHTML" in document.createElement("div")){
Element.Methods.replace=function(_237,_238){
_237=$(_237);
if(_238&&_238.toElement){
_238=_238.toElement();
}
if(Object.isElement(_238)){
_237.parentNode.replaceChild(_238,_237);
return _237;
}
_238=Object.toHTML(_238);
var _239=_237.parentNode,_23a=_239.tagName.toUpperCase();
if(Element._insertionTranslations.tags[_23a]){
var _23b=_237.next();
var _23c=Element._getContentFromAnonymousElement(_23a,_238.stripScripts());
_239.removeChild(_237);
if(_23b){
_23c.each(function(node){
_239.insertBefore(node,_23b);
});
}else{
_23c.each(function(node){
_239.appendChild(node);
});
}
}else{
_237.outerHTML=_238.stripScripts();
}
_238.evalScripts.bind(_238).defer();
return _237;
};
}
Element._returnOffset=function(l,t){
var _241=[l,t];
_241.left=l;
_241.top=t;
return _241;
};
Element._getContentFromAnonymousElement=function(_242,html){
var div=new Element("div"),t=Element._insertionTranslations.tags[_242];
if(t){
div.innerHTML=t[0]+html+t[1];
t[2].times(function(){
div=div.firstChild;
});
}else{
div.innerHTML=html;
}
return $A(div.childNodes);
};
Element._insertionTranslations={before:function(_246,node){
_246.parentNode.insertBefore(node,_246);
},top:function(_248,node){
_248.insertBefore(node,_248.firstChild);
},bottom:function(_24a,node){
_24a.appendChild(node);
},after:function(_24c,node){
_24c.parentNode.insertBefore(node,_24c.nextSibling);
},tags:{TABLE:["<table>","</table>",1],TBODY:["<table><tbody>","</tbody></table>",2],TR:["<table><tbody><tr>","</tr></tbody></table>",3],TD:["<table><tbody><tr><td>","</td></tr></tbody></table>",4],SELECT:["<select>","</select>",1]}};
(function(){
Object.extend(this.tags,{THEAD:this.tags.TBODY,TFOOT:this.tags.TBODY,TH:this.tags.TD});
}).call(Element._insertionTranslations);
Element.Methods.Simulated={hasAttribute:function(_24e,_24f){
_24f=Element._attributeTranslations.has[_24f]||_24f;
var node=$(_24e).getAttributeNode(_24f);
return node&&node.specified;
}};
Element.Methods.ByTag={};
Object.extend(Element,Element.Methods);
if(!Prototype.BrowserFeatures.ElementExtensions&&document.createElement("div").__proto__){
window.HTMLElement={};
window.HTMLElement.prototype=document.createElement("div").__proto__;
Prototype.BrowserFeatures.ElementExtensions=true;
}
Element.extend=(function(){
if(Prototype.BrowserFeatures.SpecificElementExtensions){
return Prototype.K;
}
var _251={},_252=Element.Methods.ByTag;
var _253=Object.extend(function(_254){
if(!_254||_254._extendedByPrototype||_254.nodeType!=1||_254==window){
return _254;
}
var _255=Object.clone(_251),_256=_254.tagName,_257,_258;
if(_252[_256]){
Object.extend(_255,_252[_256]);
}
for(_257 in _255){
_258=_255[_257];
if(Object.isFunction(_258)&&!(_257 in _254)){
_254[_257]=_258.methodize();
}
}
_254._extendedByPrototype=Prototype.emptyFunction;
return _254;
},{refresh:function(){
if(!Prototype.BrowserFeatures.ElementExtensions){
Object.extend(_251,Element.Methods);
Object.extend(_251,Element.Methods.Simulated);
}
}});
_253.refresh();
return _253;
})();
Element.hasAttribute=function(_259,_25a){
if((_259=$(_259)).hasAttribute){
return _259.hasAttribute(_25a);
}
return Element.Methods.Simulated.hasAttribute(_259,_25a);
};
Element.addMethods=function(_25b){
var F=Prototype.BrowserFeatures,T=Element.Methods.ByTag;
if(!_25b){
Object.extend(Form,Form.Methods);
Object.extend(Form.Element,Form.Element.Methods);
Object.extend(Element.Methods.ByTag,{"FORM":Object.clone(Form.Methods),"INPUT":Object.clone(Form.Element.Methods),"SELECT":Object.clone(Form.Element.Methods),"TEXTAREA":Object.clone(Form.Element.Methods)});
}
if(arguments.length==2){
var _25e=_25b;
_25b=arguments[1];
}
if(!_25e){
Object.extend(Element.Methods,_25b||{});
}else{
if(Object.isArray(_25e)){
_25e.each(_25f);
}else{
_25f(_25e);
}
}
function _25f(_260){
_260=_260.toUpperCase();
if(!Element.Methods.ByTag[_260]){
Element.Methods.ByTag[_260]={};
}
Object.extend(Element.Methods.ByTag[_260],_25b);
};
function copy(_262,_263,_264){
_264=_264||false;
for(var _265 in _262){
var _266=_262[_265];
if(!Object.isFunction(_266)){
continue;
}
if(!_264||!(_265 in _263)){
_263[_265]=_266.methodize();
}
}
};
function _267(_268){
var _269;
var _26a={"OPTGROUP":"OptGroup","TEXTAREA":"TextArea","P":"Paragraph","FIELDSET":"FieldSet","UL":"UList","OL":"OList","DL":"DList","DIR":"Directory","H1":"Heading","H2":"Heading","H3":"Heading","H4":"Heading","H5":"Heading","H6":"Heading","Q":"Quote","INS":"Mod","DEL":"Mod","A":"Anchor","IMG":"Image","CAPTION":"TableCaption","COL":"TableCol","COLGROUP":"TableCol","THEAD":"TableSection","TFOOT":"TableSection","TBODY":"TableSection","TR":"TableRow","TH":"TableCell","TD":"TableCell","FRAMESET":"FrameSet","IFRAME":"IFrame"};
if(_26a[_268]){
_269="HTML"+_26a[_268]+"Element";
}
if(window[_269]){
return window[_269];
}
_269="HTML"+_268+"Element";
if(window[_269]){
return window[_269];
}
_269="HTML"+_268.capitalize()+"Element";
if(window[_269]){
return window[_269];
}
window[_269]={};
window[_269].prototype=document.createElement(_268).__proto__;
return window[_269];
};
if(F.ElementExtensions){
copy(Element.Methods,HTMLElement.prototype);
copy(Element.Methods.Simulated,HTMLElement.prototype,true);
}
if(F.SpecificElementExtensions){
for(var tag in Element.Methods.ByTag){
var _26c=_267(tag);
if(Object.isUndefined(_26c)){
continue;
}
copy(T[tag],_26c.prototype);
}
}
Object.extend(Element,Element.Methods);
delete Element.ByTag;
if(Element.extend.refresh){
Element.extend.refresh();
}
Element.cache={};
};
document.viewport={getDimensions:function(){
var _26d={};
var B=Prototype.Browser;
$w("width height").each(function(d){
var D=d.capitalize();
_26d[d]=(B.WebKit&&!document.evaluate)?self["inner"+D]:(B.Opera)?document.body["client"+D]:document.documentElement["client"+D];
});
return _26d;
},getWidth:function(){
return this.getDimensions().width;
},getHeight:function(){
return this.getDimensions().height;
},getScrollOffsets:function(){
return Element._returnOffset(window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft,window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop);
}};
var Selector=Class.create({initialize:function(_271){
this.expression=_271.strip();
this.compileMatcher();
},shouldUseXPath:function(){
if(!Prototype.BrowserFeatures.XPath){
return false;
}
var e=this.expression;
if(Prototype.Browser.WebKit&&(e.include("-of-type")||e.include(":empty"))){
return false;
}
if((/(\[[\w-]*?:|:checked)/).test(this.expression)){
return false;
}
return true;
},compileMatcher:function(){
if(this.shouldUseXPath()){
return this.compileXPathMatcher();
}
var e=this.expression,ps=Selector.patterns,h=Selector.handlers,c=Selector.criteria,le,p,m;
if(Selector._cache[e]){
this.matcher=Selector._cache[e];
return;
}
this.matcher=["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];
while(e&&le!=e&&(/\S/).test(e)){
le=e;
for(var i in ps){
p=ps[i];
if(m=e.match(p)){
this.matcher.push(Object.isFunction(c[i])?c[i](m):new Template(c[i]).evaluate(m));
e=e.replace(m[0],"");
break;
}
}
}
this.matcher.push("return h.unique(n);\n}");
eval(this.matcher.join("\n"));
Selector._cache[this.expression]=this.matcher;
},compileXPathMatcher:function(){
var e=this.expression,ps=Selector.patterns,x=Selector.xpath,le,m;
if(Selector._cache[e]){
this.xpath=Selector._cache[e];
return;
}
this.matcher=[".//*"];
while(e&&le!=e&&(/\S/).test(e)){
le=e;
for(var i in ps){
if(m=e.match(ps[i])){
this.matcher.push(Object.isFunction(x[i])?x[i](m):new Template(x[i]).evaluate(m));
e=e.replace(m[0],"");
break;
}
}
}
this.xpath=this.matcher.join("");
Selector._cache[this.expression]=this.xpath;
},findElements:function(root){
root=root||document;
if(this.xpath){
return document._getElementsByXPath(this.xpath,root);
}
return this.matcher(root);
},match:function(_282){
this.tokens=[];
var e=this.expression,ps=Selector.patterns,as=Selector.assertions;
var le,p,m;
while(e&&le!==e&&(/\S/).test(e)){
le=e;
for(var i in ps){
p=ps[i];
if(m=e.match(p)){
if(as[i]){
this.tokens.push([i,Object.clone(m)]);
e=e.replace(m[0],"");
}else{
return this.findElements(document).include(_282);
}
}
}
}
var _28a=true,name,_28c;
for(var i=0,_28d;_28d=this.tokens[i];i++){
name=_28d[0],_28c=_28d[1];
if(!Selector.assertions[name](_282,_28c)){
_28a=false;
break;
}
}
return _28a;
},toString:function(){
return this.expression;
},inspect:function(){
return "#<Selector:"+this.expression.inspect()+">";
}});
Object.extend(Selector,{_cache:{},xpath:{descendant:"//*",child:"/*",adjacent:"/following-sibling::*[1]",laterSibling:"/following-sibling::*",tagName:function(m){
if(m[1]=="*"){
return "";
}
return "[local-name()='"+m[1].toLowerCase()+"' or local-name()='"+m[1].toUpperCase()+"']";
},className:"[contains(concat(' ', @class, ' '), ' #{1} ')]",id:"[@id='#{1}']",attrPresence:function(m){
m[1]=m[1].toLowerCase();
return new Template("[@#{1}]").evaluate(m);
},attr:function(m){
m[1]=m[1].toLowerCase();
m[3]=m[5]||m[6];
return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
},pseudo:function(m){
var h=Selector.xpath.pseudos[m[1]];
if(!h){
return "";
}
if(Object.isFunction(h)){
return h(m);
}
return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
},operators:{"=":"[@#{1}='#{3}']","!=":"[@#{1}!='#{3}']","^=":"[starts-with(@#{1}, '#{3}')]","$=":"[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']","*=":"[contains(@#{1}, '#{3}')]","~=":"[contains(concat(' ', @#{1}, ' '), ' #{3} ')]","|=":"[contains(concat('-', @#{1}, '-'), '-#{3}-')]"},pseudos:{"first-child":"[not(preceding-sibling::*)]","last-child":"[not(following-sibling::*)]","only-child":"[not(preceding-sibling::* or following-sibling::*)]","empty":"[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]","checked":"[@checked]","disabled":"[@disabled]","enabled":"[not(@disabled)]","not":function(m){
var e=m[6],p=Selector.patterns,x=Selector.xpath,le,v;
var _299=[];
while(e&&le!=e&&(/\S/).test(e)){
le=e;
for(var i in p){
if(m=e.match(p[i])){
v=Object.isFunction(x[i])?x[i](m):new Template(x[i]).evaluate(m);
_299.push("("+v.substring(1,v.length-1)+")");
e=e.replace(m[0],"");
break;
}
}
}
return "[not("+_299.join(" and ")+")]";
},"nth-child":function(m){
return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ",m);
},"nth-last-child":function(m){
return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ",m);
},"nth-of-type":function(m){
return Selector.xpath.pseudos.nth("position() ",m);
},"nth-last-of-type":function(m){
return Selector.xpath.pseudos.nth("(last() + 1 - position()) ",m);
},"first-of-type":function(m){
m[6]="1";
return Selector.xpath.pseudos["nth-of-type"](m);
},"last-of-type":function(m){
m[6]="1";
return Selector.xpath.pseudos["nth-last-of-type"](m);
},"only-of-type":function(m){
var p=Selector.xpath.pseudos;
return p["first-of-type"](m)+p["last-of-type"](m);
},nth:function(_2a3,m){
var mm,_2a6=m[6],_2a7;
if(_2a6=="even"){
_2a6="2n+0";
}
if(_2a6=="odd"){
_2a6="2n+1";
}
if(mm=_2a6.match(/^(\d+)$/)){
return "["+_2a3+"= "+mm[1]+"]";
}
if(mm=_2a6.match(/^(-?\d*)?n(([+-])(\d+))?/)){
if(mm[1]=="-"){
mm[1]=-1;
}
var a=mm[1]?Number(mm[1]):1;
var b=mm[2]?Number(mm[2]):0;
_2a7="[((#{fragment} - #{b}) mod #{a} = 0) and "+"((#{fragment} - #{b}) div #{a} >= 0)]";
return new Template(_2a7).evaluate({fragment:_2a3,a:a,b:b});
}
}}},criteria:{tagName:"n = h.tagName(n, r, \"#{1}\", c);      c = false;",className:"n = h.className(n, r, \"#{1}\", c);    c = false;",id:"n = h.id(n, r, \"#{1}\", c);           c = false;",attrPresence:"n = h.attrPresence(n, r, \"#{1}\", c); c = false;",attr:function(m){
m[3]=(m[5]||m[6]);
return new Template("n = h.attr(n, r, \"#{1}\", \"#{3}\", \"#{2}\", c); c = false;").evaluate(m);
},pseudo:function(m){
if(m[6]){
m[6]=m[6].replace(/"/g,"\\\"");
}
return new Template("n = h.pseudo(n, \"#{1}\", \"#{6}\", r, c); c = false;").evaluate(m);
},descendant:"c = \"descendant\";",child:"c = \"child\";",adjacent:"c = \"adjacent\";",laterSibling:"c = \"laterSibling\";"},patterns:{laterSibling:/^\s*~\s*/,child:/^\s*>\s*/,adjacent:/^\s*\+\s*/,descendant:/^\s/,tagName:/^\s*(\*|[\w\-]+)(\b|$)?/,id:/^#([\w\-\*]+)(\b|$)/,className:/^\.([\w\-\*]+)(\b|$)/,pseudo:/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,attrPresence:/^\[([\w]+)\]/,attr:/\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/},assertions:{tagName:function(_2ac,_2ad){
return _2ad[1].toUpperCase()==_2ac.tagName.toUpperCase();
},className:function(_2ae,_2af){
return Element.hasClassName(_2ae,_2af[1]);
},id:function(_2b0,_2b1){
return _2b0.id===_2b1[1];
},attrPresence:function(_2b2,_2b3){
return Element.hasAttribute(_2b2,_2b3[1]);
},attr:function(_2b4,_2b5){
var _2b6=Element.readAttribute(_2b4,_2b5[1]);
return _2b6&&Selector.operators[_2b5[2]](_2b6,_2b5[5]||_2b5[6]);
}},handlers:{concat:function(a,b){
for(var i=0,node;node=b[i];i++){
a.push(node);
}
return a;
},mark:function(_2bb){
var _2bc=Prototype.emptyFunction;
for(var i=0,node;node=_2bb[i];i++){
node._countedByPrototype=_2bc;
}
return _2bb;
},unmark:function(_2bf){
for(var i=0,node;node=_2bf[i];i++){
node._countedByPrototype=undefined;
}
return _2bf;
},index:function(_2c2,_2c3,_2c4){
_2c2._countedByPrototype=Prototype.emptyFunction;
if(_2c3){
for(var _2c5=_2c2.childNodes,i=_2c5.length-1,j=1;i>=0;i--){
var node=_2c5[i];
if(node.nodeType==1&&(!_2c4||node._countedByPrototype)){
node.nodeIndex=j++;
}
}
}else{
for(var i=0,j=1,_2c5=_2c2.childNodes;node=_2c5[i];i++){
if(node.nodeType==1&&(!_2c4||node._countedByPrototype)){
node.nodeIndex=j++;
}
}
}
},unique:function(_2c9){
if(_2c9.length==0){
return _2c9;
}
var _2ca=[],n;
for(var i=0,l=_2c9.length;i<l;i++){
if(!(n=_2c9[i])._countedByPrototype){
n._countedByPrototype=Prototype.emptyFunction;
_2ca.push(Element.extend(n));
}
}
return Selector.handlers.unmark(_2ca);
},descendant:function(_2ce){
var h=Selector.handlers;
for(var i=0,_2d1=[],node;node=_2ce[i];i++){
h.concat(_2d1,node.getElementsByTagName("*"));
}
return _2d1;
},child:function(_2d3){
var h=Selector.handlers;
for(var i=0,_2d6=[],node;node=_2d3[i];i++){
for(var j=0,_2d9;_2d9=node.childNodes[j];j++){
if(_2d9.nodeType==1&&_2d9.tagName!="!"){
_2d6.push(_2d9);
}
}
}
return _2d6;
},adjacent:function(_2da){
for(var i=0,_2dc=[],node;node=_2da[i];i++){
var next=this.nextElementSibling(node);
if(next){
_2dc.push(next);
}
}
return _2dc;
},laterSibling:function(_2df){
var h=Selector.handlers;
for(var i=0,_2e2=[],node;node=_2df[i];i++){
h.concat(_2e2,Element.nextSiblings(node));
}
return _2e2;
},nextElementSibling:function(node){
while(node=node.nextSibling){
if(node.nodeType==1){
return node;
}
}
return null;
},previousElementSibling:function(node){
while(node=node.previousSibling){
if(node.nodeType==1){
return node;
}
}
return null;
},tagName:function(_2e6,root,_2e8,_2e9){
var _2ea=_2e8.toUpperCase();
var _2eb=[],h=Selector.handlers;
if(_2e6){
if(_2e9){
if(_2e9=="descendant"){
for(var i=0,node;node=_2e6[i];i++){
h.concat(_2eb,node.getElementsByTagName(_2e8));
}
return _2eb;
}else{
_2e6=this[_2e9](_2e6);
}
if(_2e8=="*"){
return _2e6;
}
}
for(var i=0,node;node=_2e6[i];i++){
if(node.tagName.toUpperCase()===_2ea){
_2eb.push(node);
}
}
return _2eb;
}else{
return root.getElementsByTagName(_2e8);
}
},id:function(_2ef,root,id,_2f2){
var _2f3=$(id),h=Selector.handlers;
if(!_2f3){
return [];
}
if(!_2ef&&root==document){
return [_2f3];
}
if(_2ef){
if(_2f2){
if(_2f2=="child"){
for(var i=0,node;node=_2ef[i];i++){
if(_2f3.parentNode==node){
return [_2f3];
}
}
}else{
if(_2f2=="descendant"){
for(var i=0,node;node=_2ef[i];i++){
if(Element.descendantOf(_2f3,node)){
return [_2f3];
}
}
}else{
if(_2f2=="adjacent"){
for(var i=0,node;node=_2ef[i];i++){
if(Selector.handlers.previousElementSibling(_2f3)==node){
return [_2f3];
}
}
}else{
_2ef=h[_2f2](_2ef);
}
}
}
}
for(var i=0,node;node=_2ef[i];i++){
if(node==_2f3){
return [_2f3];
}
}
return [];
}
return (_2f3&&Element.descendantOf(_2f3,root))?[_2f3]:[];
},className:function(_2f7,root,_2f9,_2fa){
if(_2f7&&_2fa){
_2f7=this[_2fa](_2f7);
}
return Selector.handlers.byClassName(_2f7,root,_2f9);
},byClassName:function(_2fb,root,_2fd){
if(!_2fb){
_2fb=Selector.handlers.descendant([root]);
}
var _2fe=" "+_2fd+" ";
for(var i=0,_300=[],node,_302;node=_2fb[i];i++){
_302=node.className;
if(_302.length==0){
continue;
}
if(_302==_2fd||(" "+_302+" ").include(_2fe)){
_300.push(node);
}
}
return _300;
},attrPresence:function(_303,root,attr,_306){
if(!_303){
_303=root.getElementsByTagName("*");
}
if(_303&&_306){
_303=this[_306](_303);
}
var _307=[];
for(var i=0,node;node=_303[i];i++){
if(Element.hasAttribute(node,attr)){
_307.push(node);
}
}
return _307;
},attr:function(_30a,root,attr,_30d,_30e,_30f){
if(!_30a){
_30a=root.getElementsByTagName("*");
}
if(_30a&&_30f){
_30a=this[_30f](_30a);
}
var _310=Selector.operators[_30e],_311=[];
for(var i=0,node;node=_30a[i];i++){
var _314=Element.readAttribute(node,attr);
if(_314===null){
continue;
}
if(_310(_314,_30d)){
_311.push(node);
}
}
return _311;
},pseudo:function(_315,name,_317,root,_319){
if(_315&&_319){
_315=this[_319](_315);
}
if(!_315){
_315=root.getElementsByTagName("*");
}
return Selector.pseudos[name](_315,_317,root);
}},pseudos:{"first-child":function(_31a,_31b,root){
for(var i=0,_31e=[],node;node=_31a[i];i++){
if(Selector.handlers.previousElementSibling(node)){
continue;
}
_31e.push(node);
}
return _31e;
},"last-child":function(_320,_321,root){
for(var i=0,_324=[],node;node=_320[i];i++){
if(Selector.handlers.nextElementSibling(node)){
continue;
}
_324.push(node);
}
return _324;
},"only-child":function(_326,_327,root){
var h=Selector.handlers;
for(var i=0,_32b=[],node;node=_326[i];i++){
if(!h.previousElementSibling(node)&&!h.nextElementSibling(node)){
_32b.push(node);
}
}
return _32b;
},"nth-child":function(_32d,_32e,root){
return Selector.pseudos.nth(_32d,_32e,root);
},"nth-last-child":function(_330,_331,root){
return Selector.pseudos.nth(_330,_331,root,true);
},"nth-of-type":function(_333,_334,root){
return Selector.pseudos.nth(_333,_334,root,false,true);
},"nth-last-of-type":function(_336,_337,root){
return Selector.pseudos.nth(_336,_337,root,true,true);
},"first-of-type":function(_339,_33a,root){
return Selector.pseudos.nth(_339,"1",root,false,true);
},"last-of-type":function(_33c,_33d,root){
return Selector.pseudos.nth(_33c,"1",root,true,true);
},"only-of-type":function(_33f,_340,root){
var p=Selector.pseudos;
return p["last-of-type"](p["first-of-type"](_33f,_340,root),_340,root);
},getIndices:function(a,b,_345){
if(a==0){
return b>0?[b]:[];
}
return $R(1,_345).inject([],function(memo,i){
if(0==(i-b)%a&&(i-b)/a>=0){
memo.push(i);
}
return memo;
});
},nth:function(_348,_349,root,_34b,_34c){
if(_348.length==0){
return [];
}
if(_349=="even"){
_349="2n+0";
}
if(_349=="odd"){
_349="2n+1";
}
var h=Selector.handlers,_34e=[],_34f=[],m;
h.mark(_348);
for(var i=0,node;node=_348[i];i++){
if(!node.parentNode._countedByPrototype){
h.index(node.parentNode,_34b,_34c);
_34f.push(node.parentNode);
}
}
if(_349.match(/^\d+$/)){
_349=Number(_349);
for(var i=0,node;node=_348[i];i++){
if(node.nodeIndex==_349){
_34e.push(node);
}
}
}else{
if(m=_349.match(/^(-?\d*)?n(([+-])(\d+))?/)){
if(m[1]=="-"){
m[1]=-1;
}
var a=m[1]?Number(m[1]):1;
var b=m[2]?Number(m[2]):0;
var _355=Selector.pseudos.getIndices(a,b,_348.length);
for(var i=0,node,l=_355.length;node=_348[i];i++){
for(var j=0;j<l;j++){
if(node.nodeIndex==_355[j]){
_34e.push(node);
}
}
}
}
}
h.unmark(_348);
h.unmark(_34f);
return _34e;
},"empty":function(_358,_359,root){
for(var i=0,_35c=[],node;node=_358[i];i++){
if(node.tagName=="!"||(node.firstChild&&!node.innerHTML.match(/^\s*$/))){
continue;
}
_35c.push(node);
}
return _35c;
},"not":function(_35e,_35f,root){
var h=Selector.handlers,_362,m;
var _364=new Selector(_35f).findElements(root);
h.mark(_364);
for(var i=0,_366=[],node;node=_35e[i];i++){
if(!node._countedByPrototype){
_366.push(node);
}
}
h.unmark(_364);
return _366;
},"enabled":function(_368,_369,root){
for(var i=0,_36c=[],node;node=_368[i];i++){
if(!node.disabled){
_36c.push(node);
}
}
return _36c;
},"disabled":function(_36e,_36f,root){
for(var i=0,_372=[],node;node=_36e[i];i++){
if(node.disabled){
_372.push(node);
}
}
return _372;
},"checked":function(_374,_375,root){
for(var i=0,_378=[],node;node=_374[i];i++){
if(node.checked){
_378.push(node);
}
}
return _378;
}},operators:{"=":function(nv,v){
return nv==v;
},"!=":function(nv,v){
return nv!=v;
},"^=":function(nv,v){
return nv.startsWith(v);
},"$=":function(nv,v){
return nv.endsWith(v);
},"*=":function(nv,v){
return nv.include(v);
},"~=":function(nv,v){
return (" "+nv+" ").include(" "+v+" ");
},"|=":function(nv,v){
return ("-"+nv.toUpperCase()+"-").include("-"+v.toUpperCase()+"-");
}},split:function(_388){
var _389=[];
_388.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m){
_389.push(m[1].strip());
});
return _389;
},matchElements:function(_38b,_38c){
var _38d=$$(_38c),h=Selector.handlers;
h.mark(_38d);
for(var i=0,_390=[],_391;_391=_38b[i];i++){
if(_391._countedByPrototype){
_390.push(_391);
}
}
h.unmark(_38d);
return _390;
},findElement:function(_392,_393,_394){
if(Object.isNumber(_393)){
_394=_393;
_393=false;
}
return Selector.matchElements(_392,_393||"*")[_394||0];
},findChildElements:function(_395,_396){
_396=Selector.split(_396.join(","));
var _397=[],h=Selector.handlers;
for(var i=0,l=_396.length,_39b;i<l;i++){
_39b=new Selector(_396[i].strip());
h.concat(_397,_39b.findElements(_395));
}
return (l>1)?h.unique(_397):_397;
}});
if(Prototype.Browser.IE){
Object.extend(Selector.handlers,{concat:function(a,b){
for(var i=0,node;node=b[i];i++){
if(node.tagName!=="!"){
a.push(node);
}
}
return a;
},unmark:function(_3a0){
for(var i=0,node;node=_3a0[i];i++){
node.removeAttribute("_countedByPrototype");
}
return _3a0;
}});
}
function $$(){
return Selector.findChildElements(document,$A(arguments));
};
var Form={reset:function(form){
$(form).reset();
return form;
},serializeElements:function(_3a4,_3a5){
if(typeof _3a5!="object"){
_3a5={hash:!!_3a5};
}else{
if(Object.isUndefined(_3a5.hash)){
_3a5.hash=true;
}
}
var key,_3a7,_3a8=false,_3a9=_3a5.submit;
var data=_3a4.inject({},function(_3ab,_3ac){
if(!_3ac.disabled&&_3ac.name){
key=_3ac.name;
_3a7=$(_3ac).getValue();
if(_3a7!=null&&(_3ac.type!="submit"||(!_3a8&&_3a9!==false&&(!_3a9||key==_3a9)&&(_3a8=true)))){
if(key in _3ab){
if(!Object.isArray(_3ab[key])){
_3ab[key]=[_3ab[key]];
}
_3ab[key].push(_3a7);
}else{
_3ab[key]=_3a7;
}
}
}
return _3ab;
});
return _3a5.hash?data:Object.toQueryString(data);
}};
Form.Methods={serialize:function(form,_3ae){
return Form.serializeElements(Form.getElements(form),_3ae);
},getElements:function(form){
return $A($(form).getElementsByTagName("*")).inject([],function(_3b0,_3b1){
if(Form.Element.Serializers[_3b1.tagName.toLowerCase()]){
_3b0.push(Element.extend(_3b1));
}
return _3b0;
});
},getInputs:function(form,_3b3,name){
form=$(form);
var _3b5=form.getElementsByTagName("input");
if(!_3b3&&!name){
return $A(_3b5).map(Element.extend);
}
for(var i=0,_3b7=[],_3b8=_3b5.length;i<_3b8;i++){
var _3b9=_3b5[i];
if((_3b3&&_3b9.type!=_3b3)||(name&&_3b9.name!=name)){
continue;
}
_3b7.push(Element.extend(_3b9));
}
return _3b7;
},disable:function(form){
form=$(form);
Form.getElements(form).invoke("disable");
return form;
},enable:function(form){
form=$(form);
Form.getElements(form).invoke("enable");
return form;
},findFirstElement:function(form){
var _3bd=$(form).getElements().findAll(function(_3be){
return "hidden"!=_3be.type&&!_3be.disabled;
});
var _3bf=_3bd.findAll(function(_3c0){
return _3c0.hasAttribute("tabIndex")&&_3c0.tabIndex>=0;
}).sortBy(function(_3c1){
return _3c1.tabIndex;
}).first();
return _3bf?_3bf:_3bd.find(function(_3c2){
return ["input","select","textarea"].include(_3c2.tagName.toLowerCase());
});
},focusFirstElement:function(form){
form=$(form);
form.findFirstElement().activate();
return form;
},request:function(form,_3c5){
form=$(form),_3c5=Object.clone(_3c5||{});
var _3c6=_3c5.parameters,_3c7=form.readAttribute("action")||"";
if(_3c7.blank()){
_3c7=window.location.href;
}
_3c5.parameters=form.serialize(true);
if(_3c6){
if(Object.isString(_3c6)){
_3c6=_3c6.toQueryParams();
}
Object.extend(_3c5.parameters,_3c6);
}
if(form.hasAttribute("method")&&!_3c5.method){
_3c5.method=form.method;
}
return new Ajax.Request(_3c7,_3c5);
}};
Form.Element={focus:function(_3c8){
$(_3c8).focus();
return _3c8;
},select:function(_3c9){
$(_3c9).select();
return _3c9;
}};
Form.Element.Methods={serialize:function(_3ca){
_3ca=$(_3ca);
if(!_3ca.disabled&&_3ca.name){
var _3cb=_3ca.getValue();
if(_3cb!=undefined){
var pair={};
pair[_3ca.name]=_3cb;
return Object.toQueryString(pair);
}
}
return "";
},getValue:function(_3cd){
_3cd=$(_3cd);
var _3ce=_3cd.tagName.toLowerCase();
return Form.Element.Serializers[_3ce](_3cd);
},setValue:function(_3cf,_3d0){
_3cf=$(_3cf);
var _3d1=_3cf.tagName.toLowerCase();
Form.Element.Serializers[_3d1](_3cf,_3d0);
return _3cf;
},clear:function(_3d2){
$(_3d2).value="";
return _3d2;
},present:function(_3d3){
return $(_3d3).value!="";
},activate:function(_3d4){
_3d4=$(_3d4);
try{
_3d4.focus();
if(_3d4.select&&(_3d4.tagName.toLowerCase()!="input"||!["button","reset","submit"].include(_3d4.type))){
_3d4.select();
}
}
catch(e){
}
return _3d4;
},disable:function(_3d5){
_3d5=$(_3d5);
_3d5.blur();
_3d5.disabled=true;
return _3d5;
},enable:function(_3d6){
_3d6=$(_3d6);
_3d6.disabled=false;
return _3d6;
}};
var Field=Form.Element;
var $F=Form.Element.Methods.getValue;
Form.Element.Serializers={input:function(_3d7,_3d8){
switch(_3d7.type.toLowerCase()){
case "checkbox":
case "radio":
return Form.Element.Serializers.inputSelector(_3d7,_3d8);
default:
return Form.Element.Serializers.textarea(_3d7,_3d8);
}
},inputSelector:function(_3d9,_3da){
if(Object.isUndefined(_3da)){
return _3d9.checked?_3d9.value:null;
}else{
_3d9.checked=!!_3da;
}
},textarea:function(_3db,_3dc){
if(Object.isUndefined(_3dc)){
return _3db.value;
}else{
_3db.value=_3dc;
}
},select:function(_3dd,_3de){
if(Object.isUndefined(_3de)){
return this[_3dd.type=="select-one"?"selectOne":"selectMany"](_3dd);
}else{
var opt,_3e0,_3e1=!Object.isArray(_3de);
for(var i=0,_3e3=_3dd.length;i<_3e3;i++){
opt=_3dd.options[i];
_3e0=this.optionValue(opt);
if(_3e1){
if(_3e0==_3de){
opt.selected=true;
return;
}
}else{
opt.selected=_3de.include(_3e0);
}
}
}
},selectOne:function(_3e4){
var _3e5=_3e4.selectedIndex;
return _3e5>=0?this.optionValue(_3e4.options[_3e5]):null;
},selectMany:function(_3e6){
var _3e7,_3e8=_3e6.length;
if(!_3e8){
return null;
}
for(var i=0,_3e7=[];i<_3e8;i++){
var opt=_3e6.options[i];
if(opt.selected){
_3e7.push(this.optionValue(opt));
}
}
return _3e7;
},optionValue:function(opt){
return Element.extend(opt).hasAttribute("value")?opt.value:opt.text;
}};
Abstract.TimedObserver=Class.create(PeriodicalExecuter,{initialize:function(_3ec,_3ed,_3ee,_3ef){
_3ec(_3ef,_3ee);
this.element=$(_3ed);
this.lastValue=this.getValue();
},execute:function(){
var _3f0=this.getValue();
if(Object.isString(this.lastValue)&&Object.isString(_3f0)?this.lastValue!=_3f0:String(this.lastValue)!=String(_3f0)){
this.callback(this.element,_3f0);
this.lastValue=_3f0;
}
}});
Form.Element.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){
return Form.Element.getValue(this.element);
}});
Form.Observer=Class.create(Abstract.TimedObserver,{getValue:function(){
return Form.serialize(this.element);
}});
Abstract.EventObserver=Class.create({initialize:function(_3f1,_3f2){
this.element=$(_3f1);
this.callback=_3f2;
this.lastValue=this.getValue();
if(this.element.tagName.toLowerCase()=="form"){
this.registerFormCallbacks();
}else{
this.registerCallback(this.element);
}
},onElementEvent:function(){
var _3f3=this.getValue();
if(this.lastValue!=_3f3){
this.callback(this.element,_3f3);
this.lastValue=_3f3;
}
},registerFormCallbacks:function(){
Form.getElements(this.element).each(this.registerCallback,this);
},registerCallback:function(_3f4){
if(_3f4.type){
switch(_3f4.type.toLowerCase()){
case "checkbox":
case "radio":
Event.observe(_3f4,"click",this.onElementEvent.bind(this));
break;
default:
Event.observe(_3f4,"change",this.onElementEvent.bind(this));
break;
}
}
}});
Form.Element.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){
return Form.Element.getValue(this.element);
}});
Form.EventObserver=Class.create(Abstract.EventObserver,{getValue:function(){
return Form.serialize(this.element);
}});
if(!window.Event){
var Event={};
}
Object.extend(Event,{KEY_BACKSPACE:8,KEY_TAB:9,KEY_RETURN:13,KEY_ESC:27,KEY_LEFT:37,KEY_UP:38,KEY_RIGHT:39,KEY_DOWN:40,KEY_DELETE:46,KEY_HOME:36,KEY_END:35,KEY_PAGEUP:33,KEY_PAGEDOWN:34,KEY_INSERT:45,cache:{},relatedTarget:function(_3f5){
var _3f6;
switch(_3f5.type){
case "mouseover":
_3f6=_3f5.fromElement;
break;
case "mouseout":
_3f6=_3f5.toElement;
break;
default:
return null;
}
return Element.extend(_3f6);
}});
Event.Methods=(function(){
var _3f7;
if(Prototype.Browser.IE){
var _3f8={0:1,1:4,2:2};
_3f7=function(_3f9,code){
return _3f9.button==_3f8[code];
};
}else{
if(Prototype.Browser.WebKit){
_3f7=function(_3fb,code){
switch(code){
case 0:
return _3fb.which==1&&!_3fb.metaKey;
case 1:
return _3fb.which==1&&_3fb.metaKey;
default:
return false;
}
};
}else{
_3f7=function(_3fd,code){
return _3fd.which?(_3fd.which===code+1):(_3fd.button===code);
};
}
}
return {isLeftClick:function(_3ff){
return _3f7(_3ff,0);
},isMiddleClick:function(_400){
return _3f7(_400,1);
},isRightClick:function(_401){
return _3f7(_401,2);
},element:function(_402){
var node=Event.extend(_402).target;
return Element.extend(node.nodeType==Node.TEXT_NODE?node.parentNode:node);
},findElement:function(_404,_405){
var _406=Event.element(_404);
if(!_405){
return _406;
}
var _407=[_406].concat(_406.ancestors());
return Selector.findElement(_407,_405,0);
},pointer:function(_408){
return {x:_408.pageX||(_408.clientX+(document.documentElement.scrollLeft||document.body.scrollLeft)),y:_408.pageY||(_408.clientY+(document.documentElement.scrollTop||document.body.scrollTop))};
},pointerX:function(_409){
return Event.pointer(_409).x;
},pointerY:function(_40a){
return Event.pointer(_40a).y;
},stop:function(_40b){
Event.extend(_40b);
_40b.preventDefault();
_40b.stopPropagation();
_40b.stopped=true;
}};
})();
Event.extend=(function(){
var _40c=Object.keys(Event.Methods).inject({},function(m,name){
m[name]=Event.Methods[name].methodize();
return m;
});
if(Prototype.Browser.IE){
Object.extend(_40c,{stopPropagation:function(){
this.cancelBubble=true;
},preventDefault:function(){
this.returnValue=false;
},inspect:function(){
return "[object Event]";
}});
return function(_40f){
if(!_40f){
return false;
}
if(_40f._extendedByPrototype){
return _40f;
}
_40f._extendedByPrototype=Prototype.emptyFunction;
var _410=Event.pointer(_40f);
Object.extend(_40f,{target:_40f.srcElement,relatedTarget:Event.relatedTarget(_40f),pageX:_410.x,pageY:_410.y});
return Object.extend(_40f,_40c);
};
}else{
Event.prototype=Event.prototype||document.createEvent("HTMLEvents").__proto__;
Object.extend(Event.prototype,_40c);
return Prototype.K;
}
})();
Object.extend(Event,(function(){
var _411=Event.cache;
function _412(_413){
if(_413._prototypeEventID){
return _413._prototypeEventID[0];
}
arguments.callee.id=arguments.callee.id||1;
return _413._prototypeEventID=[++arguments.callee.id];
};
function _414(_415){
if(_415&&_415.include(":")){
return "dataavailable";
}
return _415;
};
function _416(id){
return _411[id]=_411[id]||{};
};
function _418(id,_41a){
var c=_416(id);
return c[_41a]=c[_41a]||[];
};
function _41c(_41d,_41e,_41f){
var id=_412(_41d);
var c=_418(id,_41e);
if(c.pluck("handler").include(_41f)){
return false;
}
var _422=function(_423){
if(!Event||!Event.extend||(_423.eventName&&_423.eventName!=_41e)){
return false;
}
Event.extend(_423);
_41f.call(_41d,_423);
};
_422.handler=_41f;
c.push(_422);
return _422;
};
function _424(id,_426,_427){
var c=_418(id,_426);
return c.find(function(_429){
return _429.handler==_427;
});
};
function _42a(id,_42c,_42d){
var c=_416(id);
if(!c[_42c]){
return false;
}
c[_42c]=c[_42c].without(_424(id,_42c,_42d));
};
function _42f(){
for(var id in _411){
for(var _431 in _411[id]){
_411[id][_431]=null;
}
}
};
if(window.attachEvent){
window.attachEvent("onunload",_42f);
}
return {observe:function(_432,_433,_434){
_432=$(_432);
var name=_414(_433);
var _436=_41c(_432,_433,_434);
if(!_436){
return _432;
}
if(_432.addEventListener){
_432.addEventListener(name,_436,false);
}else{
_432.attachEvent("on"+name,_436);
}
return _432;
},stopObserving:function(_437,_438,_439){
_437=$(_437);
var id=_412(_437),name=_414(_438);
if(!_439&&_438){
_418(id,_438).each(function(_43c){
_437.stopObserving(_438,_43c.handler);
});
return _437;
}else{
if(!_438){
Object.keys(_416(id)).each(function(_43d){
_437.stopObserving(_43d);
});
return _437;
}
}
var _43e=_424(id,_438,_439);
if(!_43e){
return _437;
}
if(_437.removeEventListener){
_437.removeEventListener(name,_43e,false);
}else{
_437.detachEvent("on"+name,_43e);
}
_42a(id,_438,_439);
return _437;
},fire:function(_43f,_440,memo){
_43f=$(_43f);
if(_43f==document&&document.createEvent&&!_43f.dispatchEvent){
_43f=document.documentElement;
}
var _442;
if(document.createEvent){
_442=document.createEvent("HTMLEvents");
_442.initEvent("dataavailable",true,true);
}else{
_442=document.createEventObject();
_442.eventType="ondataavailable";
}
_442.eventName=_440;
_442.memo=memo||{};
if(document.createEvent){
_43f.dispatchEvent(_442);
}else{
_43f.fireEvent(_442.eventType,_442);
}
return Event.extend(_442);
}};
})());
Object.extend(Event,Event.Methods);
Element.addMethods({fire:Event.fire,observe:Event.observe,stopObserving:Event.stopObserving});
Object.extend(document,{fire:Element.Methods.fire.methodize(),observe:Element.Methods.observe.methodize(),stopObserving:Element.Methods.stopObserving.methodize(),loaded:false});
(function(){
var _443;
function _444(){
if(document.loaded){
return;
}
if(_443){
window.clearInterval(_443);
}
document.fire("dom:loaded");
document.loaded=true;
};
if(document.addEventListener){
if(Prototype.Browser.WebKit){
_443=window.setInterval(function(){
if(/loaded|complete/.test(document.readyState)){
_444();
}
},0);
Event.observe(window,"load",_444);
}else{
document.addEventListener("DOMContentLoaded",_444,false);
}
}else{
document.write("<script id=__onDOMContentLoaded defer src=//:></script>");
$("__onDOMContentLoaded").onreadystatechange=function(){
if(this.readyState=="complete"){
this.onreadystatechange=null;
_444();
}
};
}
})();
Hash.toQueryString=Object.toQueryString;
var Toggle={display:Element.toggle};
Element.Methods.childOf=Element.Methods.descendantOf;
var Insertion={Before:function(_445,_446){
return Element.insert(_445,{before:_446});
},Top:function(_447,_448){
return Element.insert(_447,{top:_448});
},Bottom:function(_449,_44a){
return Element.insert(_449,{bottom:_44a});
},After:function(_44b,_44c){
return Element.insert(_44b,{after:_44c});
}};
var $continue=new Error("\"throw $continue\" is deprecated, use \"return\" instead");
var Position={includeScrollOffsets:false,prepare:function(){
this.deltaX=window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0;
this.deltaY=window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0;
},within:function(_44d,x,y){
if(this.includeScrollOffsets){
return this.withinIncludingScrolloffsets(_44d,x,y);
}
this.xcomp=x;
this.ycomp=y;
this.offset=Element.cumulativeOffset(_44d);
return (y>=this.offset[1]&&y<this.offset[1]+_44d.offsetHeight&&x>=this.offset[0]&&x<this.offset[0]+_44d.offsetWidth);
},withinIncludingScrolloffsets:function(_450,x,y){
var _453=Element.cumulativeScrollOffset(_450);
this.xcomp=x+_453[0]-this.deltaX;
this.ycomp=y+_453[1]-this.deltaY;
this.offset=Element.cumulativeOffset(_450);
return (this.ycomp>=this.offset[1]&&this.ycomp<this.offset[1]+_450.offsetHeight&&this.xcomp>=this.offset[0]&&this.xcomp<this.offset[0]+_450.offsetWidth);
},overlap:function(mode,_455){
if(!mode){
return 0;
}
if(mode=="vertical"){
return ((this.offset[1]+_455.offsetHeight)-this.ycomp)/_455.offsetHeight;
}
if(mode=="horizontal"){
return ((this.offset[0]+_455.offsetWidth)-this.xcomp)/_455.offsetWidth;
}
},cumulativeOffset:Element.Methods.cumulativeOffset,positionedOffset:Element.Methods.positionedOffset,absolutize:function(_456){
Position.prepare();
return Element.absolutize(_456);
},relativize:function(_457){
Position.prepare();
return Element.relativize(_457);
},realOffset:Element.Methods.cumulativeScrollOffset,offsetParent:Element.Methods.getOffsetParent,page:Element.Methods.viewportOffset,clone:function(_458,_459,_45a){
_45a=_45a||{};
return Element.clonePosition(_459,_458,_45a);
}};
if(!document.getElementsByClassName){
document.getElementsByClassName=function(_45b){
function iter(name){
return name.blank()?null:"[contains(concat(' ', @class, ' '), ' "+name+" ')]";
};
_45b.getElementsByClassName=Prototype.BrowserFeatures.XPath?function(_45e,_45f){
_45f=_45f.toString().strip();
var cond=/\s/.test(_45f)?$w(_45f).map(iter).join(""):iter(_45f);
return cond?document._getElementsByXPath(".//*"+cond,_45e):[];
}:function(_461,_462){
_462=_462.toString().strip();
var _463=[],_464=(/\s/.test(_462)?$w(_462):null);
if(!_464&&!_462){
return _463;
}
var _465=$(_461).getElementsByTagName("*");
_462=" "+_462+" ";
for(var i=0,_467,cn;_467=_465[i];i++){
if(_467.className&&(cn=" "+_467.className+" ")&&(cn.include(_462)||(_464&&_464.all(function(name){
return !name.toString().blank()&&cn.include(" "+name+" ");
})))){
_463.push(Element.extend(_467));
}
}
return _463;
};
return function(_46a,_46b){
return $(_46b||document.body).getElementsByClassName(_46a);
};
}(Element.Methods);
}
Element.ClassNames=Class.create();
Element.ClassNames.prototype={initialize:function(_46c){
this.element=$(_46c);
},_each:function(_46d){
this.element.className.split(/\s+/).select(function(name){
return name.length>0;
})._each(_46d);
},set:function(_46f){
this.element.className=_46f;
},add:function(_470){
if(this.include(_470)){
return;
}
this.set($A(this).concat(_470).join(" "));
},remove:function(_471){
if(!this.include(_471)){
return;
}
this.set($A(this).without(_471).join(" "));
},toString:function(){
return $A(this).join(" ");
}};
Object.extend(Element.ClassNames.prototype,Enumerable);
Element.addMethods();



// script.aculo.us scriptaculous.js v1.8.1, Thu Jan 03 22:07:12 -0500 2008

// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
// 
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// For details, see the script.aculo.us web site: http://script.aculo.us/

var Scriptaculous = {
  Version: '1.8.1',
  require: function(libraryName) {
    // inserting via DOM fails in Safari 2.0, so brute force approach
    document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
  },
  REQUIRED_PROTOTYPE: '1.6.0',
  load: function() {
    function convertVersionString(versionString){
      var r = versionString.split('.');
      return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
    }
 
    if((typeof Prototype=='undefined') || 
       (typeof Element == 'undefined') || 
       (typeof Element.Methods=='undefined') ||
       (convertVersionString(Prototype.Version) < 
        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
        Scriptaculous.REQUIRED_PROTOTYPE);
    
    $A(document.getElementsByTagName("script")).findAll( function(s) {
      return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
    }).each( function(s) {
      var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
      var includes = s.src.match(/\?.*load=([a-z,]*)/);
      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
       function(include) { Scriptaculous.require(path+include+'.js') });
    });
  }
}

Scriptaculous.load();

String.prototype.parseColor=function(){
var _1="#";
if(this.slice(0,4)=="rgb("){
var _2=this.slice(4,this.length-1).split(",");
var i=0;
do{
_1+=parseInt(_2[i]).toColorPart();
}while(++i<3);
}else{
if(this.slice(0,1)=="#"){
if(this.length==4){
for(var i=1;i<4;i++){
_1+=(this.charAt(i)+this.charAt(i)).toLowerCase();
}
}
if(this.length==7){
_1=this.toLowerCase();
}
}
}
return (_1.length==7?_1:(arguments[0]||this));
};
Element.collectTextNodes=function(_4){
return $A($(_4).childNodes).collect(function(_5){
return (_5.nodeType==3?_5.nodeValue:(_5.hasChildNodes()?Element.collectTextNodes(_5):""));
}).flatten().join("");
};
Element.collectTextNodesIgnoreClass=function(_6,_7){
return $A($(_6).childNodes).collect(function(_8){
return (_8.nodeType==3?_8.nodeValue:((_8.hasChildNodes()&&!Element.hasClassName(_8,_7))?Element.collectTextNodesIgnoreClass(_8,_7):""));
}).flatten().join("");
};
Element.setContentZoom=function(_9,_a){
_9=$(_9);
_9.setStyle({fontSize:(_a/100)+"em"});
if(Prototype.Browser.WebKit){
window.scrollBy(0,0);
}
return _9;
};
Element.getInlineOpacity=function(_b){
return $(_b).style.opacity||"";
};
Element.forceRerendering=function(_c){
try{
_c=$(_c);
var n=document.createTextNode(" ");
_c.appendChild(n);
_c.removeChild(n);
}
catch(e){
}
};
var Effect={_elementDoesNotExistError:{name:"ElementDoesNotExistError",message:"The specified DOM element does not exist, but is required for this effect to operate"},Transitions:{linear:Prototype.K,sinoidal:function(_e){
return (-Math.cos(_e*Math.PI)/2)+0.5;
},reverse:function(_f){
return 1-_f;
},flicker:function(pos){
var pos=((-Math.cos(pos*Math.PI)/4)+0.75)+Math.random()/4;
return pos>1?1:pos;
},wobble:function(pos){
return (-Math.cos(pos*Math.PI*(9*pos))/2)+0.5;
},pulse:function(pos,_13){
_13=_13||5;
return (((pos%(1/_13))*_13).round()==0?((pos*_13*2)-(pos*_13*2).floor()):1-((pos*_13*2)-(pos*_13*2).floor()));
},spring:function(pos){
return 1-(Math.cos(pos*4.5*Math.PI)*Math.exp(-pos*6));
},none:function(pos){
return 0;
},full:function(pos){
return 1;
}},DefaultOptions:{duration:1,fps:100,sync:false,from:0,to:1,delay:0,queue:"parallel"},tagifyText:function(_17){
var _18="position:relative";
if(Prototype.Browser.IE){
_18+=";zoom:1";
}
_17=$(_17);
$A(_17.childNodes).each(function(_19){
if(_19.nodeType==3){
_19.nodeValue.toArray().each(function(_1a){
_17.insertBefore(new Element("span",{style:_18}).update(_1a==" "?String.fromCharCode(160):_1a),_19);
});
Element.remove(_19);
}
});
},multiple:function(_1b,_1c){
var _1d;
if(((typeof _1b=="object")||Object.isFunction(_1b))&&(_1b.length)){
_1d=_1b;
}else{
_1d=$(_1b).childNodes;
}
var _1e=Object.extend({speed:0.1,delay:0},arguments[2]||{});
var _1f=_1e.delay;
$A(_1d).each(function(_20,_21){
new _1c(_20,Object.extend(_1e,{delay:_21*_1e.speed+_1f}));
});
},PAIRS:{"slide":["SlideDown","SlideUp"],"blind":["BlindDown","BlindUp"],"appear":["Appear","Fade"]},toggle:function(_22,_23){
_22=$(_22);
_23=(_23||"appear").toLowerCase();
var _24=Object.extend({queue:{position:"end",scope:(_22.id||"global"),limit:1}},arguments[2]||{});
Effect[_22.visible()?Effect.PAIRS[_23][1]:Effect.PAIRS[_23][0]](_22,_24);
}};
Effect.DefaultOptions.transition=Effect.Transitions.sinoidal;
Effect.ScopedQueue=Class.create(Enumerable,{initialize:function(){
this.effects=[];
this.interval=null;
},_each:function(_25){
this.effects._each(_25);
},add:function(_26){
var _27=new Date().getTime();
var _28=Object.isString(_26.options.queue)?_26.options.queue:_26.options.queue.position;
switch(_28){
case "front":
this.effects.findAll(function(e){
return e.state=="idle";
}).each(function(e){
e.startOn+=_26.finishOn;
e.finishOn+=_26.finishOn;
});
break;
case "with-last":
_27=this.effects.pluck("startOn").max()||_27;
break;
case "end":
_27=this.effects.pluck("finishOn").max()||_27;
break;
}
_26.startOn+=_27;
_26.finishOn+=_27;
if(!_26.options.queue.limit||(this.effects.length<_26.options.queue.limit)){
this.effects.push(_26);
}
if(!this.interval){
this.interval=setInterval(this.loop.bind(this),15);
}
},remove:function(_2b){
this.effects=this.effects.reject(function(e){
return e==_2b;
});
if(this.effects.length==0){
clearInterval(this.interval);
this.interval=null;
}
},loop:function(){
var _2d=new Date().getTime();
for(var i=0,len=this.effects.length;i<len;i++){
this.effects[i]&&this.effects[i].loop(_2d);
}
}});
Effect.Queues={instances:$H(),get:function(_30){
if(!Object.isString(_30)){
return _30;
}
return this.instances.get(_30)||this.instances.set(_30,new Effect.ScopedQueue());
}};
Effect.Queue=Effect.Queues.get("global");
Effect.Base=Class.create({position:null,start:function(_31){
function _32(_33,_34){
return ((_33[_34+"Internal"]?"this.options."+_34+"Internal(this);":"")+(_33[_34]?"this.options."+_34+"(this);":""));
};
if(_31&&_31.transition===false){
_31.transition=Effect.Transitions.linear;
}
this.options=Object.extend(Object.extend({},Effect.DefaultOptions),_31||{});
this.currentFrame=0;
this.state="idle";
this.startOn=this.options.delay*1000;
this.finishOn=this.startOn+(this.options.duration*1000);
this.fromToDelta=this.options.to-this.options.from;
this.totalTime=this.finishOn-this.startOn;
this.totalFrames=this.options.fps*this.options.duration;
eval("this.render = function(pos){ "+"if (this.state==\"idle\"){this.state=\"running\";"+_32(this.options,"beforeSetup")+(this.setup?"this.setup();":"")+_32(this.options,"afterSetup")+"};if (this.state==\"running\"){"+"pos=this.options.transition(pos)*"+this.fromToDelta+"+"+this.options.from+";"+"this.position=pos;"+_32(this.options,"beforeUpdate")+(this.update?"this.update(pos);":"")+_32(this.options,"afterUpdate")+"}}");
this.event("beforeStart");
if(!this.options.sync){
Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).add(this);
}
},loop:function(_35){
if(_35>=this.startOn){
if(_35>=this.finishOn){
this.render(1);
this.cancel();
this.event("beforeFinish");
if(this.finish){
this.finish();
}
this.event("afterFinish");
return;
}
var pos=(_35-this.startOn)/this.totalTime,_37=(pos*this.totalFrames).round();
if(_37>this.currentFrame){
this.render(pos);
this.currentFrame=_37;
}
}
},cancel:function(){
if(!this.options.sync){
Effect.Queues.get(Object.isString(this.options.queue)?"global":this.options.queue.scope).remove(this);
}
this.state="finished";
},event:function(_38){
if(this.options[_38+"Internal"]){
this.options[_38+"Internal"](this);
}
if(this.options[_38]){
this.options[_38](this);
}
},inspect:function(){
var _39=$H();
for(property in this){
if(!Object.isFunction(this[property])){
_39.set(property,this[property]);
}
}
return "#<Effect:"+_39.inspect()+",options:"+$H(this.options).inspect()+">";
}});
Effect.Parallel=Class.create(Effect.Base,{initialize:function(_3a){
this.effects=_3a||[];
this.start(arguments[1]);
},update:function(_3b){
this.effects.invoke("render",_3b);
},finish:function(_3c){
this.effects.each(function(_3d){
_3d.render(1);
_3d.cancel();
_3d.event("beforeFinish");
if(_3d.finish){
_3d.finish(_3c);
}
_3d.event("afterFinish");
});
}});
Effect.Tween=Class.create(Effect.Base,{initialize:function(_3e,_3f,to){
_3e=Object.isString(_3e)?$(_3e):_3e;
var _41=$A(arguments),_42=_41.last(),_43=_41.length==5?_41[3]:null;
this.method=Object.isFunction(_42)?_42.bind(_3e):Object.isFunction(_3e[_42])?_3e[_42].bind(_3e):function(_44){
_3e[_42]=_44;
};
this.start(Object.extend({from:_3f,to:to},_43||{}));
},update:function(_45){
this.method(_45);
}});
Effect.Event=Class.create(Effect.Base,{initialize:function(){
this.start(Object.extend({duration:0},arguments[0]||{}));
},update:Prototype.emptyFunction});
Effect.Opacity=Class.create(Effect.Base,{initialize:function(_46){
this.element=$(_46);
if(!this.element){
throw (Effect._elementDoesNotExistError);
}
if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){
this.element.setStyle({zoom:1});
}
var _47=Object.extend({from:this.element.getOpacity()||0,to:1},arguments[1]||{});
this.start(_47);
},update:function(_48){
this.element.setOpacity(_48);
}});
Effect.Move=Class.create(Effect.Base,{initialize:function(_49){
this.element=$(_49);
if(!this.element){
throw (Effect._elementDoesNotExistError);
}
var _4a=Object.extend({x:0,y:0,mode:"relative"},arguments[1]||{});
this.start(_4a);
},setup:function(){
this.element.makePositioned();
this.originalLeft=parseFloat(this.element.getStyle("left")||"0");
this.originalTop=parseFloat(this.element.getStyle("top")||"0");
if(this.options.mode=="absolute"){
this.options.x=this.options.x-this.originalLeft;
this.options.y=this.options.y-this.originalTop;
}
},update:function(_4b){
this.element.setStyle({left:(this.options.x*_4b+this.originalLeft).round()+"px",top:(this.options.y*_4b+this.originalTop).round()+"px"});
}});
Effect.MoveBy=function(_4c,_4d,_4e){
return new Effect.Move(_4c,Object.extend({x:_4e,y:_4d},arguments[3]||{}));
};
Effect.Scale=Class.create(Effect.Base,{initialize:function(_4f,_50){
this.element=$(_4f);
if(!this.element){
throw (Effect._elementDoesNotExistError);
}
var _51=Object.extend({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:"box",scaleFrom:100,scaleTo:_50},arguments[2]||{});
this.start(_51);
},setup:function(){
this.restoreAfterFinish=this.options.restoreAfterFinish||false;
this.elementPositioning=this.element.getStyle("position");
this.originalStyle={};
["top","left","width","height","fontSize"].each(function(k){
this.originalStyle[k]=this.element.style[k];
}.bind(this));
this.originalTop=this.element.offsetTop;
this.originalLeft=this.element.offsetLeft;
var _53=this.element.getStyle("font-size")||"100%";
["em","px","%","pt"].each(function(_54){
if(_53.indexOf(_54)>0){
this.fontSize=parseFloat(_53);
this.fontSizeType=_54;
}
}.bind(this));
this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;
this.dims=null;
if(this.options.scaleMode=="box"){
this.dims=[this.element.offsetHeight,this.element.offsetWidth];
}
if(/^content/.test(this.options.scaleMode)){
this.dims=[this.element.scrollHeight,this.element.scrollWidth];
}
if(!this.dims){
this.dims=[this.options.scaleMode.originalHeight,this.options.scaleMode.originalWidth];
}
},update:function(_55){
var _56=(this.options.scaleFrom/100)+(this.factor*_55);
if(this.options.scaleContent&&this.fontSize){
this.element.setStyle({fontSize:this.fontSize*_56+this.fontSizeType});
}
this.setDimensions(this.dims[0]*_56,this.dims[1]*_56);
},finish:function(_57){
if(this.restoreAfterFinish){
this.element.setStyle(this.originalStyle);
}
},setDimensions:function(_58,_59){
var d={};
if(this.options.scaleX){
d.width=_59.round()+"px";
}
if(this.options.scaleY){
d.height=_58.round()+"px";
}
if(this.options.scaleFromCenter){
var _5b=(_58-this.dims[0])/2;
var _5c=(_59-this.dims[1])/2;
if(this.elementPositioning=="absolute"){
if(this.options.scaleY){
d.top=this.originalTop-_5b+"px";
}
if(this.options.scaleX){
d.left=this.originalLeft-_5c+"px";
}
}else{
if(this.options.scaleY){
d.top=-_5b+"px";
}
if(this.options.scaleX){
d.left=-_5c+"px";
}
}
}
this.element.setStyle(d);
}});
Effect.Highlight=Class.create(Effect.Base,{initialize:function(_5d){
this.element=$(_5d);
if(!this.element){
throw (Effect._elementDoesNotExistError);
}
var _5e=Object.extend({startcolor:"#ffff99"},arguments[1]||{});
this.start(_5e);
},setup:function(){
if(this.element.getStyle("display")=="none"){
this.cancel();
return;
}
this.oldStyle={};
if(!this.options.keepBackgroundImage){
this.oldStyle.backgroundImage=this.element.getStyle("background-image");
this.element.setStyle({backgroundImage:"none"});
}
if(!this.options.endcolor){
this.options.endcolor=this.element.getStyle("background-color").parseColor("#ffffff");
}
if(!this.options.restorecolor){
this.options.restorecolor=this.element.getStyle("background-color");
}
this._base=$R(0,2).map(function(i){
return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16);
}.bind(this));
this._delta=$R(0,2).map(function(i){
return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i];
}.bind(this));
},update:function(_61){
this.element.setStyle({backgroundColor:$R(0,2).inject("#",function(m,v,i){
return m+((this._base[i]+(this._delta[i]*_61)).round().toColorPart());
}.bind(this))});
},finish:function(){
this.element.setStyle(Object.extend(this.oldStyle,{backgroundColor:this.options.restorecolor}));
}});
Effect.ScrollTo=function(_65){
var _66=arguments[1]||{},_67=document.viewport.getScrollOffsets(),_68=$(_65).cumulativeOffset(),max=(window.height||document.body.scrollHeight)-document.viewport.getHeight();
if(_66.offset){
_68[1]+=_66.offset;
}
return new Effect.Tween(null,_67.top,_68[1]>max?max:_68[1],_66,function(p){
scrollTo(_67.left,p.round());
});
};
Effect.Fade=function(_6b){
_6b=$(_6b);
var _6c=_6b.getInlineOpacity();
var _6d=Object.extend({from:_6b.getOpacity()||1,to:0,afterFinishInternal:function(_6e){
if(_6e.options.to!=0){
return;
}
_6e.element.hide().setStyle({opacity:_6c});
}},arguments[1]||{});
return new Effect.Opacity(_6b,_6d);
};
Effect.Appear=function(_6f){
_6f=$(_6f);
var _70=Object.extend({from:(_6f.getStyle("display")=="none"?0:_6f.getOpacity()||0),to:1,afterFinishInternal:function(_71){
_71.element.forceRerendering();
},beforeSetup:function(_72){
_72.element.setOpacity(_72.options.from).show();
}},arguments[1]||{});
return new Effect.Opacity(_6f,_70);
};
Effect.Puff=function(_73){
_73=$(_73);
var _74={opacity:_73.getInlineOpacity(),position:_73.getStyle("position"),top:_73.style.top,left:_73.style.left,width:_73.style.width,height:_73.style.height};
return new Effect.Parallel([new Effect.Scale(_73,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),new Effect.Opacity(_73,{sync:true,to:0})],Object.extend({duration:1,beforeSetupInternal:function(_75){
Position.absolutize(_75.effects[0].element);
},afterFinishInternal:function(_76){
_76.effects[0].element.hide().setStyle(_74);
}},arguments[1]||{}));
};
Effect.BlindUp=function(_77){
_77=$(_77);
_77.makeClipping();
return new Effect.Scale(_77,0,Object.extend({scaleContent:false,scaleX:false,restoreAfterFinish:true,afterFinishInternal:function(_78){
_78.element.hide().undoClipping();
}},arguments[1]||{}));
};
Effect.BlindDown=function(_79){
_79=$(_79);
var _7a=_79.getDimensions();
return new Effect.Scale(_79,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:_7a.height,originalWidth:_7a.width},restoreAfterFinish:true,afterSetup:function(_7b){
_7b.element.makeClipping().setStyle({height:"0px"}).show();
},afterFinishInternal:function(_7c){
_7c.element.undoClipping();
}},arguments[1]||{}));
};
Effect.SwitchOff=function(_7d){
_7d=$(_7d);
var _7e=_7d.getInlineOpacity();
return new Effect.Appear(_7d,Object.extend({duration:0.4,from:0,transition:Effect.Transitions.flicker,afterFinishInternal:function(_7f){
new Effect.Scale(_7f.element,1,{duration:0.3,scaleFromCenter:true,scaleX:false,scaleContent:false,restoreAfterFinish:true,beforeSetup:function(_80){
_80.element.makePositioned().makeClipping();
},afterFinishInternal:function(_81){
_81.element.hide().undoClipping().undoPositioned().setStyle({opacity:_7e});
}});
}},arguments[1]||{}));
};
Effect.DropOut=function(_82){
_82=$(_82);
var _83={top:_82.getStyle("top"),left:_82.getStyle("left"),opacity:_82.getInlineOpacity()};
return new Effect.Parallel([new Effect.Move(_82,{x:0,y:100,sync:true}),new Effect.Opacity(_82,{sync:true,to:0})],Object.extend({duration:0.5,beforeSetup:function(_84){
_84.effects[0].element.makePositioned();
},afterFinishInternal:function(_85){
_85.effects[0].element.hide().undoPositioned().setStyle(_83);
}},arguments[1]||{}));
};
Effect.Shake=function(_86){
_86=$(_86);
var _87=Object.extend({distance:20,duration:0.5},arguments[1]||{});
var _88=parseFloat(_87.distance);
var _89=parseFloat(_87.duration)/10;
var _8a={top:_86.getStyle("top"),left:_86.getStyle("left")};
return new Effect.Move(_86,{x:_88,y:0,duration:_89,afterFinishInternal:function(_8b){
new Effect.Move(_8b.element,{x:-_88*2,y:0,duration:_89*2,afterFinishInternal:function(_8c){
new Effect.Move(_8c.element,{x:_88*2,y:0,duration:_89*2,afterFinishInternal:function(_8d){
new Effect.Move(_8d.element,{x:-_88*2,y:0,duration:_89*2,afterFinishInternal:function(_8e){
new Effect.Move(_8e.element,{x:_88*2,y:0,duration:_89*2,afterFinishInternal:function(_8f){
new Effect.Move(_8f.element,{x:-_88,y:0,duration:_89,afterFinishInternal:function(_90){
_90.element.undoPositioned().setStyle(_8a);
}});
}});
}});
}});
}});
}});
};
Effect.SlideDown=function(_91){
_91=$(_91).cleanWhitespace();
var _92=_91.down().getStyle("bottom");
var _93=_91.getDimensions();
return new Effect.Scale(_91,100,Object.extend({scaleContent:false,scaleX:false,scaleFrom:window.opera?0:1,scaleMode:{originalHeight:_93.height,originalWidth:_93.width},restoreAfterFinish:true,afterSetup:function(_94){
_94.element.makePositioned();
_94.element.down().makePositioned();
if(window.opera){
_94.element.setStyle({top:""});
}
_94.element.makeClipping().setStyle({height:"0px"}).show();
},afterUpdateInternal:function(_95){
_95.element.down().setStyle({bottom:(_95.dims[0]-_95.element.clientHeight)+"px"});
},afterFinishInternal:function(_96){
_96.element.undoClipping().undoPositioned();
_96.element.down().undoPositioned().setStyle({bottom:_92});
}},arguments[1]||{}));
};
Effect.SlideUp=function(_97){
_97=$(_97).cleanWhitespace();
var _98=_97.down().getStyle("bottom");
var _99=_97.getDimensions();
return new Effect.Scale(_97,window.opera?0:1,Object.extend({scaleContent:false,scaleX:false,scaleMode:"box",scaleFrom:100,scaleMode:{originalHeight:_99.height,originalWidth:_99.width},restoreAfterFinish:true,afterSetup:function(_9a){
_9a.element.makePositioned();
_9a.element.down().makePositioned();
if(window.opera){
_9a.element.setStyle({top:""});
}
_9a.element.makeClipping().show();
},afterUpdateInternal:function(_9b){
_9b.element.down().setStyle({bottom:(_9b.dims[0]-_9b.element.clientHeight)+"px"});
},afterFinishInternal:function(_9c){
_9c.element.hide().undoClipping().undoPositioned();
_9c.element.down().undoPositioned().setStyle({bottom:_98});
}},arguments[1]||{}));
};
Effect.Squish=function(_9d){
return new Effect.Scale(_9d,window.opera?1:0,{restoreAfterFinish:true,beforeSetup:function(_9e){
_9e.element.makeClipping();
},afterFinishInternal:function(_9f){
_9f.element.hide().undoClipping();
}});
};
Effect.Grow=function(_a0){
_a0=$(_a0);
var _a1=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.full},arguments[1]||{});
var _a2={top:_a0.style.top,left:_a0.style.left,height:_a0.style.height,width:_a0.style.width,opacity:_a0.getInlineOpacity()};
var _a3=_a0.getDimensions();
var _a4,_a5;
var _a6,_a7;
switch(_a1.direction){
case "top-left":
_a4=_a5=_a6=_a7=0;
break;
case "top-right":
_a4=_a3.width;
_a5=_a7=0;
_a6=-_a3.width;
break;
case "bottom-left":
_a4=_a6=0;
_a5=_a3.height;
_a7=-_a3.height;
break;
case "bottom-right":
_a4=_a3.width;
_a5=_a3.height;
_a6=-_a3.width;
_a7=-_a3.height;
break;
case "center":
_a4=_a3.width/2;
_a5=_a3.height/2;
_a6=-_a3.width/2;
_a7=-_a3.height/2;
break;
}
return new Effect.Move(_a0,{x:_a4,y:_a5,duration:0.01,beforeSetup:function(_a8){
_a8.element.hide().makeClipping().makePositioned();
},afterFinishInternal:function(_a9){
new Effect.Parallel([new Effect.Opacity(_a9.element,{sync:true,to:1,from:0,transition:_a1.opacityTransition}),new Effect.Move(_a9.element,{x:_a6,y:_a7,sync:true,transition:_a1.moveTransition}),new Effect.Scale(_a9.element,100,{scaleMode:{originalHeight:_a3.height,originalWidth:_a3.width},sync:true,scaleFrom:window.opera?1:0,transition:_a1.scaleTransition,restoreAfterFinish:true})],Object.extend({beforeSetup:function(_aa){
_aa.effects[0].element.setStyle({height:"0px"}).show();
},afterFinishInternal:function(_ab){
_ab.effects[0].element.undoClipping().undoPositioned().setStyle(_a2);
}},_a1));
}});
};
Effect.Shrink=function(_ac){
_ac=$(_ac);
var _ad=Object.extend({direction:"center",moveTransition:Effect.Transitions.sinoidal,scaleTransition:Effect.Transitions.sinoidal,opacityTransition:Effect.Transitions.none},arguments[1]||{});
var _ae={top:_ac.style.top,left:_ac.style.left,height:_ac.style.height,width:_ac.style.width,opacity:_ac.getInlineOpacity()};
var _af=_ac.getDimensions();
var _b0,_b1;
switch(_ad.direction){
case "top-left":
_b0=_b1=0;
break;
case "top-right":
_b0=_af.width;
_b1=0;
break;
case "bottom-left":
_b0=0;
_b1=_af.height;
break;
case "bottom-right":
_b0=_af.width;
_b1=_af.height;
break;
case "center":
_b0=_af.width/2;
_b1=_af.height/2;
break;
}
return new Effect.Parallel([new Effect.Opacity(_ac,{sync:true,to:0,from:1,transition:_ad.opacityTransition}),new Effect.Scale(_ac,window.opera?1:0,{sync:true,transition:_ad.scaleTransition,restoreAfterFinish:true}),new Effect.Move(_ac,{x:_b0,y:_b1,sync:true,transition:_ad.moveTransition})],Object.extend({beforeStartInternal:function(_b2){
_b2.effects[0].element.makePositioned().makeClipping();
},afterFinishInternal:function(_b3){
_b3.effects[0].element.hide().undoClipping().undoPositioned().setStyle(_ae);
}},_ad));
};
Effect.Pulsate=function(_b4){
_b4=$(_b4);
var _b5=arguments[1]||{};
var _b6=_b4.getInlineOpacity();
var _b7=_b5.transition||Effect.Transitions.sinoidal;
var _b8=function(pos){
return _b7(1-Effect.Transitions.pulse(pos,_b5.pulses));
};
_b8.bind(_b7);
return new Effect.Opacity(_b4,Object.extend(Object.extend({duration:2,from:0,afterFinishInternal:function(_ba){
_ba.element.setStyle({opacity:_b6});
}},_b5),{transition:_b8}));
};
Effect.Fold=function(_bb){
_bb=$(_bb);
var _bc={top:_bb.style.top,left:_bb.style.left,width:_bb.style.width,height:_bb.style.height};
_bb.makeClipping();
return new Effect.Scale(_bb,5,Object.extend({scaleContent:false,scaleX:false,afterFinishInternal:function(_bd){
new Effect.Scale(_bb,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(_be){
_be.element.hide().undoClipping().setStyle(_bc);
}});
}},arguments[1]||{}));
};
Effect.Morph=Class.create(Effect.Base,{initialize:function(_bf){
this.element=$(_bf);
if(!this.element){
throw (Effect._elementDoesNotExistError);
}
var _c0=Object.extend({style:{}},arguments[1]||{});
if(!Object.isString(_c0.style)){
this.style=$H(_c0.style);
}else{
if(_c0.style.include(":")){
this.style=_c0.style.parseStyle();
}else{
this.element.addClassName(_c0.style);
this.style=$H(this.element.getStyles());
this.element.removeClassName(_c0.style);
var css=this.element.getStyles();
this.style=this.style.reject(function(_c2){
return _c2.value==css[_c2.key];
});
_c0.afterFinishInternal=function(_c3){
_c3.element.addClassName(_c3.options.style);
_c3.transforms.each(function(_c4){
_c3.element.style[_c4.style]="";
});
};
}
}
this.start(_c0);
},setup:function(){
function _c5(_c6){
if(!_c6||["rgba(0, 0, 0, 0)","transparent"].include(_c6)){
_c6="#ffffff";
}
_c6=_c6.parseColor();
return $R(0,2).map(function(i){
return parseInt(_c6.slice(i*2+1,i*2+3),16);
});
};
this.transforms=this.style.map(function(_c8){
var _c9=_c8[0],_ca=_c8[1],_cb=null;
if(_ca.parseColor("#zzzzzz")!="#zzzzzz"){
_ca=_ca.parseColor();
_cb="color";
}else{
if(_c9=="opacity"){
_ca=parseFloat(_ca);
if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout)){
this.element.setStyle({zoom:1});
}
}else{
if(Element.CSS_LENGTH.test(_ca)){
var _cc=_ca.match(/^([\+\-]?[0-9\.]+)(.*)$/);
_ca=parseFloat(_cc[1]);
_cb=(_cc.length==3)?_cc[2]:null;
}
}
}
var _cd=this.element.getStyle(_c9);
return {style:_c9.camelize(),originalValue:_cb=="color"?_c5(_cd):parseFloat(_cd||0),targetValue:_cb=="color"?_c5(_ca):_ca,unit:_cb};
}.bind(this)).reject(function(_ce){
return ((_ce.originalValue==_ce.targetValue)||(_ce.unit!="color"&&(isNaN(_ce.originalValue)||isNaN(_ce.targetValue))));
});
},update:function(_cf){
var _d0={},_d1,i=this.transforms.length;
while(i--){
_d0[(_d1=this.transforms[i]).style]=_d1.unit=="color"?"#"+(Math.round(_d1.originalValue[0]+(_d1.targetValue[0]-_d1.originalValue[0])*_cf)).toColorPart()+(Math.round(_d1.originalValue[1]+(_d1.targetValue[1]-_d1.originalValue[1])*_cf)).toColorPart()+(Math.round(_d1.originalValue[2]+(_d1.targetValue[2]-_d1.originalValue[2])*_cf)).toColorPart():(_d1.originalValue+(_d1.targetValue-_d1.originalValue)*_cf).toFixed(3)+(_d1.unit===null?"":_d1.unit);
}
this.element.setStyle(_d0,true);
}});
Effect.Transform=Class.create({initialize:function(_d3){
this.tracks=[];
this.options=arguments[1]||{};
this.addTracks(_d3);
},addTracks:function(_d4){
_d4.each(function(_d5){
_d5=$H(_d5);
var _d6=_d5.values().first();
this.tracks.push($H({ids:_d5.keys().first(),effect:Effect.Morph,options:{style:_d6}}));
}.bind(this));
return this;
},play:function(){
return new Effect.Parallel(this.tracks.map(function(_d7){
var ids=_d7.get("ids"),_d9=_d7.get("effect"),_da=_d7.get("options");
var _db=[$(ids)||$$(ids)].flatten();
return _db.map(function(e){
return new _d9(e,Object.extend({sync:true},_da));
});
}).flatten(),this.options);
}});
Element.CSS_PROPERTIES=$w("backgroundColor backgroundPosition borderBottomColor borderBottomStyle "+"borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth "+"borderRightColor borderRightStyle borderRightWidth borderSpacing "+"borderTopColor borderTopStyle borderTopWidth bottom clip color "+"fontSize fontWeight height left letterSpacing lineHeight "+"marginBottom marginLeft marginRight marginTop markerOffset maxHeight "+"maxWidth minHeight minWidth opacity outlineColor outlineOffset "+"outlineWidth paddingBottom paddingLeft paddingRight paddingTop "+"right textIndent top width wordSpacing zIndex");
Element.CSS_LENGTH=/^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
String.__parseStyleElement=document.createElement("div");
String.prototype.parseStyle=function(){
var _dd,_de=$H();
if(Prototype.Browser.WebKit){
_dd=new Element("div",{style:this}).style;
}else{
String.__parseStyleElement.innerHTML="<div style=\""+this+"\"></div>";
_dd=String.__parseStyleElement.childNodes[0].style;
}
Element.CSS_PROPERTIES.each(function(_df){
if(_dd[_df]){
_de.set(_df,_dd[_df]);
}
});
if(Prototype.Browser.IE&&this.include("opacity")){
_de.set("opacity",this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
}
return _de;
};
if(document.defaultView&&document.defaultView.getComputedStyle){
Element.getStyles=function(_e0){
var css=document.defaultView.getComputedStyle($(_e0),null);
return Element.CSS_PROPERTIES.inject({},function(_e2,_e3){
_e2[_e3]=css[_e3];
return _e2;
});
};
}else{
Element.getStyles=function(_e4){
_e4=$(_e4);
var css=_e4.currentStyle,_e6;
_e6=Element.CSS_PROPERTIES.inject({},function(_e7,_e8){
_e7[_e8]=css[_e8];
return _e7;
});
if(!_e6.opacity){
_e6.opacity=_e4.getOpacity();
}
return _e6;
};
}
Effect.Methods={morph:function(_e9,_ea){
_e9=$(_e9);
new Effect.Morph(_e9,Object.extend({style:_ea},arguments[2]||{}));
return _e9;
},visualEffect:function(_eb,_ec,_ed){
_eb=$(_eb);
var s=_ec.dasherize().camelize(),_ef=s.charAt(0).toUpperCase()+s.substring(1);
new Effect[_ef](_eb,_ed);
return _eb;
},highlight:function(_f0,_f1){
_f0=$(_f0);
new Effect.Highlight(_f0,_f1);
return _f0;
}};
$w("fade appear grow shrink fold blindUp blindDown slideUp slideDown "+"pulsate shake puff squish switchOff dropOut").each(function(_f2){
Effect.Methods[_f2]=function(_f3,_f4){
_f3=$(_f3);
Effect[_f2.charAt(0).toUpperCase()+_f2.substring(1)](_f3,_f4);
return _f3;
};
});
$w("getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles").each(function(f){
Effect.Methods[f]=Element[f];
});
Element.addMethods(Effect.Methods);



// Based on X, a Cross-Browser Javascript Library, Distributed under the terms of the GNU LGPL

var xOp7Up,xOp6Dn,xIE4Up,xIE4,xIE5,xNN4,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
  var i=xUA.indexOf('opera');
  if(i!=-1){
    var v=parseInt(xUA.charAt(i+6));
    xOp7Up=v>=7;
    xOp6Dn=v<7;
  }
}
else if(navigator.vendor!='KDE' && document.all && xUA.indexOf('msie')!=-1){
  xIE4Up=parseFloat(navigator.appVersion)>=4;
  xIE4=xUA.indexOf('msie 4')!=-1;
  xIE5=xUA.indexOf('msie 5')!=-1;
}
else if(document.layers){xNN4=true;}
xMac=xUA.indexOf('mac')!=-1;

function xAddEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xPCW=xClientWidth(); window.xPCH=xClientHeight(); window.xREL=eL; xResizeEvent(); return; }
    if(eT=='scroll') { window.xPSL=xScrollLeft(); window.xPST=xScrollTop(); window.xSEL=eL; xScrollEvent(); return; }
  }
  var eh='e.on'+eT+'=eL';
  if(e.addEventListener) e.addEventListener(eT,eL,cap);
  else if(e.attachEvent) e.attachEvent('on'+eT,eL);
  else eval(eh);
}
// called only from the above
function xResizeEvent()
{
  if (window.xREL) setTimeout('xResizeEvent()', 250);
  var cw = xClientWidth(), ch = xClientHeight();
  if (window.xPCW != cw || window.xPCH != ch) { window.xPCW = cw; window.xPCH = ch; if (window.xREL) window.xREL(); }
}
function xScrollEvent()
{
  if (window.xSEL) setTimeout('xScrollEvent()', 250);
  var sl = xScrollLeft(), st = xScrollTop();
  if (window.xPSL != sl || window.xPST != st) { window.xPSL = sl; window.xPST = st; if (window.xSEL) window.xSEL(); }
}

function xAppendChild(oParent, oChild)
{
  if (oParent.appendChild) return oParent.appendChild(oChild);
  else return null;
}

function xClientHeight()
{
  var h=0;
  if(xOp6Dn) h=window.innerHeight;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientHeight)
    h=document.documentElement.clientHeight;
  else if(document.body && document.body.clientHeight)
    h=document.body.clientHeight;
  else if(xDef(window.innerWidth,window.innerHeight,document.width)) {
    h=window.innerHeight;
    if(document.width>window.innerWidth) h-=16;
  }
  return h;
}

function xClientWidth()
{
  var w=0;
  if(xOp6Dn) w=window.innerWidth;
  else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientWidth)
    w=document.documentElement.clientWidth;
  else if(document.body && document.body.clientWidth)
    w=document.body.clientWidth;
  else if(xDef(window.innerWidth,window.innerHeight,document.height)) {
    w=window.innerWidth;
    if(document.height>window.innerHeight) w-=16;
  }
  return w;
}

function xClip(e,t,r,b,l)
{
  if(!(e=xGetElementById(e))) return;
  if(e.style) {
    if (xNum(l)) e.style.clip='rect('+t+'px '+r+'px '+b+'px '+l+'px)';
    else e.style.clip='rect(0 '+parseInt(e.style.width)+'px '+parseInt(e.style.height)+'px 0)';
  }
}

function xCreateElement(sTag)
{
  if (document.createElement) return document.createElement(sTag);
  else return null;
}

function xDef()
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
  return true;
}

function xDeleteCookie(name, path)
{
  if (xGetCookie(name)) {
    document.cookie = name + "=" +
                    "; path=" + ((!path) ? "/" : path) +
                    "; expires=" + new Date(0).toGMTString();
  }
}

function xDisableDrag(id, last)
{
  if (!window._xDrgMgr) return;
  var ele = xGetElementById(id);
  ele.xDraggable = false;
  ele.xODS = null;
  ele.xOD = null;
  ele.xODE = null;
  xRemoveEventListener(ele, 'mousedown', _xOMD, false);
  if (_xDrgMgr.mm && last) {
    _xDrgMgr.mm = false;
    xRemoveEventListener(document, 'mousemove', _xOMM, false);
  }
}

function xDisplay(e,s)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.display)) {
    if (xStr(s)) e.style.display = s;
    return e.style.display;
  }
  return null;
}

//// Private Data
var _xDrgMgr = {ele:null, mm:false};
//// Public Functions
function xEnableDrag(id,fS,fD,fE)
{
  var ele = xGetElementById(id);
  ele.xDraggable = true;
  ele.xODS = fS;
  ele.xOD = fD;
  ele.xODE = fE;
  xAddEventListener(ele, 'mousedown', _xOMD, false);
  if (!_xDrgMgr.mm) {
    _xDrgMgr.mm = true;
    xAddEventListener(document, 'mousemove', _xOMM, false);
  }
}
//// Private Event Listeners
function _xOMD(e) // drag start
{
  var evt = new xEvent(e);
  var ele = evt.target;
  while(ele && !ele.xDraggable) {
    ele = xParent(ele);
  }
  if (ele) {
    xPreventDefault(e);
    ele.xDPX = evt.pageX;
    ele.xDPY = evt.pageY;
    _xDrgMgr.ele = ele;
    xAddEventListener(document, 'mouseup', _xOMU, false);
    if (ele.xODS) {
      ele.xODS(ele, evt.pageX, evt.pageY);
    }
  }
}
function _xOMM(e) // drag
{
  var evt = new xEvent(e);
  if (_xDrgMgr.ele) {
    xPreventDefault(e);
    var ele = _xDrgMgr.ele;
    var dx = evt.pageX - ele.xDPX;
    var dy = evt.pageY - ele.xDPY;
    ele.xDPX = evt.pageX;
    ele.xDPY = evt.pageY;
    if (ele.xOD) {
      ele.xOD(ele, dx, dy);
    }
    else {
      xMoveTo(ele, xLeft(ele) + dx, xTop(ele) + dy);
    }
  }  
}
function _xOMU(e) // drag end
{
  if (_xDrgMgr.ele) {
    xPreventDefault(e);
    xRemoveEventListener(document, 'mouseup', _xOMU, false);
    if (_xDrgMgr.ele.xODE) {
      var evt = new xEvent(e);
      _xDrgMgr.ele.xODE(_xDrgMgr.ele, evt.pageX, evt.pageY);
    }
    _xDrgMgr.ele = null;
  }  
}

function xEvent(evt) // object prototype
{
  var e = evt || window.event;
  if(!e) return;
  if(e.type) this.type = e.type;
  if(e.target) this.target = e.target;
  else if(e.srcElement) this.target = e.srcElement;

  // Section B
  if (e.relatedTarget) this.relatedTarget = e.relatedTarget;
  else if (e.type == 'mouseover' && e.fromElement) this.relatedTarget = e.fromElement;
  else if (e.type == 'mouseout') this.relatedTarget = e.toElement;
  // End Section B

  if(xOp6Dn) { this.pageX = e.clientX; this.pageY = e.clientY; }
  else if(xDef(e.pageX,e.pageY)) { this.pageX = e.pageX; this.pageY = e.pageY; }
  else if(xDef(e.clientX,e.clientY)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); }

  // Section A
  if (xDef(e.offsetX,e.offsetY)) {
    this.offsetX = e.offsetX;
    this.offsetY = e.offsetY;
  }
  else if (xDef(e.layerX,e.layerY)) {
    this.offsetX = e.layerX;
    this.offsetY = e.layerY;
  }
  else {
    this.offsetX = this.pageX - xPageX(this.target);
    this.offsetY = this.pageY - xPageY(this.target);
  }
  // End Section A
  
  if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
  else if (xDef(e.which) && e.type.indexOf('key')!=-1) { this.keyCode = e.which; }

  this.shiftKey = e.shiftKey;
  this.ctrlKey = e.ctrlKey;
  this.altKey = e.altKey;
}


function xFirstChild(e, t)
{
  var c = e ? e.firstChild : null;
  if (t) while (c && c.nodeName != t) { c = c.nextSibling; }
  else while (c && c.nodeType != 1) { c = c.nextSibling; }
  return c;
}

function xGetComputedStyle(oEle, sProp, bInt)
{
  var s, p = 'undefined';
  var dv = document.defaultView;
  if(dv && dv.getComputedStyle){
    s = dv.getComputedStyle(oEle,'');
    if (s) p = s.getPropertyValue(sProp);
  }
  else if(oEle.currentStyle) {
    // convert css property name to object property name for IE
    var a = sProp.split('-');
    sProp = a[0];
    for (var i=1; i<a.length; ++i) {
      c = a[i].charAt(0);
      sProp += a[i].replace(c, c.toUpperCase());
    }   
    p = oEle.currentStyle[sProp];
  }
  else return null;
  return bInt ? (parseInt(p) || 0) : p;
}

function xGetCookie(name)
{
  var value=null, search=name+"=";
  if (document.cookie.length > 0) {
    var offset = document.cookie.indexOf(search);
    if (offset != -1) {
      offset += search.length;
      var end = document.cookie.indexOf(";", offset);
      if (end == -1) end = document.cookie.length;
      value = unescape(document.cookie.substring(offset, end));
    }
  }
  return value;
}

function xGetElementById(e)
{
  if(typeof(e)!='string') return e;
  if(document.getElementById) e=document.getElementById(e);
  else if(document.all) e=document.all[e];
  else e=null;
  return e;
}

function xGetElementsByAttribute(sTag, sAtt, sRE, fn)
{
  var a, list, found = new Array(), re = new RegExp(sRE, 'i');
  list = xGetElementsByTagName(sTag);
  for (var i = 0; i < list.length; ++i) {
    a = list[i].getAttribute(sAtt);
    if (!a) {a = list[i][sAtt];}
    if (typeof(a)=='string' && a.search(re) != -1) {
      found[found.length] = list[i];
      if (fn) fn(list[i]);
    }
  }
  return found;
}

function xGetElementsByClassName(c,p,t,f)
{
  var found = new Array();
  var re = new RegExp('\\b'+c+'\\b', 'i');
  var list = xGetElementsByTagName(t, p);
  for (var i = 0; i < list.length; ++i) {
    if (list[i].className && list[i].className.search(re) != -1) {
      found[found.length] = list[i];
      if (f) f(list[i]);
    }
  }
  return found;
}

function xGetElementsByTagName(t,p)
{
  var list = null;
  t = t || '*';
  p = p || document;
  if (xIE4 || xIE5) {
    if (t == '*') list = p.all;
    else list = p.all.tags(t);
  }
  else if (p.getElementsByTagName) list = p.getElementsByTagName(t);
  return list || new Array();
}

function xHasPoint(e,x,y,t,r,b,l)
{
  if (!xNum(t)){t=r=b=l=0;}
  else if (!xNum(r)){r=b=l=t;}
  else if (!xNum(b)){l=r; b=t;}
  var eX = xPageX(e), eY = xPageY(e);
  return (x >= eX + l && x <= eX + xWidth(e) - r &&
          y >= eY + t && y <= eY + xHeight(e) - b );
}

function xHeight(e,h)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(h)) {
    if (h<0) h = 0;
    else h=Math.round(h);
  }
  else h=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    h = xClientHeight();
  }
  else if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
    if(h>=0) {
      var pt=0,pb=0,bt=0,bb=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pt=gcs(e,'padding-top',1);
        if (pt !== null) {
          pb=gcs(e,'padding-bottom',1);
          bt=gcs(e,'border-top-width',1);
          bb=gcs(e,'border-bottom-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetHeight,e.style.height)){
          e.style.height=h+'px';
          pt=e.offsetHeight-h;
        }
      }
      h-=(pt+pb+bt+bb);
      if(isNaN(h)||h<0) return;
      else e.style.height=h+'px';
    }
    h=e.offsetHeight;
  }
  else if(css && xDef(e.style.pixelHeight)) {
    if(h>=0) e.style.pixelHeight=h;
    h=e.style.pixelHeight;
  }
  return h;
}

function xHide(e){return xVisibility(e,0);}

function xImgRollSetup(p,s,x)
{
  var ele, id;
  for (var i=3; i<arguments.length; ++i) {
    id = arguments[i];
    if (ele = xGetElementById(id)) {
      ele.xIOU = p + id + x;
      ele.xIOO = new Image();
      ele.xIOO.src = p + id + s + x;
      ele.onmouseout = imgOnMouseout;
      ele.onmouseover = imgOnMouseover;
    }
  }
  function imgOnMouseout(e)
  {
    if (this.xIOU) {
      this.src = this.xIOU;
    }
  }
  function imgOnMouseover(e)
  {
    if (this.xIOO && this.xIOO.complete) {
      this.src = this.xIOO.src;
    }
  }
}

function xInnerHtml(e,h)
{
  if(!(e=xGetElementById(e)) || !xStr(e.innerHTML)) return null;
  var s = e.innerHTML;
  if (xStr(h)) {e.innerHTML = h;}
  return s;
}


function xLeft(e, iX)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if (css && xStr(e.style.left)) {
    if(xNum(iX)) e.style.left=iX+'px';
    else {
      iX=parseInt(e.style.left);
      if(isNaN(iX)) iX=0;
    }
  }
  else if(css && xDef(e.style.pixelLeft)) {
    if(xNum(iX)) e.style.pixelLeft=iX;
    else iX=e.style.pixelLeft;
  }
  return iX;
}

function xMoveTo(e,x,y)
{
  xLeft(e,x);
  xTop(e,y);
}

function xName(e)
{
  if (!e) return e;
  else if (e.id && e.id != "") return e.id;
  else if (e.name && e.name != "") return e.name;
  else if (e.nodeName && e.nodeName != "") return e.nodeName;
  else if (e.tagName && e.tagName != "") return e.tagName;
  else return e;
}

function xNextSib(e,t)
{
  var s = e ? e.nextSibling : null;
  if (t) while (s && s.nodeName != t) { s = s.nextSibling; }
  else while (s && s.nodeType != 1) { s = s.nextSibling; }
  return s;
}

function xNum()
{
  for(var i=0; i<arguments.length; ++i){if(isNaN(arguments[i]) || typeof(arguments[i])!='number') return false;}
  return true;
}

function xOffsetLeft(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetLeft)) return e.offsetLeft;
  else return 0;
}

function xOffsetTop(e)
{
  if (!(e=xGetElementById(e))) return 0;
  if (xDef(e.offsetTop)) return e.offsetTop;
  else return 0;
}

function xPad(s,len,c,left)
{
  if(typeof s != 'string') s=s+'';
  if(left) {for(var i=s.length; i<len; ++i) s=c+s;}
  else {for (var i=s.length; i<len; ++i) s+=c;}
  return s;
}

function xPageX(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var x = 0;
  while (e) {
    if (xDef(e.offsetLeft)) x += e.offsetLeft;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
  return x;
}

function xPageY(e)
{
  if (!(e=xGetElementById(e))) return 0;
  var y = 0;
  while (e) {
    if (xDef(e.offsetTop)) y += e.offsetTop;
    e = xDef(e.offsetParent) ? e.offsetParent : null;
  }
//  if (xOp7Up) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324 (reported 1nov03)
  return y;
}

function xParent(e, bNode)
{
  if (!(e=xGetElementById(e))) return null;
  var p=null;
  if (!bNode && xDef(e.offsetParent)) p=e.offsetParent;
  else if (xDef(e.parentNode)) p=e.parentNode;
  else if (xDef(e.parentElement)) p=e.parentElement;
  return p;
}

function xPreventDefault(e)
{
  if (e && e.preventDefault) e.preventDefault();
  else if (window.event) window.event.returnValue = false;
}

function xPrevSib(e,t)
{
  var s = e ? e.previousSibling : null;
  if (t) while(s && s.nodeName != t) {s=s.previousSibling;}
  else while(s && s.nodeType != 1) {s=s.previousSibling;}
  return s;
}

function xRemoveEventListener(e,eT,eL,cap)
{
  if(!(e=xGetElementById(e))) return;
  eT=eT.toLowerCase();
  if((!xIE4Up && !xOp7Up) && e==window) {
    if(eT=='resize') { window.xREL=null; return; }
    if(eT=='scroll') { window.xSEL=null; return; }
  }
  var eh='e.on'+eT+'=null';
  if(e.removeEventListener) e.removeEventListener(eT,eL,cap);
  else if(e.detachEvent) e.detachEvent('on'+eT,eL);
  else eval(eh);
}

function xResizeTo(e,w,h)
{
  xWidth(e,w);
  xHeight(e,h);
}

function xScrollLeft(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollLeft) offset=w.document.documentElement.scrollLeft;
    else if(w.document.body && xDef(w.document.body.scrollLeft)) offset=w.document.body.scrollLeft;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollLeft)) offset = e.scrollLeft;
  }
  return offset;
}

function xScrollTop(e, bWin)
{
  var offset=0;
  if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    var w = window;
    if (bWin && e) w = e;
    if(w.document.documentElement && w.document.documentElement.scrollTop) offset=w.document.documentElement.scrollTop;
    else if(w.document.body && xDef(w.document.body.scrollTop)) offset=w.document.body.scrollTop;
  }
  else {
    e = xGetElementById(e);
    if (e && xNum(e.scrollTop)) offset = e.scrollTop;
  }
  return offset;
}

function xSetCookie(name, value, expire, path)
{
  document.cookie = name + "=" + escape(value) +
                    ((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
                    "; path=" + ((!path) ? "/" : path);
}

function xShow(e) {return xVisibility(e,1);}

function xStopPropagation(evt)
{
  if (evt && evt.stopPropagation) evt.stopPropagation();
  else if (window.event) window.event.cancelBubble = true;
}

function xStr(s)
{
  for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
  return true;
}

function xTop(e, iY)
{
  if(!(e=xGetElementById(e))) return 0;
  var css=xDef(e.style);
  if(css && xStr(e.style.top)) {
    if(xNum(iY)) e.style.top=iY+'px';
    else {
      iY=parseInt(e.style.top);
      if(isNaN(iY)) iY=0;
    }
  }
  else if(css && xDef(e.style.pixelTop)) {
    if(xNum(iY)) e.style.pixelTop=iY;
    else iY=e.style.pixelTop;
  }
  return iY;
}

function xTriStateImage(idOut, urlOver, urlDown, fnUp) // Object Prototype
{
  var img;
  // Downgrade Detection
  if (typeof Image != 'undefined' && document.getElementById) {
    img = document.getElementById(idOut);
    if (img) {
      // Constructor Code
      var urlOut = img.src;
      var i = new Image();
      i.src = urlOver;
      i = new Image();
      i.src = urlDown;
      // Event Listeners (closure)
      img.onmouseover = function()
      {
        this.src = urlOver;
      };
      img.onmouseout = function()
      {
        this.src = urlOut;
      };
      img.onmousedown = function()
      {
        this.src = urlDown;
      };
      img.onmouseup = function()
      {
        this.src = urlOver;
        if (fnUp) {
          fnUp();
        }
      };
    }
  }
  // Destructor Method
  this.onunload = function()
  {
    if (xIE4Up && img) { // Remove any circular references for IE
      img.onmouseover = img.onmouseout = img.onmousedown = null;
      img = null;
    }
  };    
}

var xVersion = "4.0";

function xVisibility(e, bShow)
{
  if(!(e=xGetElementById(e))) return null;
  if(e.style && xDef(e.style.visibility)) {
    if (xDef(bShow)) e.style.visibility = bShow ? 'visible' : 'hidden';
    return e.style.visibility;
  }
  return null;
}

function xWalkEleTree(n,f,d,l,b)
{
  if (typeof l == 'undefined') l = 0;
  if (typeof b == 'undefined') b = 0;
  var v = f(n,l,b,d);
  if (!v) return 0;
  if (v == 1) {
    for (var c = n.firstChild; c; c = c.nextSibling) {
      if (c.nodeType == 1) {
        if (!l) ++b;
        if (!xWalkEleTree(c,f,d,l+1,b)) return 0;
      }
    }
  }
  return 1;
}

function xWalkTree(n, f)
{
  f(n);
  for (var c = n.firstChild; c; c = c.nextSibling) {
    if (c.nodeType == 1) xWalkTree(c, f);
  }
}

function xWidth(e,w)
{
  if(!(e=xGetElementById(e))) return 0;
  if (xNum(w)) {
    if (w<0) w = 0;
    else w=Math.round(w);
  }
  else w=-1;
  var css=xDef(e.style);
  if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
    w = xClientWidth();
  }
  else if(css && xDef(e.offsetWidth) && xStr(e.style.width)) {
    if(w>=0) {
      var pl=0,pr=0,bl=0,br=0;
      if (document.compatMode=='CSS1Compat') {
        var gcs = xGetComputedStyle;
        pl=gcs(e,'padding-left',1);
        if (pl !== null) {
          pr=gcs(e,'padding-right',1);
          bl=gcs(e,'border-left-width',1);
          br=gcs(e,'border-right-width',1);
        }
        // Should we try this as a last resort?
        // At this point getComputedStyle and currentStyle do not exist.
        else if(xDef(e.offsetWidth,e.style.width)){
          e.style.width=w+'px';
          pl=e.offsetWidth-w;
        }
      }
      w-=(pl+pr+bl+br);
      if(isNaN(w)||w<0) return;
      else e.style.width=w+'px';
    }
    w=e.offsetWidth;
  }
  else if(css && xDef(e.style.pixelWidth)) {
    if(w>=0) e.style.pixelWidth=w;
    w=e.style.pixelWidth;
  }
  return w;
}

function xZIndex(e,uZ)
{
  if(!(e=xGetElementById(e))) return 0;
  if(e.style && xDef(e.style.zIndex)) {
    if(xNum(uZ)) e.style.zIndex=uZ;
    uZ=parseInt(e.style.zIndex);
  }
  return uZ;
}

// SciVantage additions

function xAddClass(e,cls) {
  if (!(e=xGetElementById(e))) return null;
  var newClassName = e.className + " " + cls;
  e.className = newClassName.replace(new RegExp(" +", "g"), " ");
}

function xRemoveClass(e,cls) {
  if (!(e=xGetElementById(e))) return null;
  var newClassName = e.className.replace(new RegExp(cls, "gi"), "");
  e.className = newClassName.replace(new RegExp(" +", "g"), " ");
}

function xHasClass(e,cls) {
  if (!(e=xGetElementById(e))) return false;
  var classes = e.className.split(" ");
  for (var x in classes) {if (classes[x] === cls) return true;}
  return false;
}

function xGetClasses(e) {
  if (!(e=xGetElementById(e))) return new Array();
  return (e.className.split(" "));
}

function xSendXMLHttpRequest(method, url, callFunc) {
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    req.onreadystatechange = callFunc;
    req.open(method, url, true);
    req.send(null);
    return req;
  } else if (window.ActiveXObject) {
    req = new ActiveXObject("Microsoft.XMLHTTP");
    if (req) {
      req.onreadystatechange = callFunc;
      req.open(method, url, true);
      req.send();
      return req;
    }
  }
  return null;
}

// retrieve text of an XML document element
function xGetElementText(local, parentElem, index) {
  var result = parentElem.getElementsByTagName(local)[index];
  if (result) {
    // get text, accounting for possible
    // whitespace (carriage return) text nodes 
    if (result.childNodes.length > 1) {
      return result.childNodes[1].nodeValue;
    } else {
      child = result.firstChild;
      if (child == null) return "";
      return child.nodeValue;
    }
  } else {
    return "";
  }
}


// Flash Player Version Detection - Rev 1.6
// Detect Client Browser type
// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

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

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

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

	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";

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

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

		} catch (e) {
		}
	}

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

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

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

// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
			//alert("flashVer="+flashVer);
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}

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

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

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

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

    document.write(str);
}

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

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

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

// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;
// Version check based upon the values entered above in "Globals"
var hasRequestedFlashVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);

var ErrorObj=Class.create();
ErrorObj.prototype={
	/**
	* constructor - initializes object
	* @param mix - either a string, array of string, or an ErrorObj object
	* @return void
	**/
	initialize:function(errors, identifier) {
		this.errors=[];
		this.className='jsErrors';
		
		if(typeof(errors)=="string") {
			this.errors.push(errors);
		}
		else if(errors instanceof Array) {
			this.errors=errors;
		}
		else if(errors instanceof ErrorObj) {
			this.errors=errors.getErrors();
		}
		else if(errors instanceof Error) {
			this.errors.push(errors.message);
		}
		return;
	},
	/**
	* return the errors in an array
	* @return array - the errors in an array of strings
	**/
	getErrors:function() {
		return this.errors;
	},
	/**
	* display errors on the page
	* @return void
	**/
	display:function() {
		var errorArea=null;
		
		if(this.errors.length < 0) {
			return;
		}
		if(!(errorArea = $("main"))) {
			errorArea=document.createElement("UL");
			errorArea.id='main';
			errorArea.className='errors';
		}
		
		for(var i=0; i< this.errors.length; i++) {
			var error=document.createElement("LI");
			error.innerHTML=this.errors[i];
			error.className=this.className;
			errorArea.appendChild(error);
			$$(".messageContainer")[0].appendChild(errorArea);
		}
	},
	/**
	* Clear all errors set by ErrorObj class
	* @return void
	**/
	clearAll:function() {
		$$("."+this.className).each(function(element) {
			var parent=element.parentNode;
			parent.removeChild(element);
			
			//if no errors at all, remove the parent's parent node
			if(parent.childNodes.length <= 0) {
				parent.parentNode.removeChild(parent);
			}
			return false;
		});
	}
};

var HTML = new Object;
HTML["positive"] = new Object;
HTML["negative"] = new Object;
HTML["zero"] = new Object;
HTML["bidMidAsk"] = new Object;
HTML["positive"]["normal"] = "<span class=\"positive\">*VALUE*</span>";
HTML["positive"]["arrow"] = "<span class=\"positive\">*VALUE*<img src=\"https://www.tradeking.com/Web/Images/Icons/gain.gif\" /></span>";
HTML["positive"]["brackets"] = "<span class=\"positive\">[*VALUE*]</span>";
HTML["negative"]["normal"] = "<span class=\"negative\">*VALUE*</span>";
HTML["negative"]["arrow"] = "<span class=\"negative\">*VALUE*<img src=\"https://www.tradeking.com/Web/Images/Icons/loss.gif\" /></span>";
HTML["negative"]["brackets"] = "<span class=\"negative\">[*VALUE*]</span>";
HTML["zero"]["normal"] = "*VALUE*";
HTML["zero"]["arrow"] = "*VALUE*";
HTML["zero"]["brackets"] = "[*VALUE*]";
HTML["bidMidAsk"]["debit"]="<span class=\"bidMidAsk\">*VALUE*</span><span class=\"creditDebitEven\" id=\"debit\">debit</span>";
HTML["bidMidAsk"]["credit"]="<span class=\"bidMidAsk\">*VALUE*</span><span class=\"creditDebitEven\" id=\"credit\">credit</span>";
HTML["bidMidAsk"]["even"]="<span class=\"bidMidAsk\">*VALUE*</span><span class=\"creditDebitEven\" id=\"even\">even</span>";

HTML["zero"]["sign"] = "*VALUE*";
HTML["positive"]["sign"] = "<span class=\"positive\">+*VALUE*</span>";
HTML["negative"]["sign"] = "<span class=\"negative\">*VALUE*</span>";

var rtTradeQuotes = true;

var FORMAT = new Object;
FORMAT["quoteLast"] = "|2|.|,|3||N/A";
FORMAT["quoteChange"] = "|2|.|,|3||N/A";
FORMAT["quotePctChange"] = "|2|.|,|3|%|N/A";
FORMAT["quoteBid"] = "|2|.|,|3||0.00";
FORMAT["quoteMid"] = "|2|.|,|3||0.00";
FORMAT["quoteAsk"] = "|2|.|,|3||0.00";
FORMAT["quoteVolume"] = "|0|.|,|3||0";
FORMAT["quoteDelta"] = "|2|.|,|3||0";
FORMAT["quoteOpenInterest"] = "|0|.|,|3||0";

var showStateIfNonUS = false;
var hideSSNIfNonUs = false;
var rolloverMenuBesideBox = false;
var showGreencardRegistrationInfo = false;
var showVisaRegistrationInfo = false;


var globalMFA = true;

// turn flash keyboard on/off
var hasGlobalFlashVersion = true;

/* if no firebug */
if (!window.console) {
	window.console = {
		log:function(e){alert(e);}
	}
}

/* scivantage Investor JS lib */
function winPop(url,winName,width,height,scroll,resize,menus){
	w = (typeof width != "undefined") ? width : 750;
	h = (typeof height != "undefined") ? height : 600;
	s = (typeof scroll != "undefined") ? scroll : "yes";
	r = (typeof resize != "undefined") ? resize : "yes";
	m = (typeof resize != "undefined") ? menus : "no";

	window.open(url,winName,"width="+w+",height="+h+",scrollbars="+s+",resizable="+r+",menubar="+m);
	return false;
}

// Enable popup links created by HTML::createLink()
function addPopupLinks(configs) {
	xGetElementsByClassName("popupWindow", null, "A", function(ele) {
		var href = ele.href;
		var eleID = ele.id;
		xAddEventListener(ele, "click", function(evt) {
			var winName = "popupWindow";
			if (typeof configs != "undefined" && typeof configs[eleID] != "undefined") {
				var width = configs[eleID].width;
				var height = configs[eleID].height;
				var scroll = configs[eleID].scroll;
				var resize = configs[eleID].resize;
				var menus = configs[eleID].menus;
			}
			winPop(href, winName, width, height, scroll, resize, menus);
			xPreventDefault(evt);
			xStopPropagation(evt);
		});
	});
}

function toggleElement(id,imgId,imgOn,imgOff,useEmptyStr) {
	if(useEmptyStr == null)
		useEmptyStr = false;

	if(!useEmptyStr){
		if (xDisplay(id, null) != "block") {
			xDisplay(id, "block");
			if(imgOff)
				xGetElementById(imgId).src = imgOff;
		} else {
			xDisplay(id, "none");
			if(imgOn)
				xGetElementById(imgId).src = imgOn;
		}
	}else{
		if (xDisplay(id, null) == "none") {
			xDisplay(id, "");
			if(imgOff)
				xGetElementById(imgId).src = imgOff;
		} else {
			xDisplay(id, "none");
			if(imgOn)
			xGetElementById(imgId).src = imgOn;
		}
	}
}

/**
 * @author		Reginald Mullin <reginald.mullin@scivantage.com>
 * @copyright	Scivantage 9/15/2005
 * @example		toggleElements(['id1','id2','id3'],imgId,imgOn,imgOff)
 * @name		toggleElements
 * @param		array [ids] an array of element ids
 * @param		string [imgId] the id of active/inactive image
 * @param		string [imgOff] the path to inactive image
 * @param		string [imgOn] the path to active image
 */
function toggleElements(ids, imgId, imgOn, imgOff,useEmptyStr)
{
	for ( var i = 0; i < ids.length; i++ )
	{
		toggleElement(ids[i], imgId, imgOn, imgOff,useEmptyStr);
	}
}

function doSubstitutions(originalString, substitutions) {
	if (substitutions.length == 0) return originalString;
	for (var token in substitutions) {
		var replacement = substitutions[token];
		originalString = originalString.replace(new RegExp("\\*" + token + "\\*", "g"), replacement);
	}
	return originalString;
}

function applyPosNegStyle(value, styleName) {
	var subs = new Object;
	subs["VALUE"] = value;
	if (value.match(/^[-]+/)) {
		// negative
		return doSubstitutions(HTML["negative"][styleName], subs);
	}
	if (value != "N/A" && value != "" && parseFloat(value) != 0) {
		// positive
		return doSubstitutions(HTML["positive"][styleName], subs);
	}

	// zero or unformatted
	return doSubstitutions(HTML["zero"][styleName], subs);
}

/**
* append the label debit, credit, or even for positive, netative, 
* or 0 values respectively for given bid, mid, and ask 
* @param string - the value
* @param int - the style name; debit, credit, or zero
* @return string - the HTML value
**/
function applyDebitCreditEven(value, styleName) {
	var subs=new Object;
	subs["VALUE"]=value;
	
	return doSubstitutions(HTML["bidMidAsk"][styleName], subs);
}

// Formats a number based on a format string, which is a pipe-delimited list:
// Item 1: prefix string, e.g. $
// Item 2: number of decimal places, e.g. 3
// Item 3: decimal separator, e.g. .
// Item 4: group separator, e.g. ,
// Item 5: group length, e.g. 3
// Item 6: suffix string, e.g. %
// Item 7: value to display if zero or empty; e.g. N/A
function formatNumber(value, formatStr) {
	if (typeof formatStr != "string") return "ERROR";
	var formatItems = formatStr.split("|");
	if (formatItems.length != 7) return "ERROR";
	var result = "";

	if (typeof value == "string") {
		if (value == "") return formatItems[6];
		if (isNaN(parseFloat(value))) return value;
		value = parseFloat(value);
	}

	var numDecimals = parseInt(formatItems[1]);
	value = value.toFixed(numDecimals);
	if (value == 0) return formatItems[6];

	var valueParts = value.split(".");
	if (valueParts[0].charAt(0) == "-") {
		result += "-";
		valueParts[0] = valueParts[0].substr(1);
	}
	result += formatItems[0];

	var intLength = valueParts[0].length;
	var groupLength = parseInt(formatItems[4]);
	var remainder = intLength % groupLength;
	result += valueParts[0].substr(0, remainder);
	for (var i = remainder; i < intLength; i = i + groupLength) {
		if (i > 0) result += formatItems[3];
		result += valueParts[0].substr(i, groupLength);
	}
	if (valueParts.length == 2)
		result += formatItems[2] + valueParts[1];

	result += formatItems[5];
	return result;
}

// Gets the number of elements for a given checkbox/radio array. If there's only one element,
// it's not an array, but this function will still return 1. Use getFormArrayItem to get an
// individual item.
function getFormArrayCount(element) {
	if (!xDef(element))
		return 0;
	if (element[0]) {
		return element.length;
	}
	return 1;
}

// Gets an individual element of a checkbox/radio array. If there's only one element, it's not
// an array, but this function will get the element itself.
function getFormArrayItem(element, index) {
	if (!xDef(element))
		return null;
	if (element[0]) {
		return element[index];
	}
	return element;
}

function isArray(obj) {return obj instanceof Array || typeof obj == "Array";}
function inArray(obj, val) {for (var x in obj) {if (obj[x] === val) return true;} return false;}

// Get the value of a form field. The element can be either a form field object,
// or an array obtained from form.elements[]. The result will be an array if
// multiple is true (useful for checkbox groups and multi-select boxes)
function getFormVal(element, multiple) {
	if (typeof multiple == "undefined") multiple = false;
	var result = [];
	if (element[0] && !element.tagName) {
		// checkbox or radio array
		for (var i = 0; i < element.length; i++) {
			if (element[i].checked)
				result.push(element[i].value);
		}
	} else switch (element.tagName) {
		case "SELECT":
			if (element.type == "select-multiple") {
				for (var i = 0; i < element.options.length; i++) {
					if (element.options[i].selected)
						result.push(element.options[i].value);
				}
			} else {
				result.push(element.options[element.selectedIndex].value);
			}
			break;
		case "TEXTAREA":
			result.push(element.value);
			break;
		case "INPUT":
			switch (element.type) {
				case "hidden":
				case "text":
				case "password":
					result.push(element.value);
					break;
				case "radio":
				case "checkbox":
					if (element.checked)
						result.push(element.value);
					break;
			}
	}
	if (multiple) return result;
	if (result.length == 0) return null;
	return result[0];
}

// Set the value of a form field. The element can be either a form field object,
// or an array obtained from form.elements[]. The new value may be an array
// (useful for checkbox groups and multi-select boxes)
function setFormVal(element, newVal) {
	var multiple = isArray(newVal);
	if (multiple && newVal.length == 0) {
		multiple = false;
		newVal = "";
	}
	if (element[0] && !element.tagName) {
		// checkbox or radio array
		for (var i = 0; i < element.length; i++) {
			if (multiple) {
				element[i].checked = inArray(newVal, element[i].value);
			}
			else element[i].checked = newVal === element[i].value;
		}
	} else switch (element.tagName) {
		case "SELECT":
			if (element.type == "select-multiple") {
				for (var i = 0; i < element.options.length; i++) {
					if (multiple)
						element.options[i].selected = inArray(newVal, element.options[i].value);
					else element.options[i].selected = newVal === element.options[i].value;
				}
			} else {
				for (var i = 0; i < element.options.length; i++) {
					if ((multiple && inArray(newVal, element.options[i].value))
						|| (!multiple && newVal === element.options[i].value)) {
						element.selectedIndex = i;
						break;
					}
				}
			}
			break;
		case "TEXTAREA":
			if (multiple) element.value = newVal[0];
			else element.value = newVal;
			break;
		case "INPUT":
			switch (element.type) {
				case "hidden":
				case "text":
				case "password":
					if (multiple) element.value = newVal[0];
					else element.value = newVal;
					break;
				case "radio":
				case "checkbox":
					if (multiple)
						element.checked = inArray(newVal, element.value);
					else element.checked = newVal === element.value;
					break;
			}
	}
}

// Given a form element and a parent element, look for a label inside the
// parent element that is attached to the form element
function getLabelForId(formEle, parentEle) {
	var label;
	var labels = xGetElementsByTagName("label", parentEle);
	for (var i = 0; (label = labels[i]); i++) {
		if (label.htmlFor == formEle) return label;
	}
	return false;
}

function isFormElement(element, allowHidden, allowButtons) {
	if (typeof allowHidden == "undefined") allowHidden = false;
	if (typeof allowButtons == "undefined") allowButtons = false;
	if (!xDef(element))
		return false;
	if (element[0]) element = element[0];
	if (element.tagName == "SELECT" || element.tagName == "TEXTAREA")
		return true;
	if (element.tagName == "INPUT") {
		if (element.type == "hidden" && !allowHidden) return false;
		else if ((element.type == "button" || element.type == "submit") && !allowButtons) return false;
		else return true;
	}
	return false;
}

function selectFormField(field, errorsOverride) {
	if (errorsOverride && typeof firstError != "undefined")
		field = firstError;
	var ele = xGetElementById(field);
	if (!ele) return;
	ele.focus();
}

// To make a rollover menu appear when you move the mouse over a target element,
// give the element the class "rolloverTarget" and the ID "rolloverTarget_x",
// where x is a unique ID.
// Then create a menu element (e.g. a UL) and give it the ID "rolloverMenu_x".
function initRollovers() {
	xGetElementsByClassName("rolloverTarget", null, "",
		function(targetEle) {
			// find the associated rollover menu
			var idParts = targetEle.id.split("_");
			var menuEle = xGetElementById("rolloverMenu_" + idParts[1]);
			xAddEventListener(targetEle, "mouseover", getRolloverMoveInFunc(targetEle, menuEle));
			xAddEventListener(targetEle, "mouseout", getRolloverMoveOutFunc(targetEle, menuEle));
			xAddEventListener(menuEle, "mouseover", getRolloverMoveInFunc(targetEle, menuEle));
			xAddEventListener(menuEle, "mouseout", getRolloverMoveOutFunc(targetEle, menuEle));
		}
	);
}

var rolloverTimer;
var visibleRollover;

function getRolloverMoveInFunc(targetEle, menuEle) {
	return function(evt) {
		// stop the timer to hide the old menu, and just hide it now
		if (rolloverTimer)
			clearTimeout(rolloverTimer);
		if (visibleRollover && visibleRollover.id != menuEle.id)
			hideRollover();
		m = (typeof resize != "undefined") ? menus : "no";

		coordX = (rolloverMenuBesideBox) ? xPageX(targetEle)  + xWidth(targetEle) + 2 : xPageX(targetEle);
		coordY = (rolloverMenuBesideBox) ? xPageY(targetEle) : xPageY(targetEle) + xHeight(targetEle) + 2;
		xMoveTo(menuEle, coordX, coordY);
		xDisplay(menuEle, "block");
		visibleRollover = menuEle;
	};
}

function getRolloverMoveOutFunc(targetEle, menuEle) {
	return function(evt) {
		// start a timer to hide the menu
		if (visibleRollover)
			rolloverTimer = setTimeout('hideRollover()', 50);
	};
}

function hideRollover() {
	xDisplay(visibleRollover.id, "none");
}


// If fieldEle is an input field, this will hook things up so that when you press enter in the field,
// it sends a click to submitItem. Or if submitItem is a function, it will call it.
// If you pass cancelItem, it will use it when you press escape.
// If fieldEle is a form, it will apply this behavior to every input field in the form.
function attachDefaultButton(fieldEle, submitItem, cancelItem) {
	var eventFunc = function(evt) {
		myEvent = new xEvent(evt);
		if (myEvent.keyCode == 13 || myEvent.keyCode == 3) {
			xPreventDefault(evt);
			if (typeof submitItem == "function")
				submitItem();
			else submitItem.click();
		} else if (typeof cancelItem != "undefined" && myEvent.keyCode == 27) {
			xPreventDefault(evt);
			if (typeof cancelItem == "function")
				cancelItem();
			else cancelItem.click();
		}
	};

	if (isFormElement(fieldEle)) {
		xAddEventListener(fieldEle, "keypress", eventFunc);
	} else if (fieldEle.tagName == "FORM") {
		var formElements = xGetElementsByTagName("*", fieldEle);
		for (var i = 0; i < formElements.length; i++) {
			if (isFormElement(formElements[i]))
				xAddEventListener(formElements[i], "keypress", eventFunc);
		}
	}
}

function nlToBR(str) {
	return str.replace(/\r\n|\r|\n/g, "<br />");
}

function getFilterCharsFunc(allowedChars, illegalChars) {
	var eventFunc = function(evt) {
		myEvent = new xEvent(evt);
		if (illegalChars == "")
			regex = new RegExp("[^" + allowedChars + "]", "g");
		else if (allowedChars == "")
			regex = new RegExp("[" + allowedChars + "]", "g");
		else return;
		myEvent.target.value = myEvent.target.value.replace(regex, "");
	};

	return eventFunc;
}

function sortForm(sortBy, sortDir, formID) {
	xGetElementById(formID).sortBy.value = sortBy;
	xGetElementById(formID).sortDir.value = sortDir;
	xGetElementById(formID).submit();
}

function removeErrorIndicators(containerID) {
	xGetElementsByClassName("errorField", xGetElementById(containerID), "*",
		function(ele){xRemoveClass(ele, "errorField");}, false);
}

function removeErrorMessages(messageID) {
	if (typeof messageID == "undefined") {
		xGetElementsByClassName("errors", null, "UL",
			function(ele){xDisplay(ele, "none");}, false);
	} else {
		xDisplay(messageID, "none");
	}
}

function reportDownloadTimes() {
	var downloadTimerJSEnd = new Date().getTime();
	var loadTime = downloadTimerJSStart - downloadTimerStart;
	var scriptTime = downloadTimerJSEnd - downloadTimerJSStart;
	var currentURL = escape(location.href);

	var url = "/Modules/Util/downloadTimer.php?loadTime=" + loadTime
		+ "&scriptTime=" + scriptTime + "&currentURL=" + currentURL;
	xSendXMLHttpRequest("GET", url, function(){}); // ignore response
}


//Cookie Functions
function $C(name) {
  return Try.these(function() {
      return document.cookie.split(';').find(function(c) {
          return (c.split('=')[0].indexOf(name) >= 0);
      }).split('=')[1];
  }, function() {
      return null;
  });
}



// Formats a number based on a format string, which is a pipe-delimited list:
// Item 1: prefix string, e.g. $
// Item 2: number of decimal places, e.g. 3
// Item 3: decimal separator, e.g. .
// Item 4: group separator, e.g. ,
// Item 5: group length, e.g. 3
// Item 6: suffix string, e.g. %
// Item 7: value to display if zero or empty; e.g. N/A
function formatNumber(value, formatStr) {
    if (typeof formatStr != "string") return "ERROR";
    if (typeof value == 'undefined' || value==null) return "ERROR";
    var formatItems = formatStr.split("|");
    if (formatItems.length != 7) return "ERROR";
    var result = "";

    if (typeof value == "string") {
        if (value == "") return formatItems[6];
        if (isNaN(parseFloat(value))) return value;
        value = parseFloat(value);
    }

    var numDecimals = parseInt(formatItems[1]);
    value = value.toFixed(numDecimals);
    if (value == 0) return formatItems[6];

    var valueParts = value.split(".");
    if (valueParts[0].charAt(0) == "-") {
        result += "-";
        valueParts[0] = valueParts[0].substr(1);
    }
    result += formatItems[0];

    var intLength = valueParts[0].length;
    var groupLength = parseInt(formatItems[4]);
    var remainder = intLength % groupLength;
    result += valueParts[0].substr(0, remainder);
    for (var i = remainder; i < intLength; i = i + groupLength) {
        if (i > 0) result += formatItems[3];
        result += valueParts[0].substr(i, groupLength);
    }
    if (valueParts.length == 2)
        result += formatItems[2] + valueParts[1];

    result += formatItems[5];
    return result;
}

function doSubstitutions(originalString, substitutions) {
    if (substitutions.length == 0) return originalString;
    for (var token in substitutions) {
        var replacement = substitutions[token];
        originalString = originalString.replace(new RegExp("\\*" + token + "\\*", "g"), replacement);
    }
    return originalString;
}

function applyPosNegStyle(value, styleName) {
    var subs = new Object;
    subs["VALUE"] = value;
    if (value.match(/^[-]+/)) {
        // negative
        return doSubstitutions(HTML["negative"][styleName], subs);
    }
    if (value != "N/A" && value != "" && parseFloat(value) != 0) {
        // positive
        return doSubstitutions(HTML["positive"][styleName], subs);
    }

    // zero or unformatted
    return doSubstitutions(HTML["zero"][styleName], subs);
}

var currentHostname = "https://www.tradeking.com";
var isDragDropPage = false;//this should be overridden later by a script in the page itself, if it is a drag-drip page, which affects the position ing of tooltips
var stdEffectDuration = 0.5;

function BrowserDetectLite() {
    var ua = navigator.userAgent.toLowerCase(); 
    var versionMinor = parseFloat(navigator.appVersion);
    if (this.isNS && this.isGecko) {
        this.versionMinor = parseFloat( ua.substring( ua.lastIndexOf('/') + 1 ) );
	}
	// correct version number for IE4+ 
	else if (this.isIE && this.versionMinor >= 4) {
	        this.versionMinor = parseFloat( ua.substring( ua.indexOf('msie ') + 5 ) );
	}
	var versionMajor = parseInt(this.versionMinor,10); 

	return {
	    isIE:   Prototype.Browser.IE,
	    isOpera:  Prototype.Browser.Opera,
	    isWebKit: Prototype.Browser.WebKit,
	    isGecko:  Prototype.Browser.Gecko, 
	    isMobileSafari: Prototype.Browser.MobileSafari,
	    isMozilla: (this.isGecko && ua.indexOf("gecko/") + 14 == ua.length),
	    isNS:  ((this.isGecko) ? (ua.indexOf('netscape') != -1) : ((ua.indexOf('mozilla') != -1) && (ua.indexOf('spoofer') == -1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera') == -1) && (ua.indexOf('webtv') == -1) && (ua.indexOf('hotjava') == -1))),
		geckoVersion: ((this.isGecko) ? ua.substring( (ua.lastIndexOf('gecko/') + 6), (ua.lastIndexOf('gecko/') + 14) ) : -1 ),
        isNS6: (this.isNS && versionMajor == 6),
        isIE6: (this.isIE && versionMajor == 6),
        isIE7: (this.isIE && versionMajor == 7),   
        isIE8: (this.isIE && versionMajor == 8),            
        isIEv6: (navigator.appVersion.indexOf("MSIE 6.")==-1) ? false : true,
        isIEv7: (navigator.appVersion.indexOf("MSIE 7.")==-1) ? false : true,
        isIEv8: (navigator.appVersion.indexOf("MSIE 8.")==-1) ? false : true
	};
}
var brsr = new BrowserDetectLite();
/* String utility functions, added directly to the String object */

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g,"");
};
String.prototype.ltrim = function() {
    return this.replace(/^\s+/,"");
};
String.prototype.rtrim = function() {
    return this.replace(/\s+$/,"");
};

String.prototype.squeeze = function(pattern) {
    if (pattern == '') {
        return this;
    }
    if (pattern === undefined) {
        pattern = /(.)\1+/g;
    }
    else {
        pattern = new RegExp('([' + pattern.replace(/(\\|\^)/g, '\\$1') + '])\\1+', 'g');
    }
    return this.replace(pattern, '$1');
};

/* attach event handlers to html elements */
function loadHandler() {
        downloadTimerJSStart = new Date().getTime();
        if (typeof(tkGlobals.inlineEvents)!='undefined')
        var eventList = tkGlobals.inlineEvents;
        var l = eventList.length
        for(var i=0;i<l;i++) {
        	eventList[i].f.apply(eventList[i].scope||window,eventList[i].args||[]);
        }
        initCommon(); // initcommon will prevent multiple calls now.
    	// Structure of  inlineEvents:  
    	//	{ f     : function to call, 
    	//	  scope : object scopt to run the function (becomes the "this" object within the function.), 
    	//	  args  : arguments to send to function.
    	//	}

        if (typeof autoLoadAccount != "undefined" && autoLoadAccount
                        && $("currentAccount")) {
                $("currentAccount").observe("change",
                        function(){this.form.submit();});
        }

        $$(".showTooltip").invoke('observe','mouseover',showTip);
        $$(".showTooltip").invoke('observe','mouseout',hideTip);
        installTooltipChrome();
        
        initPowerMenus();

        // Load page-specific events
        if (typeof initEvents != "undefined"){
            initEvents();
        }

        shouldReportDownloadTimes && reportDownloadTimes();
		
}

function initPowerMenus(){
    $$(".powerMenuTrigger").invoke('observe','mouseover',powerMenuRollover);
    $$(".powerMenuTrigger").invoke('observe','mouseout',powerMenuRollout);
    $$(".powerMenu").invoke('observe','mouseover',powerMenuRollover);
    $$(".powerMenu").invoke('observe','mouseout',powerMenuRollout);
	
	$$(".pmQuote").invoke('observe', 'click', powerMenuQuote);	
	$$(".pmTradeAgain").invoke('observe','click', powerMenuTradeAgain)
}

//these dummy functions are here to get called on all pages which are not the Summary page
//on that page, we have to disable dragdrop and un-position the elements on the page in order
//for the tooltips to sit properly above everything else. In the summay page JS file is the full definition
//of these functions, which overrides these.
function deactivateDragDrop(){
        //no op
        return null;
}
function activateDragDrop(){
        //no op
        return null;
}


var iFrameMoved = false; //global to indicate whether the IFrame that hides form elements in IE has been moved behind the tooltip - so it only happens once
//var draggingInProgress = false;

var tooltipItemCounter = 0;//counter to make tooltip element IDs unique
function installTooltipChrome(){
//    ttEl = $(elWithProperId.id + "Tooltip");
    if (!$('ttEl')) {
    	ttPe=document.createElement('div');
    	ttPe.id="ttEl";
    	ttPe.style.position="absolute";
    	ttPe.style.display="none";
    	ttPe.style.zIndex="9999";
    	ttPe.innerHTML='<div class="tooltipHeader" id="ActiveTooltipTop"></div>'+
	        			'<div class="tooltipContent" id="ActiveTooltipContent"><div id="tipWrapper" class="tipWrapper"> </div></div>'+
	        			'<div class="tooltipFooterLeft" id="ActiveTooltipBottomLeft" style="display:block"></div>'+
	        			'<div class="tooltipFooterRight" id="ActiveTooltipBottomRight" style="display:none"></div>';

        document.body.appendChild(ttPe);
    }
}

var UI={}; // Create a namespace for some UI stuff... tired of using global
function showTip(e){
    // in IE, we  move an iFrame behind the tooltip element so that form elements do not show through
	if (UI.currentTip)
		hideTip(UI.currentTip);
	UI.currentTip=e;
    var el = Event.element(e);
    var elWithProperId = el;//clone element, so that one can be used to find the tooltip element and the other can be used for positioning
    while (!elWithProperId.hasClassName("showTooltip")) {
        //loop up the containing element list to find the element that has the "showTooltip" class
        //that's the element whose ID is combined with "Tooltip" to find the tooltip element.
        elWithProperId = elWithProperId.up();
    }
   	var ttEl = $(elWithProperId.id+"Tooltip");
    var content = ttEl.innerHTML;
    $('tipWrapper').innerHTML=content;
    ttPe = $('ttEl');
    if(ttPe){
        var minDistanceToRightEdge = 120;//used to reposition the tooltip if it will end up going off the right edge of the screen
        //var tooCloseToRightEdge = true;

        var tooCloseToRightEdge = ((Position.cumulativeOffset(el)[0]+ttEl.offsetWidth+minDistanceToRightEdge)> document.body.clientWidth);
        (!tooCloseToRightEdge) ? pmOffset = el.offsetWidth : pmOffset = -ttPe.offsetWidth+1;

        Position.clone(ttEl, ttPe,{setWidth: true, setHeight: false, offsetTop:+0,offsetLeft: pmOffset });

        if (tooCloseToRightEdge ||  isDragDropPage) {
            $('ActiveTooltipBottomLeft').show();
            $('ActiveTooltipBottomRight').hide();
        }else {
            $('ActiveTooltipBottomLeft').hide();
            $('ActiveTooltipBottomRight').show();
        }
        //the tooltips are positioned differently on pages where they appear within elements that are drag and droppable
        ttPe.style.display="block";
        if(!tooCloseToRightEdge && !isDragDropPage){//the usual execution path  
            ttPe.clonePosition(el,{setWidth: false, setHeight: false, offsetTop: -ttPe.offsetHeight+3,offsetLeft: el.offsetWidth-5});
        }else{
            ttPe.clonePosition(el,{setWidth: false, setHeight: false, offsetTop: -ttPe.offsetHeight+3,offsetLeft: -ttPe.offsetWidth});
        }
        ttPe.style.display="block";
    }
}

function hideTip(e){
		UI.currentTip=undefined;
        var el = Event.element(e);
        while (!el.hasClassName("showTooltip")) {
            el = el.up();
        }
        tooltipElementName = el.id+"Tooltip";
		if ($('MenuDisplayFixer')) {
			$('MenuDisplayFixer').style.display = "none";
			//$('MenuDisplayFixer').hide();
			iFrameMoved = false;
		}
		$('ttEl').style.display="none";
/*
        if($(tooltipElementName)){
            $(tooltipElementName).style.left="-10000px";
        }
*/ 
 }

function keepTipVisible(e){
        var el = Event.element(e);
        //??not done here
}

function initCommon() {
	if (!window['_tkicommon']) {
	window['_tkicommon']=1;
    // deprecated
    addPopupLinks( {"nav_watchList":{height:300}} );
        
    /* If a link with the class extLink is clicked then open leaving light box */
    if (typeof(Lightbox) != "undefined") {
        Lightbox.init();
    }
    $$('.extLink').invoke('observe','click',activateOffsiteLightbox);
    deleteOldSnappyCookie();//only needed until 03/2010
	}
}
// activate off site link lightbox lightbox
function activateOffsiteLightbox(e){
    
    var oldLightBox;
    var lightBox;
    var url;
    var el;
    
    // remove old lightBox elements
    if ($('lightBox')) {
        $('lightBox').remove();
    }
    
    // get the element used to cause the event (link, button, etc) usually a link.
    el = e.element();
    
    //handle clicking on the image, rather than the href
    if (el.tagName != 'A') {
        url = el.parentNode.href;
    } else {
        url = el.href;
    }

    lightBox = document.createElement('div');
    lightBox.setAttribute('id', 'lightBox');
    lightBox.innerHTML = '<div class="pageContent"><h2>You are leaving TradeKing</h2><p>The Company whose website you are choosing to enter is not associated with TradeKing.  TradeKing does not endorse or warrant the content, product or service, commentary or opinions expressed on their website.  TradeKing does not validate the Company\'s business practices or privacy policy, and we recommend that you review the Company\'s privacy and security statements thoroughly.  TradeKing provides access to the Company\'s website for educational and information purposes only.</p><div class="link">Continue to <a href="' + url + '" target="_new"  onclick="Lightbox.hideBox()">' + url + '</a></div></div>';

    document.body.appendChild(lightBox);
    
    Lightbox.showBoxByID("lightBox", 425, 265);
    Event.stop(e);
}


function capsDetect( e ) {
  var theKey = 0;
  if( e.keyCode ) { theKey = e.keyCode; } //Internet Explorer, etc.
  else if( e.charCode ) { theKey = e.charCode;} //Gecko - probably not needed
  //was the shift key was pressed
  var theShift = false;
  if( e.shiftKey ) { theShift = e.shiftKey; } //Internet Explorer, etc.
  else if( e.modifiers ) { //Netscape 4
    //check the third bit of the modifiers value (says if SHIFT is pressed)
    if( e.modifiers & 4 ) { //bitwise AND
      theShift = true;
    }
  }
  //if upper case, check if shift is not pressed
  if( theKey > 64 && theKey < 91 && !theShift ) {
        $("password").addClassName("passwordCapsLock");
                $("passwordWarning").update("Caps Lock is On");
  }
  //if lower case, check if shift is pressed
  else if( theKey > 96 && theKey < 123 && theShift ) {
        $("password").addClassName("passwordCapsLock");
                $("passwordWarning").update("Caps Lock is On");
  }else{
        $("password").addClassName("passwordNonCapsLock");
                $("passwordWarning").update("");
  }
          
}



//Power Menu, new code
var pmTimer;

function powerMenuRollover(e) {
	clearTimeout(pmTimer);
    var el = Event.element(e);

	if(!$('pmEl')) {
		var pmEl = document.createElement('ul');
		pmEl.setAttribute('id', 'pmEl');
		pmEl.style.zIndex = '500';
		if (pmEl.addEventListener) {
	        pmEl.addEventListener("mouseout", powerMenuRollout, false); //Mozilla
	        pmEl.addEventListener("mouseover", function(){ clearTimeout(pmTimer)},false);
	    } else {
	        pmEl.attachEvent("onmouseout", powerMenuRollout); //IE
	        pmEl.attachEvent("onmouseover", function(){ clearTimeout(pmTimer)});
	    }
		document.body.appendChild(pmEl);
	}

	$('pmEl').innerHTML = $(el.id+"Menu").innerHTML;
	$('pmEl').addClassName('powerMenu');
 
    var minDistanceToRightEdge = 120;//used to reposition the tooltip if it will end up going off the right edge of the screen
    var tooCloseToRightEdge = ((Position.cumulativeOffset(el)[0]+el.offsetWidth+minDistanceToRightEdge)> document.body.clientWidth);

    (!tooCloseToRightEdge) ? pmOffset = el.offsetWidth : pmOffset = -$('pmEl').offsetWidth+1;
    Position.clone(el, $('pmEl'),{setWidth: false, setHeight: false, offsetTop:+0,offsetLeft: pmOffset });
	
	$('pmEl').style.display = 'block';
		
	// reloading event listeners
	$$(".pmQuote").invoke('observe', 'click', powerMenuQuote);	
	$$(".pmTradeAgain").invoke('observe','click', powerMenuTradeAgain);
	$$(".multilegQuote").invoke('observe', 'click', showQuote, false);
	
	if(typeof attachPMPositionsListeners == 'function') attachPMPositionsListeners();
}           

function powerMenuRollout() {
	clearTimeout(pmTimer);
	pmTimer = setTimeout("hideRollover()", 150);
}

function hideRollover() {  
	if($('pmEl') && $('pmEl').style.display == 'block') $('pmEl').style.display = 'none';
}



function powerMenuQuote(e) {
	var el = Event.element(e);
	var pmSymbol = el.id.split("_")
	pmSymbol = pmSymbol[1];
	dojo.publish('retrieveQuote',[pmSymbol,rtTradeQuotes])
	return false;
}

function powerMenuTradeAgain(e){
	var el = Event.element(e);
	var pmSymbol = el.id.split("_")
	pmSymbol = pmSymbol[1];
	window.location = '/Modules/Trading/Trade/Standard/Stock/enter.php?symbol=' + pmSymbol;
	return false; 
}

var today = new Date();
var zero_date = new Date(0,0,0);
today.setTime(today.getTime() - zero_date.getTime());
var cookieExpireDateNever= new Date(today.getTime() + (8 * 7 * 86400000));



function deleteOldSnappyCookie(e){
//only needed until 03/2010, just to clean up all the old cookies everyone has
        xDeleteCookie("snapQuoteIsOpen","/");
        xDeleteCookie("sqSymbol", "/");
        xDeleteCookie("sqUsSymbol", "/");
        xDeleteCookie("sqDesc", "/");
        xDeleteCookie("sqChange", "/");
        xDeleteCookie("sqPctChange", "/");
        xDeleteCookie("sqLast", "/");
        xDeleteCookie("sqBid", "/");
        xDeleteCookie("sqBidSize", "/");
        xDeleteCookie("sqAsk", "/");
        xDeleteCookie("sqAskSize", "/");
        xDeleteCookie("sqVol", "/");
        xDeleteCookie("sqTimestamp", "/");
}

function enterDetect(e){
                if(e.keyCode == Event.KEY_RETURN){
                        makePopQuoteRequest(false);
                }else{
                        return false;
                }
}

var monthConverter = [];
monthConverter[1] = "Jan";
monthConverter[2] = "Feb";
monthConverter[3] = "Mar";
monthConverter[4] = "Apr";
monthConverter[5] = "May";
monthConverter[6] = "Jun";
monthConverter[7] = "Jul";
monthConverter[8] = "Aug";
monthConverter[9] = "Sep";
monthConverter[10] = "Oct";
monthConverter[11] = "Nov";
monthConverter[12] = "Dec";
        
function getThreeLetterMonth(month){
        var intMonth = parseInt(month, 10);
        return monthConverter[intMonth];
}
        
function formatSecurityDescription(desc, extractionType, underlyingSymbol){
        //extractionType is not currently used
        underlyingSymbol = underlyingSymbol || "";
        var format = /(.+)(\d{2}?)\/(\d{2})\/(\d{2})(\d{2})\s(\d{1,8})(\.\d{1})?(\d{3})?\s(.+)/;
        if(desc.match(format)){//used on order entry Ack pages
                var shortDescExtractor = "$1";
                var putCallExtractor = "$9";
                var centsExtractor = "$7";
                var monthExtractor = "$2";
                var yearExtractor = "$5";
                var dollarExtractor = "$6";
                var centsValue = desc.replace(format, centsExtractor);
                var replacedString =  underlyingSymbol+" "+getThreeLetterMonth(desc.replace(format, monthExtractor));
                replacedString += desc.replace(format, yearExtractor)+" $"+desc.replace(format, dollarExtractor);
                if(centsValue!=".0"){
                        replacedString += centsValue;
                }
                return replacedString+' '+desc.replace(format, putCallExtractor).toUpperCase(); 
        }

        format = /(.+)\s(.+)\s(.+)\s(\d{1,8})\s(1\/2)/;
        if(desc.match(format)){//for option orders on order status
                var monthExtractor = "$3";
                var symbolExtractor = "$2";
                var priceExtractor = "&#36;$4";
                var centsExtractor = "$5";
                var centsValue = desc.replace(format, centsExtractor);
                var putCallExtractor= " $1";
                var replacedString = desc.replace(format, symbolExtractor)+" "+desc.replace(format, monthExtractor).capitalize()+" "+desc.replace(format, priceExtractor);
                if(centsValue!=""){
                        replacedString+= ".5 "
                }
                replacedString+=desc.replace(format,putCallExtractor) ;
                return replacedString;
        }
        format = /(.+)\s(.+)\s(\d{2})(\d{2})\s(\d{1,8})(\.\d{1,2})?\s(.+)/;
        if(desc.match(format)){//for option orders on order status       AAPL Apr 2007 42.5 Call
                var monthExtractor = "$2";
                var companyExtractor = "$1";
                var yearExtractor = "$4";
                var priceExtractor = "&#36;$5";
                var centsExtractor = "$6";
                var centsValue = desc.replace(format, centsExtractor);
                var putCallExtractor= " $7";
                var replacedString = desc.replace(format, companyExtractor)+" "+desc.replace(format, monthExtractor).capitalize();
                replacedString += desc.replace(format, yearExtractor)+" "+desc.replace(format, priceExtractor);
                if(centsValue!=""){
                        replacedString+= ".5 "
                }
                replacedString+=desc.replace(format,putCallExtractor) ;
                return replacedString;
        }

        
        format = /(.+)\s(.+)\s(.+)\s(\d{1,8})(\.\d{1,1})?(\s1\/2)?/;//CALL QAA APR 80
        if(desc.match(format)){//for option orders on order status      
                var monthExtractor = "$3";
                var symbolExtractor = "$2";
                var priceExtractor = "&#36;$4";
                var centsExtractor = "$5";
                var centsValue = desc.replace(format, centsExtractor);
                var putCallExtractor= " $1";
                var replacedString = desc.replace(format, symbolExtractor)+" "+desc.replace(format, monthExtractor).capitalize()+" "+desc.replace(format, priceExtractor);
                if(centsValue!=""){
                        replacedString+= ".5 "
                }
                replacedString+=desc.replace(format,putCallExtractor) ;
                return replacedString;
        }else{
                //console.info("default - no match");
                return desc;    
        }
}


/*---------------------------AJAX QUOTE HANDLING, USED BY SNAPQUOTE AND TRADING PAGES--------------------*/

//convert symbol into proper format, pass in the element to be cleaned up, value will be replaced
function changeSymbol(el) {
        //remove error indicator, if present
        el.style.color="#000";
        // trim surrounding spaces, change to uppercase, and add space for option symbols
        if(el.value){
                var newValue = el.value;
                newValue = newValue.replace(/^\s*(.*?)\s*$/, "$1");//remove leading and trailing spaces
                newValue = newValue.replace("."," ");//convert a period to a space
                newValue = newValue.toUpperCase();
                if (el.hasClassName("optionSymbol")) {
                        if (newValue.length > 2 && newValue.charAt(newValue.length - 3) != " ") {
                                newValue = newValue.substr(0, newValue.length - 2)
                                        + " " + newValue.substr(newValue.length - 2);
                        }
                }
                el.value = newValue;
        }
}
var isHoliday=false;

var isHalfDay=false;

var isWeekend=false;



myTime = (new Date()).getTime(); //used for calculating delta.
eventSchedule={"tzoffset":0,"order":["preOpen","mktOpen","mktClose","postClose","closed"],"events":{"preOpen":{"eventType":"preOpen","startTime":28800,"text":"U.S. Extra-Hours Trading Begins in "},"preClose":{"eventType":"preClose","startTime":34200,"text":"Pre-Market Trading. U.S. Markets Open In "},"mktOpen":{"eventType":"mktOpen","startTime":34200,"text":"Pre-Market Trading. U.S. Markets Open In "},"mktClose":{"eventType":"mktClose","startTime":57600,"text":"U.S. Markets close in "},"postOpen":{"eventType":"mktClose","startTime":57600,"text":"U.S. Markets close in "},"postClose":{"eventType":"postClose","startTime":61200,"text":"U.S. Extra-Hours Trading Ends in "},"closed":{"eventType":"closed","startTime":86399,"text":"U.S. Markets closed."}}};
//Get difference between now and midnight.
//-eventSchedule.tzoffset;

function inExtraHours(){
    var delta = Math.floor(((new Date()).getTime() - myTime)/1000);
    var time = tkGlobals.gmtTime + delta;

	var preOpen 	= eventSchedule['events']['preOpen']['startTime'] + tkGlobals.startOfDay;
	var preClose	= eventSchedule['events']['preClose']['startTime'] + tkGlobals.startOfDay;
	var postOpen	= eventSchedule['events']['postOpen']['startTime'] + tkGlobals.startOfDay;
	var postClose	= eventSchedule['events']['postClose']['startTime'] + tkGlobals.startOfDay;

    if ((preOpen <= time && time <= preClose) || (postOpen <= time && time <= postClose)) {
		return true;
	} else {
		return false;
	}
	
}

function getLegName(el){
        return el.id.substring(el.id.length-1);
}

function hmr_popup(pct){
	var rand_num = Math.ceil(Math.random()*1000);
	
	var html = " <a href='#' target='_new' style='position: relative; display: inline' onclick='$(%Qrand_hmr%Q).style.display=%Qnone%Q; return false' onmouseover='$(%Qrand_hmr%Q).style.display=%Qblock%Q'>	<img src='https://www.tradeking.com/Images/Icons/hmr.gif' alt='' border='0' /><div id='rand_hmr' class='hmr_bubble' style='display: none' onmouseout='$(%Qrand_hmr%Q).style.display=%Qnone%Q'>pct% </div></a>"; //doing this so everythig can be done in one place.  This is the only js file that can process php
	html = html.replace(/rand/g, rand_num); // replacing the 'pct' we put into the php static method with the actual percentage that was passed to the js function
	html = html.replace(/pct/, pct); // replacing the 'pct' we put into the php static method with the actual percentage that was passed to the js function
	html = html.replace(/%Q/g, '\"');
	return html;
}


var QuoteUpdater = Class.create();

/** 
* Class for rendering quotes on the page
* @return {Object}      none
*/
QuoteUpdater.prototype = {
        initialize: function(quoteContainer){
                this.quoteContainer = quoteContainer;
                this.fieldList = $$([".stockSymbol",".optionSymbol",".fundsymbol"]);//list of all symbol input fields
                //this.matchQuotes().bind(this);
                this.renderQuote().bind(this);
        },
        matchQuotes: function(){  //matches quotes coming back from server with the fields where the symbols are
                this.quoteContainer.legs.each(function(leg){
                        this.fieldLIst.each(function(el, ndx){
                                console.log(el.id +" is "+el.value+ "and value="+leg.value);
                                if(el.value==q.symbol){//TODO might need to check isFormEleement here, not sure
                                                leg.legName = getLegName(el);//grab the number off of the end of the id
                                }
                        }.bind(this));
                }.bind(this));
        },
        
        renderQuote: function (){
                var holdingsText = "";
                tabs.setActiveTab("ulQuotePanel");
                if(!this.quoteContainer.error){
                        this.quoteContainer.legs.each(function(pair){
                                        var legName = pair.key;
                                        var q = pair.value;
                                        switch(legName){
                                                case "underlying0": //note, no handling for multiiple underlyings - there is no UI for that
                                                        this.updateUnderlyingLeg(q);
                                                        break;
                                                case "net":
                                                        this.updateNetLeg(q);
                                                        break;  
                                                default: 
                                                        this.updateLeg(q);
                                                }//end switch
                                }.bind(this));
                }else{//if error
                        if ($("ulError")){
                                $("ulError").update("Error: "+quoteContainer.error);
                        }
                        if($("ulQuote").style.display==="none"){
                                Effect.Appear($("ulQuote"),{duration: stdEffectDuration});
                        }else{
                                new Effect.Highlight($("ulQuote"));
                        }
                }
        },
        
        updateUnderlyingLeg: function(q){
                        if ($("ulError")){
                                $("ulError").update(q.error?"Error: "+q.error:"");
                        }
                        //even if there is an error, draw the blank fields so that they clear out
                        if ($("ulSymbol")){
                                $("ulSymbol").update(q.symbol);
                        }
                        if ($("ulDescription")){
                                $("ulDescription").update(q.desc);
                        }
                        if ($("ulLast")){
                                $("ulLast").update(q.last);
                        }
                        if ($("ulChange")){
                                $("ulChange").update(applyPosNegStyle(q.change, "arrow"));
                        }
                        if ($("ulBid")){
                                $("ulBid").update(q.bid);
                        }
                        if ($("ulAsk")){
                                $("ulAsk").update(q.ask);
                        }
                        if ($("ulVolume")){
                                $("ulVolume").update(q.vol);
                        }
                        if ($("ulDelta")){
                                $("ulDelta").update(q.delta);
                        }
                        if ($("ulOpenInterest")){
                                $("ulOpenInterest").update(q.openInterest);     
                        }
                        //display
                        //if(q.ulSymbol!==""){
                                //tabs.setActiveTab("ulQuotePanel");
                                setTimeout(new Effect.Highlight($("ulQuotePanel")),500);//TODO not sure the timeout is necessary
                        //}
        },

        updateNetLeg: function(q){
                        if ($("netBid") && $("netBidField")){
                                $("netBid").update(q.bid);
                                $("netBidField").value = q.bid;
                        }
                        if ($("netAsk") && $("netAskField")){
                                $("netAsk").update(q.ask);
                                $("netAskField").value = q.ask;
                        }
                
                        //if(q.bid !==""){
                                tabs.setActiveTab("ulQuotePanel");
                                if($("netQuote").style.display==="none"){
                                        Effect.Appear($("netQuote"),{duration:stdEffectDuration });
                                }else{
                                        new Effect.Highlight($("netQuote"));
                                }
                        //}
        },

        updateLeg: function(q){
                        //correct leg names by matching the symbols to leg names
                        //in case symbols come in out of order
                        $$([".stockSymbol",".optionSymbol",".fundsymbol"]).each(function(el, ndx){
                                        console.log(el.id +" is "+el.value+ "and value="+q.value);
                                        if(el.value==q.symbol){//TODO might need to check isFormEleement here, not sure
                                                if(el.id!=="symbol"){//don't do this if there is only one symbol
                                                        legName = getLegName(el);//grab the number off of the end of the id
                                                //      console.log("leg:" +legName);
                                                }
                                        }
                        }.bind(this));
                        //these next four lines are arranged thusly so that error text erases itself when there is no longer an error
                        //but we need to separately highlight the symbol generating the error
                        if ($("error" + legName)){
                                $("error" + legName).update(q.legError?"Error: " +q.legError:"");
                        }
                        if(q.legError!==null){
                                $("symbol"+legName).style.color="red";
                        }               
                        if ($("description" + legName)){
                                $("description" + legName).update(q.desc?q.desc:"");
                        }
                        if ($("last" + legName)){
                                $("last" + legName).update(q.last?q.last:"");
                        }
                        if ($("change" + legName)){
                                $("change" + legName).update(q.change?applyPosNegStyle(q.change, "arrow"):"");
                        }
                        if ($("pctChange" + legName)){
                                $("pctChange" + legName).update(q.pctChange?applyPosNegStyle(q.pctChange, "brackets"):"");
                        }
                        if ($("bid" + legName)){
                                $("bid" + legName).update(q.bid?q.bid:"");
                        }
                        if ($("ask" + legName)){
                                $("ask" + legName).update(q.ask?q.ask:"");
                        }
                        if ($("volume" + legName)){
                                $("volume" + legName).update(q.vol?q.vol:"");
                        }
                        if ($("delta" + legName)){
                                $("delta" + legName).update(q.delta?q.delta:"");
                        }
                        if ($("openInterest" + legName)){
                                $("openInterest" + legName).update(q.openInterest);
                        }
                        if ($("holdings"+legName)){
                                if(q.holdings !== "" && q.holdings>0) {
                                        holdingsText += "You currently hold " + q.holdings;
                                        if (q.symbolType === "Option"){
                                                holdingsText += " contracts of ";
                                        }else{
                                                holdingsText += " shares of ";
                                        }
                                        holdingsText += q.symbol + " in this account";
                                }else{
                                        holdingsText = "None";
                                }
                                if ($("holdings" + legName)){
                                        $("holdings" + legName).update(holdingsText);
                                }
                        }//end holdings
                        //display it
                        if($("quoteBar"+legName).style.display==="none"){
                                Effect.Appear($("quoteBar"+legName),{duration: stdEffectDuration});
                                if(!chainManager.activeChains[legName]){
                                        Effect.Appear($("quoteDescription"+legName),{duration: stdEffectDuration});
                                }
                        }else{
                                new Effect.Highlight($("quoteBar"+legName));
                        }
        }
};


function makeTradeQuoteRequest(sameUnderlying,getNet){
        var symbolArr = [];
        var typeArr = [];
        var sideArr = [];
        var amountArr = [];
        sameUnderlying = sameUnderlying || false;

        if ($("type")) {
                var complexOptionType = $F("type");
                var needAmountForNet = (complexOptionType == "spread" || complexOptionType == "combo");
        } else{
                getNet = false;
        }
        
        //process all the symbols/tx/amt data in the form into  arrays
        $$([".stockSymbol",".optionSymbol",".fundSymbol"]).each(function(el, ndx){
                var symbol = (isFormElement(el) ? el.value : el.innerHTML);
                if (!!symbol) {
                        symbolArr.push(symbol);         
                        if(el.hasClassName("stockSymbol")){
                                typeArr.push("Stock");
                        }else if(el.hasClassName("optionSymbol")){
                                typeArr.push("Option");                          
                        }else if(el.hasClassName("fundSymbol")){
                                typeArr.push("Fund"); 
                        }
                }else{
                        getNet = false;
                }
                // If we're getting a net quote, figure out the associated transaction and quantity values for this symbol.
                if (getNet) {
                        var leg = (el.id).substring(6);
                        // deal with quirks in field IDs
                        if (isFormElement(el)) { // order form
                                var transaction = $F("transaction" + leg);
                                var amount = $F("amount" + leg);
                        } else { // edit/cancel form
                                transaction = $F("transaction_" + leg);
                                amount = $F("amount_" + leg);
                        }
                        if (transaction === null){
                                sideArr.push("");
                        }else if (transaction.charAt(0) == "B" || transaction.charAt(0) == "1"){
                                sideArr.push("1");
                        }else {
                                sideArr.push("2");
                        }
                        amountArr.push(amount);
                        // need quantity for spreads and combos
                        if (amount == "" && needAmountForNet){
                                getNet = false;
                        }
                }
        });
        
        //put together the URL
        if (symbolArr.length > 0) {
                var baseURL = "/Modules/Research/Quote/quoteXML.php";
                var params = "?realTime=" + (rtTradeQuotes ? "Y" : "N");
                params += "&sameUnderlying=" + (sameUnderlying ? "Y" : "N");
                if (getNet){
                        params += "&type=" + complexOptionType;
                }
                for (var i = 0; i < symbolArr.length; i++) {
                        params += "&symbol[" + i + "]=" + symbolArr[i].toUpperCase();
                        params += "&securityType[" + i + "]=" + typeArr[i];
                        if (getNet) {
                                params += "&side[" + i + "]=" + sideArr[i];
                                params += "&amount[" + i + "]=" + amountArr[i];
                        }
                }
         new Ajax.Request(baseURL, {
           method:'POST',
           asynchronous:true,
           parameters:params,
           onSuccess:handleTradeQuoteSuccess,
           onFailure:handleQuoteError,
           onError:handleQuoteError
          });
                //requests["quote"] = xSendXMLHttpRequest("GET", baseURL+params, getQuoteData);
        } else {
                //hid eall quote bar, there are no symbols
                if($("quoteBar0") && $("quoteBar0").style.display!=="none" ){
                        Effect.Fade($("quoteBar0"),{duration:stdEffectDuration});
                }
                if($("quoteBar1") && $("quoteBar1").style.display!=="none" ){
                        Effect.Fade($("quoteBar1"),{duration:stdEffectDuration});
                }
                if($("quoteBar2") && $("quoteBar2").style.display!=="none" ){
                        Effect.Fade($("quoteBar2"),{duration:stdEffectDuration});
                }
                if($("quoteBar3") && $("quoteBar3").style.display!=="none" ){
                        Effect.Fade($("quoteBar3"),{duration:stdEffectDuration});
                }
                if($("quoteBarCO") && $("quoteBarCO").style.display!=="none" ){
                        Effect.Fade($("quoteBar3"),{duration:stdEffectDuration});
                }
                if($("quoteBarTS") && $("quoteBarTS").style.display!=="none" ){
                        Effect.Fade($("quoteBar3"),{duration:stdEffectDuration});
                }
                if($("underlyingQuote") && $("underlyingQuote").style.display!=="none" ){
                        Effect.Fade($("underlyingQuote"),{duration:stdEffectDuration});
                }
                if($("netQuote") && $("netQuote").style.display!=="none" ){
                        Effect.Fade($("netQuote"),{duration:stdEffectDuration});
                }
        }
}


function makeMarketsQuoteRequest() {
        var realTime = "";       
        var getNet = false;
        var symbolArr = ["DJI","VIX","COMP","SPX"];
        var baseURL = "/Modules/Research/Quote/quoteXML.php";
        var params = "?realTime=" + (rtTradeQuotes ? "Y" : "N");
        params += "&sameUnderlying=N";
        for (var i = 0; i < symbolArr.length; i++) {
                params += "&symbol[" + i + "]=" + symbolArr[i].toUpperCase();
                params += "&securityType[" + i + "]=Stock";
        }
        
        new Ajax.Request(baseURL, {
           method:'POST',
           asynchronous:true,
           parameters:params,
           onSuccess:handleMarketsQuoteSuccess,
           onFailure:handleQuoteError,
           onError:handleQuoteError
          });
}

function handleMarketsQuoteSuccess(req){
        displayMarketsQuote(getQuoteData(req));
}

function displayMarketsQuote(quoteContainer) {
    if (quoteContainer.error) {
        $("DJIValue").style.color = "red";
        $("DJIValue").update("ERROR");
        $("SPXValue").style.color = "red";
        $("SPXValue").update("ERROR");
        $("VIXValue").style.color = "red";
        $("VIXValue").update("ERROR");
        $("COMPValue").style.color = "red";
        $("COMPValue").update("ERROR");
    }
    else {
        for (var x = 0; x < 4; x++) {//magic number, arrgh
            q = quoteContainer.legs[x];
            if ($(q.symbol + "Value")) {
                $(q.symbol + "Value").update(q.last+' '+applyPosNegStyle(q.change, "brackets"));
            }
        }
    }
}



//error in the whole quote request
function handleQuoteError(req){
        var quoteContainer = new QuoteContainer();
        if(req){
                var result = req.responseXML.documentElement;
                var error = result.getElementsByTagName("error");
                if (error !== null && error[0].firstChild && error[0].firstChild.data !== "") {
                        quoteContainer.error = error[0].firstChild.data;
                }
        }
        $("quotePopSymbol").style.color = "red";
        displayTradeQuote(quoteContainer);
}

function handleMarketsQuoteSuccess(req){
        displayMarketsQuote(getQuoteData(req));
}
function handleTradeQuoteSuccess(req){
        //mightnot want to create a new one each time, buit works for now
        var qr = new QuoteUpdater(getQuoteData(req));
}
function handlePopQuoteSuccess(req){
        displayPopQuote(getQuoteData(req));
}
function getXMLValue(key,src){
        //get the value of an XML element, returning an empty string if it is not present
        try{
                return xGetElementText(key, src, 0);
        }catch(err){
                console.error(err);
                return "";
        }
}


//returns QuoteData object
function getQuoteData(req){
        //var req = requests["quote"];
        var quoteContainer = new QuoteContainer();
        var result = req.responseXML.documentElement;

        //usually, you get an actual error message in the <error> element
        var error = result.getElementsByTagName("error");
        if (error !== null && error[0].firstChild && error[0].firstChild.data !== "") {
                quoteContainer.error = error[0].firstChild.data;
                return quoteContainer;
        }
        //for some reason, the server sometimes sends back just a result with an empty <error> element
        //and nothing else
        var quotes = result.getElementsByTagName("quote");
        if(quotes.length == 0){
                quoteContainer.error = "ERROR";
                return quoteContainer;
        }
        var complexOptionType;
        
        // Put underlying stock quotes into quote obj -- note that in the XML it's "usQuote" not "ulQuote"
        var ulQuotes = result.getElementsByTagName("usQuote");
        for (var i = 0; i < ulQuotes.length; i++) {
                var q = new Quote();
                q.symbol = getXMLValue("symbol", ulQuotes[i]);
                q.desc = getXMLValue("description", ulQuotes[i]);
                q.hmr = getXMLValue("hmr", ulQuotes[i]);
                q.change = formatNumber(getXMLValue("change", ulQuotes[i]), FORMAT.quoteChange);
                q.last = formatNumber(getXMLValue("last", ulQuotes[i]), FORMAT.quoteLast);
                q.bid = formatNumber(getXMLValue("bid", ulQuotes[i]), FORMAT.quoteBid);
                q.ask = formatNumber(getXMLValue("ask", ulQuotes[i]), FORMAT.quoteAsk);
                q.vol = formatNumber(getXMLValue("volume", ulQuotes[i]), FORMAT.quoteVolume);
                q.timestamp = getXMLValue("time", quotes[i]);
                q.symbolType = "Stock";
                quoteContainer.addQuote(q,"underlying"+i);
        }
        
        // Put requested quotes into quote object
        for (i = 0; i < quotes.length; i++) {
                q = new Quote();
                if (getXMLValue("legError", quotes[i]) === "") {
                        q.numQuotes = i;
                        q.symbol = getXMLValue("symbol", quotes[i]);
                        q.hmr = getXMLValue("hmr", quotes[i]);
                // TICKET: 23603: trading a FRO from snapquote doesn't work
                        q.subclass = getXMLValue("op_subclass", quotes[i]);
                        q.change = formatNumber(getXMLValue("change", quotes[i]), FORMAT.quoteChange);
                        q.pctChange = formatNumber(getXMLValue("pctChange", quotes[i]), FORMAT.quotePctChange);
                        q.last = formatNumber(getXMLValue("last", quotes[i]), FORMAT.quoteLast);
                        q.bid = formatNumber(getXMLValue("bid", quotes[i]), FORMAT.quoteBid);
                        q.bidSize = formatNumber(getXMLValue("bidSize", quotes[i]), FORMAT.quoteVolume);
                        q.ask = formatNumber(getXMLValue("ask", quotes[i]), FORMAT.quoteAsk);
                        q.askSize = formatNumber(getXMLValue("askSize", quotes[i]), FORMAT.quoteVolume);
                        q.vol = formatNumber(getXMLValue("volume", quotes[i]), FORMAT.quoteVolume);
                        q.delta= formatNumber(getXMLValue("delta", quotes[i]), FORMAT.quoteDelta);
                        q.openInterest = formatNumber(getXMLValue("openInterest", quotes[i]), FORMAT.quoteOpenInterest);
                        q.holdings = getXMLValue("holdings", quotes[i]);
                        q.symbolType = getXMLValue("type", quotes[i]);
                        q.holdings = getXMLValue("holdings", quotes[i]);
                        q.timestamp = new Date(parseInt(getXMLValue("time", quotes[i]),10)*1000);//time comes in seconds, we need millis
                        q.afterHoursSessionType = getXMLValue("session", quotes[i]);
                        q.desc= getXMLValue("description", quotes[i]);
                }else{
                        q.legError = getXMLValue("legError", quotes[i]);
                        q.symbol = getXMLValue("symbol", quotes[i]);//need symbol to match errors with original legs
                }
                quoteContainer.addQuote(q,i+"");
        }
        
        //hid euntil we soclve the number ov quotes problem
        //if (quoteData.numQuotes === 0) {
//              if($("underlyingQuote") && $("underlyingQuote").style.display!="none"){
//                      Effect.Fade($("quotePanel"));
//              }
//              if($("netQuote") && $("netQuote").style.display!="none"){
//                      Effect.Fade($("netQuote"));
//              }
//              return;
//      }
        

        // Put net quote data into quote obj
        var net = result.getElementsByTagName("net");
        if (net.length == 1) {
                q = new Quote();
                q.netSymbol = "NET";
                q.bid = formatNumber(getXMLValue("bid", net[0]), FORMAT.quoteBid);
                q.ask = formatNumber(getXMLValue("ask", net[0]), FORMAT.quoteAsk);
                quoteContainer.addQuote(q,"net");
        }
        
        return quoteContainer;
}

var QuoteContainer = Class.create();

/** 
* Class for representing a quote on the site, which may contain multiple legs, each of which 
* is represented by a Quote object
* @return {Object}      none
*/
QuoteContainer.prototype = {
        initialize: function(){
                        this.error="";//general errors with request
                        this.numQuotes = 0;
                        this.legs = new Hash();
        },
        getNumQuotes: function(){
                return this.legs.length;
        },
        addQuote: function(quote, legName){
                this.legs[legName] = quote;
        }
};

var Quote = Class.create();

/** 
* Class representing a security quote, can represent stock, option, net, underlying
* @return {Object}      none
*/
Quote.prototype = {
        initialize: function(){
                        this.legError = null;
                        this.symbol = null;
                        this.desc = null;
                        this.change = null;
                        this.pctChange = null;
                        this.last = null;
                        this.bid = null;
                        this.bidSize = null;
                        this.ask = null;
                        this.askSize = null;
                        this.vol = null;
                        this.delta = null;
                        this.openInterest = null;
                        this.holdings = null;
                        this.symbolType = null;
                        this.holdings = null;
                        this.timestamp = null;
                        this.afterHoursSessionType = null;
        }       
};

var today = new Date();
var zero_date = new Date(0,0,0);
today.setTime(today.getTime() - zero_date.getTime());
var cookieExpireDateNever= new Date(today.getTime() + (8 * 7 * 86400000));

function showQuote(event) {
    try {
        var element=event.element();
        var quoteData=new QuoteData();
        parts=$F(element.id+"_hidden").evalJSON();
        var strategy=parts.strategy;
        
        for(var leg=0; typeof(parts[leg]) != "undefined"; leg++) {
            quoteData.setValue("symbol", parts[leg].symbol);
            quoteData.setValue("amount", parts[leg].amount);
            quoteData.setValue("transaction", parts[leg].transaction);
            quoteData.setValue("strikePrice", parts[leg].strikePrice);
            quoteData.setValue("securityType", parts[leg].securityType);
            quoteData.setLeg();
        }
        
        (new QuoteRequestMgr(quoteData, "popup", strategy)).sendRequest();
    } catch (error) {
    }
}

//Cookie Functions
function $C(name) {
  return Try.these(function() {
      return document.cookie.split(';').find(function(c) {
          return (c.split('=')[0].indexOf(name) >= 0);
      }).split('=')[1];
  }, function() {
      return null;
  })
}

function clearAllCheckBoxes() {
  var inputs = document.getElementsByTagName('input');
  for (var i = 0; i < inputs.length; i++) {
      if (inputs[i].type === 'checkbox') {
          inputs[i].checked = false
      }
  }
}

/*
 * Changes the display value for an entire table column.
 * table_id:The ID of the table you want to effect
 * col_num:	The column number you want to effect - Starts at 0
 * display:	What you want the display property to be changed to.  Most commonly "table-cell" or "none";
 */
function show_hide_column(table_id, col_num, display) {	
	var rows = $(table_id).getElementsByTagName('tr'); // get table rows

	// loop through rows
	for (var row=0; row < rows.length; row++) {
		
		if (rows[row].getElementsByTagName('td')[col_num]) {
			var cel = rows[row].getElementsByTagName('td')[col_num]; // get rows td elements
		} else if (rows[row].getElementsByTagName('th')[col_num]){
			var cel = rows[row].getElementsByTagName('th')[col_num]; // if no td elements check for th elements
		}
		
		cel.style.display = display;
	}
}



// TICKET: 24391 - JS Error logging

jserrornum=0;
jsLogIndex=0;
_errors = {
	    "FATAL" : 1,
	    "ERROR" : 2,
	    "WARN"  : 4,
	    "INFO"  : 8,
	    "DEBUG" : 16
	};

jsLogLevel = 4|2|1;
var errorArray=[];
log=function(){return false};
if (!(brsr.isIE7 || brsr.isIE6)) {
	function log(type,msg) {
	    if (! (_errors[type] & jsLogLevel)) return; // don't log anything if we are masking it.
	    errorArray.push({type:type,index:++jsLogIndex,log:msg});
	}

if (document.domain.indexOf("tradeking.com")>0) {
	function sendLog() {
		jserrornum=errorArray.length;
		var sendArray=$A(errorArray); 
		errorArray=[];
		if (sendArray.size()>0) {
			new Ajax.Request('/log.php', { 
		        parameters: {
		            logs  : sendArray.toJSON()
		        },
		        onComplete: function(transport) {
		            window.status=jserrornum+' JS lines logged.';
		        }
		    });
		}
	}

		onerror=function() {
		  log('ERROR',''+arguments[0]+' in file '+arguments[1]+' on line '+arguments[2]);
		}
		setInterval("sendLog()",5000);
}
	
	Object.extend(Event, (function() {
	  var cache = Event.cache;

	  function getEventID(element) {
	    if (element._prototypeEventID) return element._prototypeEventID[0];
	    arguments.callee.id = arguments.callee.id || 1;
	    return element._prototypeEventID = [++arguments.callee.id];
	  }

	  function getDOMEventName(eventName) {
	    if (eventName && eventName.include(':')) return "dataavailable";
	    return eventName;
	  }

	  function getCacheForID(id) {
	    return cache[id] = cache[id] || { };
	  }

	  function getWrappersForEventName(id, eventName) {
	    var c = getCacheForID(id);
	    return c[eventName] = c[eventName] || [];
	  }

	  function createWrapper(element, eventName, handler) {
	    var id = getEventID(element);
	    var c = getWrappersForEventName(id, eventName);
	    if (c.pluck("handler").include(handler)) return false;

	    var eventTriggers=[];
	    var wrapper = function(event) {
	      if (!Event || !Event.extend ||
	        (event.eventName && event.eventName != eventName))
	          return false;

	      Event.extend(event);
	      try {
	      handler.call(element, event);
		  } catch (e) {
			  if (eventTriggers[e.fileName+e.lineNumber]) return; // stop repeat occurrences.
			  eventTriggers[e.fileName+e.lineNumber]=(new Date()).getTime();
			  // Log event errors.
			  log('ERROR',"Event: "+e+" on line "+e.lineNumber+" in file "+e.fileName+"\n"+e.stack);
		  }
	    };

	    wrapper.handler = handler;
	    c.push(wrapper);
	    return wrapper;
	  }

	  function findWrapper(id, eventName, handler) {
	    var c = getWrappersForEventName(id, eventName);
	    return c.find(function(wrapper) { return wrapper.handler == handler });
	  }

	  function destroyWrapper(id, eventName, handler) {
	    var c = getCacheForID(id);
	    if (!c[eventName]) return false;
	    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
	  }

	  function destroyCache() {
	    for (var id in cache)
	      for (var eventName in cache[id])
	        cache[id][eventName] = null;
	  }

	  if (window.attachEvent) {
	    window.attachEvent("onunload", destroyCache);
	  }

	  return {
	    observe: function(element, eventName, handler) {
	      element = $(element);
	      var name = getDOMEventName(eventName);

	      var wrapper = createWrapper(element, eventName, handler);
	      if (!wrapper) return element;

	      if (element.addEventListener) {
	        element.addEventListener(name, wrapper, false);
	      } else {
	        element.attachEvent("on" + name, wrapper);
	      }

	      return element;
	    },

	    stopObserving: function(element, eventName, handler) {
	      element = $(element);
	      var id = getEventID(element), name = getDOMEventName(eventName);

	      if (!handler && eventName) {
	        getWrappersForEventName(id, eventName).each(function(wrapper) {
	          element.stopObserving(eventName, wrapper.handler);
	        });
	        return element;

	      } else if (!eventName) {
	        Object.keys(getCacheForID(id)).each(function(eventName) {
	          element.stopObserving(eventName);
	        });
	        return element;
	      }

	      var wrapper = findWrapper(id, eventName, handler);
	      if (!wrapper) return element;

	      if (element.removeEventListener) {
	        element.removeEventListener(name, wrapper, false);
	      } else {
	        element.detachEvent("on" + name, wrapper);
	      }

	      destroyWrapper(id, eventName, handler);

	      return element;
	    },

	    fire: function(element, eventName, memo) {
	      element = $(element);
	      if (element == document && document.createEvent && !element.dispatchEvent)
	        element = document.documentElement;

	      var event;
	      if (document.createEvent) {
	        event = document.createEvent("HTMLEvents");
	        event.initEvent("dataavailable", true, true);
	      } else {
	        event = document.createEventObject();
	        event.eventType = "ondataavailable";
	      }

	      event.eventName = eventName;
	      event.memo = memo || { };

	      if (document.createEvent) {
	        element.dispatchEvent(event);
	      } else {
	        element.fireEvent(event.eventType, event);
	      }

	      return Event.extend(event);
	    }
	  };
	})());
}


var currentHostname = "https://www.tradeking.com";
dojo.registerModulePath("tk.qt",currentHostname+"/JS/toolbar");
dojo._hasResource['tk.qt']=true;
dojo.provide('tk.qt');
dojo._hasResource['tk.qt.filter']=true;
dojo.provide('tk.qt.config');
dojo._hasResource['tk.qt.config']=true;
// This was commented out to remove ties to cookies.
if (!tk.qt.config)
		tk.qt.config={};
//dojo.mixin(tk.qt.config,dojo.fromJson(dojo.cookie('tkqtConfig')||'{}'));
tk.qt.realTime=tkGlobals?tkGlobals.realTime:0;
String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g,"");
};
String.prototype.ltrim = function() {
    return this.replace(/^\s+/,"");
};
String.prototype.rtrim = function() {
    return this.replace(/\s+$/,"");
};

dojo.provide("tk.qt.error");
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.error", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
    //templatePath: dojo.moduleUrl("tk.qt","templates/error.html"),
	templateString: errorTemplate,
    constructor: function() {
		dojo.subscribe('showError',this,'showError');
		dojo.subscribe('error',this,'showError');
		dojo.subscribe('failedCall',this,'handleAPICallFailed');
		dojo.subscribe('getTradePreview',this,'hide');
		dojo.subscribe('getQuote',this,'hide');
		dojo.subscribe('triggerOrder',this,'hide');
		dojo.subscribe('hideQT',this,'hide');
	},
	hide: function() {
		if (!this.visible) return;
		dojo.publish('hideErrorTab'); // received by stack handler in popup.js.
		this.errors=[];
		this.buttons=0x01;
		this.visible=false;
		if (this.buttonText==this.txtMap[0xff])
			dojo.publish('hideQT');
	},
	show: function() {
		dojo.publish('showErrorTab');
		this.visible=true;
	},
	reset: function() {
		this.hide();
	},
	handleAPICallFailed: function(d,b) { // Handle that an API call failed, and show the error message.
		if (!tk.qt.config.popup) dojo.publish('showQT');
		this.showError(d,b||0x02);
	},
	showError: function(e,f) {
		if (!e) return;
		var err;
		this.buttons=Math.max(f||0,this.buttons);
		if (typeof(e)=='object') {
			while(err=e.shift())
				if (err&&typeof(err)=='string'&&err!='') this.errors.push(err);
		} else
			if (typeof(e)=='string'&&e!='') this.errors.push(e);
		if (!this.errors.length) return;
		this.buttonText=this.txtMap[this.buttons];
		this.render();
		this.show();
	},
	visible: false,
	errorText: null,
	textContainer: null,
	button: null,
	buttons: 0x01,
	buttonText: 'Continue',
	txtMap: {
		0x01: 'Continue',
		0x02: 'Back',
		0xff: 'Close'
	},
	errors: []
});

dojo.provide('tk.qt.snappy');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.snappy", [ dijit._Widget, dojox.dtl._Templated], {
	templateString: snappyTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/snappy.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: false,

	constructor: function() {
		dojo.subscribe('getQuote',this,'update');
		dojo.subscribe('hideSnappy',this,'hideSnappy');
		dojo.subscribe('showQT',this,'hide');
		dojo.subscribe('hideQT',this,'show');
		dojo.subscribe('failedCall',this,'hide');
	},
	destroy: function() {
		if (this.links)
		while(this.links[++i]) {
			var j=-1;
			if (this.links[i].handle)
			while(this.links[i].handle[++j]) {
				dojo.disconnect(this.links[i].handle[j]);
			}
		}
	},
	startup: function() {
		if (!this.visible) {
			this.hideSnappy(true);
		}
	},
	hideSnappy: function(b) {
		this.visible=!b;
		if (!this.domNode) return;
		if (b) hide(this.domNode);
		else show(this.domNode);
	},
	show: function() {this.hideSnappy(false)},
	hide: function() {this.hideSnappy(true)},
	update: function(data) {
		if (!data || !data.a_quotes) {
			this.dataObj=null;
		} else {
			if (data['a_quoteData'])
				ld=data.a_quoteData; // chains put quote data here.
			else
				ld=data.a_quotes[0];
			if (ld.s_quoteType=='Option') {
				var ulSymbol=ld.a_securityData.s_usSymbol.toLowerCase();
				var months=['Jan','Feb','Mar','Apr','May','June','Jul','Aug','Sept','Oct','Nov','Dec'];
				var ymd=ld.a_securityData.s_expDate.match(/(\d{2})\/(\d{2})\/(\d{4})/);
				this.description=
					ld.a_securityData.s_usSymbol+' '+ // Underlying Symbol
						months[ymd[1]-1]+' '+ymd[2]+' '+ymd[3]+' '+ // Expiration date translated
						formatNumber(ld.a_securityData.n_strikePrice,"|2|.|,|3||N/A")+' '+ // Strike price formatted.
						((ld.s_description.toLowerCase().match('(call|put)\s*')[1])=='call'?'Call':'Put'); // Call or Put.
			} else {
				this.description=ld.s_description;
			}
			this.dataObj=ld;
			if (this.dataObj.s_quoteType!='Stock')
				this.dataObj.a_securityData.s_midPrice=(parseFloat(this.dataObj.a_securityData.s_askPrice)+parseFloat(this.dataObj.a_securityData.s_bidPrice))/2;
		}
		this.render();
	},
	hideLinks: function(e) {
		clearTimeout(pmTimer);
		pmTimer = setTimeout("hide(dojo.byId('qtPm'))", 150);
	},
	showLinks: function(e) {
		var element=e.target||e;
		var i=-1;
		if (this.links) {
			// Disconnect any existing links.
			while(this.links[++i]) {
				if (!this.links[i]['handle']) continue;
				var j=0;
				while(this.links[i].handle[j]) {
					dojo.disconnect(this.links[i].handle[j++]);
				}
			}
		}
		this.links=LinkManager.getLinks(this.dataObj.s_quoteType,this.dataObj.s_symbol,this.dataObj.a_securityData['s_usSymbol']);
		if (this.root||dojo.byId('qtPm')) {
			dojo.destroy(this.root||dojo.byId('qtPm'));
		}
		this.root=dojo.create('ul',{id:'qtPm'});
		dojo.addClass(this.root,'powerMenu');
		
		for(i=0;i<this.links.length;i++) { // create and connect event handlers.
			var li=dojo.create('li',{link:this.links[i].link,innerHTML:'<a title="'+(this.links[i].description?this.links[i].description:this.links[i].text)+'" href="'+this.links[i].link+'">'+this.links[i].text+"</a>"},this.root,'last');
			this.links[i].handle=[];
			li.link=this.links[i].link;
			if (this.links[i].publish) {
				this.links[i].handle.push(dojo.connectPublisher(this.links[i].publish,li,'onclick'));
			}
			if (this.links[i].click) {
				this.links[i].handle.push(dojo.connect(li,'onclick',this.links[i],'onclick'));
			}
			if (this.links[i].hover) {
				this.links[i].handle.push(dojo.connect(li,'onmouseover',this.links[i],'hover'));
			}
			if (this.links[i].out) {
				this.links[i].handle.push(dojo.connect(li,'onmouseout',this.links[i],'out'));
			}
			this.links[i].handle.push(dojo.connect(li,'onclick',function(e){
				pmTimer = setTimeout("hide(dojo.byId('qtPm'))", 150);
				//document.location=this.link;
			})); // after all other events, run this one.
		}
		this.links[0].handle.push(dojo.connect(this.root,'onmouseout',function(e){
			if (pmTimer) clearTimeout(pmTimer);
			pmTimer = setTimeout("hide(dojo.byId('qtPm'))", 150);
		}));
		this.links[0].handle.push(dojo.connect(this.root,'onmouseover',function(e){
			if (pmTimer) clearTimeout(pmTimer);
		}));

		dojo.place(this.root,element.parentNode,'last');
		var box=dojo.coords('qtPmAct');
		dojo.style(this.root,{
			display:'block',
			bottom:box.t+(box.h/2)+'px',
			left: box.x+(box.w/2)+'px'
		});
	},
	dataObj : null,
	links:null,
	rtq: tk.qt.realTime,
	visible: true,
	description: '',
	currentHostname: currentHostname,
	errorObj: null
});


dojo.provide('tk.qt.orderPreview');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.orderPreview", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: orderPreviewTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/orderPreview.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
		dojo.subscribe('doTradeAction',this,'handleDoTradeAction');
		dojo.subscribe('showTradePreview',this,'showPreview');
		dojo.subscribe('canPreviewOrder',this,'saveOrder');
		//dojo.subscribe('getTradePreview',this,'getTradePreview')
		dojo.subscribe('updateTradeData',this,'tradeDataChanged');
		this.getConfigSub=dojo.subscribe('getConfig',this,'handleConfigChange');
		dojo.subscribe('triggerOrder',this,'orderTriggered');
		dojo.subscribe('reset',this,'resetOrder');
		dojo.subscribe('failedCall',this,'hide');
		dojo.subscribe('getQuote',this,function(o){
				if (!o||!o.length||!this.order||(o.a_quotes[0].s_symbol!=this.order.symbol&&(o.a_quotes[0].a_securityData['s_usSymbol']||'')!=this.order.symbol))
					this.hide();
				});
	},
	startup: function() {
		if (this.transactions.length==0) {
			callAPI( // These are the params we will need for this object.
				[{ // an array of objects. one param per object the object describes the command to run and it's parameters
					getConfig: // This is the command.
						{ configs: [ // these are the arguements to the command... the format of parameters are paramName: value 
							{"STANDARD_TRADING": "stock.transaction.menu"},
							{"STANDARD_TRADING": "stock.ordType.menu"},
							{"STANDARD_TRADING": "stock.timeInForce.menu"},
							{"STANDARD_TRADING": "stock.execInst.menu"},
							{"STANDARD_TRADING": "option.transaction.menu"},
							{"STANDARD_TRADING": "option.ordType.menu"},
							{"STANDARD_TRADING": "option.timeInForce.menu"},
							{"STANDARD_TRADING": "option.execInst.menu"}
						]} // end parameters
				}] // End command
			); // End call API
		}
	},
	focus: function(e) {
		var element=e.target||e;
		var bVal=element.getAttribute('blankVal');
			if (element.name==='password') {
				hide(element);
				show(this.tradingPassword);
				this.tradingPassword.focus();
				return;
			}
	},
	blur: function(e) {
		var element=e.target||e;
		var bVal=element.getAttribute('blankVal');
		if (element.name==='tradingPassword') {
			if (e.value=="") {
				show(this.password);
				hide(element);
			}
			this.tpass=element.value;
			dojo.publish('updateTradeData',[{tradingPassword:element.value}]);
		}
	},
	saveOrder: function(data) {
		this.order=data;
	},
	handleDoTradeAction: function(o,e) {
		this.errorFlag|=o.errorFlag;
		if (o.action=='Place Order' && (o.errorFlag || !o.s_clOrdID)) { // need to test if the order ID is not there.. 'cause the error flag is inconsistent.
			if (this.orderButton) {
				this.orderButton.attr('disabled',false);
				this.orderButton.attr('label','Place Order');
			}
			show(this.cancelButton);
			if (!o.errorFlag) this.hide(); // if any errors cannot be canceled....
		}
		this.gettingTradePreview=false;
	},
	showPreview: function(o,e) {
		if (!o) {
			dojo.publish('showError',['An error occured when requesting the preview']);
			return;
		}
		if (!o['orderTradeValue']) {
			if (!e || e.length == 0)
				dojo.publish('showError',['An error occured when requesting the preview']);
			else
				dojo.publish('showError',[e,o.errorFlag?0x02:0x01]);
			return;
		}
		if (o.errorFlag) {
			dojo.publish('showError',[e,0x02]);
			this.order=null;
			return;
		}
		this.tradingPasswordRequired=o.passwordRequired;
		this.orderComplete=false;
		this.gettingTradePreview=false;
        this.tradeType = o.type;
		this.order=o;
        this.order.description[0] = this.order.description[0].replace('&amp;','&');//this is the only known entity that needs conversion, but who knows
		this.trans=this.transactions[this.tradeType];
		this.ord=this.ordType[this.tradeType];
		this.tif=this.timeInForce[this.tradeType];
		this.exec=this.execInst[this.tradeType];
		this.render();
		this.show();
		if (e.length) {
			dojo.publish('showError',[e,0x01]); // show as a global message for now.
		}
		this.processed=true;
	},
	tradeDataChanged: function(o) {
		return;
		var d={};
		dojo.mixin(d,o); // mixin to keep from modifying the original object.
		delete d['tradingPassword'];
		for (var i in d) return this.hide(); // if d is not empty, then hide the object.
	},
	handleFailedAPICall: function(d) {
		if (d[0]=='doTradeAction') {
			this.resetOrder();
		}
	},
	show: function() {
		dojo.publish('showPreviewTab');
	},
	hide: function() {
		dojo.publish('hidePreviewTab');
		this.order=null;
		this.orderComplete=false;
		this.tpass='';
		this.gettingTradePreview=false;
//			dojo.publish('hideSnappy',[false]);
	},
	rotate: function(a) {
		if (!a) return [];
		var b=[];
		for (var i in a) {
			b.push({name:i,value:a[i]});
		}
		return b;
	},
	orderTriggered: function() {
		if (this.orderButton) {
			this.orderButton.attr('disabled',true);
			this.orderButton.attr('label','Submitting');
			hide(this.cancelButton);
		}
	},
	placeOrder: function() {
		dojo.publish('triggerOrder');
	},
	resetOrder: function() {
		if (this.orderComplete) return;
		this.tpass='';
		this.hide();
	},
	handleConfigChange: function(tkiConfigs) {
		if (!tkiConfigs['STANDARD_TRADING.stock.transaction.menu']) return;
		dojo.unsubscribe(this.getConfigSub);
		for (var i in {'stock':'', 'option':''}) {
			this.transactions[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.transaction.menu']);
			this.ordType[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.ordType.menu']);
			this.timeInForce[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.timeInForce.menu']);
			this.execInst[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.execInst.menu']);
		}
	},
	tradeType: 'stock', // default type is stock. Set in attribute of tag in template.
	gettingTradePreview: false,
	tradingPasswordRequired: false,
	tradingPassword: null,
	tpass: '',
	password: null,
	orderButton: null,
	cancelButton: null,
	transactions : {},
	ordType : {},
	timeInForce : {},
	execInst : {},
	orderComplete: false,
	trans: [],
	ord: [],
	tif: [],
	exec: [],
	order: null
});


dojo.provide('tk.qt.orderConfirm');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.orderConfirm", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: orderConfirmTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/orderConfirm.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
		dojo.subscribe('doTradeAction',this,'handleDoTradeAction');
		dojo.subscribe('showTradeConfirm',this,'showConfirm');
		dojo.subscribe('hideConfirm',this,'hideConfirm');
		dojo.subscribe('getTradePreview',this,'getTradePreview');
		this.getConfigSub=dojo.subscribe('getConfig',this,'handleConfigChange');
		dojo.subscribe('triggerOrder',this,'orderTriggered');
		dojo.subscribe('reset',this,'resetOrder');
		dojo.subscribe('failedCall',this,'hide');
		dojo.subscribe('getQuote',this,'hide');
	},
	startup: function() {
		if (this.transactions.length==0) {
			callAPI( // These are the params we will need for this object.
				[{ // an array of objects. one param per object the object describes the command to run and it's parameters
					getConfig: // This is the command.
						{ configs: [ // these are the arguements to the command... the format of parameters are paramName: value 
							{"STANDARD_TRADING": "stock.transaction.menu"},
							{"STANDARD_TRADING": "stock.ordType.menu"},
							{"STANDARD_TRADING": "stock.timeInForce.menu"},
							{"STANDARD_TRADING": "stock.execInst.menu"},
							{"STANDARD_TRADING": "option.transaction.menu"},
							{"STANDARD_TRADING": "option.ordType.menu"},
							{"STANDARD_TRADING": "option.timeInForce.menu"},
							{"STANDARD_TRADING": "option.execInst.menu"}
						]} // end parameters
				}] // End command
			); // End call API
		}
	},
	handleDoTradeAction: function(o,e) {
		this.gettingTradePreview=false;
		if (this.orderComplete) { // don't hide order status of a completed order.
			return;  
		}
		hide(this.domNode);
	},
	handleFailedAPICall: function(d) {
		if (d[0]=='doTradeAction') {
			this.resetOrder();
		}
	},
	hide: function() {
		hide(this.domNode);
		this.order=null;
		this.orderComplete=false;
		this.gettingTradePreview=false;
	},
	showConfirm: function(o,e) { // this is called 
		this.orderComplete=true;
		this.order=dojo.mixin({},o);
		this.render();
		show(this.domNode);
		if (e.length) {
			dojo.publish('showError',[e]); // show as a global message for now.
		}
	},
	hideConfirm: function() {
		this.hide();
	},
	getTradePreview: function() {
		this.gettingTradePreview=true;
		this.render();
		show(this.domNode);
	},
	rotate: function(a) {
		if (!a) return [];
		var b=[];
		for (var i in a) {
			b.push({name:i,value:a[i]});
		}
		return b;
	},
	orderTriggered: function() {
		this.gettingTradePreview=true;
		this.render();
		show(this.domNode);
	},
	resetOrder: function() {
		if (this.orderComplete) return;
		this.hide();
	},
	handleConfigChange: function(tkiConfigs) {
		if (!tkiConfigs['STANDARD_TRADING.stock.transaction.menu']) return;
		dojo.unsubscribe(this.getConfigSub);
		for (var i in {'stock':'', 'option':''}) {
			this.transactions[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.transaction.menu']);
			this.ordType[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.ordType.menu']);
			this.timeInForce[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.timeInForce.menu']);
			this.execInst[i]=this.rotate(tkiConfigs['STANDARD_TRADING.'+i+'.execInst.menu']);
		}
	},
	tradeType: 'stock', // default type is stock. Set in attribute of tag in template.
	gettingTradePreview: false,
	orderButton: null,
	transactions : {},
	ordType : {},
	timeInForce : {},
	execInst : {},
	orderComplete: false,
	trans: [],
	ord: [],
	tif: [],
	exec: [],
	order: null,
    currentHostname: currentHostname
});


dojo.provide('tk.qt.stockTools');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.stockTools", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: stockToolsTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/stockTools.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
		this.getConfigSub=dojo.subscribe('getConfig',this,'handleConfigChange');
		//dojo.subscribe('selectTab',this,'handleTabChange');
		dojo.subscribe('doTradeAction',this,'handleTradeAction');
		dojo.subscribe('syncTradeInfo',this,'handleSomethingChanged');
		dojo.subscribe('canPreviewOrder',this,'handlePreviewReady');
		dojo.subscribe('getQuote',this,'handleGetQuote');
		dojo.subscribe('reset',this,'reset');
        dojo.subscribe('validationError',this,'showValidationErrors');
	},
	postMixInProperties: function() {
		this.defaults=dojo.mixin({},tk.qt.config.tradeInfo[this.toolType]||{timeInForce:0});
		this.defaults.price=this.defaults['price']||"";
		this.defaults.stopPrice=this.defaults['stopPrice']||"";
		this.defaults.stopLimitStopPrice=this.defaults['stopLimitStopPrice']||"";
		this.defaults.stopLimitLimitPrice=this.defaults['stopLimitLimitPrice']||"";
	},
	startup: function() {
		if (this.transactions.length==0) {
			callAPI( // These are the params we will need for this object.
				[{ // an array of objects. one param per object the object describes the command to run and it's parameters
					getConfig: // This is the command.
						{ configs: [ // these are the arguements to the command... the format of parameters are paramName: value 
							{"STANDARD_TRADING": "stock.transaction.menu"},
							{"STANDARD_TRADING": "stock.ordType.menu"},
							{"STANDARD_TRADING": "stock.timeInForce.menu"},
							{"STANDARD_TRADING": "stock.execInst.menu"},
							{"STANDARD_TRADING": "option.transaction.menu"},
							{"STANDARD_TRADING": "option.ordType.menu"},
							{"STANDARD_TRADING": "option.timeInForce.menu"},
							{"STANDARD_TRADING": "option.execInst.menu"}
						]} // end parameters
				}] // End command
			); // End call API
		}
	},
	render: function() {
		this.inherited(arguments);
		if (this.skipPreview && this.tradingPasswordRequired) show(this.tradingPassword.value?this.tradingPassword:this.password);
	},
	reset: function() {
		this.defaults={};
		this.canPreview=false;
		if (this.skipPreview) {
			this.buttonLabel="Place Order";
		} else
			this.buttonLabel="Preview Order";
		this.buttonClass='qt-green';
		this.tpass="";
		this.previewOrderReady=false;
		this.render();
	},
	resetButton: function() {
		dojo.publish('reset',[]);
	},
	focus: function(e) {
		var element=e.target||e;
		var bVal=element.getAttribute('blankVal');
		if (element.value===bVal) {
			if (element.name==='password') {
				hide(element);
				show(this.tradingPassword);
				this.tradingPassword.focus();
				return;
			}
			element.value='';
		}
	},
	blur: function(e) {
		var element=e.target||e;
		var bVal=element.getAttribute('blankVal');

		if (element.value==='') {
			element.value=bVal;
			if (element.name==='tradingPassword') {
				show(this.password);
				hide(element);
			}
		}
		if (element.name==='tradingPassword') {
				this.tpass=element.value;
		}
	},
	rotate: function(a) {
		if (!a) return [];
		var b=[];
		for (i in a) {
			b.push({name:i,value:a[i]});
		}
		return b;
	},
	handleConfigChange: function(tkiConfigs) {
		if (!this.tkiConfigs && (!tkiConfigs || !tkiConfigs['STANDARD_TRADING.stock.transaction.menu'])) return;
		if (this.getConfigSub) {
			dojo.unsubscribe(this.getConfigSub);
			this.getConfigSub=null;
		}
		if (tkiConfigs) this.tkiConfigs=tkiConfigs;
		if (this.toolType=='stock') {
			this.transactions=this.rotate(this.tkiConfigs['STANDARD_TRADING.stock.transaction.menu']);
			this.ordType=this.rotate(this.tkiConfigs['STANDARD_TRADING.stock.ordType.menu']);
			this.timeInForce=this.rotate(this.tkiConfigs['STANDARD_TRADING.stock.timeInForce.menu']);
			this.execInst=this.rotate(this.tkiConfigs['STANDARD_TRADING.stock.execInst.menu']);
		} else if (this.toolType=='option') {
			this.transactions=this.rotate(this.tkiConfigs['STANDARD_TRADING.option.transaction.menu']);
			this.ordType=this.rotate(this.tkiConfigs['STANDARD_TRADING.option.ordType.menu']);
			this.timeInForce=this.rotate(this.tkiConfigs['STANDARD_TRADING.option.timeInForce.menu']);
			this.execInst=this.rotate(this.tkiConfigs['STANDARD_TRADING.option.execInst.menu']);
		}
		this.render();
	},
	handleGetQuote: function(data) {
		if (!data || !data['a_quotes'] || data.a_quotes[0].b_unknownSymbol) {
			hide(dojo.query('form',this.domNode)[0]);
			return;
		}
		if (this.toolType!=data.a_quotes[0].s_quoteType.toLowerCase()) { // update drop downs with new fields if quote type is different.
			this.toolType=data.a_quotes[0].s_quoteType.toLowerCase();
			this.defaults=dojo.mixin({},tk.qt.config.tradeInfo[this.toolType]||{timeInForce:0});
			this.handleConfigChange();
			this.handleSomethingChanged(this.defaults);
		}
		if (!tradingPermission[this.toolType]) {
			hide(this.domNode);
		}
	},
	handleTabChange: function(t) {
		if (this.activeTab===this.toolType) return;
	},
	handlePreviewReady: function(data) {
//		this.previewOrderData=data;
		this.canPreview=true;
//		if (this.previewOrderData.skipPreview) {
//			this.buttonLabel="Place Order";
//		}
//		this.actionButton.attr('label',this.buttonLabel);
//		this.actionButton.attr('disabled',false); // We have enough information to submit.
	},
	handleActionButton: function(e) {
		if (!this.canPreview) {
            this.showValidationErrors();
            return;
        }
		var text = this.actionButton.attr('label').trim();
		this.actionButton.attr('disabled',true);
		hide(this.clearButton);
		if (text=='Place Order') {
			dojo.publish('triggerOrder');
		} else if (text=='Preview Order') {
			dojo.publish('getTradePreview',[this.previewOrderData]);
		}
	},
	handleTradeAction: function(data) { // just disable the preview button and reset the form data when a trade is complete.
		this.skipPreview|=data.skipPreview;
		this.tradingPasswordRequired=data.passwordRequired;
		if (data.skipPreview && this.tradingPasswordRequired) show(this.tradingPassword.value?this.tradingPassword:this.password);
		this.actionButton.attr('disabled',false);
		show(this.clearButton);
		if (data.skipPreview) {
			this.actionButton.attr('label','Place Order');
			this.buttonLabel="Place Order";
			this.previewOrderReady=true;
			this.render();
		}
		if (!data.quoteSymbol&&this.canPreview) return; // if this is an enter action, and we already can preview...
		if (data.quoteSymbol==null||data.quoteSymbol[0]!=data.symbol&&!data.s_clOrdID) {
			return;
		}
		if (data.action=="Preview Order") {
			if (data.errorFlag) return; // if an exception occured on the backend that was an error, and not a notice, don't clear.
			this.previewOrderReady=true;
		} else if (data.s_clOrdID) {// only clear it up if the order passed (we have an order ID in the data)
			this.buttonLabel="Preview Order";
			this.reset();
		} else {
			if (this.tradingPasswordRequired) show(this.tradingPassword.value?this.tradingPassword:this.password);
		}
	},
	handleSomethingChanged: function(d) {
		var l = this.price.form.elements.length;
		this.invalidFieldNames=[];
		for (var i = 0; i < l; i++) {
			if (dojo.hasClass(this.price.form.elements[i],'error') && d[this.price.form.elements[i].name])
				dojo.removeClass(this.price.form.elements[i], 'error');
		}
		for (var i in d) {
			if (i=='tradingPassword') {
				continue;
			}
			this.previewOrderReady=false;
			this.previewOrderData=null;
			if (d[i]==this.defaults[i]) continue; // no need to render anything if the values are the same.
			this.defaults=dojo.mixin({},tk.qt.config.tradeInfo[this.toolType]||{timeInForce:0});
			this.render();
			break;
		}
	},
	valueChanged: function(e) {
		var t=e['target']||e;
//		this.actionButton.attr('disabled',true);
		var o={};
		switch (t.name) {
		case 'ordType':
			setTimeout('dijit.byId("'+this.id+'").render();',250); // render after all of the publishing.
		case 'transaction':
		case 'execInst':
		case 'timeInForce':
			if (t.options[0].value==t.options[0].text)t.remove(0);
			break;
		default:
			//console.log('no action for '+t.name);
		}
		o[t.name]=t.value;
        var relatedFields = false;//t.name=='ordType'?true:false;
		if (t.value!='' && t.value!=0) {// don't set it if it's blank or zero.
			this.defaults[t.name]=t.value;
		} else {
			delete this.defaults[t.name];
		}
		this.suspendDataEvent=true; // we made the change, tell our own event to ignore this.	
		dojo.publish('updateTradeData',[o,relatedFields]);
		return false;
	},
    showValidationErrors: function(invalids){
       //get form refrence (using the price field is aritrary)
       var f = this.price.form;
       if (!f) return;
       //if we're called with no parameter, use the saved invalidFields list, and highlight the fields
       //if one is passed in, save it, but don't highlight
       l = this.invalidFieldNames.length;
       if (typeof(invalids) != 'undefined') {
           this.invalidFieldNames = invalids;
           if (this.hasErrors) {
               for (var i = 0; i < l; i++) {
                   dojo.addClass(f[this.invalidFieldNames[i]], 'error');
               }
           }
       } else {
           for (var i = 0; i < l; i++) {
               dojo.addClass(f[this.invalidFieldNames[i]], 'error');
           }
       }
    },
    invalidFieldNames: [],
    hasErrors: false,
	actionButton: null,
	buttonLabel: 'Preview Order',
	buttonClass: 'qt-green',
	clearButton: null,
	tradingPasswordRequired: false,
	tradingPassword: null,
	tpass: '',
	password: null,
	quantity: null,
	skipPreview: false,
	canPreview: false,
	symbol: (tk.qt.config['tradeInfo']&&tk.qt.config.tradeInfo['stock']&&tk.qt.config.tradeInfo.stock['symbol'])||'',
	suspendDataEvent: false,
	active: false,
	previewOrderData: null,
	previewOrderReady: true,
	price: null,
	price2: null,
	toolType: 'stock', // default type is stock. Set in attribute of tag in template.
	transactions : [],
	ordType : [],
	timeInForce : [],
	execInst : [],
	qtOrderType: null ,
	qtStockPrice: null,
	defaults: null
});

dojo.provide('tk.qt.accountBalance');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.accountBalance", [ dijit._Widget, dojox.dtl._Templated], {
	templateString: accountBalanceTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/accountBalance.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: false,

	constructor: function() {
		this.dataObj=1;
	},
	startup: function() {
		var now=(new Date()).getTime();
		dojo.subscribe('getAccountBalance',this,'update');
		dojo.subscribe('changeAccount',null,function(d) {if (d&&d['newAccount'])tk.qt.accountBalance.lastTime=0});
		if (60000>now-tk.qt.accountBalance.lastTime) return; // only get the balance once per minute.
		tk.qt.accountBalance.lastTime=now;
		//callAPI([{'getAccountBalance':{}}]);
	},
	update: function(data) {
		this.dataObj=data;
		tk.qt.accountBalance.lastTime=(new Date()).getTime();
		this.render();
	},
	refresh: function() {
		this.dataObj=2;
		this.render();
		callAPI([{'getAccountBalance':{}}]);
	},
	dataObj : null
});


dojo.provide('tk.qt.optionTradeChain');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.require('dojo.data.ItemFileReadStore');
dojo.require('dijit.form.FilteringSelect');
dojo.require('dijit.Tooltip');
// Register dojo filters in the global scope.
dojo.declare("tk.qt.optionTradeChain", [ dijit._Widget, dojox.dtl._Templated], {
	templateString: optionTradeChainTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/optionTradeChain.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,

	constructor: function() {
		this.getChainSubscription=dojo.subscribe('getChain',this,'parseChain');
		this.getQuoteSub=dojo.subscribe('getQuote',this,'handleGetQuote');
		dojo.subscribe('failedCall',this,'handleAPICallFailed');
		//dojo.subscribe('reset',this,'reset');
	},
	destroy: function() {
		dojo.unsubscribe(this.getChainSubscription);
		dojo.unsubscribe(this.getQuoteSub);
		if (this.links)
			while(this.links[++i]) {
				var j=-1;
				if (this.links[i].handle)
				while(this.links[i].handle[++j]) {
					dojo.disconnect(this.links[i].handle[j]);
				}
			}
	},
	startup: function() {
		if (this.progressEl) hide(this.progressEl);
	},
	reset: function() {
		this.symbol=this.ulSymbol=this.description=this.highMarginDisplay='';
		this.quoteTime=0;
		this.render();
	},
	symbolKeyPress: function(e) { // e is suppose to be normalized.
		if (e.keyCode == dojo.keys.ENTER) {
			this.symbol=this.symbolEl.value;
			dojo.publish('updateTradeData',[{symbol:this.symbol}]);
			this.refresh();
            dojo.stopEvent(e);
		}
	},
	symbolBlur: function(e) {
		if (this.symbolEl.value != this.symbol) {
			this.symbol=this.symbolEl.value;
			dojo.publish('updateTradeData',[{symbol:this.symbol}]);
			this.refresh();
		}
	},
	parseChain: function(data) {
		if (data==null) { // OptionChainLookup will handle showing this data.
			this.errors=null;
			this.chainAvailable=false;
    		this.render();
    		return;
		} else
			this.errors=null;
		this.chainAvailable=true;
		this.render();
		this.chain=data.a_callsPutsData.a_callsPuts;
		this.dates=data.a_expDates;
		var months=['Jan','Feb','Mar','Apr','May','June','Jul','Aug','Sept','Oct','Nov','Dec'];
		this.dates=dojo.map(this.dates,function(e) { // Create array.
			var ymd=e.match(/(\d{4})(\d{2})(\d{2})/);
			return {id:e,label:months[ymd[2]-1]+' '+ymd[3]+", "+ymd[1]};
		});
		if (this.dates)
			this.expiration.attr('store',new dojo.data.ItemFileReadStore({data:{identifier:'id',label:'label',items:this.dates}}));
		this.expiration.attr('value','Expiration');
		this.strike.attr('value','Strike');
	},
	expChange: function(e) {
		if(!this.strike || !this.chain) return;
		this.strike.attr('store',new dojo.data.ItemFileReadStore({data:{identifier:'n_strike',label:'n_strike',items:this.chain[e]}}));
	},
	call: function(e) {
		if (!this.strike.attr('item')) return;
		show(this.progressEl);
		hide(this.boxesEl);
		dojo.publish('retrieveQuote',[this.strike.attr('item')['s_callSymbol'][0]]); // if we have a symbol, then make a request.
	},
	put: function(e) {
		if (!this.strike.attr('item')) return;
		show(this.progressEl);
		hide(this.boxesEl);
		dojo.publish('retrieveQuote',[this.strike.attr('item')['s_putSymbol'][0]]); // if we have a symbol, then make a request.
	},
	getChain: function() {
		if (this.ulSymbol) {
			show(this.progressEl);
			hide(this.boxesEl);
			callAPI([{getChain:{baseSymbol:this.ulSymbol,chainType:'CP',expMonth:'ALL + LEAPS',strikeRange:5}}]);
		}
	},
    refresh: function() { // this.symbol should be updated any time symbol is changed.
		if (this.symbolEl && this.symbolEl['value']) {
			show(this.progressEl);
			hide(this.boxesEl);
			this.goButton.disabled=true;
			hide(this.refreshButton);
			//this.refreshButton.src="/Images/toolbar/refresh_anim.gif";
			dojo.publish('retrieveQuote',[this.symbol]); // if we have a symbol, then make a request.
		}
    },
    getQuote: function() { // this.symbol should be updated any time symbol is changed.
		if (this.symbolEl && this.symbolEl['value']) {
			this.symbol=this.symbolEl['value'];
			dojo.publish('updateTradeData',[{symbol:this.symbol}]);
			this.refresh();
		}
    },
    handleAPICallFailed: function() {
		if (this.progressEl) {
			hide(this.progressEl);
			show(this.boxesEl);
		}
    },
	handleGetQuote: function(data,error) {
    	this.dataObj=null;
		if (this.progressEl) {
			this.goButton.disabled=false
			show(this.refreshButton);
			//this.refreshButton.src="/Images/toolbar/refresh.gif";
			hide(this.progressEl);
			show(this.boxesEl);
		}
		if (!data || (!data['a_quotes'] && !data['a_quoteData'])) {
            return;// handle null data. errors are handled separately.
        }
		if (data['a_quoteData']) {
            ld = data.a_quoteData; // chains put quote data here.
        } else {
            ld = data.a_quotes[0];
        }	
        var el=this.symbolEl;
		if (ld.b_unknownSymbol) {
			dojo.addClass(el,'error');
			var clickevent=dojo.connect(this.symbolEl,'onclick',function(evt){
				dojo.disconnect(clickevent);
				dojo.removeClass(el,'error');
			});
			tk.qt.config.lastQuote='';
			saveQtState();
			return;
		}
		this.dataObj=ld;
		this.highMarginDisplay=data.highMarginDisplay;
		dojo.removeClass(el,'error');
		var ulSymbol;
		this.symbol=ld.s_symbol;
		dojo.publish('updateTradeData',[{symbol:this.symbol}]);
		if (ld.s_quoteType=='Option') {
			ulSymbol=ld.a_securityData.s_usSymbol.toLowerCase();
			var months=['Jan','Feb','Mar','Apr','May','June','Jul','Aug','Sept','Oct','Nov','Dec'];
			var ymd=ld.a_securityData.s_expDate.match(/(\d{2})\/(\d{2})\/(\d{4})/);
			this.description=
				ld.a_securityData.s_usSymbol+' '+ // Underlying Symbol
					months[ymd[1]-1]+' '+ymd[2]+' '+ymd[3]+' '+ // Expiration date translated
					formatNumber(ld.a_securityData.n_strikePrice,"|2|.|,|3||N/A")+' '+ // Strike price formatted.
					((ld.s_description.toLowerCase().match('(call|put)\s*')[1])=='call'?'Call':'Put'); // Call or Put.
		} else {
			ulSymbol=ld.s_symbol.toLowerCase();
			this.description=ld.s_description;
		}
		this.symbolEl.value=ulSymbol;
		this.quoteTime=data.n_serverTime;
		if (this.ulSymbol != ulSymbol) {
			this.chain=null;
			this.ulSymbol=ulSymbol;
			this.chainAvailable=false;
			this.render();
		} else
			this.descriptionEl.innerHTML=this.description+' '+this.highMarginDisplay;
		
	},
	hideLinks: function(e) {
		clearTimeout(pmTimer);
		pmTimer = setTimeout("hide(dojo.byId('qtPm'))", 150);
	},
	showLinks: function(e) {
		var element=e.target||e;
		var i=-1;
		if (this.links) {
			// Disconnect any existing links.
			while(this.links[++i]) {
				if (!this.links[i]['handle']) continue;
				var j=0;
				while(this.links[i].handle[j]) {
					dojo.disconnect(this.links[i].handle[j++]);
				}
			}
		}
		if (!this.dataObj) return;
		this.links=LinkManager.getLinks(this.dataObj.s_quoteType,this.dataObj.s_symbol,this.dataObj.a_securityData['s_usSymbol']);
		if (this.root||dojo.byId('qtPm')) {
			dojo.destroy(this.root||dojo.byId('qtPm'));
		}
		this.root=dojo.create('ul',{id:'qtPm'});
		dojo.addClass(this.root,'powerMenu');
		
		for(i=0;i<this.links.length;i++) { // create and connect event handlers.
			var li=dojo.create('li',{link:this.links[i].link,innerHTML:'<a title="'+(this.links[i].description?this.links[i].description:this.links[i].text)+'" href="'+this.links[i].link+'">'+this.links[i].text+"</a>"},this.root,'last');
			this.links[i].handle=[];
			li.link=this.links[i].link;
			if (this.links[i].publish) {
				this.links[i].handle.push(dojo.connectPublisher(this.links[i].publish,li,'onclick'));
			}
			if (this.links[i].click) {
				this.links[i].handle.push(dojo.connect(li,'onclick',this.links[i],'onclick'));
			}
			if (this.links[i].hover) {
				this.links[i].handle.push(dojo.connect(li,'onmouseover',this.links[i],'hover'));
			}
			if (this.links[i].out) {
				this.links[i].handle.push(dojo.connect(li,'onmouseout',this.links[i],'out'));
			}
			this.links[i].handle.push(dojo.connect(li,'onclick',function(e){
				pmTimer = setTimeout("hide(dojo.byId('qtPm'))", 150);
				//location.href=this.link;
			})); // after all other events, run this one.
		}
		this.links[0].handle.push(dojo.connect(this.root,'onmouseout',function(e){
			if (pmTimer) clearTimeout(pmTimer);
			pmTimer = setTimeout("hide(dojo.byId('qtPm'))", 150);
		}));
		this.links[0].handle.push(dojo.connect(this.root,'onmouseover',function(e){
			if (pmTimer) clearTimeout(pmTimer);
		}));
		dojo.place(this.root,element.parentNode,'last');
		var box=dojo.coords('qtPuPmAct');
		dojo.style(this.root,{
			display:'block',
			top:box.h/2+'px',
			left: box.l+(box.w/2)+'px'
		});
		box=box; // this is here for debugging the above.. remove when squashed
	},
	links: null,
	dataObj: null,
	expiration: null, // FilteringSelect.
	chainAvailable: false,
	strike: null, // FilteringSelect.
	ulSymbol: "",
	quoteTime: 0,
	rtq: tk.qt.realTime,
	goButton: null,
	refreshButton: null,
	symbol: '',
	symbolEl: null,
	descriptionEl: null,
	progressEl: null,
	boxesEl: null,
	chain : {}, // All of the chains data
//		calls: null, // Just the calls.
//		puts: null, // Just the puts.
	dates: [], // just dates.
	errors: null, // if set, there was an error getting chain.
	tooltip: null,
	description: '',
	highMarginDisplay: '',
	form: null, // the whole form object
    currentHostname: currentHostname
});
var unknownSymbol = "Unknown Symbol";
var fortune=['Unknown Symbol.','Let me know what message you really want here.','This space intentionally left blank',"<pre>	7,140 pounds on the Sun\n	   97 pounds on Mercury or Mars\n	  255 pounds on Earth\n	  232 pounds on Venus or Uranus\n	   43 pounds on the Moon\n	  648 pounds on Jupiter\n	  275 pounds on Saturn\n	  303 pounds on Neptune\n	   13 pounds on Pluto\n\n		-- How much Elvis Presley would weigh at various places\n		   in the solar system</pre>",
"<pre>I don\'t have to take this abuse from you -- I\'ve got\nhundreds of people waiting to abuse me.\n\t		-- Bill Murray, \"Ghostbusters</pre>\"",
"<pre>I don\'t have any use for bodyguards, but I do have a specific use for two\nhighly trained certified public accountants.\n\t		-- Elvis Presley</pre>",
"<pre>I don't know why anyone would want a computer in their home.\n\t		-- Ken Olsen, president of DEC, 1974</pre>",
"<pre>I got this powdered water -- now I don't know what to add.\n\t		-- Steven Wright</pre>"
];


dojo.provide('tk.qt.optionChainLookup');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.require('dojo.data.ItemFileReadStore');
dojo.require('dijit.form.FilteringSelect');
// Register dojo filters in the global scope.
dojo.declare("tk.qt.optionChainLookup", [ dijit._Widget, dojox.dtl._Templated], {
	templateString: optionChainLookupTemplate,
//    templatePath: dojo.moduleUrl("tk.qt","templates/optionChainLookup.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
		dojo.subscribe('getChain',this,'parseChain');
		dojo.subscribe('getQuote',this,'getQuote');
		dojo.subscribe('hideSnappy',this,'hide');
		//dojo.subscribe('failedCall',this,'hide');
	},
	destroy: function() {
		//dojo.unsubscribe(this.getChainSubscription);
		//dojo.unsubscribe(this.getQuoteSub);
	},
	getQuote: function(data,error) {
		if (!data || data.a_quotes[0].b_unknownSymbol) {
			this.chainAvailable=false;
			this.ulSymbol="";
			this.render();
			return;
		}
		if (data.a_quotes[0]['s_quoteType']=='Option') {
			if (this.ulSymbol==data.a_quotes[0]['a_securityData']['s_usSymbol']) return;
			this.ulSymbol=data.a_quotes[0]['a_securityData']['s_usSymbol'];
		}
		if (this.symbol==data.a_quotes[0]['s_symbol']) return;
		if (data.a_quotes[0]['s_quoteType']=='Stock') {
			if (this.ulSymbol!=data.a_quotes[0]['s_symbol']) this.chainAvailable=false
			this.ulSymbol=data.a_quotes[0]['s_symbol'];
		}
		this.symbol=data.a_quotes[0]['s_symbol'];
		this.render();
	},
	hide: function(b) {
		this.visible=!b;
	},
	render: function() {
		this.inherited(arguments);
		if (this.chainAvailable) {
			var months=['Jan','Feb','Mar','Apr','May','June','Jul','Aug','Sept','Oct','Nov','Dec'];
			this.dates=dojo.map(this.dates,function(e) { // Create array.
				var ymd=e.match(/(\d{2}\d{2})(\d{2})(\d{2})/);
				return {id:e,label:months[ymd[2]-1]+' '+ymd[3]+", "+ymd[1]};
			});
			if (this.dates)
				this.expiration.attr('store',new dojo.data.ItemFileReadStore({data:{identifier:'id',label:'label',items:this.dates}}));
			this.expiration.attr('value','Expiration');
			this.strike.attr('value','Strike');
		}
	},
	parseChain: function(data,error) {
		if (data==null) {
			this.dataObj=null;
		    this.chainAvailable=false;
		    this.ulSymbol=this.symbol='';
    		this.render();
			if (error && error!="") dojo.publish('error',[error,tk.qt.config.popup?0x02:0xff]);
    		return;
		}
		this.errors=null;
		this.chainAvailable=true;
		this.dataObj=data;
		this.chain=this.dataObj.a_callsPutsData.a_callsPuts;
		this.dates=this.dataObj.a_expDates;
		this.render();
	},
	expChange: function(e) {
		if(!this.strike || !this.chain) return;
		this.strike.attr('store',new dojo.data.ItemFileReadStore({data:{identifier:'n_strike',label:'n_strike',items:this.chain[e]}}));
	},
	call: function(e) {
		if (!this.strike.attr('item')) return;
		dojo.publish('retrieveQuote',[this.strike.attr('item')['s_callSymbol'][0]]); // if we have a symbol, then make a request.
	},
	put: function(e) {
		if (!this.strike.attr('item')) return;
		dojo.publish('retrieveQuote',[this.strike.attr('item')['s_putSymbol'][0]]); // if we have a symbol, then make a request.
	},
	getChain: function() {
		this.findButton.value='Retrieving...';
		if (this.ulSymbol) {
			callAPI([{getChain:{baseSymbol:this.ulSymbol,chainType:'CP',expMonth:'ALL + LEAPS',strikeRange:5}}]);
		}
	},
	expiration: null, // FilteringSelect.
	chainAvailable: false,
	strike: null, // FilteringSelect.
	ulSymbol: '',
	visible: true,
	findButton: null,
	quoteTime: 0,
	symbol: '',
	chain : {}, // All of the chains data
	dates: [], // just dates.
	description: ''
});
var unknownSymbol = "Unknown Symbol";


dojo.provide('tk.qt.optionTrade');// Curently don't know how to inline object values as parameters. Using concat instead.
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.require('tk.qt.stockTools');
dojo.require('tk.qt.accountBalance');
dojo.require('dojo.date.locale');
dojo.declare("tk.qt.optionTrade", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: optionTradeTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/optionTrade.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
		dojo.subscribe('getQuote',this,'update');
	},
	startup: function() {
	},
	update: function(data) {
		var dataObj=data.a_quotes[0];
		this.symbol.value=dataObj.s_symbol;
		if (dataObj.s_quoteType=='Option') { // format special for option quotes.
			var months=['Jan','Feb','Mar','Apr','May','June','Jul','Aug','Sept','Oct','Nov','Dec'];
			var ymd=dataObj.a_securityData.s_expDate.match(/(\d{2})\/(\d{2})\/(\d{2})(\d{2})/);
			this.description.innerHTML=
					dataObj.a_securityData.s_usSymbol+' '+ // Underlying Symbol
					months[ymd[1]-1]+' '+ymd[4]+' '+ // Expiration date translated
					formatNumber(dataObj.a_securityData.n_strikePrice,"|2|.|,|3||N/A")+' '+ // Strike price formatted.
					dataObj.s_description.toLowerCase().match('(call|put)\s*')[1]; // Call or Put.
			this.underlying.innerHTML=dataObj.a_securityData.s_usDesc.toLowerCase();
			this.ulPrice.innerHTML=formatNumber(dataObj.a_securityData.s_usLastPrice,"$|2|.|,|3||N/A");
			this.ulChange.innerHTML=applyPosNegStyle(formatNumber(dataObj.a_securityData.s_usNetChange,"|2|.|,|3|%|N/A"),"sign");
		} else {
			this.description.innerHTML=dataObj.s_description;
			this.underlying.innerHTML=dataObj.s_description.toLowerCase();
			this.ulPrice.innerHTML=formatNumber(dataObj.s_lastPrice,"$|2|.|,|3||N/A");
			this.ulChange.innerHTML=applyPosNegStyle(formatNumber(dataObj.s_change,"|2|.|,|3|%|N/A"),"sign");
		}
		this.serverTime.innerHTML = dojo.date.locale.format(tk.qt.filter.createDate(dataObj.n_serverTime),{formatLength: "short", locale: "en"});
	},
    getQuote: function() {
		if (this.symbol && this.symbol['value']) {
			dojo.publish('retrieveQuote',[this.symbol.value]); // if we have a symbol, then make a request.
		}
    },
	symbol: null,
	serverTime: null,
	underlying: null,
	ulPrice: null,
	ulChange: null,
	description: null,
	tradeButton: null,
	previewButton: null
});

dojo.provide('tk.qt.orderStatus');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
// Register dojo filters in the global scope.
dojo.declare("tk.qt.orderStatus", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: orderStatusTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/orderStatus.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
		dojo.subscribe('getOrderStatus',this,'loadStatus');
	},
	startup: function() {
	},
	update: function(order) {
	},
	loadStatus: function(data) {
	},
	refreshButton: null
});

dojo.provide('tk.qt.stockTradeQuote');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.stockTradeQuote", [ dijit._Widget, dojox.dtl._Templated], {
	templateString: stockTradeQuoteTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/stockTradeQuote.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,

	constructor: function() {
		dojo.subscribe('getQuote',this,'update');
		//dojo.subscribe('reset',this,'clear');
	},
	update: function(data) {
		var ld;
		if (!data || (!data['a_quotes'] && !data['a_quoteData'])) return this.clear(); // handle null data. errors are handled separately.
		if (data['a_quoteData'])
			ld=data.a_quoteData; // chains put quote data here.
		else {
			ld=data.a_quotes[0];
		}
		if (ld.b_unknownSymbol) {
			return this.clear();
		}
		this.dataObj=ld;
		this.render();
		dojo.publish('updateTradeData',[{symbol:ld.s_symbol}]);
		if (this.dataObj.s_quoteType=='Option') { // format special for option quotes.
			this.ulSymbol=ld.a_securityData.s_usSymbol.toLowerCase();
			this.underlying.innerHTML=this.dataObj.a_securityData.s_usDesc.toLowerCase();
			this.ulPrice.innerHTML=formatNumber(this.dataObj.a_securityData.s_usLastPrice,"|2|.|,|3||N/A");
			this.ulChange.innerHTML=applyPosNegStyle(formatNumber(this.dataObj.a_securityData.s_usNetChange,"|2|.|,|3|%|N/A"),"sign");
		} else {
			this.underlying=this.dataObj.s_description.toLowerCase();
			this.ulSymbol=ld.s_symbol.toLowerCase();
		}
	},
	clear: function() {
		this.dataObj=null;
		this.render();
		return false;
	},
    ulSymbol:null,
	underlying: null,
	ulPrice: null,
	ulChange: null,
	description: null,
	rtq: tk.qt.realTime,
	dataObj : null
});

dojo.provide('tk.qt.stockTrade');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.require('tk.qt.stockTradeQuote');
dojo.require('tk.qt.stockTools');
dojo.require('tk.qt.optionTradeChain');
dojo.require('tk.qt.accountBalance');
dojo.declare("tk.qt.stockTrade", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: stockTradingTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/stockTrading.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	constructor: function() {
	},
	startup: function() {
		dojo.subscribe('getQuote',this,'update');
	},
	getQuote: function(e) {
		dojo.publish('retrieveQuote',[this.symbol.value]);
	},
	update: function(data) {
		if (!data || !data.a_quotes) {
			this.dataObj=null;
		} else {
			if (data['a_quoteData'])
				ld=data.a_quoteData; // chains put quote data here.
			else
				ld=data.a_quotes[0];
		}
		this.dataObj=ld;
	},
	currentHostname: currentHostname,
	tradeButton: null,
	previewButton: null,
	symbol: null,
	dataObj : null,
	form: null
});

dojo.provide('tk.qt.tradeWidget');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.declare("tk.qt.tradeWidget", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: "<span></span>", // empty.
    _dijitTemplateCompat: true,
	widgetsInTemplate: false,
	id: 'tradeWidget',
	constructor: function() {
		dojo.subscribe('doTradeAction',this,'handleTradeAction'); // Handler for response event from backend call.
		dojo.subscribe('updateTradeData',this,'updateTradeData'); // Handle updates on trading forms.
		dojo.subscribe('submitTrade',this,'submitTrade'); // submit stored data to make a trade.
		dojo.subscribe('getTradePreview',this,'getTradePreview'); // get trade preview information. This is good for getting the 
		dojo.subscribe('getQuote',this,'updateQuote');
		dojo.subscribe('selectTab',this,'changeOrderType');
		//dojo.subscribe('changeAccount',this,'changeAccount');
		dojo.subscribe('triggerOrder',this,'submitTrade'); // this submits the trade.
		dojo.subscribe('reset',this,'reset'); // called when all forms should be reset to defaults.
		if (typeof tk.qt.config.tradeInfo == 'undefined') {
            tk.qt.config.tradeInfo = {};
        }
	},
	startup: function() {
		if (this.orderData[this.orderType]) {
            this.orderData[this.orderType].command = "enter";
        } else {
            this.orderData[this.orderType] = {
                command: "enter"
            };
        }
		callAPI( // These are the params we will need for this object.
				[{ // an array of objects. one param per object the object describes the command to run and it's parameters
					doTradeAction: // This is the command.
						this.orderData[this.orderType] // Just starting... this gets a template to fill in and send to perform trades.
				}] // End command
			); // End call API
	},
	handleTradeAction: function(data,errors) {
		if (data === null) {
            return;
        }
		if (!this.actionData) { // this request should be a template.
            data.timeInForce = 0;
            this.actionData = dojo.toJson(data); // populate with template. using JSON prevents references between saved data.
            this.orderData = {}; // clear order data for each order type.
            for (var i in tk.qt.config.tradeInfo) { // for each saved set of order data...
                this.orderData[i] = dojo.fromJson(this.actionData); // create copy of template.
                delete this.orderData[i].errorFlag;
                dojo.mixin(this.orderData[i], tk.qt.config.tradeInfo[i]); // mixin the saved data.
                this.orderData[i].optionChainSymbol = this.symbol.stock || null; // set this no matter what. it's used in option trades.
                //this.orderData[i].currentAccount = tk.qt.config.currentAccount;
                //this.orderData[i].symbol=this.symbol[i]||'';
                if (this.orderType === i && this.canPreview(this.orderData[i])) {
                    dojo.publish('canPreviewOrder', [this.orderData[i]]);
                }
            }
        } else {
            this.orderData[data.type || tk.qt.config.selectedTab || 'stock'] = data;
        }
		if (data.s_clOrdID) { // successful trade.
			dojo.publish('showTradeConfirm',[data,errors]);
	        dojo.publish('reset');
			// commenting this out because it's causing errors in IE, not sure what it does anyway
            //tk.qt.config.tradeInfo[this.orderType]={symbol:data.o_quote.s_symbol,timeInForce:0};
			saveQtState();
		}
		if (data.action=="Place Order") {
			if (data.forcedPreview=="Y") {
				this.orderData.forcedPreview="Y";
				dojo.publish('showTradePreview',[data,errors]); // show the preview data.
			} else {
				if (errors)
					dojo.publish("error",[errors,data.errorFlag?0x02:0x01]);
			}
		}
//			if (data.errorFlag)
//				dojo.publish('showTradePreview',[data,errors]); // show the preview data.
		if ((data.action == "Preview Order" || data.action == "Modify") && data.type == this.orderType) {
            dojo.publish('showTradePreview', [data, errors]); // show the preview data.
        }
	},
/*
 	changeAccount: function(d) {
		if (!d || !d.newAccount) {
            return;
        }
		for (var i in this.orderData) {
			this.orderData[i].currentAccount=d.newAccount;
		}
	},
 */
	reset: function() {
		this.actionData=null;
		this.orderData={};
		if (tk.qt.config.tradeInfo[this.orderType].symbol) {
			tk.qt.config.tradeInfo[this.orderType]={symbol:tk.qt.config.tradeInfo[this.orderType].symbol};
				this.orderData[this.orderType]={
					command:"enter",
					symbol:tk.qt.config.tradeInfo[this.orderType].symbol
				}
				this.symbol={};
				this.symbol[this.orderType]=tk.qt.config.tradeInfo[this.orderType].symbol;
			} else {
				tk.qt.config.tradeInfo[this.orderType]={};
				this.symbol={};
				this.orderData[this.orderType]={
					command:"enter"
				}
			}
			if (tk.qt.config.currentAccount!=null) this.orderData[this.orderType]["currentAccount"]=tk.qt.config.currentAccount;
			saveQtState();
			callAPI([{doTradeAction:this.orderData[this.orderType]}]); // get new template... with new token.
	},
	updateTradeData: function(data,t) {
		if (!this.orderData[this.orderType]) {
            this.orderData[this.orderType] = {};
        }
		if (t) {
			if (data.limitPrice) {
                this.orderData[this.orderType].limitPrice = data.limitPrice;
                tk.qt.config.tradeInfo[this.orderType].limitPrice = data.limitPrice;
            } else {
                this.orderData[this.orderType].limitPrice = '';
                tk.qt.config.tradeInfo[this.orderType].limitPrice = '';
            }
			dojo.mixin(data,tk.qt.config.tradeInfo[this.orderType]);
		}
		dojo.mixin(this.orderData[this.orderType],data); // merge the data together.
		delete data["tradingPassword"];
		dojo.mixin(tk.qt.config.tradeInfo[this.orderType],data); // save the updated data.
		saveQtState();
		dojo.publish('syncTradeInfo',[data]);
		if (this.canPreview(this.orderData[this.orderType])) {
			dojo.publish('canPreviewOrder',[this.orderData[this.orderType]]); // notify that the preview is able to be shown.
		}
	},
	getTradePreview: function() {
		this.orderData[this.orderType].command="preview";
		this.orderData[this.orderType].action="Preview Order";
		this.orderData[this.orderType].type=this.orderType;
		delete this.orderData[this.orderType]["currentAccount"];//.currentAccount=tk.qt.config.currentAccount;
		this.orderData[this.orderType].optionChainSymbol=this.symbol.stock; //underlying for option preview.
		delete this.orderData[this.orderType].amountType;
		this.dirty=true; // after we get our first preview, consider the token dirty.. require a new one on a new symbol.
		this.orderData[this.orderType].errorFlag=false;
		callAPI([{doTradeAction:this.orderData[this.orderType]},{'getAccountBalance':{}}]);
	},
	submitTrade: function() {
		this.orderData[this.orderType].command="submit";
		this.orderData[this.orderType].action="Place Order";
		this.orderData[this.orderType].type=this.orderType;
		delete this.orderData[this.orderType]["currentAccount"];//.currentAccount=tk.qt.config.currentAccount;
		this.orderData[this.orderType].optionChainSymbol=this.symbol.stock;
		this.orderData[this.orderType].errorFlag=false;
		callAPI([{doTradeAction:this.orderData[this.orderType]}]);
	},
	updateQuote: function(data) {
		if (!data || !data.a_quotes || data.a_quotes[0].b_unknownSymbol) {
			dojo.publish('reset');
			return;
		}
		var type=data.a_quotes[0].s_quoteType.toLowerCase();
		if (this.orderType != type) {
            this.changeOrderType(type);
        }
		var noReset=!this.symbol[type];
		if (this.symbol[type] == data.a_quotes[0].s_symbol) {
            return;
        }
		if (!tk.qt.config.tradeInfo[this.orderType]) {
            tk.qt.config.tradeInfo[this.orderType] = {
                symbol: data.a_quotes[0].s_symbol
            };
        }
		this.symbol[type]=data.a_quotes[0].s_symbol;
		if (data.a_quotes[0].a_securityData.s_usSymbol) {// special case. usSymbols are stocks.
            this.symbol.stock = data.a_quotes[0].a_securityData.s_usSymbol;
        }
		if (!noReset) {
            dojo.publish('reset');
        }
	},
	changeOrderType: function(tab) {
		this.orderType=tab;
		if (!tk.qt.config.tradeInfo[this.orderType]) {
            tk.qt.config.tradeInfo[this.orderType] = {
                timeInForce: 0
            };
        }
		if (!this.orderData[this.orderType]) {
			if (this.actionData) {
                this.orderData[this.orderType] = dojo.fromJson(this.actionData);
                this.orderData[this.orderType].currentAccount = tk.qt.config.currentAccount;
                this.orderData[this.orderType].symbol = this.symbol[this.orderType] || '';
            } else {
                this.orderData[this.orderType] = {
                    timeInForce: 0
                };
            }
		}
		if (this.canPreview(this.orderData[this.orderType])) {
            dojo.publish('canPreviewOrder', [this.orderData[this.orderType]]);
        }
	},
	canPreview: function(d) {
        var invalidFieldNames = [];
        //chech required fields
        var required = ["amount", "transaction","ordType"];
        var l = required.length;
        for (var i= 0;i<l;i++){
            if (!d[required[i]] && d[required[i]]!=="") {
                invalidFieldNames.push(required[i]);
            }
        }    
		// Check pricing rules.
		if (d.ordType == 2 && d.limitPrice <= 0) {
            invalidFieldNames.push('limitPrice');
        }
        if (d.ordType == 3 && d.stopPrice <= 0) {
            invalidFieldNames.push('stopPrice');
        }
        if (d.ordType == 4 && (d.stopLimitPrice <= 0 && d.stopLimitLimitPrice <= 0)) {
            invalidFieldNames.push('stopLimitLimitPrice');
            invalidFieldNames.push('stopLimitPrice');
        }
        var allValid = !invalidFieldNames.length;//convert length to boolean
        if (!allValid) {
            dojo.publish('validationError', [invalidFieldNames]);
        }
		return allValid;
	},
	dirty: false,
	symbol: {},
	actionData: null,
	orderData: {}, // an array of order data.
	orderType: null // this will automatically be set when the default tab is selected.
});


dojo.subscribe('retrieveQuote',null,function(symbol,realtime,refresh){
	var now=(new Date().getTime());
//	if (!refresh && tk.qt.config.lastQuote==symbol && (now-tk.qt.config.lastQuoteTime)/1000<60) return; // Don't let duplicate quotes hit more than once a minute.
	var retryCount=2;
	var retries=0;
	if (!symbol || symbol == "") {
        return;
    }
	if (refresh) {
        tk.qt.config.lastChain = '';
    }
	symbol=symbol.toUpperCase();
	var delayedChainSubscription=null;
    var delayedQuoteSubscription=null;
	var chain=null;

/*	delayedQuoteSubscription=dojo.subscribe('getQuote',null,function(data) { // because of where this is declared, it will be the LAST function to be called on this published event.
		if (!data || (typeof data=='object' && !data.a_quotes)) {
			if (++retries<retryCount) {
				//console.log('toolbar.js: getQuote failed to return a record. Retry #'+retries);
				callAPI([{getQuote:{symbol:symbol}}]);
				return;
			}
			dojo.unsubscribe(delayedQuoteSubscription);
			delayedQuoteSubscription=null;
			return;
		}
		if (data.b_unknownSymbol) { // Bad symbol. Stop here.
			tk.qt.config.lastChain='';
			tk.qt.config.lastSymbol='';
			saveQtState();
			return;
		}
		if (data.b_systemError && ++retries<retryCount) { // if there was an error, retry.
			callAPI([{getQuote:{symbol:symbol,realTime:realtime||tk.qt.realtime||'N'}}]);
		}
		dojo.unsubscribe(delayedQuoteSubscription);
		delayedQuoteSubscription=null;
		tk.qt.config.lastQuoteTime=now;
		tk.qt.config.lastQuote=data.a_quotes[0].s_symbol;
		if (data.a_quotes[0].s_quoteType == 'Stock') { // if this was an option quote... we need to handle getting underlying chain.
			tk.qt.config.lastChain=data.a_quotes[0].s_symbol.toUpperCase();
		}
		saveQtState();
	});
	*/
	callAPI([{getQuote:{symbol:symbol,realTime:realtime||tk.qt.realtime||'N'}}]);
	saveQtState();
});


dojo.provide('tk.qt.toolbar');
dojo.provide('dojo.global');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.require("dijit.form.ComboButton");
dojo.require('tk.qt.error');
dojo.require('tk.qt.optionChainLookup');
dojo.require("tk.qt.snappy"); // Shows quote data
dojo.require('tk.qt.orderPreview'); // Shows order preview and trade submit confirmation data
dojo.require('tk.qt.orderConfirm'); // Shows order preview and trade submit confirmation data
// Register dojo filters in the global scope.
dojo.declare("tk.qt.toolbar", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: toolbarTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/toolbar.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,
	_stockText:'Trade Stocks',
	_optionText:'Trade Options',

//	iframeFix = (new UI.IframeShim()).positionUnder('qt'); // old style.. need to make a dojo object.
//	setInterval('iframeFix.positionUnder("qt")',500);
	constructor: function() {
		dojo.subscribe('getQuote',this,'update');
		dojo.subscribe('getChain',this,'update');
		dojo.subscribe('failedCall',this,'handleAPICallFailed');
//			dojo.subscribe('reset',this,'reset');
//			dojo.subscribe('selectTab',this,'selectTab');  ** Tab Selection is disabled. **
//	    	this.defaultText=(tk.qt.config.selectedTab=='option'?this._optionText:this._stockText); ** Tab Selection is disabled. **
		dojo.subscribe('showQT',this,'hideQuoteArea');
		dojo.subscribe('hideQT',this,'showQuoteArea');
	    dojo.subscribe('retrieveQuote',this,'retrieveQuote');
    },
	startup: function() {
    	if (!this.tradeButton) return;
		if (tk.qt.config.lastQuote && tk.qt.config.lastQuote!='') { // request updated quote on construction if the last page had a quote.
			dojo.publish('retrieveQuote',[tk.qt.config.lastQuote,tk.qt.config.realTime,true]); // if we have a symbol, then make a request.
		}
		if (dojo.byId('qtPopup')) // if we included the stockTrade widget, enable support for trading. Permissions handling too.
			this.showTrade = true;
		this.tradeButton.value=this.defaultText;
		this.visible=tk.qt.popup;
		if (this.visible) this.show();
	},
	reset: function() {
		tk.qt.config.lastChain='';
		tk.qt.config.lastQuote='';
		saveQtState();
	},
	retrieveQuote: function() {
		this.getQuoteButton.value="Retrieving ...";
		this.tradeButton.disabled=true;
		this.getQuoteButton.disabled=true;
	},
	handleRefreshButton: function() {
		dojo.publish('retrieveQuote',[this.refreshSymbol]);
	},
	getQuote: function() {
		if (this.symbol && this.symbol['value']) {
			dojo.publish('updateTradeData',[{symbol:this.symbol.value}]);
			dojo.publish('retrieveQuote',[this.symbol.value]); // if we have a symbol, then make a request.
		}
    },
    symbolKeyPress: function(e) { // e is suppose to be normalized.
		if (e.keyCode == dojo.keys.ENTER) {
			this.symbol.blur();
			// Commented out the next line since moving focus should cause the submit to occur.
			// It is left here if a case occurs when a browser does not trigger the blur event when
			// the focus is removed from the symbol entry field.
//			this.getQuote(); 
		}
	},
	symbolBlur: function(e) {
		if (this.symbol.value != this.currentSymbol) {
			this.getQuote();
		}
	},
    selectTab: function(t) {
    	if (t==='') {
	    	t=tk.qt.config.selectedTab||'stock';
    	} else {
    		this.defaultText=(t=='option'?this._optionText:this._stockText);
    	}
		tk.qt.config.selectedTab=t;
		saveQtState();
		this.tradeButton.value=this.defaultText;
    },
    handleAPICallFailed: function() {
		this.getQuoteButton.value="Go";
		this.getQuoteButton.disabled=false;
		if (this.tradeButton) this.tradeButton.disabled=false;
    },
    update: function(data,errors) {
		this.getQuoteButton.value="Go";
		this.getQuoteButton.disabled=false;
		this.tradeButton.disabled=false;
    	if (data==null || !data.a_quotes) return;
		this.quoteType=data.a_quotes[0]['s_quoteType'];
		this.refreshSymbol=data.a_quotes[0]['s_symbol'];
		if (this.quoteType=="Stock") {
			this.currentSymbol=data.a_quotes[0]['s_symbol'];
			this.refreshButton.style.display="none";
		} else {
			this.refreshButton.style.display="";
			this.currentSymbol=data.a_quotes[0].a_securityData['s_usSymbol'];
		}
		this.symbol.value=this.currentSymbol;
    	if (!data.a_quotes[0].b_unknownSymbol && this.symbol.value && this.showTrade) {// Verify that the return data contains a symbol.
    		show(this.tradeButton); // if so, show the trade button.
    	} else {
    		this.symbol.value=this.currentSymbol='';
    		//hide(this.tradeButton.domNode);
    		//if (!tk.qt.config.tearout) dojo.publish("hideQT");
    	}
    },
	openTrade: function(e) {
		hide(this.tradeButton);
		if (tk.qt.config.tearout) {
			//document.location='https://www.tradeking.com/Modules/Trading/Trade/Standard/'+this.quoteType+'/enter.php?symbol='+this.currentSymbol;
			window.open('#','QT');
			return;
		}
		dojo.publish('showQT');
	},
	closeTrade: function(e) {
		show(this.tradeButton);
		dojo.publish('hideQT');
	},
	show: function() {
		this.isVisible=true;
		show(this.domNode); // global function
	},
	restore: function() {
        this.show();
	},
	hide: function() {
		this.isVisible=false;
		hide(this.domNode); // global function
	},
	showQuoteArea: function() {
		if (tk.qt.config.tearout) {
//			hide(this.tradeButton);
		}
        show(this.quoteArea);
    },
	hideQuoteArea: function() {
        hide(this.quoteArea);
    },
	/* Properties */
	showTrade: false,
	opener: window.opener||window.top,
	lastQuickLink: '',
	symbol: null,
	quoteType: '',
	currentSymbol:'',
	tradeButton: null,
	quoteArea: null,
	getQuoteButton: null,
	refreshButton: {},
	visible: true,
	defaultText: 'Trade',
    currentHostname: currentHostname
});


var ldomain=document.domain;
if(/tradeking\.com$/i.test(document.domain)){
    ldomain='tradeking.com';
}else if (/scivantage\.com$/i.test(document.domain)){
	ldomain='scivantage.com';
}

function saveQtState() {
	return; // ignore all save states.
    if (tk.qt.config.loaded) {
        dojo.cookie('tkqtConfig',dojo.toJson(window.tk.qt.config),{domain:ldomain,path:'/'});
    } else if (!tk.qt.config.tearout) {
        dojo.cookie('tkqtConfig',dojo.toJson(window.tk.qt.config),{domain:ldomain,path:'/'});
    }
}

dojo.addOnUnload(window,function(e){
    dojo.cookie(location.href,dojo.toJson(window.tk.qt.config),{domain:ldomain,path:'/',expires:new Date((new Date()).getTime() + 5000 )}); 
});

function toggle(e) {
    dojo.style(e,'display',(dojo.style(e,'display')=='none'?'inline':'none'));
}
function toggleQT() {
    dojo.query("#qt-bg,.qt-snappy,.qt-in-input,.qt-in-link").forEach(toggle);
    return false;
}
function show(e) {
    dojo.style(e,'display','');
}
function hide(e) {
    dojo.style(e,'display','none');
}
function getToken() {
    return dojo.cookie('qtToken');
}

function callAPI(commandList){
    scrapChangeAccount=false;
    
    if (tk.qt.config.currentAccount!=null) {
	    commandList.unshift({
	        bufferedChangeAccount: {
	            accountIndex: tk.qt.config.currentAccount
	        }
	    });
    }
    dojo.io.script.get({
        callbackParamName: 'callback',
        url: 'https://www.tradeking.com/Modules/REST/api.php',
        preventCache: true,
        content: tk.qt.debug?{commandList:dojo.toJson(commandList),debug:tk.qt.debug,qtToken:getToken()}:{commandList:dojo.toJson(commandList),qtToken:getToken()},
        load: function(response, ioArgs) {
            if (!response||response=='') {
                dojo.publish("failedCall",["There was an error contacting the server. Please try agan."]);
            }
            //dojo.forEach(response.dConsole,function(l){console.log(l)}); // print out things set in dConsole array in results to the firebug console.
            delete response['dConsole'];
            var results;
            var iter=0;
            if (typeof(response)=='xml' && response.search('top.location')) { // handle redirects caused by sessiontimeouts and other backend reasons.
                if (tearout) {
                    window.opener.eval(response);
                    window.close();
                    return;
                }
                eval(response);
                return; 
            }
            var errors = response.errors;//assume that any errors listed are fatal, don't process the rest of the response
            if (typeof(errors) == 'object') { //token errors return a string, not an array of arrays
                while (results = response.results.shift()) {
                    if (!results) 
                        break;
                    for (var i in results) { // send out results for each
                        if (!i) 
                            break;
                        dojo.publish(i, [results[i], response.errors.shift(), results]);
                    }
                    iter++;
                }
                if (!iter) {
                    dojo.publish("failedCall",["There was an error contacting the server. Please try again.",tk.qt.config.popup?0x02:0xff]);
                }
            } else {
                dojo.publish("failedCall",[errors,tk.qt.config.popup?0x02:0xff]);
            }
        },
        error: function(response, ioArgs){
            return response;
        }
    });
}
LinkManager=(function(){
    /*
     *
     * name: arbitrary text used to identify the menu item.
     * text: visible text shown in menu
     * type: array of symbol types with which this menu item can be used. If omitted, this item is always shown.
     * link: base URL (without any query prarms) to go when clicked.
     * params: list of parameters by name and associated value. a value refixed with @ is used verbatim (minus the @)
     * publish: event for dojo to publish when this item is clicked. Good for function based menu items where link is javascript:void()
     * hover: function (full definition, not function name) that is run when mouse hovers over this menu item.
     * click: function that is run when this menu item is clicked.
     * out:   function that is run when the mouse moves out of this menu item
     * popup: if set, a popup window is opened, and the object parameters are passed directly to window.open as attributes
     */
    var linkList=[
/*
        {
            name:"ordStatus",
            text:"Order Status",
            type:["stock","option"],
            link:"https://www.tradeking.com/Modules/Trading/OrderStatus/orderStatus.php"
        },
*/
        {
            name:"idcchart",
            text:"Charts",
            type:["stock"],
            link:"https://www.tradeking.com/Modules/ThirdParty/idc.php",
            params:{page:'@charts',ulSymbol:'underlying',symbol:'symbol'}
        },
        {
            name:"idcnews",
            text:"News",
            type:["stock","option"],
            link:"https://www.tradeking.com/Modules/ThirdParty/idc.php",
            params:{page:'@news',baseSymbol:'underlying',symbol:'symbol'}
        },
        {
            name:"chain",
            text:"Chain",
            type:["stock","option"],
            link:"https://www.tradeking.com/Modules/Research/OptionChain/optionChain.php",
            params:{baseSymbol:'underlying'}
        }
    ];
     // type: type of symbol sent
     // symbol: the quoted symbol, could also be a full OSI symbol.
     // underlying: the underlying symbol, if available, otherwise null/undefined
     // page: the page to be filtered out of the link set
     // 
    return {getLinks:function(type,symbol,underlying,page,description) {
                    if (!underlying) {
                        underlying=symbol;
                    }
                    type=type.toLowerCase();
                    var p={};
                    p.symbol=symbol;
                    p.underlying=underlying;
                    p.type=type;
                    var ret=dojo.filter(dojo.map(linkList,function(x) {
                        if (x.type && x.type.indexOf(type)==-1) return null;
                        ret={
                        	    text:x.text,
                                link:x.link
                            };
                            // Build query string parameters.
                        var query=[];
                        var params=x.params;
                            
                        for(k in params) {
                            if (params[k].charAt(0)=='@')
                                query.push(k+'='+params[k].substring(1));
                            else query.push(k+'='+p[params[k]]);
                        }
                        if (query.length) ret.link+='?'+query.join("&");
                        return ret;
                    }),function(x){return x!=null});
                    return ret;
                } // getLinks
            }
})(); //end LinkManager function


var tkiConfigs={};
dojo.subscribe('getConfig',null,function(e) {
    dojo.mixin(tkiConfigs,e);
});

dojo.provide('tk.qt.filter');
dojo.mixin(tk.qt.filter,{ // defines custom filters for our templates.
        createDate: function(d){
            if (typeof d == 'string') d=parseInt(d)||d;
            return new Date(d);
        },
        midPrice: function(o) {
            o=o||{};
            return (parseInt(o.s_askPrice||0)+parseInt(o.s_bidPrice||0))/2;
        },
        match: function(s,r) {
            return (s||'').match(r)||s;
        }
});

dojo.provide('tk.qt.popup');
dojo.require("dojox.dtl");
dojo.require("dojox.dtl.Context");
dojo.require("dojox.dtl._Templated");
dojo.require("dijit._Widget");
dojo.require("dijit.form.Form");
dojo.require("dijit.layout.TabContainer");
dojo.require("tk.qt.stockTrade");
dojo.require("tk.qt.optionTrade");
dojo.require("tk.qt.orderPreview");
dojo.require('tk.qt.tradeWidget');
dojo.config.debugAtAllCosts=true;
dojo.declare("tk.qt.popup", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: popupTemplate,
    //templatePath: dojo.moduleUrl("tk.qt","templates/popup.html"),
    _dijitTemplateCompat: true,
	widgetsInTemplate: true,

	constructor: function() {
		dojo.subscribe('showQT',this,'show');
		dojo.subscribe('hideQT',this,'hide');
		dojo.subscribe('selectTab',this,'selectTab');
		dojo.subscribe('showPreviewTab',this,'showPreviewTab');
		dojo.subscribe('hidePreviewTab',this,'hidePreviewTab');
		dojo.subscribe('showErrorTab',this,'showErrorTab');
		dojo.subscribe('hideErrorTab',this,'hideErrorTab');
		this.tearout=window.tearout;
	},
	postCreate: function() { // This event happens before the browser has the chance to render. Hide if we aren't suppose to show.
		dojo.publish('selectTab',[tk.qt.config.selectedTab||'stock']);
	},
	startup: function() {
		if (tk.qt.noTrade) {
			console.log('popup backing out.. not rendering')
            return;
        }
		this.visible=tk.qt.config.popup;
		/*
		dojo.connect(this.tabs.tablist,'onSelectChild',function(w) { // select child
			dojo.publish('selectTab',[w.domNode.id.match(/(.+)Tab/)[1]]);
		})
		*/;
		if (this.visible) {
            dojo.publish('showQT');
        }
	},
	closeTrade: function(e) {
		dojo.publish('hideQT');
	},
	showPreviewTab: function(e) {
		this.lastTab='previewTab';
		this.tabs.selectChild('previewTab');
	},
	hidePreviewTab: function(e) {
//		if (this.lastTab) {
			this.tabs.selectChild('stockTab');
			this.lastTab='stockTab';
//		}
	},
	showErrorTab: function(e) {
		if (this.tabs.selectedChildWidget.id=='errorTab') return;
		this.lastTab=(this.tabs&&this.tabs.selectedChildWidget)?this.tabs.selectedChildWidget.id:'stockTab';
		if (!this.visible) {
			this.show();
			this.visible=false;
		}
		this.tabs.selectChild('errorTab');
	},
	hideErrorTab: function(e) {
		if (!this.visible) // this means that the error tab was shown when the popup was not... so we made it visible, and now we have to make it hide.
			this.hide();
		if (this.lastTab)
			this.tabs.selectChild(this.lastTab);
		this.lastTab=null;
	},
	selectTab: function(t) {
		if (!this.dorender) {
            return;
        }
    	if (t==='' || !t) { // it's blank, null or undefined.
	    	t=tk.qt.config.selectedTab||'stock';
    	}
		tk.qt.config.selectedTab=t;
		saveQtState();
		this.lastTab=t+'Tab';
		this.tabs.selectChild(this.lastTab);
	},
	show: function() {
		this.visible = true;
		tk.qt.config.popup=1;
		show(this.domNode); // global function
	},
	hide: function() {
		if (this.visible && this.tearout) {
            return window.close();
        }
		this.visible = false;
		tk.qt.config.popup=0;
		hide(this.domNode); // global function
	},
	popOut: function() {
		tk.qt.config.loaded=0; // we're unloading it.
		tk.qt.config.tearout=0;
		saveQtState();
		window.popupWindow=window.open('https://www.tradeking.com/Modules/Util/toolbar.php','QT','location=0,status=0,menu=0,width=720,height=250');
		tk.qt.config.tearout=1;
	},
	accountSelector: null,
	lastTab: null,
	visible: true,
	tearout: window.tearout,
	tabs: null
});

dojo.provide('tk.qt.AccountSelector');
dojo.declare("tk.qt.AccountSelector", [ dijit._Widget, dojox.dtl._Templated,dijit._Container], {
	templateString: '<div style="display: {{showMe}}"><form action="#"><select dojoAttachPoint="select" dojoAttachEvent="onchange: changeAccount">{% for key in accountList %}<option value="{{ key.value }}" {% ifequal current key.value %}selected="true"{% endifequal %}>{{ key.name }}</option>{% endfor %}</select></form></div>',
    _dijitTemplateCompat: true,
	widgetsInTemplate: false,
	accountList: [],
	constructor: function() {
		tk.qt.config.currentAccount=null;
		saveQtState();
		dojo.subscribe('getAccountList',this,'receivedAccountList');
		callAPI([{'getAccountList':{}}]);
	},
	changePageAccount: function() {
		var f=dojo.query('#currentAccount');
		if (!f || f.length===0) {
			callAPI([{'getAccountBalance':{}}]);
//			callAPI([{'changeAccount':{'accountIndex':this.current}},{'getAccountBalance':{}}]);
			return; // don't refresh page if there is no account selector to change.
		}
		f=f[0];
		f.selectedIndex=this.current;
		f.value=f.options[f.selectedIndex].value;
		if (!brsr.isIE) {
			var e = document.createEvent("HTMLEvents");
			e.initEvent('change',false,true);
			f.dispatchEvent(e);
		} else {
			f.form.submit(); // IE hack.. there is a better way somewhere... (over the rainbow, see the wizard)
		}
	},
	changeAccount: function(d) {
		d=d||window.event;
		var t=d.target;
		this.current=tk.qt.config.currentAccount=t.options.length>0?t.selectedIndex:0;
		saveQtState();
		this.changePageAccount();
	},
	currentAccount: function() {
		return this.current;
	},
	setCurrentAccount: function(e) {
		this.current=e;
	},
	rotate: function(a) { // turn an object [id:label,id:label] into: [{name:labelValue, value:idValue},{name:labelValue, value:idValue}]
		if (!a) {
            return [];
        }
		var b=[];
		for (i in a) {
			b.push({name:i,value:a[i]});
		}
		return b;
	},
	receivedAccountList: function(d){
		if (!d || typeof(d._currentAccount) == 'undefined') {
            return;
        }
//			alert('received Account List');
		this.current=tk.qt.config.currentAccount=d._currentAccount||0;
		delete d._currentAccount;
		this.accountList=this.rotate(d);
		if (this.accountList.length) this.showMe="";
		else this.showMe="none";
		this.render();
	},
	current: 0,
	showMe: 'none',
	select: null
});

