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 parent=null,properties=$A(arguments);
 if(Object.isFunction(properties[0]))
 parent=properties.shift();

 function klass(){
 this.initialize.apply(this,arguments);
}

 Object.extend(klass,Class.Methods);
 klass.superclass=parent;
 klass.subclasses=[];

 if(parent){
 var subclass=function(){};
 subclass.prototype=parent.prototype;
 klass.prototype=new subclass;
 parent.subclasses.push(klass);
}

 for(var i=0;i<properties.length;i++)
 klass.addMethods(properties[i]);

 if(!klass.prototype.initialize)
 klass.prototype.initialize=Prototype.emptyFunction;

 klass.prototype.constructor=klass;

 return klass;
}
};

Class.Methods={
 addMethods:function(source){
 var ancestor=this.superclass&&this.superclass.prototype;
 var properties=Object.keys(source);

 if(!Object.keys({toString:true}).length)
 properties.push("toString","valueOf");

 for(var i=0,length=properties.length;i<length;i++){
 var property=properties[i],value=source[property];
 if(ancestor&&Object.isFunction(value)&&
 value.argumentNames().first()=="$super"){
 var method=value,value=Object.extend((function(m){
 return function(){return ancestor[m].apply(this,arguments)};
})(property).wrap(method),{
 valueOf:function(){return method},
 toString:function(){return method.toString()}
});
}
 this.prototype[property]=value;
}

 return this;
}
};

var Abstract={};

Object.extend=function(destination,source){
 for(var property in source)
 destination[property]=source[property];
 return destination;
};

Object.extend(Object,{
 inspect:function(object){
 try{
 if(Object.isUndefined(object))return'undefined';
 if(object===null)return'null';
 return object.inspect?object.inspect():String(object);
}catch(e){
 if(e instanceof RangeError)return'...';
 throw e;
}
},

 toJSON:function(object){
 var type=typeof object;
 switch(type){
 case'undefined':
 case'function':
 case'unknown':return;
 case'boolean':return object.toString();
}

 if(object===null)return'null';
 if(object.toJSON)return object.toJSON();
 if(Object.isElement(object))return;

 var results=[];
 for(var property in object){
 var value=Object.toJSON(object[property]);
 if(!Object.isUndefined(value))
 results.push(property.toJSON()+': '+value);
}

 return'{'+results.join(', ')+'}';
},

 toQueryString:function(object){
 return $H(object).toQueryString();
},

 toHTML:function(object){
 return object&&object.toHTML?object.toHTML():String.interpret(object);
},

 keys:function(object){
 var keys=[];
 for(var property in object)
 keys.push(property);
 return keys;
},

 values:function(object){
 var values=[];
 for(var property in object)
 values.push(object[property]);
 return values;
},

 clone:function(object){
 return Object.extend({},object);
},

 isElement:function(object){
 return object&&object.nodeType==1;
},

 isArray:function(object){
 return!!(object&&object.join&&object.splice);
},

 isHash:function(object){
 return object instanceof Hash;
},

 isFunction:function(object){
 return typeof object=="function";
},

 isString:function(object){
 return typeof object=="string";
},

 isNumber:function(object){
 return typeof object=="number";
},

 isUndefined:function(object){
 return typeof object=="undefined";
}
});

Object.extend(Function.prototype,{
 argumentNames:function(){
 var names=this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
 return names.length==1&&!names[0]?[]:names;
},

 bind:function(){
 var __method=this,object=arguments[0];
 if(arguments.length<2){
 return!object?this:function(){
 return __method.apply(object,arguments);
}
}
 var args=$A(arguments);
 args.shift();
 return function(){
 return __method.apply(object,args.concat($A(arguments)));
}
},

 bindAsEventListener:function(){
 var __method=this,args=$A(arguments),object=args.shift();
 return function(event){
 return __method.apply(object,[event||window.event].concat(args));
}
},

 curry:function(){
 if(!arguments.length)return this;
 var __method=this,args=$A(arguments);
 return function(){
 return __method.apply(this,args.concat($A(arguments)));
}
},

 delay:function(){
 var __method=this,args=$A(arguments),timeout=args.shift()*1000;
 return window.setTimeout(function(){
 return __method.apply(__method,args);
},timeout);
},

 wrap:function(wrapper){
 var __method=this;
 return function(){
 return wrapper.apply(this,[__method.bind(this)].concat($A(arguments)));
}
},

 methodize:function(){
 if(this._methodized)return this._methodized;
 var __method=this;
 return this._methodized=function(){
 return __method.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 returnValue;

 for(var i=0,length=arguments.length;i<length;i++){
 var lambda=arguments[i];
 try{
 returnValue=lambda();
 break;
}catch(e){}
}

 return returnValue;
}
};

RegExp.prototype.match=RegExp.prototype.test;

RegExp.escape=function(str){
 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g,'\\$1');
};



var PeriodicalExecuter=Class.create({
 initialize:function(callback,frequency){
 this.callback=callback;
 this.frequency=frequency;
 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(value){
 return value==null?'':String(value);
},
 specialChar:{
'\b':'\\b',
'\t':'\\t',
'\n':'\\n',
'\f':'\\f',
'\r':'\\r',
'\\':'\\\\'
}
});

Object.extend(String.prototype,{
 gsub:function(pattern,replacement){
 var result='',source=this,match;
 replacement=arguments.callee.prepareReplacement(replacement);

 while(source.length>0){
 if(match=source.match(pattern)){
 result+=source.slice(0,match.index);
 result+=String.interpret(replacement(match));
 source=source.slice(match.index+match[0].length);
}else{
 result+=source,source='';
}
}
 return result;
},

 sub:function(pattern,replacement,count){
 replacement=this.gsub.prepareReplacement(replacement);
 count=Object.isUndefined(count)?1:count;

 return this.gsub(pattern,function(match){
 if(--count<0)return match[0];
 return replacement(match);
});
},

 scan:function(pattern,iterator){
 this.gsub(pattern,iterator);
 return String(this);
},

 truncate:function(length,truncation){
 length=length||30;
 truncation=Object.isUndefined(truncation)?'...':truncation;
 return this.length>length?
 this.slice(0,length-truncation.length)+truncation: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 matchAll=new RegExp(Prototype.ScriptFragment,'img');
 var matchOne=new RegExp(Prototype.ScriptFragment,'im');
 return(this.match(matchAll)||[]).map(function(scriptTag){
 return(scriptTag.match(matchOne)||['',''])[1];
});
},

 evalScripts:function(){
 return this.extractScripts().map(function(script){return eval(script)});
},

 escapeHTML:function(){
 var self=arguments.callee;
 self.text.data=this;
 return self.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(memo,node){return memo+node.nodeValue}):
 div.childNodes[0].nodeValue):'';
},

 toQueryParams:function(separator){
 var match=this.strip().match(/([^?#]*)(#.*)?$/);
 if(!match)return{};

 return match[1].split(separator||'&').inject({},function(hash,pair){
 if((pair=pair.split('='))[0]){
 var key=decodeURIComponent(pair.shift());
 var value=pair.length>1?pair.join('='):pair[0];
 if(value!=undefined)value=decodeURIComponent(value);

 if(key in hash){
 if(!Object.isArray(hash[key]))hash[key]=[hash[key]];
 hash[key].push(value);
}
 else hash[key]=value;
}
 return hash;
});
},

 toArray:function(){
 return this.split('');
},

 succ:function(){
 return this.slice(0,this.length-1)+
 String.fromCharCode(this.charCodeAt(this.length-1)+1);
},

 times:function(count){
 return count<1?'':new Array(count+1).join(this);
},

 camelize:function(){
 var parts=this.split('-'),len=parts.length;
 if(len==1)return parts[0];

 var camelized=this.charAt(0)=='-'
?parts[0].charAt(0).toUpperCase()+parts[0].substring(1)
:parts[0];

 for(var i=1;i<len;i++)
 camelized+=parts[i].charAt(0).toUpperCase()+parts[i].substring(1);

 return camelized;
},

 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(useDoubleQuotes){
 var escapedString=this.gsub(/[\x00-\x1f\\]/,function(match){
 var character=String.specialChar[match[0]];
 return character?character:'\\u00'+match[0].charCodeAt().toPaddedString(2,16);
});
 if(useDoubleQuotes)return'"'+escapedString.replace(/"/g,'\\"')+'"';
 return"'"+escapedString.replace(/'/g,'\\\'')+"'";
},

 toJSON:function(){
 return this.inspect(true);
},

 unfilterJSON:function(filter){
 return this.sub(filter||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(sanitize){
 var json=this.unfilterJSON();
 try{
 if(!sanitize||json.isJSON())return eval('('+json+')');
}catch(e){}
 throw new SyntaxError('Badly formed JSON string: '+this.inspect());
},

 include:function(pattern){
 return this.indexOf(pattern)>-1;
},

 startsWith:function(pattern){
 return this.indexOf(pattern)===0;
},

 endsWith:function(pattern){
 var d=this.length-pattern.length;
 return d>=0&&this.lastIndexOf(pattern)===d;
},

 empty:function(){
 return this=='';
},

 blank:function(){
 return/^\s*$/.test(this);
},

 interpolate:function(object,pattern){
 return new Template(this,pattern).evaluate(object);
}
});

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(replacement){
 if(Object.isFunction(replacement))return replacement;
 var template=new Template(replacement);
 return function(match){return template.evaluate(match)};
};

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(template,pattern){
 this.template=template.toString();
 this.pattern=pattern||Template.Pattern;
},

 evaluate:function(object){
 if(Object.isFunction(object.toTemplateReplacements))
 object=object.toTemplateReplacements();

 return this.template.gsub(this.pattern,function(match){
 if(object==null)return'';

 var before=match[1]||'';
 if(before=='\\')return match[2];

 var ctx=object,expr=match[3];
 var pattern=/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
 match=pattern.exec(expr);
 if(match==null)return before;

 while(match!=null){
 var comp=match[1].startsWith('[')?match[2].gsub('\\\\]',']'):match[1];
 ctx=ctx[comp];
 if(null==ctx||''==match[3])break;
 expr=expr.substring('['==match[3]?match[1].length:match[0].length);
 match=pattern.exec(expr);
}

 return before+String.interpret(ctx);
});
}
});
Template.Pattern=/(^|.|\r|\n)(#\{(.*?)\})/;

var $break={};

var Enumerable={
 each:function(iterator,context){
 var index=0;
 iterator=iterator.bind(context);
 try{
 this._each(function(value){
 iterator(value,index++);
});
}catch(e){
 if(e!=$break)throw e;
}
 return this;
},

 eachSlice:function(number,iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var index=-number,slices=[],array=this.toArray();
 while((index+=number)<array.length)
 slices.push(array.slice(index,index+number));
 return slices.collect(iterator,context);
},

 all:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result=true;
 this.each(function(value,index){
 result=result&&!!iterator(value,index);
 if(!result)throw $break;
});
 return result;
},

 any:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result=false;
 this.each(function(value,index){
 if(result=!!iterator(value,index))
 throw $break;
});
 return result;
},

 collect:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var results=[];
 this.each(function(value,index){
 results.push(iterator(value,index));
});
 return results;
},

 detect:function(iterator,context){
 iterator=iterator.bind(context);
 var result;
 this.each(function(value,index){
 if(iterator(value,index)){
 result=value;
 throw $break;
}
});
 return result;
},

 findAll:function(iterator,context){
 iterator=iterator.bind(context);
 var results=[];
 this.each(function(value,index){
 if(iterator(value,index))
 results.push(value);
});
 return results;
},

 grep:function(filter,iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var results=[];

 if(Object.isString(filter))
 filter=new RegExp(filter);

 this.each(function(value,index){
 if(filter.match(value))
 results.push(iterator(value,index));
});
 return results;
},

 include:function(object){
 if(Object.isFunction(this.indexOf))
 if(this.indexOf(object)!=-1)return true;

 var found=false;
 this.each(function(value){
 if(value==object){
 found=true;
 throw $break;
}
});
 return found;
},

 inGroupsOf:function(number,fillWith){
 fillWith=Object.isUndefined(fillWith)?null:fillWith;
 return this.eachSlice(number,function(slice){
 while(slice.length<number)slice.push(fillWith);
 return slice;
});
},

 inject:function(memo,iterator,context){
 iterator=iterator.bind(context);
 this.each(function(value,index){
 memo=iterator(memo,value,index);
});
 return memo;
},

 invoke:function(method){
 var args=$A(arguments).slice(1);
 return this.map(function(value){
 return value[method].apply(value,args);
});
},

 max:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result;
 this.each(function(value,index){
 value=iterator(value,index);
 if(result==null||value>=result)
 result=value;
});
 return result;
},

 min:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var result;
 this.each(function(value,index){
 value=iterator(value,index);
 if(result==null||value<result)
 result=value;
});
 return result;
},

 partition:function(iterator,context){
 iterator=iterator?iterator.bind(context):Prototype.K;
 var trues=[],falses=[];
 this.each(function(value,index){
(iterator(value,index)?
 trues:falses).push(value);
});
 return[trues,falses];
},

 pluck:function(property){
 var results=[];
 this.each(function(value){
 results.push(value[property]);
});
 return results;
},

 reject:function(iterator,context){
 iterator=iterator.bind(context);
 var results=[];
 this.each(function(value,index){
 if(!iterator(value,index))
 results.push(value);
});
 return results;
},

 sortBy:function(iterator,context){
 iterator=iterator.bind(context);
 return this.map(function(value,index){
 return{value:value,criteria:iterator(value,index)};
}).sort(function(left,right){
 var a=left.criteria,b=right.criteria;
 return a<b?-1:a>b?1:0;
}).pluck('value');
},

 toArray:function(){
 return this.map();
},

 zip:function(){
 var iterator=Prototype.K,args=$A(arguments);
 if(Object.isFunction(args.last()))
 iterator=args.pop();

 var collections=[this].concat(args).map($A);
 return this.map(function(value,index){
 return iterator(collections.pluck(index));
});
},

 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(iterable){
 if(!iterable)return[];
 if(iterable.toArray)return iterable.toArray();
 var length=iterable.length||0,results=new Array(length);
 while(length--)results[length]=iterable[length];
 return results;
}

if(Prototype.Browser.WebKit){
 $A=function(iterable){
 if(!iterable)return[];
 if(!(Object.isFunction(iterable)&&iterable=='[object NodeList]')&&
 iterable.toArray)return iterable.toArray();
 var length=iterable.length||0,results=new Array(length);
 while(length--)results[length]=iterable[length];
 return results;
};
}

Array.from=$A;

Object.extend(Array.prototype,Enumerable);

if(!Array.prototype._reverse)Array.prototype._reverse=Array.prototype.reverse;

Object.extend(Array.prototype,{
 _each:function(iterator){
 for(var i=0,length=this.length;i<length;i++)
 iterator(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(value){
 return value!=null;
});
},

 flatten:function(){
 return this.inject([],function(array,value){
 return array.concat(Object.isArray(value)?
 value.flatten():[value]);
});
},

 without:function(){
 var values=$A(arguments);
 return this.select(function(value){
 return!values.include(value);
});
},

 reverse:function(inline){
 return(inline!==false?this:this.toArray())._reverse();
},

 reduce:function(){
 return this.length>1?this:this[0];
},

 uniq:function(sorted){
 return this.inject([],function(array,value,index){
 if(0==index||(sorted?array.last()!=value:!array.include(value)))
 array.push(value);
 return array;
});
},

 intersect:function(array){
 return this.uniq().findAll(function(item){
 return array.detect(function(value){return item===value});
});
},

 clone:function(){
 return[].concat(this);
},

 size:function(){
 return this.length;
},

 inspect:function(){
 return'['+this.map(Object.inspect).join(', ')+']';
},

 toJSON:function(){
 var results=[];
 this.each(function(object){
 var value=Object.toJSON(object);
 if(!Object.isUndefined(value))results.push(value);
});
 return'['+results.join(', ')+']';
}
});


if(Object.isFunction(Array.prototype.forEach))
 Array.prototype._each=Array.prototype.forEach;

if(!Array.prototype.indexOf)Array.prototype.indexOf=function(item,i){
 i||(i=0);
 var length=this.length;
 if(i<0)i=length+i;
 for(;i<length;i++)
 if(this[i]===item)return i;
 return-1;
};

if(!Array.prototype.lastIndexOf)Array.prototype.lastIndexOf=function(item,i){
 i=isNaN(i)?this.length:(i<0?this.length+i:i)+1;
 var n=this.slice(0,i).reverse().indexOf(item);
 return(n<0)?n:i-n-1;
};

Array.prototype.toArray=Array.prototype.clone;

function $w(string){
 if(!Object.isString(string))return[];
 string=string.strip();
 return string?string.split(/\s+/):[];
}

if(Prototype.Browser.Opera){
 Array.prototype.concat=function(){
 var array=[];
 for(var i=0,length=this.length;i<length;i++)array.push(this[i]);
 for(var i=0,length=arguments.length;i<length;i++){
 if(Object.isArray(arguments[i])){
 for(var j=0,arrayLength=arguments[i].length;j<arrayLength;j++)
 array.push(arguments[i][j]);
}else{
 array.push(arguments[i]);
}
}
 return array;
};
}
Object.extend(Number.prototype,{
 toColorPart:function(){
 return this.toPaddedString(2,16);
},

 succ:function(){
 return this+1;
},

 times:function(iterator){
 $R(0,this,true).each(iterator);
 return this;
},

 toPaddedString:function(length,radix){
 var string=this.toString(radix||10);
 return'0'.times(length-string.length)+string;
},

 toJSON:function(){
 return isFinite(this)?this.toString():'null';
}
});

$w('abs round ceil floor').each(function(method){
 Number.prototype[method]=Math[method].methodize();
});
function $H(object){
 return new Hash(object);
};

var Hash=Class.create(Enumerable,(function(){

 function toQueryPair(key,value){
 if(Object.isUndefined(value))return key;
 return key+'='+encodeURIComponent(String.interpret(value));
}

 return{
 initialize:function(object){
 this._object=Object.isHash(object)?object.toObject():Object.clone(object);
},

 _each:function(iterator){
 for(var key in this._object){
 var value=this._object[key],pair=[key,value];
 pair.key=key;
 pair.value=value;
 iterator(pair);
}
},

 set:function(key,value){
 return this._object[key]=value;
},

 get:function(key){
 return this._object[key];
},

 unset:function(key){
 var value=this._object[key];
 delete this._object[key];
 return value;
},

 toObject:function(){
 return Object.clone(this._object);
},

 keys:function(){
 return this.pluck('key');
},

 values:function(){
 return this.pluck('value');
},

 index:function(value){
 var match=this.detect(function(pair){
 return pair.value===value;
});
 return match&&match.key;
},

 merge:function(object){
 return this.clone().update(object);
},

 update:function(object){
 return new Hash(object).inject(this,function(result,pair){
 result.set(pair.key,pair.value);
 return result;
});
},

 toQueryString:function(){
 return this.map(function(pair){
 var key=encodeURIComponent(pair.key),values=pair.value;

 if(values&&typeof values=='object'){
 if(Object.isArray(values))
 return values.map(toQueryPair.curry(key)).join('&');
}
 return toQueryPair(key,values);
}).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(start,end,exclusive){
 this.start=start;
 this.end=end;
 this.exclusive=exclusive;
},

 _each:function(iterator){
 var value=this.start;
 while(this.include(value)){
 iterator(value);
 value=value.succ();
}
},

 include:function(value){
 if(value<this.start)
 return false;
 if(this.exclusive)
 return value<this.end;
 return value<=this.end;
}
});

var $R=function(start,end,exclusive){
 return new ObjectRange(start,end,exclusive);
};

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(iterator){
 this.responders._each(iterator);
},

 register:function(responder){
 if(!this.include(responder))
 this.responders.push(responder);
},

 unregister:function(responder){
 this.responders=this.responders.without(responder);
},

 dispatch:function(callback,request,transport,json){
 this.each(function(responder){
 if(Object.isFunction(responder[callback])){
 try{
 responder[callback].apply(responder,[request,transport,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(options){
 this.options={
 method:'post',
 asynchronous:true,
 contentType:'application/x-www-form-urlencoded',
 encoding:'UTF-8',
 parameters:'',
 evalJSON:true,
 evalJS:true
};
 Object.extend(this.options,options||{});

 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,options){
 $super(options);
 this.transport=Ajax.getTransport();
 this.request(url);
},

 request:function(url){
 this.url=url;
 this.method=this.options.method;
 var params=Object.clone(this.options.parameters);

 if(!['get','post'].include(this.method)){

 params['_method']=this.method;
 this.method='post';
}

 this.parameters=params;

 if(params=Object.toQueryString(params)){

 if(this.method=='get')
 this.url+=(this.url.include('?')?'&':'?')+params;
 else if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
 params+='&_=';
}

 try{
 var response=new Ajax.Response(this);
 if(this.options.onCreate)this.options.onCreate(response);
 Ajax.Responders.dispatch('onCreate',this,response);

 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||params):null;
 this.transport.send(this.body);


 if(!this.options.asynchronous&&this.transport.overrideMimeType)
 this.onStateChange();

}
 catch(e){
 this.dispatchException(e);
}
},

 onStateChange:function(){
 var readyState=this.transport.readyState;
 if(readyState>1&&!((readyState==4)&&this._complete))
 this.respondToReadyState(this.transport.readyState);
},

 setRequestHeaders:function(){
 var headers={
'X-Requested-With':'XMLHttpRequest',
'X-Prototype-Version':Prototype.Version,
'Accept':'text/javascript, text/html, application/xml, text/xml, */*'
};

 if(this.method=='post'){
 headers['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)
 headers['Connection']='close';
}


 if(typeof this.options.requestHeaders=='object'){
 var extras=this.options.requestHeaders;

 if(Object.isFunction(extras.push))
 for(var i=0,length=extras.length;i<length;i+=2)
 headers[extras[i]]=extras[i+1];
 else
 $H(extras).each(function(pair){headers[pair.key]=pair.value});
}

 for(var name in headers)
 this.transport.setRequestHeader(name,headers[name]);
},

 success:function(){
 var status=this.getStatus();
 return!status||(status>=200&&status<300);
},

 getStatus:function(){
 try{



 return this.transport.status==1223?204:this.transport.status||0;
}catch(e){return 0}
},

 respondToReadyState:function(readyState){
 var state=Ajax.Request.Events[readyState],response=new Ajax.Response(this);

 if(state=='Complete'){
 var startAt=new Date();
 try{
 this._complete=true;
(this.options['on'+response.status]
||this.options['on'+(this.success()?'Success':'Failure')]
||Prototype.emptyFunction)(response,response.headerJSON);
}catch(e){
 this.dispatchException(e);
}finally{

 var processTime=(new Date()-startAt)/1000;
 if(processTime>.5){
 var durl=this.url.replace(/.*\/([^/?]*).*/,'$1');
 console.warn('Warning! '+durl+' took '+processTime+' seconds to process - this may be affecting useability.');
}
}

 var contentType=response.getHeader('Content-type');
 if(this.options.evalJS=='force'
||(this.options.evalJS&&this.isSameOrigin()&&contentType
&&contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
 this.evalResponse();
}

 try{
(this.options['on'+state]||Prototype.emptyFunction)(response,response.headerJSON);
 Ajax.Responders.dispatch('on'+state,this,response,response.headerJSON);
}catch(e){
 this.dispatchException(e);
}

 if(state=='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(exception){
(this.options.onException||Prototype.emptyFunction)(this,exception);
 Ajax.Responders.dispatch('onException',this,exception);
}
});

Ajax.Request.Events=
['Uninitialized','Loading','Loaded','Interactive','Complete'];

Ajax.Response=Class.create({
 initialize:function(request){
 this.request=request;
 var transport=this.transport=request.transport,
 readyState=this.readyState=transport.readyState;

 if((readyState>2&&!Prototype.Browser.IE)||readyState==4){
 this.status=this.getStatus();
 this.statusText=this.getStatusText();
 this.responseText=String.interpret(transport.responseText);
 this.headerJSON=this._getHeaderJSON();
}

 if(readyState==4){
 var xml=transport.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 options=this.request.options;
 if(!options.evalJSON||(options.evalJSON!='force'&&
!(this.getHeader('Content-type')||'').include('application/json'))||
 this.responseText.blank())
 return null;
 try{
 return this.responseText.evalJSON(options.sanitizeJSON||
!this.request.isSameOrigin());
}catch(e){
 this.request.dispatchException(e);
}
}
});

Ajax.Updater=Class.create(Ajax.Request,{
 initialize:function($super,container,url,options){
 this.container={
 success:(container.success||container),
 failure:(container.failure||(container.success?null:container))
};

 options=Object.clone(options);
 var onComplete=options.onComplete;
 options.onComplete=(function(response,json){
 this.updateContent(response.responseText);
 if(Object.isFunction(onComplete))onComplete(response,json);
}).bind(this);

 $super(url,options);
},

 updateContent:function(responseText){
 var receiver=this.container[this.success()?'success':'failure'],
 options=this.options;

 if(!options.evalScripts)responseText=responseText.stripScripts();

 if(receiver=$(receiver)){
 if(options.insertion){
 if(Object.isString(options.insertion)){
 var insertion={};insertion[options.insertion]=responseText;
 receiver.insert(insertion);
}
 else options.insertion(receiver,responseText);
}
 else receiver.update(responseText);
}
}
});

Ajax.PeriodicalUpdater=Class.create(Ajax.Base,{
 initialize:function($super,container,url,options){
 $super(options);
 this.onComplete=this.options.onComplete;

 this.frequency=(this.options.frequency||2);
 this.decay=(this.options.decay||1);

 this.updater={};
 this.container=container;
 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(response){
 if(this.options.decay){
 this.decay=(response.responseText==this.lastText?
 this.decay*this.options.decay:1);

 this.lastText=response.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 $(element){
 if(arguments.length>1){
 for(var i=0,elements=[],length=arguments.length;i<length;i++)
 elements.push($(arguments[i]));
 return elements;
}
 if(Object.isString(element))
 element=document.getElementById(element);
 return Element.extend(element);
}

if(Prototype.BrowserFeatures.XPath){
 document._getElementsByXPath=function(expression,parentElement){
 var results=[];
 var query=document.evaluate(expression,$(parentElement)||document,
 null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
 for(var i=0,length=query.snapshotLength;i<length;i++)
 results.push(Element.extend(query.snapshotItem(i)));
 return results;
};
}



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 element=this.Element;
 this.Element=function(tagName,attributes){
 attributes=attributes||{};
 tagName=tagName.toLowerCase();
 var cache=Element.cache;
 if(Prototype.Browser.IE&&attributes.name){
 tagName='<'+tagName+' name="'+attributes.name+'">';
 delete attributes.name;
 return Element.writeAttribute(document.createElement(tagName),attributes);
}
 if(!cache[tagName])cache[tagName]=Element.extend(document.createElement(tagName));
 return Element.writeAttribute(cache[tagName].cloneNode(false),attributes);
};
 Object.extend(this.Element,element||{});
}).call(window);

Element.cache={};

Element.Methods={
 visible:function(element){
 return $(element).style.display!='none';
},

 toggle:function(element){
 element=$(element);
 Element[Element.visible(element)?'hide':'show'](element);
 return element;
},

 hide:function(element){
 $(element).style.display='none';
 return element;
},

 show:function(element){
 $(element).style.display='';
 return element;
},

 remove:function(element){
 element=$(element);
 element.parentNode.removeChild(element);
 return element;
},

 update:function(element,content){
 element=$(element);
 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content))return element.update().insert(content);
 content=Object.toHTML(content);
 element.innerHTML=content.stripScripts();
 content.evalScripts.bind(content).defer();
 return element;
},

 replace:function(element,content){
 element=$(element);
 if(content&&content.toElement)content=content.toElement();
 else if(!Object.isElement(content)){
 content=Object.toHTML(content);
 var range=element.ownerDocument.createRange();
 range.selectNode(element);
 content.evalScripts.bind(content).defer();
 content=range.createContextualFragment(content.stripScripts());
}
 element.parentNode.replaceChild(content,element);
 return element;
},

 insert:function(element,insertions){
 element=$(element);

 if(Object.isString(insertions)||Object.isNumber(insertions)||
 Object.isElement(insertions)||(insertions&&(insertions.toElement||insertions.toHTML)))
 insertions={bottom:insertions};

 var content,insert,tagName,childNodes;

 for(var position in insertions){
 content=insertions[position];
 position=position.toLowerCase();
 insert=Element._insertionTranslations[position];

 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content)){
 insert(element,content);
 continue;
}

 content=Object.toHTML(content);

 tagName=((position=='before'||position=='after')
?element.parentNode:element).tagName.toUpperCase();

 childNodes=Element._getContentFromAnonymousElement(tagName,content.stripScripts());

 if(position=='top'||position=='after')childNodes.reverse();
 childNodes.each(insert.curry(element));

 content.evalScripts.bind(content).defer();
}

 return element;
},

 wrap:function(element,wrapper,attributes){
 element=$(element);
 if(Object.isElement(wrapper))
 $(wrapper).writeAttribute(attributes||{});
 else if(Object.isString(wrapper))wrapper=new Element(wrapper,attributes);
 else wrapper=new Element('div',wrapper);
 if(element.parentNode)
 element.parentNode.replaceChild(wrapper,element);
 wrapper.appendChild(element);
 return wrapper;
},

 inspect:function(element){
 element=$(element);
 var result='<'+element.tagName.toLowerCase();
 $H({'id':'id','className':'class'}).each(function(pair){
 var property=pair.first(),attribute=pair.last();
 var value=(element[property]||'').toString();
 if(value)result+=' '+attribute+'='+value.inspect(true);
});
 return result+'>';
},

 recursivelyCollect:function(element,property){
 element=$(element);
 var elements=[];
 while(element=element[property])
 if(element.nodeType==1)
 elements.push(Element.extend(element));
 return elements;
},

 ancestors:function(element){
 return $(element).recursivelyCollect('parentNode');
},

 descendants:function(element){
 return $(element).select("*");
},

 firstDescendant:function(element){
 element=$(element).firstChild;
 while(element&&element.nodeType!=1)element=element.nextSibling;
 return $(element);
},

 immediateDescendants:function(element){
 if(!(element=$(element).firstChild))return[];
 while(element&&element.nodeType!=1)element=element.nextSibling;
 if(element)return[element].concat($(element).nextSiblings());
 return[];
},

 previousSiblings:function(element){
 return $(element).recursivelyCollect('previousSibling');
},

 nextSiblings:function(element){
 return $(element).recursivelyCollect('nextSibling');
},

 siblings:function(element){
 element=$(element);
 return element.previousSiblings().reverse().concat(element.nextSiblings());
},

 match:function(element,selector){
 if(Object.isString(selector))
 selector=new Selector(selector);
 return selector.match($(element));
},

 up:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return $(element.parentNode);
 var ancestors=element.ancestors();
 return Object.isNumber(expression)?ancestors[expression]:
 Selector.findElement(ancestors,expression,index);
},

 down:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return element.firstDescendant();
 return Object.isNumber(expression)?element.descendants()[expression]:
 element.select(expression)[index||0];
},

 previous:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return $(Selector.handlers.previousElementSibling(element));
 var previousSiblings=element.previousSiblings();
 return Object.isNumber(expression)?previousSiblings[expression]:
 Selector.findElement(previousSiblings,expression,index);
},

 next:function(element,expression,index){
 element=$(element);
 if(arguments.length==1)return $(Selector.handlers.nextElementSibling(element));
 var nextSiblings=element.nextSiblings();
 return Object.isNumber(expression)?nextSiblings[expression]:
 Selector.findElement(nextSiblings,expression,index);
},

 select:function(){
 var args=$A(arguments),element=$(args.shift());
 return Selector.findChildElements(element,args);
},

 adjacent:function(){
 var args=$A(arguments),element=$(args.shift());
 return Selector.findChildElements(element.parentNode,args).without(element);
},

 identify:function(element){
 element=$(element);
 var id=element.readAttribute('id'),self=arguments.callee;
 if(id)return id;
 do{id='anonymous_element_'+self.counter++}while($(id));
 element.writeAttribute('id',id);
 return id;
},

 readAttribute:function(element,name){
 element=$(element);
 if(Prototype.Browser.IE){
 var t=Element._attributeTranslations.read;
 if(t.values[name])return t.values[name](element,name);
 if(t.names[name])name=t.names[name];
 if(name.include(':')){
 return(!element.attributes||!element.attributes[name])?null:
 element.attributes[name].value;
}
}
 return element.getAttribute(name);
},

 writeAttribute:function(element,name,value){
 element=$(element);
 var attributes={},t=Element._attributeTranslations.write;

 if(typeof name=='object')attributes=name;
 else attributes[name]=Object.isUndefined(value)?true:value;

 for(var attr in attributes){
 name=t.names[attr]||attr;
 value=attributes[attr];
 if(t.values[attr])name=t.values[attr](element,value);
 if(value===false||value===null)
 element.removeAttribute(name);
 else if(value===true)
 element.setAttribute(name,name);
 else element.setAttribute(name,value);
}
 return element;
},

 getHeight:function(element){
 return $(element).getDimensions().height;
},

 getWidth:function(element){
 return $(element).getDimensions().width;
},

 classNames:function(element){
 return new Element.ClassNames(element);
},

 hasClassName:function(element,className){
 if(!(element=$(element)))return;
 var elementClassName=element.className;
 return(elementClassName.length>0&&(elementClassName==className||
 new RegExp("(^|\\s)"+className+"(\\s|$)").test(elementClassName)));
},

 addClassName:function(element,className){
 if(!(element=$(element)))return;
 if(!element.hasClassName(className))
 element.className+=(element.className?' ':'')+className;
 return element;
},

 removeClassName:function(element,className){
 if(!(element=$(element)))return;
 element.className=element.className.replace(
 new RegExp("(^|\\s+)"+className+"(\\s+|$)"),' ').strip();
 return element;
},

 toggleClassName:function(element,className){
 if(!(element=$(element)))return;
 return element[element.hasClassName(className)?
'removeClassName':'addClassName'](className);
},


 cleanWhitespace:function(element){
 element=$(element);
 var node=element.firstChild;
 while(node){
 var nextNode=node.nextSibling;
 if(node.nodeType==3&&!/\S/.test(node.nodeValue))
 element.removeChild(node);
 node=nextNode;
}
 return element;
},

 empty:function(element){
 return $(element).innerHTML.blank();
},

 descendantOf:function(element,ancestor){
 element=$(element),ancestor=$(ancestor);
 var originalAncestor=ancestor;

 if(element.compareDocumentPosition)
 return(element.compareDocumentPosition(ancestor)&8)===8;

 if(element.sourceIndex&&!Prototype.Browser.Opera){
 var e=element.sourceIndex,a=ancestor.sourceIndex,
 nextAncestor=ancestor.nextSibling;
 if(!nextAncestor){
 do{ancestor=ancestor.parentNode;}
 while(!(nextAncestor=ancestor.nextSibling)&&ancestor.parentNode);
}
 if(nextAncestor&&nextAncestor.sourceIndex)
 return(e>a&&e<nextAncestor.sourceIndex);
}

 while(element=element.parentNode)
 if(element==originalAncestor)return true;
 return false;
},

 scrollTo:function(element){
 element=$(element);
 var pos=element.cumulativeOffset();
 window.scrollTo(pos[0],pos[1]);
 return element;
},

 getStyle:function(element,style){
 element=$(element);
 style=style=='float'?'cssFloat':style.camelize();
 var value=element.style[style];
 if(!value){
 var css=document.defaultView.getComputedStyle(element,null);
 value=css?css[style]:null;
}
 if(style=='opacity')return value?parseFloat(value):1.0;
 return value=='auto'?null:value;
},

 getOpacity:function(element){
 return $(element).getStyle('opacity');
},

 setStyle:function(element,styles){
 element=$(element);
 var elementStyle=element.style,match;
 if(Object.isString(styles)){
 element.style.cssText+=';'+styles;
 return styles.include('opacity')?
 element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]):element;
}
 for(var property in styles)
 if(property=='opacity')element.setOpacity(styles[property]);
 else
 elementStyle[(property=='float'||property=='cssFloat')?
(Object.isUndefined(elementStyle.styleFloat)?'cssFloat':'styleFloat'):
 property]=styles[property];

 return element;
},

 setOpacity:function(element,value){
 element=$(element);
 element.style.opacity=(value==1||value==='')?'':
(value<0.00001)?0:value;
 return element;
},

 getDimensions:function(element){
 element=$(element);
 var display=$(element).getStyle('display');
 if(display!='none'&&display!=null)
 return{width:element.offsetWidth,height:element.offsetHeight};



 var els=element.style;
 var originalVisibility=els.visibility;
 var originalPosition=els.position;
 var originalDisplay=els.display;
 els.visibility='hidden';
 els.position='absolute';
 els.display='block';
 var originalWidth=element.clientWidth;
 var originalHeight=element.clientHeight;
 els.display=originalDisplay;
 els.position=originalPosition;
 els.visibility=originalVisibility;
 return{width:originalWidth,height:originalHeight};
},

 makePositioned:function(element){
 element=$(element);
 var pos=Element.getStyle(element,'position');
 if(pos=='static'||!pos){
 element._madePositioned=true;
 element.style.position='relative';


 if(window.opera){
 element.style.top=0;
 element.style.left=0;
}
}
 return element;
},

 undoPositioned:function(element){
 element=$(element);
 if(element._madePositioned){
 element._madePositioned=undefined;
 element.style.position=
 element.style.top=
 element.style.left=
 element.style.bottom=
 element.style.right='';
}
 return element;
},

 makeClipping:function(element){
 element=$(element);
 if(element._overflow)return element;
 element._overflow=Element.getStyle(element,'overflow')||'auto';
 if(element._overflow!=='hidden')
 element.style.overflow='hidden';
 return element;
},

 undoClipping:function(element){
 element=$(element);
 if(!element._overflow)return element;
 element.style.overflow=element._overflow=='auto'?'':element._overflow;
 element._overflow=null;
 return element;
},

 cumulativeOffset:function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;
 element=element.offsetParent;
}while(element);
 return Element._returnOffset(valueL,valueT);
},

 positionedOffset:function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;
 element=element.offsetParent;
 if(element){
 if(element.tagName=='BODY')break;
 var p=Element.getStyle(element,'position');
 if(p!=='static')break;
}
}while(element);
 return Element._returnOffset(valueL,valueT);
},

 absolutize:function(element){
 element=$(element);
 if(element.getStyle('position')=='absolute')return;


 var offsets=element.positionedOffset();
 var top=offsets[1];
 var left=offsets[0];
 var width=element.clientWidth;
 var height=element.clientHeight;

 element._originalLeft=left-parseFloat(element.style.left||0);
 element._originalTop=top-parseFloat(element.style.top||0);
 element._originalWidth=element.style.width;
 element._originalHeight=element.style.height;

 element.style.position='absolute';
 element.style.top=top+'px';
 element.style.left=left+'px';
 element.style.width=width+'px';
 element.style.height=height+'px';
 return element;
},

 relativize:function(element){
 element=$(element);
 if(element.getStyle('position')=='relative')return;


 element.style.position='relative';
 var top=parseFloat(element.style.top||0)-(element._originalTop||0);
 var left=parseFloat(element.style.left||0)-(element._originalLeft||0);

 element.style.top=top+'px';
 element.style.left=left+'px';
 element.style.height=element._originalHeight;
 element.style.width=element._originalWidth;
 return element;
},

 cumulativeScrollOffset:function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.scrollTop||0;
 valueL+=element.scrollLeft||0;
 element=element.parentNode;
}while(element);
 return Element._returnOffset(valueL,valueT);
},

 getOffsetParent:function(element){
 if(element.offsetParent)return $(element.offsetParent);
 if(element==document.body)return $(element);

 while((element=element.parentNode)&&element!=document.body)
 if(Element.getStyle(element,'position')!='static')
 return $(element);

 return $(document.body);
},

 viewportOffset:function(forElement){
 var valueT=0,valueL=0;

 var element=forElement;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;


 if(element.offsetParent==document.body&&
 Element.getStyle(element,'position')=='absolute')break;

}while(element=element.offsetParent);

 element=forElement;
 do{
 if(!Prototype.Browser.Opera||element.tagName=='BODY'){
 valueT-=element.scrollTop||0;
 valueL-=element.scrollLeft||0;
}
}while(element=element.parentNode);

 return Element._returnOffset(valueL,valueT);
},

 clonePosition:function(element,source){
 var options=Object.extend({
 setLeft:true,
 setTop:true,
 setWidth:true,
 setHeight:true,
 offsetTop:0,
 offsetLeft:0
},arguments[2]||{});


 source=$(source);
 var p=source.viewportOffset();


 element=$(element);
 var delta=[0,0];
 var parent=null;


 if(Element.getStyle(element,'position')=='absolute'){
 parent=element.getOffsetParent();
 delta=parent.viewportOffset();
}


 if(parent==document.body){
 delta[0]-=document.body.offsetLeft;
 delta[1]-=document.body.offsetTop;
}


 if(options.setLeft)element.style.left=(p[0]-delta[0]+options.offsetLeft)+'px';
 if(options.setTop)element.style.top=(p[1]-delta[1]+options.offsetTop)+'px';
 if(options.setWidth)element.style.width=source.offsetWidth+'px';
 if(options.setHeight)element.style.height=source.offsetHeight+'px';
 return element;
}
};

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(proceed,element,style){
 switch(style){
 case'left':case'top':case'right':case'bottom':
 if(proceed(element,'position')==='static')return null;
 case'height':case'width':

 if(!Element.visible(element))return null;



 var dim=parseInt(proceed(element,style),10);

 if(dim!==element['offset'+style.capitalize()])
 return dim+'px';

 var properties;
 if(style==='height'){
 properties=['border-top-width','padding-top',
'padding-bottom','border-bottom-width'];
}
 else{
 properties=['border-left-width','padding-left',
'padding-right','border-right-width'];
}
 return properties.inject(dim,function(memo,property){
 var val=proceed(element,property);
 return val===null?memo:memo-parseInt(val,10);
})+'px';
 default:return proceed(element,style);
}
}
);

 Element.Methods.readAttribute=Element.Methods.readAttribute.wrap(
 function(proceed,element,attribute){
 if(attribute==='title')return element.title;
 return proceed(element,attribute);
}
);
}

else if(Prototype.Browser.IE){


 Element.Methods.getOffsetParent=Element.Methods.getOffsetParent.wrap(
 function(proceed,element){
 element=$(element);
 var position=element.getStyle('position');
 if(position!=='static')return proceed(element);
 element.setStyle({position:'relative'});
 var value=proceed(element);
 element.setStyle({position:position});
 return value;
}
);

 $w('positionedOffset viewportOffset').each(function(method){
 Element.Methods[method]=Element.Methods[method].wrap(
 function(proceed,element){
 element=$(element);
 var position=element.getStyle('position');
 if(position!=='static')return proceed(element);


 var offsetParent=element.getOffsetParent();
 if(offsetParent&&offsetParent.getStyle('position')==='fixed')
 offsetParent.setStyle({zoom:1});
 element.setStyle({position:'relative'});
 var value=proceed(element);
 element.setStyle({position:position});
 return value;
}
);
});

 Element.Methods.getStyle=function(element,style){
 element=$(element);
 style=(style=='float'||style=='cssFloat')?'styleFloat':style.camelize();
 var value=element.style[style];
 if(!value&&element.currentStyle)value=element.currentStyle[style];

 if(style=='opacity'){
 if(value=(element.getStyle('filter')||'').match(/alpha\(opacity=(.*)\)/))
 if(value[1])return parseFloat(value[1])/100;
 return 1.0;
}

 if(value=='auto'){
 if((style=='width'||style=='height')&&(element.getStyle('display')!='none'))
 return element['offset'+style.capitalize()]+'px';
 return null;
}
 return value;
};

 Element.Methods.setOpacity=function(element,value){
 function stripAlpha(filter){
 return filter.replace(/alpha\([^\)]*\)/gi,'');
}
 element=$(element);
 var currentStyle=element.currentStyle;
 if((currentStyle&&!currentStyle.hasLayout)||
(!currentStyle&&element.style.zoom=='normal'))
 element.style.zoom=1;

 var filter=element.getStyle('filter'),style=element.style;
 if(value==1||value===''){
(filter=stripAlpha(filter))?
 style.filter=filter:style.removeAttribute('filter');
 return element;
}else if(value<0.00001)value=0;
 style.filter=stripAlpha(filter)+
'alpha(opacity='+(value*100)+')';
 return element;
};

 Element._attributeTranslations={
 read:{
 names:{
'class':'className',
'for':'htmlFor'
},
 values:{
 _getAttr:function(element,attribute){
 return element.getAttribute(attribute,2);
},
 _getAttrNode:function(element,attribute){
 var node=element.getAttributeNode(attribute);
 return node?node.value:"";
},
 _getEv:function(element,attribute){
 attribute=element.getAttribute(attribute);
 return attribute?attribute.toString().slice(23,-2):null;
},
 _flag:function(element,attribute){
 return $(element).hasAttribute(attribute)?attribute:null;
},
 style:function(element){
 return element.style.cssText.toLowerCase();
},
 title:function(element){
 return element.title;
}
}
}
};

 Element._attributeTranslations.write={
 names:Object.extend({
 cellpadding:'cellPadding',
 cellspacing:'cellSpacing'
},Element._attributeTranslations.read.names),
 values:{
 checked:function(element,value){
 element.checked=!!value;
},

 style:function(element,value){
 element.style.cssText=value?value:'';
}
}
};

 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(element,value){
 element=$(element);
 element.style.opacity=(value==1)?0.999999:
(value==='')?'':(value<0.00001)?0:value;
 return element;
};
}

else if(Prototype.Browser.WebKit){
 Element.Methods.setOpacity=function(element,value){
 element=$(element);
 element.style.opacity=(value==1||value==='')?'':
(value<0.00001)?0:value;

 if(value==1)
 if(element.tagName=='IMG'&&element.width){
 element.width++;element.width--;
}else try{
 var n=document.createTextNode(' ');
 element.appendChild(n);
 element.removeChild(n);
}catch(e){}

 return element;
};




 Element.Methods.cumulativeOffset=function(element){
 var valueT=0,valueL=0;
 do{
 valueT+=element.offsetTop||0;
 valueL+=element.offsetLeft||0;
 if(element.offsetParent==document.body)
 if(Element.getStyle(element,'position')=='absolute')break;

 element=element.offsetParent;
}while(element);

 return Element._returnOffset(valueL,valueT);
};
}

if(Prototype.Browser.IE||Prototype.Browser.Opera){

 Element.Methods.update=function(element,content){
 element=$(element);

 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content))return element.update().insert(content);

 content=Object.toHTML(content);
 var tagName=element.tagName.toUpperCase();

 if(tagName in Element._insertionTranslations.tags){
 $A(element.childNodes).each(function(node){element.removeChild(node)});
 Element._getContentFromAnonymousElement(tagName,content.stripScripts())
.each(function(node){element.appendChild(node)});
}
 else element.innerHTML=content.stripScripts();

 content.evalScripts.bind(content).defer();
 return element;
};
}

if('outerHTML'in document.createElement('div')){
 Element.Methods.replace=function(element,content){
 element=$(element);

 if(content&&content.toElement)content=content.toElement();
 if(Object.isElement(content)){
 element.parentNode.replaceChild(content,element);
 return element;
}

 content=Object.toHTML(content);
 var parent=element.parentNode,tagName=parent.tagName.toUpperCase();

 if(Element._insertionTranslations.tags[tagName]){
 var nextSibling=element.next();
 var fragments=Element._getContentFromAnonymousElement(tagName,content.stripScripts());
 parent.removeChild(element);
 if(nextSibling)
 fragments.each(function(node){parent.insertBefore(node,nextSibling)});
 else
 fragments.each(function(node){parent.appendChild(node)});
}
 else element.outerHTML=content.stripScripts();

 content.evalScripts.bind(content).defer();
 return element;
};
}

Element._returnOffset=function(l,t){
 var result=[l,t];
 result.left=l;
 result.top=t;
 return result;
};

Element._getContentFromAnonymousElement=function(tagName,html){
 var div=new Element('div'),t=Element._insertionTranslations.tags[tagName];
 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(element,node){
 element.parentNode.insertBefore(node,element);
},
 top:function(element,node){
 element.insertBefore(node,element.firstChild);
},
 bottom:function(element,node){
 element.appendChild(node);
},
 after:function(element,node){
 element.parentNode.insertBefore(node,element.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(element,attribute){
 attribute=Element._attributeTranslations.has[attribute]||attribute;
 var node=$(element).getAttributeNode(attribute);
 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 Methods={},ByTag=Element.Methods.ByTag;

 var extend=Object.extend(function(element){
 if(!element||element._extendedByPrototype||
 element.nodeType!=1||element==window)return element;

 var methods=Object.clone(Methods),
 tagName=element.tagName,property,value;


 if(ByTag[tagName])Object.extend(methods,ByTag[tagName]);

 for(property in methods){
 value=methods[property];
 if(Object.isFunction(value)&&!(property in element))
 element[property]=value.methodize();
}

 element._extendedByPrototype=Prototype.emptyFunction;
 return element;

},{
 refresh:function(){

 if(!Prototype.BrowserFeatures.ElementExtensions){
 Object.extend(Methods,Element.Methods);
 Object.extend(Methods,Element.Methods.Simulated);
}
}
});

 extend.refresh();
 return extend;
})();

Element.hasAttribute=function(element,attribute){
 if(element.hasAttribute)return element.hasAttribute(attribute);
 return Element.Methods.Simulated.hasAttribute(element,attribute);
};

Element.addMethods=function(methods){
 var F=Prototype.BrowserFeatures,T=Element.Methods.ByTag;

 if(!methods){
 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 tagName=methods;
 methods=arguments[1];
}

 if(!tagName)Object.extend(Element.Methods,methods||{});
 else{
 if(Object.isArray(tagName))tagName.each(extend);
 else extend(tagName);
}

 function extend(tagName){
 tagName=tagName.toUpperCase();
 if(!Element.Methods.ByTag[tagName])
 Element.Methods.ByTag[tagName]={};
 Object.extend(Element.Methods.ByTag[tagName],methods);
}

 function copy(methods,destination,onlyIfAbsent){
 onlyIfAbsent=onlyIfAbsent||false;
 for(var property in methods){
 var value=methods[property];
 if(!Object.isFunction(value))continue;
 if(!onlyIfAbsent||!(property in destination))
 destination[property]=value.methodize();
}
}

 function findDOMClass(tagName){
 var klass;
 var trans={
"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(trans[tagName])klass='HTML'+trans[tagName]+'Element';
 if(window[klass])return window[klass];
 klass='HTML'+tagName+'Element';
 if(window[klass])return window[klass];
 klass='HTML'+tagName.capitalize()+'Element';
 if(window[klass])return window[klass];

 window[klass]={};
 window[klass].prototype=document.createElement(tagName).__proto__;
 return window[klass];
}

 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 klass=findDOMClass(tag);
 if(Object.isUndefined(klass))continue;
 copy(T[tag],klass.prototype);
}
}

 Object.extend(Element,Element.Methods);
 delete Element.ByTag;

 if(Element.extend.refresh)Element.extend.refresh();
 Element.cache={};
};

document.viewport={
 getDimensions:function(){
 var dimensions={};
 var B=Prototype.Browser;
 $w('width height').each(function(d){
 var D=d.capitalize();
 dimensions[d]=(B.WebKit&&!document.evaluate)?self['inner'+D]:
(B.Opera)?document.body['client'+D]:document.documentElement['client'+D];
});
 return dimensions;
},

 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(expression){
 this.expression=expression.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(element){
 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(element);
}
}
}
}

 var match=true,name,matches;
 for(var i=0,token;token=this.tokens[i];i++){
 name=token[0],matches=token[1];
 if(!Selector.assertions[name](element,matches)){
 match=false;break;
}
}

 return match;
},

 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 exclusion=[];
 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);
 exclusion.push("("+v.substring(1,v.length-1)+")");
 e=e.replace(m[0],'');
 break;
}
}
}
 return"[not("+exclusion.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(fragment,m){
 var mm,formula=m[6],predicate;
 if(formula=='even')formula='2n+0';
 if(formula=='odd')formula='2n+1';
 if(mm=formula.match(/^(\d+)$/))
 return'['+fragment+"= "+mm[1]+']';
 if(mm=formula.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;
 predicate="[((#{fragment} - #{b}) mod #{a} = 0) and "+
"((#{fragment} - #{b}) div #{a} >= 0)]";
 return new Template(predicate).evaluate({
 fragment:fragment,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(element,matches){
 return matches[1].toUpperCase()==element.tagName.toUpperCase();
},

 className:function(element,matches){
 return Element.hasClassName(element,matches[1]);
},

 id:function(element,matches){
 return element.id===matches[1];
},

 attrPresence:function(element,matches){
 return Element.hasAttribute(element,matches[1]);
},

 attr:function(element,matches){
 var nodeValue=Element.readAttribute(element,matches[1]);
 return nodeValue&&Selector.operators[matches[2]](nodeValue,matches[5]||matches[6]);
}
},

 handlers:{


 concat:function(a,b){
 for(var i=0,node;node=b[i];i++)
 a.push(node);
 return a;
},


 mark:function(nodes){
 var _true=Prototype.emptyFunction;
 for(var i=0,node;node=nodes[i];i++)
 node._countedByPrototype=_true;
 return nodes;
},

 unmark:function(nodes){
 for(var i=0,node;node=nodes[i];i++)
 node._countedByPrototype=undefined;
 return nodes;
},




 index:function(parentNode,reverse,ofType){
 parentNode._countedByPrototype=Prototype.emptyFunction;
 if(reverse){
 for(var nodes=parentNode.childNodes,i=nodes.length-1,j=1;i>=0;i--){
 var node=nodes[i];
 if(node.nodeType==1&&(!ofType||node._countedByPrototype))node.nodeIndex=j++;
}
}else{
 for(var i=0,j=1,nodes=parentNode.childNodes;node=nodes[i];i++)
 if(node.nodeType==1&&(!ofType||node._countedByPrototype))node.nodeIndex=j++;
}
},


 unique:function(nodes){
 if(nodes.length==0)return nodes;
 var results=[],n;
 for(var i=0,l=nodes.length;i<l;i++)
 if(!(n=nodes[i])._countedByPrototype){
 n._countedByPrototype=Prototype.emptyFunction;
 results.push(Element.extend(n));
}
 return Selector.handlers.unmark(results);
},


 descendant:function(nodes){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++)
 h.concat(results,node.getElementsByTagName('*'));
 return results;
},

 child:function(nodes){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++){
 for(var j=0,child;child=node.childNodes[j];j++)
 if(child.nodeType==1&&child.tagName!='!')results.push(child);
}
 return results;
},

 adjacent:function(nodes){
 for(var i=0,results=[],node;node=nodes[i];i++){
 var next=this.nextElementSibling(node);
 if(next)results.push(next);
}
 return results;
},

 laterSibling:function(nodes){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++)
 h.concat(results,Element.nextSiblings(node));
 return results;
},

 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(nodes,root,tagName,combinator){
 var uTagName=tagName.toUpperCase();
 var results=[],h=Selector.handlers;
 if(nodes){
 if(combinator){

 if(combinator=="descendant"){
 for(var i=0,node;node=nodes[i];i++)
 h.concat(results,node.getElementsByTagName(tagName));
 return results;
}else nodes=this[combinator](nodes);
 if(tagName=="*")return nodes;
}
 for(var i=0,node;node=nodes[i];i++)
 if(node.tagName.toUpperCase()===uTagName)results.push(node);
 return results;
}else return root.getElementsByTagName(tagName);
},

 id:function(nodes,root,id,combinator){
 var targetNode=$(id),h=Selector.handlers;
 if(!targetNode)return[];
 if(!nodes&&root==document)return[targetNode];
 if(nodes){
 if(combinator){
 if(combinator=='child'){
 for(var i=0,node;node=nodes[i];i++)
 if(targetNode.parentNode==node)return[targetNode];
}else if(combinator=='descendant'){
 for(var i=0,node;node=nodes[i];i++)
 if(Element.descendantOf(targetNode,node))return[targetNode];
}else if(combinator=='adjacent'){
 for(var i=0,node;node=nodes[i];i++)
 if(Selector.handlers.previousElementSibling(targetNode)==node)
 return[targetNode];
}else nodes=h[combinator](nodes);
}
 for(var i=0,node;node=nodes[i];i++)
 if(node==targetNode)return[targetNode];
 return[];
}
 return(targetNode&&Element.descendantOf(targetNode,root))?[targetNode]:[];
},

 className:function(nodes,root,className,combinator){
 if(nodes&&combinator)nodes=this[combinator](nodes);
 return Selector.handlers.byClassName(nodes,root,className);
},

 byClassName:function(nodes,root,className){
 if(!nodes)nodes=Selector.handlers.descendant([root]);
 var needle=' '+className+' ';
 for(var i=0,results=[],node,nodeClassName;node=nodes[i];i++){
 nodeClassName=node.className;
 if(nodeClassName.length==0)continue;
 if(nodeClassName==className||(' '+nodeClassName+' ').include(needle))
 results.push(node);
}
 return results;
},

 attrPresence:function(nodes,root,attr,combinator){
 if(!nodes)nodes=root.getElementsByTagName("*");
 if(nodes&&combinator)nodes=this[combinator](nodes);
 var results=[];
 for(var i=0,node;node=nodes[i];i++)
 if(Element.hasAttribute(node,attr))results.push(node);
 return results;
},

 attr:function(nodes,root,attr,value,operator,combinator){
 if(!nodes)nodes=root.getElementsByTagName("*");
 if(nodes&&combinator)nodes=this[combinator](nodes);
 var handler=Selector.operators[operator],results=[];
 for(var i=0,node;node=nodes[i];i++){
 var nodeValue=Element.readAttribute(node,attr);
 if(nodeValue===null)continue;
 if(handler(nodeValue,value))results.push(node);
}
 return results;
},

 pseudo:function(nodes,name,value,root,combinator){
 if(nodes&&combinator)nodes=this[combinator](nodes);
 if(!nodes)nodes=root.getElementsByTagName("*");
 return Selector.pseudos[name](nodes,value,root);
}
},

 pseudos:{
'first-child':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++){
 if(Selector.handlers.previousElementSibling(node))continue;
 results.push(node);
}
 return results;
},
'last-child':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++){
 if(Selector.handlers.nextElementSibling(node))continue;
 results.push(node);
}
 return results;
},
'only-child':function(nodes,value,root){
 var h=Selector.handlers;
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(!h.previousElementSibling(node)&&!h.nextElementSibling(node))
 results.push(node);
 return results;
},
'nth-child':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root);
},
'nth-last-child':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root,true);
},
'nth-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root,false,true);
},
'nth-last-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,formula,root,true,true);
},
'first-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,"1",root,false,true);
},
'last-of-type':function(nodes,formula,root){
 return Selector.pseudos.nth(nodes,"1",root,true,true);
},
'only-of-type':function(nodes,formula,root){
 var p=Selector.pseudos;
 return p['last-of-type'](p['first-of-type'](nodes,formula,root),formula,root);
},


 getIndices:function(a,b,total){
 if(a==0)return b>0?[b]:[];
 return $R(1,total).inject([],function(memo,i){
 if(0==(i-b)%a&&(i-b)/a>=0)memo.push(i);
 return memo;
});
},


 nth:function(nodes,formula,root,reverse,ofType){
 if(nodes.length==0)return[];
 if(formula=='even')formula='2n+0';
 if(formula=='odd')formula='2n+1';
 var h=Selector.handlers,results=[],indexed=[],m;
 h.mark(nodes);
 for(var i=0,node;node=nodes[i];i++){
 if(!node.parentNode._countedByPrototype){
 h.index(node.parentNode,reverse,ofType);
 indexed.push(node.parentNode);
}
}
 if(formula.match(/^\d+$/)){
 formula=Number(formula);
 for(var i=0,node;node=nodes[i];i++)
 if(node.nodeIndex==formula)results.push(node);
}else if(m=formula.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 indices=Selector.pseudos.getIndices(a,b,nodes.length);
 for(var i=0,node,l=indices.length;node=nodes[i];i++){
 for(var j=0;j<l;j++)
 if(node.nodeIndex==indices[j])results.push(node);
}
}
 h.unmark(nodes);
 h.unmark(indexed);
 return results;
},

'empty':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++){

 if(node.tagName=='!'||(node.firstChild&&!node.innerHTML.match(/^\s*$/)))continue;
 results.push(node);
}
 return results;
},

'not':function(nodes,selector,root){
 var h=Selector.handlers,selectorType,m;
 var exclusions=new Selector(selector).findElements(root);
 h.mark(exclusions);
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(!node._countedByPrototype)results.push(node);
 h.unmark(exclusions);
 return results;
},

'enabled':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(!node.disabled)results.push(node);
 return results;
},

'disabled':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(node.disabled)results.push(node);
 return results;
},

'checked':function(nodes,value,root){
 for(var i=0,results=[],node;node=nodes[i];i++)
 if(node.checked)results.push(node);
 return results;
}
},

 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(expression){
 var expressions=[];
 expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m){
 expressions.push(m[1].strip());
});
 return expressions;
},

 matchElements:function(elements,expression){
 var matches=$$(expression),h=Selector.handlers;
 h.mark(matches);
 for(var i=0,results=[],element;element=elements[i];i++)
 if(element._countedByPrototype)results.push(element);
 h.unmark(matches);
 return results;
},

 findElement:function(elements,expression,index){
 if(Object.isNumber(expression)){
 index=expression;expression=false;
}
 return Selector.matchElements(elements,expression||'*')[index||0];
},

 findChildElements:function(element,expressions){
 expressions=Selector.split(expressions.join(','));
 var results=[],h=Selector.handlers;
 for(var i=0,l=expressions.length,selector;i<l;i++){
 selector=new Selector(expressions[i].strip());
 h.concat(results,selector.findElements(element));
}
 return(l>1)?h.unique(results):results;
}
});

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(nodes){
 for(var i=0,node;node=nodes[i];i++)
 node.removeAttribute('_countedByPrototype');
 return nodes;
}
});
}

function $$(){
 return Selector.findChildElements(document,$A(arguments));
}
var Form={
 reset:function(form){
 $(form).reset();
 return form;
},

 serializeElements:function(elements,options){
 if(typeof options!='object')options={hash:!!options};
 else if(Object.isUndefined(options.hash))options.hash=true;
 var key,value,submitted=false,submit=options.submit;

 var data=elements.inject({},function(result,element){
 if(!element.disabled&&element.name){
 key=element.name;value=$(element).getValue();
 if(value!=null&&(element.type!='submit'||(!submitted&&
 submit!==false&&(!submit||key==submit)&&(submitted=true)))){
 if(key in result){

 if(!Object.isArray(result[key]))result[key]=[result[key]];
 result[key].push(value);
}
 else result[key]=value;
}
}
 return result;
});

 return options.hash?data:Object.toQueryString(data);
}
};

Form.Methods={
 serialize:function(form,options){
 return Form.serializeElements(Form.getElements(form),options);
},

 getElements:function(form){
 return $A($(form).getElementsByTagName('*')).inject([],
 function(elements,child){
 if(Form.Element.Serializers[child.tagName.toLowerCase()])
 elements.push(Element.extend(child));
 return elements;
}
);
},

 getInputs:function(form,typeName,name){
 form=$(form);
 var inputs=form.getElementsByTagName('input');

 if(!typeName&&!name)return $A(inputs).map(Element.extend);

 for(var i=0,matchingInputs=[],length=inputs.length;i<length;i++){
 var input=inputs[i];
 if((typeName&&input.type!=typeName)||(name&&input.name!=name))
 continue;
 matchingInputs.push(Element.extend(input));
}

 return matchingInputs;
},

 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 elements=$(form).getElements().findAll(function(element){
 return'hidden'!=element.type&&!element.disabled;
});
 var firstByIndex=elements.findAll(function(element){
 return element.hasAttribute('tabIndex')&&element.tabIndex>=0;
}).sortBy(function(element){return element.tabIndex}).first();

 return firstByIndex?firstByIndex:elements.find(function(element){
 return['input','select','textarea'].include(element.tagName.toLowerCase());
});
},

 focusFirstElement:function(form){
 form=$(form);
 form.findFirstElement().activate();
 return form;
},

 request:function(form,options){
 form=$(form),options=Object.clone(options||{});

 var params=options.parameters,action=form.readAttribute('action')||'';
 if(action.blank())action=window.location.href;
 options.parameters=form.serialize(true);

 if(params){
 if(Object.isString(params))params=params.toQueryParams();
 Object.extend(options.parameters,params);
}

 if(form.hasAttribute('method')&&!options.method)
 options.method=form.method;

 return new Ajax.Request(action,options);
}
};



Form.Element={
 focus:function(element){
 $(element).focus();
 return element;
},

 select:function(element){
 $(element).select();
 return element;
}
};

Form.Element.Methods={
 serialize:function(element){
 element=$(element);
 if(!element.disabled&&element.name){
 var value=element.getValue();
 if(value!=undefined){
 var pair={};
 pair[element.name]=value;
 return Object.toQueryString(pair);
}
}
 return'';
},

 getValue:function(element){
 element=$(element);
 var method=element.tagName.toLowerCase();
 return Form.Element.Serializers[method](element);
},

 setValue:function(element,value){
 element=$(element);
 var method=element.tagName.toLowerCase();
 Form.Element.Serializers[method](element,value);
 return element;
},

 clear:function(element){
 $(element).value='';
 return element;
},

 present:function(element){
 return $(element).value!='';
},

 activate:function(element){
 element=$(element);
 try{
 element.focus();
 if(element.select&&(element.tagName.toLowerCase()!='input'||
!['button','reset','submit'].include(element.type)))
 element.select();
}catch(e){}
 return element;
},

 disable:function(element){
 element=$(element);
 element.blur();
 element.disabled=true;
 return element;
},

 enable:function(element){
 element=$(element);
 element.disabled=false;
 return element;
}
};



var Field=Form.Element;
var $F=Form.Element.Methods.getValue;



Form.Element.Serializers={
 input:function(element,value){
 switch(element.type.toLowerCase()){
 case'checkbox':
 case'radio':
 return Form.Element.Serializers.inputSelector(element,value);
 default:
 return Form.Element.Serializers.textarea(element,value);
}
},

 inputSelector:function(element,value){
 if(Object.isUndefined(value))return element.checked?element.value:null;
 else element.checked=!!value;
},

 textarea:function(element,value){
 if(Object.isUndefined(value))return element.value;
 else element.value=value;
},

 select:function(element,index){
 if(Object.isUndefined(index))
 return this[element.type=='select-one'?
'selectOne':'selectMany'](element);
 else{
 var opt,value,single=!Object.isArray(index);
 for(var i=0,length=element.length;i<length;i++){
 opt=element.options[i];
 value=this.optionValue(opt);
 if(single){
 if(value==index){
 opt.selected=true;
 return;
}
}
 else opt.selected=index.include(value);
}
}
},

 selectOne:function(element){
 var index=element.selectedIndex;
 return index>=0?this.optionValue(element.options[index]):null;
},

 selectMany:function(element){
 var values,length=element.length;
 if(!length)return null;

 for(var i=0,values=[];i<length;i++){
 var opt=element.options[i];
 if(opt.selected)values.push(this.optionValue(opt));
}
 return values;
},

 optionValue:function(opt){

 return Element.extend(opt).hasAttribute('value')?opt.value:opt.text;
}
};



Abstract.TimedObserver=Class.create(PeriodicalExecuter,{
 initialize:function($super,element,frequency,callback){
 $super(callback,frequency);
 this.element=$(element);
 this.lastValue=this.getValue();
},

 execute:function(){
 var value=this.getValue();
 if(Object.isString(this.lastValue)&&Object.isString(value)?
 this.lastValue!=value:String(this.lastValue)!=String(value)){
 this.callback(this.element,value);
 this.lastValue=value;
}
}
});

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(element,callback){
 this.element=$(element);
 this.callback=callback;

 this.lastValue=this.getValue();
 if(this.element.tagName.toLowerCase()=='form')
 this.registerFormCallbacks();
 else
 this.registerCallback(this.element);
},

 onElementEvent:function(){
 var value=this.getValue();
 if(this.lastValue!=value){
 this.callback(this.element,value);
 this.lastValue=value;
}
},

 registerFormCallbacks:function(){
 Form.getElements(this.element).each(this.registerCallback,this);
},

 registerCallback:function(element){
 if(element.type){
 switch(element.type.toLowerCase()){
 case'checkbox':
 case'radio':
 Event.observe(element,'click',this.onElementEvent.bind(this));
 break;
 default:
 Event.observe(element,'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(event){
 var element;
 switch(event.type){
 case'mouseover':element=event.fromElement;break;
 case'mouseout':element=event.toElement;break;
 default:return null;
}
 return Element.extend(element);
}
});

Event.Methods=(function(){
 var isButton;

 if(Prototype.Browser.IE){
 var buttonMap={0:1,1:4,2:2};
 isButton=function(event,code){
 return event.button==buttonMap[code];
};

}else if(Prototype.Browser.WebKit){
 isButton=function(event,code){
 switch(code){
 case 0:return event.which==1&&!event.metaKey;
 case 1:return event.which==1&&event.metaKey;
 default:return false;
}
};

}else{
 isButton=function(event,code){
 return event.which?(event.which===code+1):(event.button===code);
};
}

 return{
 isLeftClick:function(event){return isButton(event,0)},
 isMiddleClick:function(event){return isButton(event,1)},
 isRightClick:function(event){return isButton(event,2)},

 element:function(event){
 var node=Event.extend(event).target;
 return Element.extend(node.nodeType==Node.TEXT_NODE?node.parentNode:node);
},

 findElement:function(event,expression){
 var element=Event.element(event);
 if(!expression)return element;
 var elements=[element].concat(element.ancestors());
 return Selector.findElement(elements,expression,0);
},

 pointer:function(event){
 return{
 x:event.pageX||(event.clientX+
(document.documentElement.scrollLeft||document.body.scrollLeft)),
 y:event.pageY||(event.clientY+
(document.documentElement.scrollTop||document.body.scrollTop))
};
},

 pointerX:function(event){return Event.pointer(event).x},
 pointerY:function(event){return Event.pointer(event).y},

 stop:function(event){
 Event.extend(event);
 event.preventDefault();
 event.stopPropagation();
 event.stopped=true;
}
};
})();

Event.extend=(function(){
 var methods=Object.keys(Event.Methods).inject({},function(m,name){
 m[name]=Event.Methods[name].methodize();
 return m;
});

 if(Prototype.Browser.IE){
 Object.extend(methods,{
 stopPropagation:function(){this.cancelBubble=true},
 preventDefault:function(){this.returnValue=false},
 inspect:function(){return"[object Event]"}
});

 return function(event){
 if(!event)return false;
 if(event._extendedByPrototype)return event;

 event._extendedByPrototype=Prototype.emptyFunction;
 var pointer=Event.pointer(event);
 Object.extend(event,{
 target:event.srcElement,
 relatedTarget:Event.relatedTarget(event),
 pageX:pointer.x,
 pageY:pointer.y
});
 return Object.extend(event,methods);
};

}else{
 Event.prototype=Event.prototype||document.createEvent("HTMLEvents").__proto__;
 Object.extend(Event.prototype,methods);
 return Prototype.K;
}
})();

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";
 if(!Prototype.Browser.IE)eventName={mouseenter:"mouseover",mouseleave:"mouseout"}[eventName]||eventName;
 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 wrapper=function(event){
 if(!Event||!Event.extend||
(event.eventName&&event.eventName!=eventName))
 return false;

 Event.extend(event);
 handler.call(element,event);
};

 if(!(Prototype.Browser.IE)&&['mouseenter','mouseleave'].include(eventName)){
 wrapper=wrapper.wrap(function(proceed,event){
 var rel=event.relatedTarget,cur=event.currentTarget;
 if(rel&&rel.nodeType==Node.TEXT_NODE)rel=rel.parentNode;
 if(rel&&rel!=cur&&!rel.descendantOf(cur))
 return proceed(event);
});
}

 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);
}
};
})());

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 timer;

 function fireContentLoadedEvent(){
 if(document.loaded)return;
 if(timer)window.clearInterval(timer);
 document.fire("dom:loaded");
 document.loaded=true;
}

 if(document.addEventListener){
 if(Prototype.Browser.WebKit){
 timer=window.setInterval(function(){
 if(/loaded|complete/.test(document.readyState))
 fireContentLoadedEvent();
},0);

 Event.observe(window,"load",fireContentLoadedEvent);

}else{
 document.addEventListener("DOMContentLoaded",
 fireContentLoadedEvent,false);
}

}else{
 document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
 $("__onDOMContentLoaded").onreadystatechange=function(){
 if(this.readyState=="complete"){
 this.onreadystatechange=null;
 fireContentLoadedEvent();
}
};
}
})();


Hash.toQueryString=Object.toQueryString;

var Toggle={display:Element.toggle};

Element.Methods.childOf=Element.Methods.descendantOf;

var Insertion={
 Before:function(element,content){
 return Element.insert(element,{before:content});
},

 Top:function(element,content){
 return Element.insert(element,{top:content});
},

 Bottom:function(element,content){
 return Element.insert(element,{bottom:content});
},

 After:function(element,content){
 return Element.insert(element,{after:content});
}
};

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(element,x,y){
 if(this.includeScrollOffsets)
 return this.withinIncludingScrolloffsets(element,x,y);
 this.xcomp=x;
 this.ycomp=y;
 this.offset=Element.cumulativeOffset(element);

 return(y>=this.offset[1]&&
 y<this.offset[1]+element.offsetHeight&&
 x>=this.offset[0]&&
 x<this.offset[0]+element.offsetWidth);
},

 withinIncludingScrolloffsets:function(element,x,y){
 var offsetcache=Element.cumulativeScrollOffset(element);

 this.xcomp=x+offsetcache[0]-this.deltaX;
 this.ycomp=y+offsetcache[1]-this.deltaY;
 this.offset=Element.cumulativeOffset(element);

 return(this.ycomp>=this.offset[1]&&
 this.ycomp<this.offset[1]+element.offsetHeight&&
 this.xcomp>=this.offset[0]&&
 this.xcomp<this.offset[0]+element.offsetWidth);
},


 overlap:function(mode,element){
 if(!mode)return 0;
 if(mode=='vertical')
 return((this.offset[1]+element.offsetHeight)-this.ycomp)/
 element.offsetHeight;
 if(mode=='horizontal')
 return((this.offset[0]+element.offsetWidth)-this.xcomp)/
 element.offsetWidth;
},



 cumulativeOffset:Element.Methods.cumulativeOffset,

 positionedOffset:Element.Methods.positionedOffset,

 absolutize:function(element){
 Position.prepare();
 return Element.absolutize(element);
},

 relativize:function(element){
 Position.prepare();
 return Element.relativize(element);
},

 realOffset:Element.Methods.cumulativeScrollOffset,

 offsetParent:Element.Methods.getOffsetParent,

 page:Element.Methods.viewportOffset,

 clone:function(source,target,options){
 options=options||{};
 return Element.clonePosition(target,source,options);
}
};



if(!document.getElementsByClassName)document.getElementsByClassName=function(instanceMethods){
 function iter(name){
 return name.blank()?null:"[contains(concat(' ', @class, ' '), ' "+name+" ')]";
}

 instanceMethods.getElementsByClassName=Prototype.BrowserFeatures.XPath?
 function(element,className){
 className=className.toString().strip();
 var cond=/\s/.test(className)?$w(className).map(iter).join(''):iter(className);
 return cond?document._getElementsByXPath('.//*'+cond,element):[];
}:function(element,className){
 className=className.toString().strip();
 var elements=[],classNames=(/\s/.test(className)?$w(className):null);
 if(!classNames&&!className)return elements;

 var nodes=$(element).getElementsByTagName('*');
 className=' '+className+' ';

 for(var i=0,child,cn;child=nodes[i];i++){
 if(child.className&&(cn=' '+child.className+' ')&&(cn.include(className)||
(classNames&&classNames.all(function(name){
 return!name.toString().blank()&&cn.include(' '+name+' ');
}))))
 elements.push(Element.extend(child));
}
 return elements;
};

 return function(className,parentElement){
 return $(parentElement||document.body).getElementsByClassName(className);
};
}(Element.Methods);



Element.ClassNames=Class.create();
Element.ClassNames.prototype={
 initialize:function(element){
 this.element=$(element);
},

 _each:function(iterator){
 this.element.className.split(/\s+/).select(function(name){
 return name.length>0;
})._each(iterator);
},

 set:function(className){
 this.element.className=className;
},

 add:function(classNameToAdd){
 if(this.include(classNameToAdd))return;
 this.set($A(this).concat(classNameToAdd).join(' '));
},

 remove:function(classNameToRemove){
 if(!this.include(classNameToRemove))return;
 this.set($A(this).without(classNameToRemove).join(' '));
},

 toString:function(){
 return $A(this).join(' ');
}
};

Object.extend(Element.ClassNames.prototype,Enumerable);



Element.addMethods();














String.prototype.parseColor=function(){
 var color='#';
 if(this.slice(0,4)=='rgb('){
 var cols=this.slice(4,this.length-1).split(',');
 var i=0;do{color+=parseInt(cols[i]).toColorPart()}while(++i<3);
}else{
 if(this.slice(0,1)=='#'){
 if(this.length==4)for(var i=1;i<4;i++)color+=(this.charAt(i)+this.charAt(i)).toLowerCase();
 if(this.length==7)color=this.toLowerCase();
}
}
 return(color.length==7?color:(arguments[0]||this));
};



Element.collectTextNodes=function(element){
 return $A($(element).childNodes).collect(function(node){
 return(node.nodeType==3?node.nodeValue:
(node.hasChildNodes()?Element.collectTextNodes(node):''));
}).flatten().join('');
};

Element.collectTextNodesIgnoreClass=function(element,className){
 return $A($(element).childNodes).collect(function(node){
 return(node.nodeType==3?node.nodeValue:
((node.hasChildNodes()&&!Element.hasClassName(node,className))?
 Element.collectTextNodesIgnoreClass(node,className):''));
}).flatten().join('');
};

Element.setContentZoom=function(element,percent){
 element=$(element);
 element.setStyle({fontSize:(percent/100)+'em'});
 if(Prototype.Browser.WebKit)window.scrollBy(0,0);
 return element;
};

Element.getInlineOpacity=function(element){
 return $(element).style.opacity||'';
};

Element.forceRerendering=function(element){
 try{
 element=$(element);
 var n=document.createTextNode(' ');
 element.appendChild(n);
 element.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(pos){
 return(-Math.cos(pos*Math.PI)/2)+0.5;
},
 reverse:function(pos){
 return 1-pos;
},
 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,pulses){
 pulses=pulses||5;
 return(
((pos%(1/pulses))*pulses).round()==0?
((pos*pulses*2)-(pos*pulses*2).floor()):
 1-((pos*pulses*2)-(pos*pulses*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.0,
 fps:100,
 sync:false,
 from:0.0,
 to:1.0,
 delay:0.0,
 queue:'parallel'
},
 tagifyText:function(element){
 var tagifyStyle='position:relative';
 if(Prototype.Browser.IE)tagifyStyle+=';zoom:1';

 element=$(element);
 $A(element.childNodes).each(function(child){
 if(child.nodeType==3){
 child.nodeValue.toArray().each(function(character){
 element.insertBefore(
 new Element('span',{style:tagifyStyle}).update(
 character==' '?String.fromCharCode(160):character),
 child);
});
 Element.remove(child);
}
});
},
 multiple:function(element,effect){
 var elements;
 if(((typeof element=='object')||
 Object.isFunction(element))&&
(element.length))
 elements=element;
 else
 elements=$(element).childNodes;

 var options=Object.extend({
 speed:0.1,
 delay:0.0
},arguments[2]||{});
 var masterDelay=options.delay;

 $A(elements).each(function(element,index){
 new effect(element,Object.extend(options,{delay:index*options.speed+masterDelay}));
});
},
 PAIRS:{
'slide':['SlideDown','SlideUp'],
'blind':['BlindDown','BlindUp'],
'appear':['Appear','Fade']
},
 toggle:function(element,effect){
 element=$(element);
 effect=(effect||'appear').toLowerCase();
 var options=Object.extend({
 queue:{position:'end',scope:(element.id||'global'),limit:1}
},arguments[2]||{});
 Effect[element.visible()?
 Effect.PAIRS[effect][1]:Effect.PAIRS[effect][0]](element,options);
}
};

Effect.DefaultOptions.transition=Effect.Transitions.sinoidal;



Effect.ScopedQueue=Class.create(Enumerable,{
 initialize:function(){
 this.effects=[];
 this.interval=null;
},
 _each:function(iterator){
 this.effects._each(iterator);
},
 add:function(effect){
 var timestamp=new Date().getTime();

 var position=Object.isString(effect.options.queue)?
 effect.options.queue:effect.options.queue.position;

 switch(position){
 case'front':

 this.effects.findAll(function(e){return e.state=='idle'}).each(function(e){
 e.startOn+=effect.finishOn;
 e.finishOn+=effect.finishOn;
});
 break;
 case'with-last':
 timestamp=this.effects.pluck('startOn').max()||timestamp;
 break;
 case'end':

 timestamp=this.effects.pluck('finishOn').max()||timestamp;
 break;
}

 effect.startOn+=timestamp;
 effect.finishOn+=timestamp;

 if(!effect.options.queue.limit||(this.effects.length<effect.options.queue.limit))
 this.effects.push(effect);

 if(!this.interval)
 this.interval=setInterval(this.loop.bind(this),15);
},
 remove:function(effect){
 this.effects=this.effects.reject(function(e){return e==effect});
 if(this.effects.length==0){
 clearInterval(this.interval);
 this.interval=null;
}
},
 loop:function(){
 var timePos=new Date().getTime();
 for(var i=0,len=this.effects.length;i<len;i++)
 this.effects[i]&&this.effects[i].loop(timePos);
}
});

Effect.Queues={
 instances:$H(),
 get:function(queueName){
 if(!Object.isString(queueName))return queueName;

 return this.instances.get(queueName)||
 this.instances.set(queueName,new Effect.ScopedQueue());
}
};
Effect.Queue=Effect.Queues.get('global');

Effect.Base=Class.create({
 position:null,
 start:function(options){
 function codeForEvent(options,eventName){
 return(
(options[eventName+'Internal']?'this.options.'+eventName+'Internal(this);':'')+
(options[eventName]?'this.options.'+eventName+'(this);':'')
);
}
 if(options&&options.transition===false)options.transition=Effect.Transitions.linear;
 this.options=Object.extend(Object.extend({},Effect.DefaultOptions),options||{});
 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";'+
 codeForEvent(this.options,'beforeSetup')+
(this.setup?'this.setup();':'')+
 codeForEvent(this.options,'afterSetup')+
'};if (this.state=="running"){'+
'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
'this.position=pos;'+
 codeForEvent(this.options,'beforeUpdate')+
(this.update?'this.update(pos);':'')+
 codeForEvent(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(timePos){
 if(timePos>=this.startOn){
 if(timePos>=this.finishOn){
 this.render(1.0);
 this.cancel();
 this.event('beforeFinish');
 if(this.finish)this.finish();
 this.event('afterFinish');
 return;
}
 var pos=(timePos-this.startOn)/this.totalTime,
 frame=(pos*this.totalFrames).round();
 if(frame>this.currentFrame){
 this.render(pos);
 this.currentFrame=frame;
}
}
},
 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(eventName){
 if(this.options[eventName+'Internal'])this.options[eventName+'Internal'](this);
 if(this.options[eventName])this.options[eventName](this);
},
 inspect:function(){
 var data=$H();
 for(property in this)
 if(!Object.isFunction(this[property]))data.set(property,this[property]);
 return'#<Effect:'+data.inspect()+',options:'+$H(this.options).inspect()+'>';
}
});

Effect.Parallel=Class.create(Effect.Base,{
 initialize:function(effects){
 this.effects=effects||[];
 this.start(arguments[1]);
},
 update:function(position){
 this.effects.invoke('render',position);
},
 finish:function(position){
 this.effects.each(function(effect){
 effect.render(1.0);
 effect.cancel();
 effect.event('beforeFinish');
 if(effect.finish)effect.finish(position);
 effect.event('afterFinish');
});
}
});

Effect.Tween=Class.create(Effect.Base,{
 initialize:function(object,from,to){
 object=Object.isString(object)?$(object):object;
 var args=$A(arguments),method=args.last(),
 options=args.length==5?args[3]:null;
 this.method=Object.isFunction(method)?method.bind(object):
 Object.isFunction(object[method])?object[method].bind(object):
 function(value){object[method]=value};
 this.start(Object.extend({from:from,to:to},options||{}));
},
 update:function(position){
 this.method(position);
}
});

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(element){
 this.element=$(element);
 if(!this.element)throw(Effect._elementDoesNotExistError);

 if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout))
 this.element.setStyle({zoom:1});
 var options=Object.extend({
 from:this.element.getOpacity()||0.0,
 to:1.0
},arguments[1]||{});
 this.start(options);
},
 update:function(position){
 this.element.setOpacity(position);
}
});

Effect.Move=Class.create(Effect.Base,{
 initialize:function(element){
 this.element=$(element);
 if(!this.element)throw(Effect._elementDoesNotExistError);
 var options=Object.extend({
 x:0,
 y:0,
 mode:'relative'
},arguments[1]||{});
 this.start(options);
},
 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(position){
 this.element.setStyle({
 left:(this.options.x*position+this.originalLeft).round()+'px',
 top:(this.options.y*position+this.originalTop).round()+'px'
});
}
});


Effect.MoveBy=function(element,toTop,toLeft){
 return new Effect.Move(element,
 Object.extend({x:toLeft,y:toTop},arguments[3]||{}));
};

Effect.Scale=Class.create(Effect.Base,{
 initialize:function(element,percent){
 this.element=$(element);
 if(!this.element)throw(Effect._elementDoesNotExistError);
 var options=Object.extend({
 scaleX:true,
 scaleY:true,
 scaleContent:true,
 scaleFromCenter:false,
 scaleMode:'box',
 scaleFrom:100.0,
 scaleTo:percent
},arguments[2]||{});
 this.start(options);
},
 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 fontSize=this.element.getStyle('font-size')||'100%';
['em','px','%','pt'].each(function(fontSizeType){
 if(fontSize.indexOf(fontSizeType)>0){
 this.fontSize=parseFloat(fontSize);
 this.fontSizeType=fontSizeType;
}
}.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(position){
 var currentScale=(this.options.scaleFrom/100.0)+(this.factor*position);
 if(this.options.scaleContent&&this.fontSize)
 this.element.setStyle({fontSize:this.fontSize*currentScale+this.fontSizeType});
 this.setDimensions(this.dims[0]*currentScale,this.dims[1]*currentScale);
},
 finish:function(position){
 if(this.restoreAfterFinish)this.element.setStyle(this.originalStyle);
},
 setDimensions:function(height,width){
 var d={};
 if(this.options.scaleX)d.width=width.round()+'px';
 if(this.options.scaleY)d.height=height.round()+'px';
 if(this.options.scaleFromCenter){
 var topd=(height-this.dims[0])/2;
 var leftd=(width-this.dims[1])/2;
 if(this.elementPositioning=='absolute'){
 if(this.options.scaleY)d.top=this.originalTop-topd+'px';
 if(this.options.scaleX)d.left=this.originalLeft-leftd+'px';
}else{
 if(this.options.scaleY)d.top=-topd+'px';
 if(this.options.scaleX)d.left=-leftd+'px';
}
}
 this.element.setStyle(d);
}
});

Effect.Highlight=Class.create(Effect.Base,{
 initialize:function(element){
 this.element=$(element);
 if(!this.element)throw(Effect._elementDoesNotExistError);
 var options=Object.extend({startcolor:'#ffff99'},arguments[1]||{});
 this.start(options);
},
 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(position){
 this.element.setStyle({backgroundColor:$R(0,2).inject('#',function(m,v,i){
 return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart());}.bind(this))});
},
 finish:function(){
 this.element.setStyle(Object.extend(this.oldStyle,{
 backgroundColor:this.options.restorecolor
}));
}
});

Effect.ScrollTo=function(element){
 var options=arguments[1]||{},
 scrollOffsets=document.viewport.getScrollOffsets(),
 elementOffsets=$(element).cumulativeOffset(),
 max=(window.height||document.body.scrollHeight)-document.viewport.getHeight();

 if(options.offset)elementOffsets[1]+=options.offset;

 return new Effect.Tween(null,
 scrollOffsets.top,
 elementOffsets[1]>max?max:elementOffsets[1],
 options,
 function(p){scrollTo(scrollOffsets.left,p.round())}
);
};



Effect.Fade=function(element){
 element=$(element);
 var oldOpacity=element.getInlineOpacity();
 var options=Object.extend({
 from:element.getOpacity()||1.0,
 to:0.0,
 afterFinishInternal:function(effect){
 if(effect.options.to!=0)return;
 effect.element.hide().setStyle({opacity:oldOpacity});
}
},arguments[1]||{});
 return new Effect.Opacity(element,options);
};

Effect.Appear=function(element){
 element=$(element);
 var options=Object.extend({
 from:(element.getStyle('display')=='none'?0.0:element.getOpacity()||0.0),
 to:1.0,

 afterFinishInternal:function(effect){
 effect.element.forceRerendering();
},
 beforeSetup:function(effect){
 effect.element.setOpacity(effect.options.from).show();
}},arguments[1]||{});
 return new Effect.Opacity(element,options);
};

Effect.Puff=function(element){
 element=$(element);
 var oldStyle={
 opacity:element.getInlineOpacity(),
 position:element.getStyle('position'),
 top:element.style.top,
 left:element.style.left,
 width:element.style.width,
 height:element.style.height
};
 return new Effect.Parallel(
[new Effect.Scale(element,200,
{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),
 new Effect.Opacity(element,{sync:true,to:0.0})],
 Object.extend({duration:1.0,
 beforeSetupInternal:function(effect){
 Position.absolutize(effect.effects[0].element)
},
 afterFinishInternal:function(effect){
 effect.effects[0].element.hide().setStyle(oldStyle);}
},arguments[1]||{})
);
};

Effect.BlindUp=function(element){
 element=$(element);
 element.makeClipping();
 return new Effect.Scale(element,0,
 Object.extend({scaleContent:false,
 scaleX:false,
 restoreAfterFinish:true,
 afterFinishInternal:function(effect){
 effect.element.hide().undoClipping();
}
},arguments[1]||{})
);
};

Effect.BlindDown=function(element){
 element=$(element);
 var elementDimensions=element.getDimensions();
 return new Effect.Scale(element,100,Object.extend({
 scaleContent:false,
 scaleX:false,
 scaleFrom:0,
 scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},
 restoreAfterFinish:true,
 afterSetup:function(effect){
 effect.element.makeClipping().setStyle({height:'0px'}).show();
},
 afterFinishInternal:function(effect){
 effect.element.undoClipping();
}
},arguments[1]||{}));
};

Effect.SwitchOff=function(element){
 element=$(element);
 var oldOpacity=element.getInlineOpacity();
 return new Effect.Appear(element,Object.extend({
 duration:0.4,
 from:0,
 transition:Effect.Transitions.flicker,
 afterFinishInternal:function(effect){
 new Effect.Scale(effect.element,1,{
 duration:0.3,scaleFromCenter:true,
 scaleX:false,scaleContent:false,restoreAfterFinish:true,
 beforeSetup:function(effect){
 effect.element.makePositioned().makeClipping();
},
 afterFinishInternal:function(effect){
 effect.element.hide().undoClipping().undoPositioned().setStyle({opacity:oldOpacity});
}
})
}
},arguments[1]||{}));
};

Effect.DropOut=function(element){
 element=$(element);
 var oldStyle={
 top:element.getStyle('top'),
 left:element.getStyle('left'),
 opacity:element.getInlineOpacity()};
 return new Effect.Parallel(
[new Effect.Move(element,{x:0,y:100,sync:true}),
 new Effect.Opacity(element,{sync:true,to:0.0})],
 Object.extend(
{duration:0.5,
 beforeSetup:function(effect){
 effect.effects[0].element.makePositioned();
},
 afterFinishInternal:function(effect){
 effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
}
},arguments[1]||{}));
};

Effect.Shake=function(element){
 element=$(element);
 var options=Object.extend({
 distance:20,
 duration:0.5
},arguments[1]||{});
 var distance=parseFloat(options.distance);
 var split=parseFloat(options.duration)/10.0;
 var oldStyle={
 top:element.getStyle('top'),
 left:element.getStyle('left')};
 return new Effect.Move(element,
{x:distance,y:0,duration:split,afterFinishInternal:function(effect){
 new Effect.Move(effect.element,
{x:-distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){
 new Effect.Move(effect.element,
{x:distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){
 new Effect.Move(effect.element,
{x:-distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){
 new Effect.Move(effect.element,
{x:distance*2,y:0,duration:split*2,afterFinishInternal:function(effect){
 new Effect.Move(effect.element,
{x:-distance,y:0,duration:split,afterFinishInternal:function(effect){
 effect.element.undoPositioned().setStyle(oldStyle);
}})}})}})}})}})}});
};

Effect.SlideDown=function(element){
 element=$(element).cleanWhitespace();

 var oldInnerBottom=element.down().getStyle('bottom');
 var elementDimensions=element.getDimensions();
 return new Effect.Scale(element,100,Object.extend({
 scaleContent:false,
 scaleX:false,
 scaleFrom:window.opera?0:1,
 scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},
 restoreAfterFinish:true,
 afterSetup:function(effect){
 effect.element.makePositioned();
 effect.element.down().makePositioned();
 if(window.opera)effect.element.setStyle({top:''});
 effect.element.makeClipping().setStyle({height:'0px'}).show();
},
 afterUpdateInternal:function(effect){
 effect.element.down().setStyle({bottom:
(effect.dims[0]-effect.element.clientHeight)+'px'});
},
 afterFinishInternal:function(effect){
 effect.element.undoClipping().undoPositioned();
 effect.element.down().undoPositioned().setStyle({bottom:oldInnerBottom});}
},arguments[1]||{})
);
};

Effect.SlideUp=function(element){
 element=$(element).cleanWhitespace();
 var oldInnerBottom=element.down().getStyle('bottom');
 var elementDimensions=element.getDimensions();
 return new Effect.Scale(element,window.opera?0:1,
 Object.extend({scaleContent:false,
 scaleX:false,
 scaleMode:'box',
 scaleFrom:100,
 scaleMode:{originalHeight:elementDimensions.height,originalWidth:elementDimensions.width},
 restoreAfterFinish:true,
 afterSetup:function(effect){
 effect.element.makePositioned();
 effect.element.down().makePositioned();
 if(window.opera)effect.element.setStyle({top:''});
 effect.element.makeClipping().show();
},
 afterUpdateInternal:function(effect){
 effect.element.down().setStyle({bottom:
(effect.dims[0]-effect.element.clientHeight)+'px'});
},
 afterFinishInternal:function(effect){
 effect.element.hide().undoClipping().undoPositioned();
 effect.element.down().undoPositioned().setStyle({bottom:oldInnerBottom});
}
},arguments[1]||{})
);
};


Effect.Squish=function(element){
 return new Effect.Scale(element,window.opera?1:0,{
 restoreAfterFinish:true,
 beforeSetup:function(effect){
 effect.element.makeClipping();
},
 afterFinishInternal:function(effect){
 effect.element.hide().undoClipping();
}
});
};

Effect.Grow=function(element){
 element=$(element);
 var options=Object.extend({
 direction:'center',
 moveTransition:Effect.Transitions.sinoidal,
 scaleTransition:Effect.Transitions.sinoidal,
 opacityTransition:Effect.Transitions.full
},arguments[1]||{});
 var oldStyle={
 top:element.style.top,
 left:element.style.left,
 height:element.style.height,
 width:element.style.width,
 opacity:element.getInlineOpacity()};

 var dims=element.getDimensions();
 var initialMoveX,initialMoveY;
 var moveX,moveY;

 switch(options.direction){
 case'top-left':
 initialMoveX=initialMoveY=moveX=moveY=0;
 break;
 case'top-right':
 initialMoveX=dims.width;
 initialMoveY=moveY=0;
 moveX=-dims.width;
 break;
 case'bottom-left':
 initialMoveX=moveX=0;
 initialMoveY=dims.height;
 moveY=-dims.height;
 break;
 case'bottom-right':
 initialMoveX=dims.width;
 initialMoveY=dims.height;
 moveX=-dims.width;
 moveY=-dims.height;
 break;
 case'center':
 initialMoveX=dims.width/2;
 initialMoveY=dims.height/2;
 moveX=-dims.width/2;
 moveY=-dims.height/2;
 break;
}

 return new Effect.Move(element,{
 x:initialMoveX,
 y:initialMoveY,
 duration:0.01,
 beforeSetup:function(effect){
 effect.element.hide().makeClipping().makePositioned();
},
 afterFinishInternal:function(effect){
 new Effect.Parallel(
[new Effect.Opacity(effect.element,{sync:true,to:1.0,from:0.0,transition:options.opacityTransition}),
 new Effect.Move(effect.element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition}),
 new Effect.Scale(effect.element,100,{
 scaleMode:{originalHeight:dims.height,originalWidth:dims.width},
 sync:true,scaleFrom:window.opera?1:0,transition:options.scaleTransition,restoreAfterFinish:true})
],Object.extend({
 beforeSetup:function(effect){
 effect.effects[0].element.setStyle({height:'0px'}).show();
},
 afterFinishInternal:function(effect){
 effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
}
},options)
)
}
});
};

Effect.Shrink=function(element){
 element=$(element);
 var options=Object.extend({
 direction:'center',
 moveTransition:Effect.Transitions.sinoidal,
 scaleTransition:Effect.Transitions.sinoidal,
 opacityTransition:Effect.Transitions.none
},arguments[1]||{});
 var oldStyle={
 top:element.style.top,
 left:element.style.left,
 height:element.style.height,
 width:element.style.width,
 opacity:element.getInlineOpacity()};

 var dims=element.getDimensions();
 var moveX,moveY;

 switch(options.direction){
 case'top-left':
 moveX=moveY=0;
 break;
 case'top-right':
 moveX=dims.width;
 moveY=0;
 break;
 case'bottom-left':
 moveX=0;
 moveY=dims.height;
 break;
 case'bottom-right':
 moveX=dims.width;
 moveY=dims.height;
 break;
 case'center':
 moveX=dims.width/2;
 moveY=dims.height/2;
 break;
}

 return new Effect.Parallel(
[new Effect.Opacity(element,{sync:true,to:0.0,from:1.0,transition:options.opacityTransition}),
 new Effect.Scale(element,window.opera?1:0,{sync:true,transition:options.scaleTransition,restoreAfterFinish:true}),
 new Effect.Move(element,{x:moveX,y:moveY,sync:true,transition:options.moveTransition})
],Object.extend({
 beforeStartInternal:function(effect){
 effect.effects[0].element.makePositioned().makeClipping();
},
 afterFinishInternal:function(effect){
 effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle);}
},options)
);
};

Effect.Pulsate=function(element){
 element=$(element);
 var options=arguments[1]||{};
 var oldOpacity=element.getInlineOpacity();
 var transition=options.transition||Effect.Transitions.sinoidal;
 var reverser=function(pos){return transition(1-Effect.Transitions.pulse(pos,options.pulses))};
 reverser.bind(transition);
 return new Effect.Opacity(element,
 Object.extend(Object.extend({duration:2.0,from:0,
 afterFinishInternal:function(effect){effect.element.setStyle({opacity:oldOpacity});}
},options),{transition:reverser}));
};

Effect.Fold=function(element){
 element=$(element);
 var oldStyle={
 top:element.style.top,
 left:element.style.left,
 width:element.style.width,
 height:element.style.height};
 element.makeClipping();
 return new Effect.Scale(element,5,Object.extend({
 scaleContent:false,
 scaleX:false,
 afterFinishInternal:function(effect){
 new Effect.Scale(element,1,{
 scaleContent:false,
 scaleY:false,
 afterFinishInternal:function(effect){
 effect.element.hide().undoClipping().setStyle(oldStyle);
}});
}},arguments[1]||{}));
};

Effect.Morph=Class.create(Effect.Base,{
 initialize:function(element){
 this.element=$(element);
 if(!this.element)throw(Effect._elementDoesNotExistError);
 var options=Object.extend({
 style:{}
},arguments[1]||{});

 if(!Object.isString(options.style))this.style=$H(options.style);
 else{
 if(options.style.include(':'))
 this.style=options.style.parseStyle();
 else{
 this.element.addClassName(options.style);
 this.style=$H(this.element.getStyles());
 this.element.removeClassName(options.style);
 var css=this.element.getStyles();
 this.style=this.style.reject(function(style){
 return style.value==css[style.key];
});
 options.afterFinishInternal=function(effect){
 effect.element.addClassName(effect.options.style);
 effect.transforms.each(function(transform){
 effect.element.style[transform.style]='';
});
}
}
}
 this.start(options);
},

 setup:function(){
 function parseColor(color){
 if(!color||['rgba(0, 0, 0, 0)','transparent'].include(color))color='#ffffff';
 color=color.parseColor();
 return $R(0,2).map(function(i){
 return parseInt(color.slice(i*2+1,i*2+3),16)
});
}
 this.transforms=this.style.map(function(pair){
 var property=pair[0],value=pair[1],unit=null;

 if(value.parseColor('#zzzzzz')!='#zzzzzz'){
 value=value.parseColor();
 unit='color';
}else if(property=='opacity'){
 value=parseFloat(value);
 if(Prototype.Browser.IE&&(!this.element.currentStyle.hasLayout))
 this.element.setStyle({zoom:1});
}else if(Element.CSS_LENGTH.test(value)){
 var components=value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
 value=parseFloat(components[1]);
 unit=(components.length==3)?components[2]:null;
}

 var originalValue=this.element.getStyle(property);
 return{
 style:property.camelize(),
 originalValue:unit=='color'?parseColor(originalValue):parseFloat(originalValue||0),
 targetValue:unit=='color'?parseColor(value):value,
 unit:unit
};
}.bind(this)).reject(function(transform){
 return(
(transform.originalValue==transform.targetValue)||
(
 transform.unit!='color'&&
(isNaN(transform.originalValue)||isNaN(transform.targetValue))
)
)
});
},
 update:function(position){
 var style={},transform,i=this.transforms.length;
 while(i--)
 style[(transform=this.transforms[i]).style]=
 transform.unit=='color'?'#'+
(Math.round(transform.originalValue[0]+
(transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart()+
(Math.round(transform.originalValue[1]+
(transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart()+
(Math.round(transform.originalValue[2]+
(transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart():
(transform.originalValue+
(transform.targetValue-transform.originalValue)*position).toFixed(3)+
(transform.unit===null?'':transform.unit);
 this.element.setStyle(style,true);
}
});

Effect.Transform=Class.create({
 initialize:function(tracks){
 this.tracks=[];
 this.options=arguments[1]||{};
 this.addTracks(tracks);
},
 addTracks:function(tracks){
 tracks.each(function(track){
 track=$H(track);
 var data=track.values().first();
 this.tracks.push($H({
 ids:track.keys().first(),
 effect:Effect.Morph,
 options:{style:data}
}));
}.bind(this));
 return this;
},
 play:function(){
 return new Effect.Parallel(
 this.tracks.map(function(track){
 var ids=track.get('ids'),effect=track.get('effect'),options=track.get('options');
 var elements=[$(ids)||$$(ids)].flatten();
 return elements.map(function(e){return new effect(e,Object.extend({sync:true},options))});
}).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 style,styleRules=$H();
 if(Prototype.Browser.WebKit)
 style=new Element('div',{style:this}).style;
 else{
 String.__parseStyleElement.innerHTML='<div style="'+this+'"></div>';
 style=String.__parseStyleElement.childNodes[0].style;
}

 Element.CSS_PROPERTIES.each(function(property){
 if(style[property])styleRules.set(property,style[property]);
});

 if(Prototype.Browser.IE&&this.include('opacity'))
 styleRules.set('opacity',this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

 return styleRules;
};

if(document.defaultView&&document.defaultView.getComputedStyle){
 Element.getStyles=function(element){
 var css=document.defaultView.getComputedStyle($(element),null);
 return Element.CSS_PROPERTIES.inject({},function(styles,property){
 styles[property]=css[property];
 return styles;
});
};
}else{
 Element.getStyles=function(element){
 element=$(element);
 var css=element.currentStyle,styles;
 styles=Element.CSS_PROPERTIES.inject({},function(hash,property){
 hash.set(property,css[property]);
 return hash;
});
 if(!styles.opacity)styles.set('opacity',element.getOpacity());
 return styles;
};
};

Effect.Methods={
 morph:function(element,style){
 element=$(element);
 new Effect.Morph(element,Object.extend({style:style},arguments[2]||{}));
 return element;
},
 visualEffect:function(element,effect,options){
 element=$(element)
 var s=effect.dasherize().camelize(),klass=s.charAt(0).toUpperCase()+s.substring(1);
 new Effect[klass](element,options);
 return element;
},
 highlight:function(element,options){
 element=$(element);
 new Effect.Highlight(element,options);
 return element;
}
};

$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
'pulsate shake puff squish switchOff dropOut').each(
 function(effect){
 Effect.Methods[effect]=function(element,options){
 element=$(element);
 Effect[effect.charAt(0).toUpperCase()+effect.substring(1)](element,options);
 return element;
}
}
);

$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
 function(f){Effect.Methods[f]=Element[f];}
);

Element.addMethods(Effect.Methods);









if(Object.isUndefined(Effect))
 throw("dragdrop.js requires including script.aculo.us' effects.js library");

var Droppables={
 drops:[],

 remove:function(element){
 this.drops=this.drops.reject(function(d){return d.element==$(element)});
},

 add:function(element){
 element=$(element);
 var options=Object.extend({
 greedy:true,
 hoverclass:null,
 tree:false
},arguments[1]||{});


 if(options.containment){
 options._containers=[];
 var containment=options.containment;
 if(Object.isArray(containment)){
 containment.each(function(c){options._containers.push($(c))});
}else{
 options._containers.push($(containment));
}
}

 if(options.accept)options.accept=[options.accept].flatten();

 Element.makePositioned(element);
 options.element=element;

 this.drops.push(options);
},

 findDeepestChild:function(drops){
 deepest=drops[0];

 for(i=1;i<drops.length;++i)
 if(Element.isParent(drops[i].element,deepest.element))
 deepest=drops[i];

 return deepest;
},

 isContained:function(element,drop){
 var containmentNode;
 if(drop.tree){
 containmentNode=element.treeNode;
}else{
 containmentNode=element.parentNode;
}
 return drop._containers.detect(function(c){return containmentNode==c});
},

 isAffected:function(point,element,drop){
 return(
(drop.element!=element)&&
((!drop._containers)||
 this.isContained(element,drop))&&
((!drop.accept)||
(Element.classNames(element).detect(
 function(v){return drop.accept.include(v)})))&&
 Position.within(drop.element,point[0],point[1]));
},

 deactivate:function(drop){
 if(drop.hoverclass)
 Element.removeClassName(drop.element,drop.hoverclass);
 this.last_active=null;
},

 activate:function(drop){
 if(drop.hoverclass)
 Element.addClassName(drop.element,drop.hoverclass);
 this.last_active=drop;
},

 show:function(point,element){
 if(!this.drops.length)return;
 var drop,affected=[];

 this.drops.each(function(drop){
 if(Droppables.isAffected(point,element,drop))
 affected.push(drop);
});

 if(affected.length>0)
 drop=Droppables.findDeepestChild(affected);

 if(this.last_active&&this.last_active!=drop)this.deactivate(this.last_active);
 if(drop){
 Position.within(drop.element,point[0],point[1]);
 if(drop.onHover)
 drop.onHover(element,drop.element,Position.overlap(drop.overlap,drop.element));

 if(drop!=this.last_active)Droppables.activate(drop);
}
},

 fire:function(event,element){
 if(!this.last_active)return;
 Position.prepare();

 if(this.isAffected([Event.pointerX(event),Event.pointerY(event)],element,this.last_active))
 if(this.last_active.onDrop){
 this.last_active.onDrop(element,this.last_active.element,event);
 return true;
}
},

 reset:function(){
 if(this.last_active)
 this.deactivate(this.last_active);
}
}

var Draggables={
 drags:[],
 observers:[],

 register:function(draggable){
 if(this.drags.length==0){
 this.eventMouseUp=this.endDrag.bindAsEventListener(this);
 this.eventMouseMove=this.updateDrag.bindAsEventListener(this);
 this.eventKeypress=this.keyPress.bindAsEventListener(this);

 Event.observe(document,"mouseup",this.eventMouseUp);
 Event.observe(document,"mousemove",this.eventMouseMove);
 Event.observe(document,"keypress",this.eventKeypress);
}
 this.drags.push(draggable);
},

 unregister:function(draggable){
 this.drags=this.drags.reject(function(d){return d==draggable});
 if(this.drags.length==0){
 Event.stopObserving(document,"mouseup",this.eventMouseUp);
 Event.stopObserving(document,"mousemove",this.eventMouseMove);
 Event.stopObserving(document,"keypress",this.eventKeypress);
}
},

 activate:function(draggable){
 if(draggable.options.delay){
 this._timeout=setTimeout(function(){
 Draggables._timeout=null;
 window.focus();
 Draggables.activeDraggable=draggable;
}.bind(this),draggable.options.delay);
}else{
 window.focus();
 this.activeDraggable=draggable;
}
},

 deactivate:function(){
 this.activeDraggable=null;
},

 updateDrag:function(event){
 if(!this.activeDraggable)return;
 var pointer=[Event.pointerX(event),Event.pointerY(event)];


 if(this._lastPointer&&(this._lastPointer.inspect()==pointer.inspect()))return;
 this._lastPointer=pointer;

 this.activeDraggable.updateDrag(event,pointer);
},

 endDrag:function(event){
 if(this._timeout){
 clearTimeout(this._timeout);
 this._timeout=null;
}
 if(!this.activeDraggable)return;
 this._lastPointer=null;
 this.activeDraggable.endDrag(event);
 this.activeDraggable=null;
},

 keyPress:function(event){
 if(this.activeDraggable)
 this.activeDraggable.keyPress(event);
},

 addObserver:function(observer){
 this.observers.push(observer);
 this._cacheObserverCallbacks();
},

 removeObserver:function(element){
 this.observers=this.observers.reject(function(o){return o.element==element});
 this._cacheObserverCallbacks();
},

 notify:function(eventName,draggable,event){
 if(this[eventName+'Count']>0)
 this.observers.each(function(o){
 if(o[eventName])o[eventName](eventName,draggable,event);
});
 if(draggable.options[eventName])draggable.options[eventName](draggable,event);
},

 _cacheObserverCallbacks:function(){
['onStart','onEnd','onDrag'].each(function(eventName){
 Draggables[eventName+'Count']=Draggables.observers.select(
 function(o){return o[eventName];}
).length;
});
}
}



var Draggable=Class.create({
 initialize:function(element){
 var defaults={
 handle:false,
 reverteffect:function(element,top_offset,left_offset){
 var dur=Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
 new Effect.Move(element,{x:-left_offset,y:-top_offset,duration:dur,
 queue:{scope:'_draggable',position:'end'}
});
},
 endeffect:function(element){
 var toOpacity=Object.isNumber(element._opacity)?element._opacity:1.0;
 new Effect.Opacity(element,{duration:0.2,from:0.7,to:toOpacity,
 queue:{scope:'_draggable',position:'end'},
 afterFinish:function(){
 Draggable._dragging[element]=false
}
});
},
 zindex:1000,
 revert:false,
 quiet:false,
 scroll:false,
 scrollSensitivity:20,
 scrollSpeed:15,
 snap:false,
 delay:0
};

 if(!arguments[1]||Object.isUndefined(arguments[1].endeffect))
 Object.extend(defaults,{
 starteffect:function(element){
 element._opacity=Element.getOpacity(element);
 Draggable._dragging[element]=true;
 new Effect.Opacity(element,{duration:0.2,from:element._opacity,to:0.7});
}
});

 var options=Object.extend(defaults,arguments[1]||{});

 this.element=$(element);

 if(options.handle&&Object.isString(options.handle))
 this.handle=this.element.down('.'+options.handle,0);

 if(!this.handle)this.handle=$(options.handle);
 if(!this.handle)this.handle=this.element;

 if(options.scroll&&!options.scroll.scrollTo&&!options.scroll.outerHTML){
 options.scroll=$(options.scroll);
 this._isScrollChild=Element.childOf(this.element,options.scroll);
}

 Element.makePositioned(this.element);

 this.options=options;
 this.dragging=false;

 this.eventMouseDown=this.initDrag.bindAsEventListener(this);
 Event.observe(this.handle,"mousedown",this.eventMouseDown);

 Draggables.register(this);
},

 destroy:function(){
 Event.stopObserving(this.handle,"mousedown",this.eventMouseDown);
 Draggables.unregister(this);
},

 currentDelta:function(){
 return([
 parseInt(Element.getStyle(this.element,'left')||'0'),
 parseInt(Element.getStyle(this.element,'top')||'0')]);
},

 initDrag:function(event){
 if(!Object.isUndefined(Draggable._dragging[this.element])&&
 Draggable._dragging[this.element])return;
 if(Event.isLeftClick(event)){

 var src=Event.element(event);
 if((tag_name=src.tagName.toUpperCase())&&(
 tag_name=='INPUT'||
 tag_name=='SELECT'||
 tag_name=='OPTION'||
 tag_name=='BUTTON'||
 tag_name=='TEXTAREA'))return;

 var pointer=[Event.pointerX(event),Event.pointerY(event)];
 var pos=Position.cumulativeOffset(this.element);
 this.offset=[0,1].map(function(i){return(pointer[i]-pos[i])});

 Draggables.activate(this);
 Event.stop(event);
}
},

 startDrag:function(event){
 this.dragging=true;
 if(!this.delta)
 this.delta=this.currentDelta();

 if(this.options.zindex){
 this.originalZ=parseInt(Element.getStyle(this.element,'z-index')||0);
 this.element.style.zIndex=this.options.zindex;
}

 if(this.options.ghosting){
 this._clone=this.element.cloneNode(true);
 this.element._originallyAbsolute=(this.element.getStyle('position')=='absolute');
 if(!this.element._originallyAbsolute)
 Position.absolutize(this.element);
 this.element.parentNode.insertBefore(this._clone,this.element);
}

 if(this.options.scroll){
 if(this.options.scroll==window){
 var where=this._getWindowScroll(this.options.scroll);
 this.originalScrollLeft=where.left;
 this.originalScrollTop=where.top;
}else{
 this.originalScrollLeft=this.options.scroll.scrollLeft;
 this.originalScrollTop=this.options.scroll.scrollTop;
}
}

 Draggables.notify('onStart',this,event);

 if(this.options.starteffect)this.options.starteffect(this.element);
},

 updateDrag:function(event,pointer){
 if(!this.dragging)this.startDrag(event);

 if(!this.options.quiet){
 Position.prepare();
 Droppables.show(pointer,this.element);
}

 Draggables.notify('onDrag',this,event);

 this.draw(pointer);
 if(this.options.change)this.options.change(this);

 if(this.options.scroll){
 this.stopScrolling();

 var p;
 if(this.options.scroll==window){
 with(this._getWindowScroll(this.options.scroll)){p=[left,top,left+width,top+height];}
}else{
 p=Position.page(this.options.scroll);
 p[0]+=this.options.scroll.scrollLeft+Position.deltaX;
 p[1]+=this.options.scroll.scrollTop+Position.deltaY;
 p.push(p[0]+this.options.scroll.offsetWidth);
 p.push(p[1]+this.options.scroll.offsetHeight);
}
 var speed=[0,0];
 if(pointer[0]<(p[0]+this.options.scrollSensitivity))speed[0]=pointer[0]-(p[0]+this.options.scrollSensitivity);
 if(pointer[1]<(p[1]+this.options.scrollSensitivity))speed[1]=pointer[1]-(p[1]+this.options.scrollSensitivity);
 if(pointer[0]>(p[2]-this.options.scrollSensitivity))speed[0]=pointer[0]-(p[2]-this.options.scrollSensitivity);
 if(pointer[1]>(p[3]-this.options.scrollSensitivity))speed[1]=pointer[1]-(p[3]-this.options.scrollSensitivity);
 this.startScrolling(speed);
}


 if(Prototype.Browser.WebKit)window.scrollBy(0,0);

 Event.stop(event);
},

 finishDrag:function(event,success){
 this.dragging=false;

 if(this.options.quiet){
 Position.prepare();
 var pointer=[Event.pointerX(event),Event.pointerY(event)];
 Droppables.show(pointer,this.element);
}

 if(this.options.ghosting){
 if(!this.element._originallyAbsolute)
 Position.relativize(this.element);
 delete this.element._originallyAbsolute;
 Element.remove(this._clone);
 this._clone=null;
}

 var dropped=false;
 if(success){
 dropped=Droppables.fire(event,this.element);
 if(!dropped)dropped=false;
}
 if(dropped&&this.options.onDropped)this.options.onDropped(this.element);
 Draggables.notify('onEnd',this,event);

 var revert=this.options.revert;
 if(revert&&Object.isFunction(revert))revert=revert(this.element);

 var d=this.currentDelta();
 if(revert&&this.options.reverteffect){
 if(dropped==0||revert!='failure')
 this.options.reverteffect(this.element,
 d[1]-this.delta[1],d[0]-this.delta[0]);
}else{
 this.delta=d;
}

 if(this.options.zindex)
 this.element.style.zIndex=this.originalZ;

 if(this.options.endeffect)
 this.options.endeffect(this.element);

 Draggables.deactivate(this);
 Droppables.reset();
},

 keyPress:function(event){
 if(event.keyCode!=Event.KEY_ESC)return;
 this.finishDrag(event,false);
 Event.stop(event);
},

 endDrag:function(event){
 if(!this.dragging)return;
 this.stopScrolling();
 this.finishDrag(event,true);
 Event.stop(event);
},

 draw:function(point){
 var pos=Position.cumulativeOffset(this.element);
 if(this.options.ghosting){
 var r=Position.realOffset(this.element);
 pos[0]+=r[0]-Position.deltaX;pos[1]+=r[1]-Position.deltaY;
}

 var d=this.currentDelta();
 pos[0]-=d[0];pos[1]-=d[1];

 if(this.options.scroll&&(this.options.scroll!=window&&this._isScrollChild)){
 pos[0]-=this.options.scroll.scrollLeft-this.originalScrollLeft;
 pos[1]-=this.options.scroll.scrollTop-this.originalScrollTop;
}

 var p=[0,1].map(function(i){
 return(point[i]-pos[i]-this.offset[i])
}.bind(this));

 if(this.options.snap){
 if(Object.isFunction(this.options.snap)){
 p=this.options.snap(p[0],p[1],this);
}else{
 if(Object.isArray(this.options.snap)){
 p=p.map(function(v,i){
 return(v/this.options.snap[i]).round()*this.options.snap[i]}.bind(this))
}else{
 p=p.map(function(v){
 return(v/this.options.snap).round()*this.options.snap}.bind(this))
}
}}

 var style=this.element.style;
 if((!this.options.constraint)||(this.options.constraint=='horizontal'))
 style.left=p[0]+"px";
 if((!this.options.constraint)||(this.options.constraint=='vertical'))
 style.top=p[1]+"px";

 if(style.visibility=="hidden")style.visibility="";
},

 stopScrolling:function(){
 if(this.scrollInterval){
 clearInterval(this.scrollInterval);
 this.scrollInterval=null;
 Draggables._lastScrollPointer=null;
}
},

 startScrolling:function(speed){
 if(!(speed[0]||speed[1]))return;
 this.scrollSpeed=[speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
 this.lastScrolled=new Date();
 this.scrollInterval=setInterval(this.scroll.bind(this),10);
},

 scroll:function(){
 var current=new Date();
 var delta=current-this.lastScrolled;
 this.lastScrolled=current;
 if(this.options.scroll==window){
 with(this._getWindowScroll(this.options.scroll)){
 if(this.scrollSpeed[0]||this.scrollSpeed[1]){
 var d=delta/1000;
 this.options.scroll.scrollTo(left+d*this.scrollSpeed[0],top+d*this.scrollSpeed[1]);
}
}
}else{
 this.options.scroll.scrollLeft+=this.scrollSpeed[0]*delta/1000;
 this.options.scroll.scrollTop+=this.scrollSpeed[1]*delta/1000;
}

 Position.prepare();
 Droppables.show(Draggables._lastPointer,this.element);
 Draggables.notify('onDrag',this);
 if(this._isScrollChild){
 Draggables._lastScrollPointer=Draggables._lastScrollPointer||$A(Draggables._lastPointer);
 Draggables._lastScrollPointer[0]+=this.scrollSpeed[0]*delta/1000;
 Draggables._lastScrollPointer[1]+=this.scrollSpeed[1]*delta/1000;
 if(Draggables._lastScrollPointer[0]<0)
 Draggables._lastScrollPointer[0]=0;
 if(Draggables._lastScrollPointer[1]<0)
 Draggables._lastScrollPointer[1]=0;
 this.draw(Draggables._lastScrollPointer);
}

 if(this.options.change)this.options.change(this);
},

 _getWindowScroll:function(w){
 var T,L,W,H;
 with(w.document){
 if(w.document.documentElement&&documentElement.scrollTop){
 T=documentElement.scrollTop;
 L=documentElement.scrollLeft;
}else if(w.document.body){
 T=body.scrollTop;
 L=body.scrollLeft;
}
 if(w.innerWidth){
 W=w.innerWidth;
 H=w.innerHeight;
}else if(w.document.documentElement&&documentElement.clientWidth){
 W=documentElement.clientWidth;
 H=documentElement.clientHeight;
}else{
 W=body.offsetWidth;
 H=body.offsetHeight
}
}
 return{top:T,left:L,width:W,height:H};
}
});

Draggable._dragging={};



var SortableObserver=Class.create({
 initialize:function(element,observer){
 this.element=$(element);
 this.observer=observer;
 this.lastValue=Sortable.serialize(this.element);
},

 onStart:function(){
 this.lastValue=Sortable.serialize(this.element);
},

 onEnd:function(){
 Sortable.unmark();
 if(this.lastValue!=Sortable.serialize(this.element))
 this.observer(this.element)
}
});

var Sortable={
 SERIALIZE_RULE:/^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,

 sortables:{},

 _findRootElement:function(element){
 while(element.tagName.toUpperCase()!="BODY"){
 if(element.id&&Sortable.sortables[element.id])return element;
 element=element.parentNode;
}
},

 options:function(element){
 element=Sortable._findRootElement($(element));
 if(!element)return;
 return Sortable.sortables[element.id];
},

 destroy:function(element){
 var s=Sortable.options(element);

 if(s){
 Draggables.removeObserver(s.element);
 s.droppables.each(function(d){Droppables.remove(d)});
 s.draggables.invoke('destroy');

 delete Sortable.sortables[s.element.id];
}
},

 create:function(element){
 element=$(element);
 var options=Object.extend({
 element:element,
 tag:'li',
 dropOnEmpty:false,
 tree:false,
 treeTag:'ul',
 overlap:'vertical',
 constraint:'vertical',
 containment:element,
 handle:false,
 only:false,
 delay:0,
 hoverclass:null,
 ghosting:false,
 quiet:false,
 scroll:false,
 scrollSensitivity:20,
 scrollSpeed:15,
 format:this.SERIALIZE_RULE,



 elements:false,
 handles:false,

 onChange:Prototype.emptyFunction,
 onUpdate:Prototype.emptyFunction
},arguments[1]||{});


 this.destroy(element);


 var options_for_draggable={
 revert:true,
 quiet:options.quiet,
 scroll:options.scroll,
 scrollSpeed:options.scrollSpeed,
 scrollSensitivity:options.scrollSensitivity,
 delay:options.delay,
 ghosting:options.ghosting,
 constraint:options.constraint,
 handle:options.handle};

 if(options.starteffect)
 options_for_draggable.starteffect=options.starteffect;

 if(options.reverteffect)
 options_for_draggable.reverteffect=options.reverteffect;
 else
 if(options.ghosting)options_for_draggable.reverteffect=function(element){
 element.style.top=0;
 element.style.left=0;
};

 if(options.endeffect)
 options_for_draggable.endeffect=options.endeffect;

 if(options.zindex)
 options_for_draggable.zindex=options.zindex;


 var options_for_droppable={
 overlap:options.overlap,
 containment:options.containment,
 tree:options.tree,
 hoverclass:options.hoverclass,
 onHover:Sortable.onHover
}

 var options_for_tree={
 onHover:Sortable.onEmptyHover,
 overlap:options.overlap,
 containment:options.containment,
 hoverclass:options.hoverclass
}


 Element.cleanWhitespace(element);

 options.draggables=[];
 options.droppables=[];


 if(options.dropOnEmpty||options.tree){
 Droppables.add(element,options_for_tree);
 options.droppables.push(element);
}

(options.elements||this.findElements(element,options)||[]).each(function(e,i){
 var handle=options.handles?$(options.handles[i]):
(options.handle?$(e).select('.'+options.handle)[0]:e);
 options.draggables.push(
 new Draggable(e,Object.extend(options_for_draggable,{handle:handle})));
 Droppables.add(e,options_for_droppable);
 if(options.tree)e.treeNode=element;
 options.droppables.push(e);
});

 if(options.tree){
(Sortable.findTreeElements(element,options)||[]).each(function(e){
 Droppables.add(e,options_for_tree);
 e.treeNode=element;
 options.droppables.push(e);
});
}


 this.sortables[element.id]=options;


 Draggables.addObserver(new SortableObserver(element,options.onUpdate));

},


 findElements:function(element,options){
 return Element.findChildren(
 element,options.only,options.tree?true:false,options.tag);
},

 findTreeElements:function(element,options){
 return Element.findChildren(
 element,options.only,options.tree?true:false,options.treeTag);
},

 onHover:function(element,dropon,overlap){
 if(Element.isParent(dropon,element))return;

 if(overlap>.33&&overlap<.66&&Sortable.options(dropon).tree){
 return;
}else if(overlap>0.5){
 Sortable.mark(dropon,'before');
 if(dropon.previousSibling!=element){
 var oldParentNode=element.parentNode;
 element.style.visibility="hidden";
 dropon.parentNode.insertBefore(element,dropon);
 if(dropon.parentNode!=oldParentNode)
 Sortable.options(oldParentNode).onChange(element);
 Sortable.options(dropon.parentNode).onChange(element);
}
}else{
 Sortable.mark(dropon,'after');
 var nextElement=dropon.nextSibling||null;
 if(nextElement!=element){
 var oldParentNode=element.parentNode;
 element.style.visibility="hidden";
 dropon.parentNode.insertBefore(element,nextElement);
 if(dropon.parentNode!=oldParentNode)
 Sortable.options(oldParentNode).onChange(element);
 Sortable.options(dropon.parentNode).onChange(element);
}
}
},

 onEmptyHover:function(element,dropon,overlap){
 var oldParentNode=element.parentNode;
 var droponOptions=Sortable.options(dropon);

 if(!Element.isParent(dropon,element)){
 var index;

 var children=Sortable.findElements(dropon,{tag:droponOptions.tag,only:droponOptions.only});
 var child=null;

 if(children){
 var offset=Element.offsetSize(dropon,droponOptions.overlap)*(1.0-overlap);

 for(index=0;index<children.length;index+=1){
 if(offset-Element.offsetSize(children[index],droponOptions.overlap)>=0){
 offset-=Element.offsetSize(children[index],droponOptions.overlap);
}else if(offset-(Element.offsetSize(children[index],droponOptions.overlap)/2)>=0){
 child=index+1<children.length?children[index+1]:null;
 break;
}else{
 child=children[index];
 break;
}
}
}

 dropon.insertBefore(element,child);

 Sortable.options(oldParentNode).onChange(element);
 droponOptions.onChange(element);
}
},

 unmark:function(){
 if(Sortable._marker)Sortable._marker.hide();
},

 mark:function(dropon,position){

 var sortable=Sortable.options(dropon.parentNode);
 if(sortable&&!sortable.ghosting)return;

 if(!Sortable._marker){
 Sortable._marker=
($('dropmarker')||Element.extend(document.createElement('DIV'))).
 hide().addClassName('dropmarker').setStyle({position:'absolute'});
 document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
}
 var offsets=Position.cumulativeOffset(dropon);
 Sortable._marker.setStyle({left:offsets[0]+'px',top:offsets[1]+'px'});

 if(position=='after')
 if(sortable.overlap=='horizontal')
 Sortable._marker.setStyle({left:(offsets[0]+dropon.clientWidth)+'px'});
 else
 Sortable._marker.setStyle({top:(offsets[1]+dropon.clientHeight)+'px'});

 Sortable._marker.show();
},

 _tree:function(element,options,parent){
 var children=Sortable.findElements(element,options)||[];

 for(var i=0;i<children.length;++i){
 var match=children[i].id.match(options.format);

 if(!match)continue;

 var child={
 id:encodeURIComponent(match?match[1]:null),
 element:element,
 parent:parent,
 children:[],
 position:parent.children.length,
 container:$(children[i]).down(options.treeTag)
}


 if(child.container)
 this._tree(child.container,options,child)

 parent.children.push(child);
}

 return parent;
},

 tree:function(element){
 element=$(element);
 var sortableOptions=this.options(element);
 var options=Object.extend({
 tag:sortableOptions.tag,
 treeTag:sortableOptions.treeTag,
 only:sortableOptions.only,
 name:element.id,
 format:sortableOptions.format
},arguments[1]||{});

 var root={
 id:null,
 parent:null,
 children:[],
 container:element,
 position:0
}

 return Sortable._tree(element,options,root);
},


 _constructIndex:function(node){
 var index='';
 do{
 if(node.id)index='['+node.position+']'+index;
}while((node=node.parent)!=null);
 return index;
},

 sequence:function(element){
 element=$(element);
 var options=Object.extend(this.options(element),arguments[1]||{});

 return $(this.findElements(element,options)||[]).map(function(item){
 return item.id.match(options.format)?item.id.match(options.format)[1]:'';
});
},

 setSequence:function(element,new_sequence){
 element=$(element);
 var options=Object.extend(this.options(element),arguments[2]||{});

 var nodeMap={};
 this.findElements(element,options).each(function(n){
 if(n.id.match(options.format))
 nodeMap[n.id.match(options.format)[1]]=[n,n.parentNode];
 n.parentNode.removeChild(n);
});

 new_sequence.each(function(ident){
 var n=nodeMap[ident];
 if(n){
 n[1].appendChild(n[0]);
 delete nodeMap[ident];
}
});
},

 serialize:function(element){
 element=$(element);
 var options=Object.extend(Sortable.options(element),arguments[1]||{});
 var name=encodeURIComponent(
(arguments[1]&&arguments[1].name)?arguments[1].name:element.id);

 if(options.tree){
 return Sortable.tree(element,arguments[1]).children.map(function(item){
 return[name+Sortable._constructIndex(item)+"[id]="+
 encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
}).flatten().join('&');
}else{
 return Sortable.sequence(element,arguments[1]).map(function(item){
 return name+"[]="+encodeURIComponent(item);
}).join('&');
}
}
}


Element.isParent=function(child,element){
 if(!child.parentNode||child==element)return false;
 if(child.parentNode==element)return true;
 return Element.isParent(child.parentNode,element);
}

Element.findChildren=function(element,only,recursive,tagName){
 if(!element.hasChildNodes())return null;
 tagName=tagName.toUpperCase();
 if(only)only=[only].flatten();
 var elements=[];
 $A(element.childNodes).each(function(e){
 if(e.tagName&&e.tagName.toUpperCase()==tagName&&
(!only||(Element.classNames(e).detect(function(v){return only.include(v)}))))
 elements.push(e);
 if(recursive){
 var grandchildren=Element.findChildren(e,only,recursive,tagName);
 if(grandchildren)elements.push(grandchildren);
}
});

 return(elements.length>0?elements.flatten():[]);
}

Element.offsetSize=function(element,type){
 return element['offset'+((type=='vertical'||type=='height')?'Height':'Width')];
}





Object.extend(Droppables,{

 add:Droppables.add.wrap(function(proceed,element,options){
 if(!!options&&options.containment&&typeof(options.containment)=='function'){
 options._containmentBuilder=options.containment;
 options._containers='dynamic';
 options.containment=null;
};
 return proceed(element,options);
}),

 isContained:Droppables.isContained.wrap(function(proceed,element,drop){
 if(!!drop._containmentBuilder&&typeof(drop._containmentBuilder)=='function')drop._containers=drop._containmentBuilder();
 return proceed(element,drop);
}),

 reset:Droppables.reset.wrap(function(proceed){
 this.drops.each(function(drop){
 if(drop._containmentBuilder)drop._containers='dynamic';
});
 return proceed();
})

});






































if(typeof Effect=='undefined')
 throw("controls.js requires including script.aculo.us' effects.js library");

var Autocompleter={}
Autocompleter.Base=Class.create({
 baseInitialize:function(element,update,options){
 element=$(element)
 this.element=element;
 this.update=$(update);
 this.hasFocus=false;
 this.changed=false;
 this.active=false;
 this.index=0;
 this.entryCount=0;
 this.oldElementValue=this.element.value;

 if(this.setOptions)
 this.setOptions(options);
 else
 this.options=options||{};

 this.options.paramName=this.options.paramName||this.element.name;
 this.options.tokens=this.options.tokens||[];
 this.options.frequency=this.options.frequency||0.4;
 this.options.minChars=this.options.minChars||1;
 this.options.onShow=this.options.onShow||
 function(element,update){
 if(!update.style.position||update.style.position=='absolute'){
 update.style.position='absolute';
 Position.clone(element,update,{
 setHeight:false,
 offsetTop:element.offsetHeight
});
}
 Effect.Appear(update,{duration:0.15});
};
 this.options.onHide=this.options.onHide||
 function(element,update){new Effect.Fade(update,{duration:0.15})};

 if(typeof(this.options.tokens)=='string')
 this.options.tokens=new Array(this.options.tokens);

 if(!this.options.tokens.include('\n'))
 this.options.tokens.push('\n');

 this.observer=null;

 this.element.setAttribute('autocomplete','off');

 Element.hide(this.update);

 Event.observe(this.element,'blur',this.onBlur.bindAsEventListener(this));
 Event.observe(this.element,'keypress',this.onKeyPress.bindAsEventListener(this));
},

 show:function(){
 if(Element.getStyle(this.update,'display')=='none')this.options.onShow(this.element,this.update);
 if(!this.iefix&&
(Prototype.Browser.IE)&&
(Element.getStyle(this.update,'position')=='absolute')){
 new Insertion.After(this.update,
'<iframe id="'+this.update.id+'_iefix" '+
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" '+
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
 this.iefix=$(this.update.id+'_iefix');
}
 if(this.iefix)setTimeout(this.fixIEOverlapping.bind(this),50);
},

 fixIEOverlapping:function(){
 Position.clone(this.update,this.iefix,{setTop:(!this.update.style.height)});
 this.iefix.style.zIndex=1;
 this.update.style.zIndex=2;
 Element.show(this.iefix);
},

 hide:function(){
 this.stopIndicator();
 if(Element.getStyle(this.update,'display')!='none')this.options.onHide(this.element,this.update);
 if(this.iefix)Element.hide(this.iefix);
},

 startIndicator:function(){
 if(this.options.indicator)Element.show(this.options.indicator);
},

 stopIndicator:function(){
 if(this.options.indicator)Element.hide(this.options.indicator);
},

 onKeyPress:function(event){
 if(this.active)
 switch(event.keyCode){
 case Event.KEY_TAB:
 case Event.KEY_RETURN:
 this.selectEntry();
 Event.stop(event);
 case Event.KEY_ESC:
 this.hide();
 this.active=false;
 Event.stop(event);
 return;
 case Event.KEY_LEFT:
 case Event.KEY_RIGHT:
 return;
 case Event.KEY_UP:
 this.markPrevious();
 this.render();
 if(Prototype.Browser.WebKit)Event.stop(event);
 return;
 case Event.KEY_DOWN:
 this.markNext();
 this.render();
 if(Prototype.Browser.WebKit)Event.stop(event);
 return;
}
 else
 if(event.keyCode==Event.KEY_TAB||event.keyCode==Event.KEY_RETURN||
(Prototype.Browser.WebKit>0&&event.keyCode==0))return;

 this.changed=true;
 this.hasFocus=true;

 if(this.observer)clearTimeout(this.observer);
 this.observer=
 setTimeout(this.onObserverEvent.bind(this),this.options.frequency*1000);
},

 activate:function(){
 this.changed=false;
 this.hasFocus=true;
 this.getUpdatedChoices();
},

 onHover:function(event){
 var element=Event.findElement(event,'LI');
 if(this.index!=element.autocompleteIndex)
{
 this.index=element.autocompleteIndex;
 this.render();
}
 Event.stop(event);
},

 onClick:function(event){
 var element=Event.findElement(event,'LI');
 this.index=element.autocompleteIndex;
 this.selectEntry();
 this.hide();
},

 onBlur:function(event){

 setTimeout(this.hide.bind(this),250);
 this.hasFocus=false;
 this.active=false;
},

 render:function(){
 if(this.entryCount>0){
 for(var i=0;i<this.entryCount;i++)
 this.index==i?
 Element.addClassName(this.getEntry(i),"selected"):
 Element.removeClassName(this.getEntry(i),"selected");
 if(this.hasFocus){
 this.show();
 this.active=true;
}
}else{
 this.active=false;
 this.hide();
}
},

 markPrevious:function(){
 if(this.index>0)this.index--
 else this.index=this.entryCount-1;
 this.getEntry(this.index).scrollIntoView(true);
},

 markNext:function(){
 if(this.index<this.entryCount-1)this.index++
 else this.index=0;
 this.getEntry(this.index).scrollIntoView(false);
},

 getEntry:function(index){
 return this.update.firstChild.childNodes[index];
},

 getCurrentEntry:function(){
 return this.getEntry(this.index);
},

 selectEntry:function(){
 this.active=false;
 this.updateElement(this.getCurrentEntry());
},

 updateElement:function(selectedElement){
 if(this.options.updateElement){
 this.options.updateElement(selectedElement);
 return;
}
 var value='';
 if(this.options.select){
 var nodes=$(selectedElement).select('.'+this.options.select)||[];
 if(nodes.length>0)value=Element.collectTextNodes(nodes[0],this.options.select);
}else
 value=Element.collectTextNodesIgnoreClass(selectedElement,'informal');

 var bounds=this.getTokenBounds();
 if(bounds[0]!=-1){
 var newValue=this.element.value.substr(0,bounds[0]);
 var whitespace=this.element.value.substr(bounds[0]).match(/^\s+/);
 if(whitespace)
 newValue+=whitespace[0];
 this.element.value=newValue+value+this.element.value.substr(bounds[1]);
}else{
 this.element.value=value;
}
 this.oldElementValue=this.element.value;
 this.element.focus();

 if(this.options.afterUpdateElement)
 this.options.afterUpdateElement(this.element,selectedElement);
},

 updateChoices:function(choices){
 if(!this.changed&&this.hasFocus){
 this.update.innerHTML=choices;
 Element.cleanWhitespace(this.update);
 Element.cleanWhitespace(this.update.down());

 if(this.update.firstChild&&this.update.down().childNodes){
 this.entryCount=
 this.update.down().childNodes.length;
 for(var i=0;i<this.entryCount;i++){
 var entry=this.getEntry(i);
 entry.autocompleteIndex=i;
 this.addObservers(entry);
}
}else{
 this.entryCount=0;
}

 this.stopIndicator();
 this.index=0;

 if(this.entryCount==1&&this.options.autoSelect){
 this.selectEntry();
 this.hide();
}else{
 this.render();
}
}
},

 addObservers:function(element){
 Event.observe(element,"mouseover",this.onHover.bindAsEventListener(this));
 Event.observe(element,"click",this.onClick.bindAsEventListener(this));
},

 onObserverEvent:function(){
 this.changed=false;
 this.tokenBounds=null;
 if(this.getToken().length>=this.options.minChars){
 this.getUpdatedChoices();
}else{
 this.active=false;
 this.hide();
}
 this.oldElementValue=this.element.value;
},

 getToken:function(){
 var bounds=this.getTokenBounds();
 return this.element.value.substring(bounds[0],bounds[1]).strip();
},

 getTokenBounds:function(){
 if(null!=this.tokenBounds)return this.tokenBounds;
 var value=this.element.value;
 if(value.strip().empty())return[-1,0];
 var diff=arguments.callee.getFirstDifferencePos(value,this.oldElementValue);
 var offset=(diff==this.oldElementValue.length?1:0);
 var prevTokenPos=-1,nextTokenPos=value.length;
 var tp;
 for(var index=0,l=this.options.tokens.length;index<l;++index){
 tp=value.lastIndexOf(this.options.tokens[index],diff+offset-1);
 if(tp>prevTokenPos)prevTokenPos=tp;
 tp=value.indexOf(this.options.tokens[index],diff+offset);
 if(-1!=tp&&tp<nextTokenPos)nextTokenPos=tp;
}
 return(this.tokenBounds=[prevTokenPos+1,nextTokenPos]);
}
});

Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos=function(newS,oldS){
 var boundary=Math.min(newS.length,oldS.length);
 for(var index=0;index<boundary;++index)
 if(newS[index]!=oldS[index])
 return index;
 return boundary;
};

Ajax.Autocompleter=Class.create(Autocompleter.Base,{
 initialize:function(element,update,url,options){
 this.baseInitialize(element,update,options);
 this.options.asynchronous=true;
 this.options.onComplete=this.onComplete.bind(this);
 this.options.defaultParams=this.options.parameters||null;
 this.url=url;
},

 getUpdatedChoices:function(){
 this.startIndicator();

 var entry=encodeURIComponent(this.options.paramName)+'='+
 encodeURIComponent(this.getToken());

 this.options.parameters=this.options.callback?
 this.options.callback(this.element,entry):entry;

 if(this.options.defaultParams)
 this.options.parameters+='&'+this.options.defaultParams;

 new Ajax.Request(this.url,this.options);
},

 onComplete:function(request){
 this.updateChoices(request.responseText);
}
});




































Autocompleter.Local=Class.create(Autocompleter.Base,{
 initialize:function(element,update,array,options){
 this.baseInitialize(element,update,options);
 this.options.array=array;
},

 getUpdatedChoices:function(){
 this.updateChoices(this.options.selector(this));
},

 setOptions:function(options){
 this.options=Object.extend({
 choices:10,
 partialSearch:true,
 partialChars:2,
 ignoreCase:true,
 fullSearch:false,
 selector:function(instance){
 var ret=[];
 var partial=[];
 var entry=instance.getToken();
 var count=0;

 for(var i=0;i<instance.options.array.length&&
 ret.length<instance.options.choices;i++){

 var elem=instance.options.array[i];
 var foundPos=instance.options.ignoreCase?
 elem.toLowerCase().indexOf(entry.toLowerCase()):
 elem.indexOf(entry);

 while(foundPos!=-1){
 if(foundPos==0&&elem.length!=entry.length){
 ret.push("<li><strong>"+elem.substr(0,entry.length)+"</strong>"+
 elem.substr(entry.length)+"</li>");
 break;
}else if(entry.length>=instance.options.partialChars&&
 instance.options.partialSearch&&foundPos!=-1){
 if(instance.options.fullSearch||/\s/.test(elem.substr(foundPos-1,1))){
 partial.push("<li>"+elem.substr(0,foundPos)+"<strong>"+
 elem.substr(foundPos,entry.length)+"</strong>"+elem.substr(
 foundPos+entry.length)+"</li>");
 break;
}
}

 foundPos=instance.options.ignoreCase?
 elem.toLowerCase().indexOf(entry.toLowerCase(),foundPos+1):
 elem.indexOf(entry,foundPos+1);

}
}
 if(partial.length)
 ret=ret.concat(partial.slice(0,instance.options.choices-ret.length))
 return"<ul>"+ret.join('')+"</ul>";
}
},options||{});
}
});







Field.scrollFreeActivate=function(field){
 setTimeout(function(){
 Field.activate(field);
},1);
}

Ajax.InPlaceEditor=Class.create({
 initialize:function(element,url,options){
 this.url=url;
 this.element=element=$(element);
 this.prepareOptions();
 this._controls={};
 arguments.callee.dealWithDeprecatedOptions(options);
 Object.extend(this.options,options||{});
 if(!this.options.formId&&this.element.id){
 this.options.formId=this.element.id+'-inplaceeditor';
 if($(this.options.formId))
 this.options.formId='';
}
 if(this.options.externalControl)
 this.options.externalControl=$(this.options.externalControl);
 if(!this.options.externalControl)
 this.options.externalControlOnly=false;
 this._originalBackground=this.element.getStyle('background-color')||'transparent';
 this.element.title=this.options.clickToEditText;
 this._boundCancelHandler=this.handleFormCancellation.bind(this);
 this._boundComplete=(this.options.onComplete||Prototype.emptyFunction).bind(this);
 this._boundFailureHandler=this.handleAJAXFailure.bind(this);
 this._boundSubmitHandler=this.handleFormSubmission.bind(this);
 this._boundWrapperHandler=this.wrapUp.bind(this);
 this.registerListeners();
},
 checkForEscapeOrReturn:function(e){
 if(!this._editing||e.ctrlKey||e.altKey||e.shiftKey)return;
 if(Event.KEY_ESC==e.keyCode)
 this.handleFormCancellation(e);
 else if(Event.KEY_RETURN==e.keyCode)
 this.handleFormSubmission(e);
},
 createControl:function(mode,handler,extraClasses){
 var control=this.options[mode+'Control'];
 var text=this.options[mode+'Text'];
 if('button'==control){
 var btn=document.createElement('input');
 btn.type='submit';
 btn.value=text;
 btn.className='editor_'+mode+'_button';
 if('cancel'==mode)
 btn.onclick=this._boundCancelHandler;
 this._form.appendChild(btn);
 this._controls[mode]=btn;
}else if('link'==control){
 var link=document.createElement('a');
 link.href='#';
 link.appendChild(document.createTextNode(text));
 link.onclick='cancel'==mode?this._boundCancelHandler:this._boundSubmitHandler;
 link.className='editor_'+mode+'_link';
 if(extraClasses)
 link.className+=' '+extraClasses;
 this._form.appendChild(link);
 this._controls[mode]=link;
}
},
 createEditField:function(){
 var text=(this.options.loadTextURL?this.options.loadingText:this.getText());
 var fld;
 if(1>=this.options.rows&&!/\r|\n/.test(this.getText())){
 fld=document.createElement('input');
 fld.type='text';
 var size=this.options.size||this.options.cols||0;
 if(0<size)fld.size=size;
}else{
 fld=document.createElement('textarea');
 fld.rows=(1>=this.options.rows?this.options.autoRows:this.options.rows);
 fld.cols=this.options.cols||40;
}
 fld.name=this.options.paramName;
 fld.value=text;
 fld.className='editor_field';
 if(this.options.submitOnBlur)
 fld.onblur=this._boundSubmitHandler;
 this._controls.editor=fld;
 if(this.options.loadTextURL)
 this.loadExternalText();
 this._form.appendChild(this._controls.editor);
},
 createForm:function(){
 var ipe=this;
 function addText(mode,condition){
 var text=ipe.options['text'+mode+'Controls'];
 if(!text||condition===false)return;
 ipe._form.appendChild(document.createTextNode(text));
};
 this._form=$(document.createElement('form'));
 this._form.id=this.options.formId;
 this._form.addClassName(this.options.formClassName);
 this._form.onsubmit=this._boundSubmitHandler;
 this.createEditField();
 if('textarea'==this._controls.editor.tagName.toLowerCase())
 this._form.appendChild(document.createElement('br'));
 if(this.options.onFormCustomization)
 this.options.onFormCustomization(this,this._form);
 addText('Before',this.options.okControl||this.options.cancelControl);
 this.createControl('ok',this._boundSubmitHandler);
 addText('Between',this.options.okControl&&this.options.cancelControl);
 this.createControl('cancel',this._boundCancelHandler,'editor_cancel');
 addText('After',this.options.okControl||this.options.cancelControl);
},
 destroy:function(){
 if(this._oldInnerHTML)
 this.element.innerHTML=this._oldInnerHTML;
 this.leaveEditMode();
 this.unregisterListeners();
},
 enterEditMode:function(e){
 if(this._saving||this._editing)return;
 this._editing=true;
 this.triggerCallback('onEnterEditMode');
 if(this.options.externalControl)
 this.options.externalControl.hide();
 this.element.hide();
 this.createForm();
 this.element.parentNode.insertBefore(this._form,this.element);
 if(!this.options.loadTextURL)
 this.postProcessEditField();
 if(e)Event.stop(e);
},
 enterHover:function(e){
 if(this.options.hoverClassName)
 this.element.addClassName(this.options.hoverClassName);
 if(this._saving)return;
 this.triggerCallback('onEnterHover');
},
 getText:function(){
 return this.element.innerHTML;
},
 handleAJAXFailure:function(transport){
 this.triggerCallback('onFailure',transport);
 if(this._oldInnerHTML){
 this.element.innerHTML=this._oldInnerHTML;
 this._oldInnerHTML=null;
}
},
 handleFormCancellation:function(e){
 this.wrapUp();
 if(e)Event.stop(e);
},
 handleFormSubmission:function(e){
 var form=this._form;
 var value=$F(this._controls.editor);
 this.prepareSubmission();
 var params=this.options.callback(form,value)||'';
 if(Object.isString(params))
 params=params.toQueryParams();
 params.editorId=this.element.id;
 if(this.options.htmlResponse){
 var options=Object.extend({evalScripts:true},this.options.ajaxOptions);
 Object.extend(options,{
 parameters:params,
 onComplete:this._boundWrapperHandler,
 onFailure:this._boundFailureHandler
});
 new Ajax.Updater({success:this.element},this.url,options);
}else{
 var options=Object.extend({method:'get'},this.options.ajaxOptions);
 Object.extend(options,{
 parameters:params,
 onComplete:this._boundWrapperHandler,
 onFailure:this._boundFailureHandler
});
 new Ajax.Request(this.url,options);
}
 if(e)Event.stop(e);
},
 leaveEditMode:function(){
 this.element.removeClassName(this.options.savingClassName);
 this.removeForm();
 this.leaveHover();
 this.element.style.backgroundColor=this._originalBackground;
 this.element.show();
 if(this.options.externalControl)
 this.options.externalControl.show();
 this._saving=false;
 this._editing=false;
 this._oldInnerHTML=null;
 this.triggerCallback('onLeaveEditMode');
},
 leaveHover:function(e){
 if(this.options.hoverClassName)
 this.element.removeClassName(this.options.hoverClassName);
 if(this._saving)return;
 this.triggerCallback('onLeaveHover');
},
 loadExternalText:function(){
 this._form.addClassName(this.options.loadingClassName);
 this._controls.editor.disabled=true;
 var options=Object.extend({method:'get'},this.options.ajaxOptions);
 Object.extend(options,{
 parameters:'editorId='+encodeURIComponent(this.element.id),
 onComplete:Prototype.emptyFunction,
 onSuccess:function(transport){
 this._form.removeClassName(this.options.loadingClassName);
 var text=transport.responseText;
 if(this.options.stripLoadedTextTags)
 text=text.stripTags();
 this._controls.editor.value=text;
 this._controls.editor.disabled=false;
 this.postProcessEditField();
}.bind(this),
 onFailure:this._boundFailureHandler
});
 new Ajax.Request(this.options.loadTextURL,options);
},
 postProcessEditField:function(){
 var fpc=this.options.fieldPostCreation;
 if(fpc)
 $(this._controls.editor)['focus'==fpc?'focus':'activate']();
},
 prepareOptions:function(){
 this.options=Object.clone(Ajax.InPlaceEditor.DefaultOptions);
 Object.extend(this.options,Ajax.InPlaceEditor.DefaultCallbacks);
[this._extraDefaultOptions].flatten().compact().each(function(defs){
 Object.extend(this.options,defs);
}.bind(this));
},
 prepareSubmission:function(){
 this._saving=true;
 this.removeForm();
 this.leaveHover();
 this.showSaving();
},
 registerListeners:function(){
 this._listeners={};
 var listener;
 $H(Ajax.InPlaceEditor.Listeners).each(function(pair){
 listener=this[pair.value].bind(this);
 this._listeners[pair.key]=listener;
 if(!this.options.externalControlOnly)
 this.element.observe(pair.key,listener);
 if(this.options.externalControl)
 this.options.externalControl.observe(pair.key,listener);
}.bind(this));
},
 removeForm:function(){
 if(!this._form)return;
 this._form.remove();
 this._form=null;
 this._controls={};
},
 showSaving:function(){
 this._oldInnerHTML=this.element.innerHTML;
 this.element.innerHTML=this.options.savingText;
 this.element.addClassName(this.options.savingClassName);
 this.element.style.backgroundColor=this._originalBackground;
 this.element.show();
},
 triggerCallback:function(cbName,arg){
 if('function'==typeof this.options[cbName]){
 this.options[cbName](this,arg);
}
},
 unregisterListeners:function(){
 $H(this._listeners).each(function(pair){
 if(!this.options.externalControlOnly)
 this.element.stopObserving(pair.key,pair.value);
 if(this.options.externalControl)
 this.options.externalControl.stopObserving(pair.key,pair.value);
}.bind(this));
},
 wrapUp:function(transport){
 this.leaveEditMode();


 this._boundComplete(transport,this.element);
}
});

Object.extend(Ajax.InPlaceEditor.prototype,{
 dispose:Ajax.InPlaceEditor.prototype.destroy
});

Ajax.InPlaceCollectionEditor=Class.create(Ajax.InPlaceEditor,{
 initialize:function($super,element,url,options){
 this._extraDefaultOptions=Ajax.InPlaceCollectionEditor.DefaultOptions;
 $super(element,url,options);
},

 createEditField:function(){
 var list=document.createElement('select');
 list.name=this.options.paramName;
 list.size=1;
 this._controls.editor=list;
 this._collection=this.options.collection||[];
 if(this.options.loadCollectionURL)
 this.loadCollection();
 else
 this.checkForExternalText();
 this._form.appendChild(this._controls.editor);
},

 loadCollection:function(){
 this._form.addClassName(this.options.loadingClassName);
 this.showLoadingText(this.options.loadingCollectionText);
 var options=Object.extend({method:'get'},this.options.ajaxOptions);
 Object.extend(options,{
 parameters:'editorId='+encodeURIComponent(this.element.id),
 onComplete:Prototype.emptyFunction,
 onSuccess:function(transport){
 var js=transport.responseText.strip();
 if(!/^\[.*\]$/.test(js))
 throw'Server returned an invalid collection representation.';
 this._collection=eval(js);
 this.checkForExternalText();
}.bind(this),
 onFailure:this.onFailure
});
 new Ajax.Request(this.options.loadCollectionURL,options);
},

 showLoadingText:function(text){
 this._controls.editor.disabled=true;
 var tempOption=this._controls.editor.firstChild;
 if(!tempOption){
 tempOption=document.createElement('option');
 tempOption.value='';
 this._controls.editor.appendChild(tempOption);
 tempOption.selected=true;
}
 tempOption.update((text||'').stripScripts().stripTags());
},

 checkForExternalText:function(){
 this._text=this.getText();
 if(this.options.loadTextURL)
 this.loadExternalText();
 else
 this.buildOptionList();
},

 loadExternalText:function(){
 this.showLoadingText(this.options.loadingText);
 var options=Object.extend({method:'get'},this.options.ajaxOptions);
 Object.extend(options,{
 parameters:'editorId='+encodeURIComponent(this.element.id),
 onComplete:Prototype.emptyFunction,
 onSuccess:function(transport){
 this._text=transport.responseText.strip();
 this.buildOptionList();
}.bind(this),
 onFailure:this.onFailure
});
 new Ajax.Request(this.options.loadTextURL,options);
},

 buildOptionList:function(){
 this._form.removeClassName(this.options.loadingClassName);
 this._collection=this._collection.map(function(entry){
 return 2===entry.length?entry:[entry,entry].flatten();
});
 var marker=('value'in this.options)?this.options.value:this._text;
 var textFound=this._collection.any(function(entry){
 return entry[0]==marker;
}.bind(this));
 this._controls.editor.update('');
 var option;
 this._collection.each(function(entry,index){
 option=document.createElement('option');
 option.value=entry[0];
 option.selected=textFound?entry[0]==marker:0==index;
 option.appendChild(document.createTextNode(entry[1]));
 this._controls.editor.appendChild(option);
}.bind(this));
 this._controls.editor.disabled=false;
 Field.scrollFreeActivate(this._controls.editor);
}
});






Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions=function(options){
 if(!options)return;
 function fallback(name,expr){
 if(name in options||expr===undefined)return;
 options[name]=expr;
};
 fallback('cancelControl',(options.cancelLink?'link':(options.cancelButton?'button':
 options.cancelLink==options.cancelButton==false?false:undefined)));
 fallback('okControl',(options.okLink?'link':(options.okButton?'button':
 options.okLink==options.okButton==false?false:undefined)));
 fallback('highlightColor',options.highlightcolor);
 fallback('highlightEndColor',options.highlightendcolor);
};

Object.extend(Ajax.InPlaceEditor,{
 DefaultOptions:{
 ajaxOptions:{},
 autoRows:3,
 cancelControl:'link',
 cancelText:'cancel',
 clickToEditText:'Click to edit',
 externalControl:null,
 externalControlOnly:false,
 fieldPostCreation:'activate',
 formClassName:'inplaceeditor-form',
 formId:null,
 highlightColor:'#ffff99',
 highlightEndColor:'#ffffff',
 hoverClassName:'',
 htmlResponse:true,
 loadingClassName:'inplaceeditor-loading',
 loadingText:'Loading...',
 okControl:'button',
 okText:'ok',
 paramName:'value',
 rows:1,
 savingClassName:'inplaceeditor-saving',
 savingText:'Saving...',
 size:0,
 stripLoadedTextTags:false,
 submitOnBlur:false,
 textAfterControls:'',
 textBeforeControls:'',
 textBetweenControls:''
},
 DefaultCallbacks:{
 callback:function(form){
 return Form.serialize(form);
},
 onComplete:function(transport,element){


 new Effect.Highlight(element,{
 startcolor:this.options.highlightColor,keepBackgroundImage:true});
},
 onEnterEditMode:null,
 onEnterHover:function(ipe){
 ipe.element.style.backgroundColor=ipe.options.highlightColor;
 if(ipe._effect)
 ipe._effect.cancel();
},
 onFailure:function(transport,ipe){
 alert('Error communication with the server: '+transport.responseText.stripTags());
},
 onFormCustomization:null,
 onLeaveEditMode:null,
 onLeaveHover:function(ipe){
 ipe._effect=new Effect.Highlight(ipe.element,{
 startcolor:ipe.options.highlightColor,endcolor:ipe.options.highlightEndColor,
 restorecolor:ipe._originalBackground,keepBackgroundImage:true
});
}
},
 Listeners:{
 click:'enterEditMode',
 keydown:'checkForEscapeOrReturn',
 mouseover:'enterHover',
 mouseout:'leaveHover'
}
});

Ajax.InPlaceCollectionEditor.DefaultOptions={
 loadingCollectionText:'Loading options...'
};





Form.Element.DelayedObserver=Class.create({
 initialize:function(element,delay,callback){
 this.delay=delay||0.5;
 this.element=$(element);
 this.callback=callback;
 this.timer=null;
 this.lastValue=$F(this.element);
 Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
},
 delayedListener:function(event){
 if(this.lastValue==$F(this.element))return;
 if(this.timer)clearTimeout(this.timer);
 this.timer=setTimeout(this.onTimerEvent.bind(this),this.delay*1000);
 this.lastValue=$F(this.element);
},
 onTimerEvent:function(){
 this.timer=null;
 this.callback(this.element,$F(this.element));
}
});








if(!Control)var Control={};







Control.Slider=Class.create({
 initialize:function(handle,track,options){
 var slider=this;

 if(Object.isArray(handle)){
 this.handles=handle.collect(function(e){return $(e)});
}else{
 this.handles=[$(handle)];
}

 this.track=$(track);
 this.options=options||{};

 this.axis=this.options.axis||'horizontal';
 this.increment=this.options.increment||1;
 this.step=parseInt(this.options.step||'1');
 this.range=this.options.range||$R(0,1);

 this.value=0;
 this.values=this.handles.map(function(){return 0});
 this.spans=this.options.spans?this.options.spans.map(function(s){return $(s)}):false;
 this.options.startSpan=$(this.options.startSpan||null);
 this.options.endSpan=$(this.options.endSpan||null);

 this.restricted=this.options.restricted||false;

 this.maximum=this.options.maximum||this.range.end;
 this.minimum=this.options.minimum||this.range.start;


 this.alignX=parseInt(this.options.alignX||'0');
 this.alignY=parseInt(this.options.alignY||'0');

 this.trackLength=this.maximumOffset()-this.minimumOffset();

 this.handleLength=this.isVertical()?
(this.handles[0].offsetHeight!=0?
 this.handles[0].offsetHeight:this.handles[0].style.height.replace(/px$/,"")):
(this.handles[0].offsetWidth!=0?this.handles[0].offsetWidth:
 this.handles[0].style.width.replace(/px$/,""));

 this.active=false;
 this.dragging=false;
 this.disabled=false;

 if(this.options.disabled)this.setDisabled();


 this.allowedValues=this.options.values?this.options.values.sortBy(Prototype.K):false;
 if(this.allowedValues){
 this.minimum=this.allowedValues.min();
 this.maximum=this.allowedValues.max();
}

 this.eventMouseDown=this.startDrag.bindAsEventListener(this);
 this.eventMouseUp=this.endDrag.bindAsEventListener(this);
 this.eventMouseMove=this.update.bindAsEventListener(this);


 this.handles.each(function(h,i){
 i=slider.handles.length-1-i;
 slider.setValue(parseFloat(
(Object.isArray(slider.options.sliderValue)?
 slider.options.sliderValue[i]:slider.options.sliderValue)||
 slider.range.start),i);
 h.makePositioned().observe("mousedown",slider.eventMouseDown);
});

 this.track.observe("mousedown",this.eventMouseDown);
 document.observe("mouseup",this.eventMouseUp);
 document.observe("mousemove",this.eventMouseMove);

 this.initialized=true;
},
 dispose:function(){
 var slider=this;
 Event.stopObserving(this.track,"mousedown",this.eventMouseDown);
 Event.stopObserving(document,"mouseup",this.eventMouseUp);
 Event.stopObserving(document,"mousemove",this.eventMouseMove);
 this.handles.each(function(h){
 Event.stopObserving(h,"mousedown",slider.eventMouseDown);
});
},
 setDisabled:function(){
 this.disabled=true;
},
 setEnabled:function(){
 this.disabled=false;
},
 getNearestValue:function(value){
 if(this.allowedValues){
 if(value>=this.allowedValues.max())return(this.allowedValues.max());
 if(value<=this.allowedValues.min())return(this.allowedValues.min());

 var offset=Math.abs(this.allowedValues[0]-value);
 var newValue=this.allowedValues[0];
 this.allowedValues.each(function(v){
 var currentOffset=Math.abs(v-value);
 if(currentOffset<=offset){
 newValue=v;
 offset=currentOffset;
}
});
 return newValue;
}
 if(value>this.range.end)return this.range.end;
 if(value<this.range.start)return this.range.start;
 return value;
},
 setValue:function(sliderValue,handleIdx){
 if(!this.active){
 this.activeHandleIdx=handleIdx||0;
 this.activeHandle=this.handles[this.activeHandleIdx];
 this.updateStyles();
}
 handleIdx=handleIdx||this.activeHandleIdx||0;
 if(this.initialized&&this.restricted){
 if((handleIdx>0)&&(sliderValue<this.values[handleIdx-1]))
 sliderValue=this.values[handleIdx-1];
 if((handleIdx<(this.handles.length-1))&&(sliderValue>this.values[handleIdx+1]))
 sliderValue=this.values[handleIdx+1];
}
 sliderValue=this.getNearestValue(sliderValue);
 this.values[handleIdx]=sliderValue;
 this.value=this.values[0];

 this.handles[handleIdx].style[this.isVertical()?'top':'left']=
 this.translateToPx(sliderValue);

 this.drawSpans();
 if(!this.dragging||!this.event)this.updateFinished();
},
 setValueBy:function(delta,handleIdx){
 this.setValue(this.values[handleIdx||this.activeHandleIdx||0]+delta,
 handleIdx||this.activeHandleIdx||0);
},
 translateToPx:function(value){
 return Math.round(
((this.trackLength-this.handleLength)/(this.range.end-this.range.start))*
(value-this.range.start))+"px";
},
 translateToValue:function(offset){
 return((offset/(this.trackLength-this.handleLength)*
(this.range.end-this.range.start))+this.range.start);
},
 getRange:function(range){
 var v=this.values.sortBy(Prototype.K);
 range=range||0;
 return $R(v[range],v[range+1]);
},
 minimumOffset:function(){
 return(this.isVertical()?this.alignY:this.alignX);
},
 maximumOffset:function(){
 return(this.isVertical()?
(this.track.offsetHeight!=0?this.track.offsetHeight:
 this.track.style.height.replace(/px$/,""))-this.alignY:
(this.track.offsetWidth!=0?this.track.offsetWidth:
 this.track.style.width.replace(/px$/,""))-this.alignX);
},
 isVertical:function(){
 return(this.axis=='vertical');
},
 drawSpans:function(){
 var slider=this;
 if(this.spans)
 $R(0,this.spans.length-1).each(function(r){slider.setSpan(slider.spans[r],slider.getRange(r))});
 if(this.options.startSpan)
 this.setSpan(this.options.startSpan,
 $R(0,this.values.length>1?this.getRange(0).min():this.value));
 if(this.options.endSpan)
 this.setSpan(this.options.endSpan,
 $R(this.values.length>1?this.getRange(this.spans.length-1).max():this.value,this.maximum));
},
 setSpan:function(span,range){
 if(this.isVertical()){
 span.style.top=this.translateToPx(range.start);
 span.style.height=this.translateToPx(range.end-range.start+this.range.start);
}else{
 span.style.left=this.translateToPx(range.start);
 span.style.width=this.translateToPx(range.end-range.start+this.range.start);
}
},
 updateStyles:function(){
 this.handles.each(function(h){Element.removeClassName(h,'selected')});
 Element.addClassName(this.activeHandle,'selected');
},
 startDrag:function(event){
 if(Event.isLeftClick(event)){
 if(!this.disabled){
 this.active=true;

 var handle=Event.element(event);
 var pointer=[Event.pointerX(event),Event.pointerY(event)];
 var track=handle;
 if(track==this.track){
 var offsets=Position.cumulativeOffset(this.track);
 this.event=event;
 this.setValue(this.translateToValue(
(this.isVertical()?pointer[1]-offsets[1]:pointer[0]-offsets[0])-(this.handleLength/2)
));
 var offsets=Position.cumulativeOffset(this.activeHandle);
 this.offsetX=(pointer[0]-offsets[0]);
 this.offsetY=(pointer[1]-offsets[1]);
}else{

 while((this.handles.indexOf(handle)==-1)&&handle.parentNode)
 handle=handle.parentNode;

 if(this.handles.indexOf(handle)!=-1){
 this.activeHandle=handle;
 this.activeHandleIdx=this.handles.indexOf(this.activeHandle);
 this.updateStyles();

 var offsets=Position.cumulativeOffset(this.activeHandle);
 this.offsetX=(pointer[0]-offsets[0]);
 this.offsetY=(pointer[1]-offsets[1]);
}
}
}
 Event.stop(event);
}
},
 update:function(event){
 if(this.active){
 if(!this.dragging)this.dragging=true;
 this.draw(event);
 if(Prototype.Browser.WebKit)window.scrollBy(0,0);
 Event.stop(event);
}
},
 draw:function(event){
 var pointer=[Event.pointerX(event),Event.pointerY(event)];
 var offsets=Position.cumulativeOffset(this.track);
 pointer[0]-=this.offsetX+offsets[0];
 pointer[1]-=this.offsetY+offsets[1];
 this.event=event;
 this.setValue(this.translateToValue(this.isVertical()?pointer[1]:pointer[0]));
 if(this.initialized&&this.options.onSlide)
 this.options.onSlide(this.values.length>1?this.values:this.value,this);
},
 endDrag:function(event){
 if(this.active&&this.dragging){
 this.finishDrag(event,true);
 Event.stop(event);
}
 this.active=false;
 this.dragging=false;
},
 finishDrag:function(event,success){
 this.active=false;
 this.dragging=false;
 this.updateFinished();
},
 updateFinished:function(){
 if(this.initialized&&this.options.onChange)
 this.options.onChange(this.values.length>1?this.values:this.value,this);
 this.event=null;
}
});

(function(){



 Function.prototype.bind=function(object){
 var __method=this;
 if(arguments.length<2&&arguments[0]===undefined)return this;
 if(arguments.length==1){
 return function(){
 return __method.apply(object,arguments);
}
}
 var args=$A(arguments);
 args.shift();
 return function(){
 return __method.apply(object,args.concat($A(arguments)));
}
}


 window.zen={

 api:function(path,obj,verbatim){
 var wrappers=zen.api._wrappers=zen.api._wrappers||{};
 obj=obj||{};

 if(!wrappers[path]){
 var wrapper=obj;
 if(typeof(obj)!='function'||obj.subclasses){


 wrapper=function(){
 var parts=path.split('.');
 var api=parts.pop();
 var loc=zen.resolve(parts);
 if(!loc)return console.errorTrace('zen.api: Can\'t create "'+path+'"')
 loc[api]=obj;
}
}
 wrappers[path]=wrapper;
}else{
 return console.errorTrace('zen.api(): "'+path+'" already defined');
}
},


 require:function(){
 var stack=zen.api._stack=zen.api._stack||[];
 $A(arguments).each(function(api){
 stack.push(api);
 try{

 var f=zen.api._wrappers&&zen.api._wrappers[api];
 if(!f)throw new Error('"'+api+'" is not a defined API');
 zen.api._wrappers[api]=Prototype.emptyFunction;
 f();
}catch(e){
 zen.logException(e,'zen.require() exception. stack = '+stack.join(' > '));
}
 zen.api._wrappers[api]=Prototype.emptyFunction;
 stack.pop();
});
},


 resolve:function(path,parent){
 parent=parent||window;
 if(path.split)path=path.split('.');
 for(var i=0;i<path.length;i++){
 if(!parent)throw new Error('zen.resolve(): "'+path[i-1]+'" in '+
 path.join('.')+' is not defined');
 parent=parent[path[i]];
}
 return parent;
},


 proxy:function(remoteName,localName){
 localName=localName||remoteName;
 if(!window[localName]){
 var obj=this.locate(remoteName);
 if(obj){
 if(obj._noproxy){
 console.error('zen.proxy: '+remoteName+' should not be proxied.');
}
 window[localName]=obj;
}else{
 console.error('zen.proxy: Unable to zen.locate "'+remoteName+'"');
}
}
},


 locate:function(name,w){
 w=w||parent;
 try{
 while(w){
 if(w[name])return w[name];
 w=(w.parent!==w)?w.parent:w.opener;
}
}catch(e){


}
 return null;
},


 deprecate:function(a,b){
 var c=arguments.callee;
 if(c[b])return;
 c[b]=true;

 if(a.indexOf('!')==0){
 console.error('Deprecation: '+a.substr(1)+(b?' --> '+b:''));
}else{
 console.warn('Deprecation: '+a+(b?' --> '+b:''));
}
},


 logException:function(e,msg){
 var msg=msg?msg+' ('+e+')':e;
 console.group();
 console.error('['+zen.getWindowName()+'] '+msg);
 console.dir(e);
 console.groupEnd();
 return e;
},


 getWindowName:function(){
 return window.name||(window==top?'top':'no name');
},


 bind:function(){
 var a=$A(arguments),o=a.shift(),k;
 while(k=a.shift()){
 var asEvent=k.indexOf('#')==0;
 k=asEvent?k.substr(1):k;
 if(!o[k])throw new Error('bind: "'+k+'" is not defined');
 o[k]=asEvent?o[k].bindAsEventListener(o):o[k].bind(o);
}
},


 escapeHTML:function(o){
 o=(o===undefined||o===null)?'':
(typeof(o)!='string'?o+'':o);
 return o.escapeHTML();
},


 preload:function(){
 $A(arguments).flatten().each(function(url){new Image().src=url});
},


 isAccessible:function(w){
 try{
 return((typeof(w.name)=='string')&&!w.closed);
}catch(e){
 console.log('window inaccessible');
}
 return false;
},


 setTitle:function(str){
 top.document.title=str;
},


 openDownload:function(url){
 if(!$('download_frame')){
 document.body.insert('<iframe name="download_frame" id="download_frame" style="display:none"></iframe>');
}
 $('download_frame').src=url;
},




 _subwins:[],

 _subwinNotify:function(){
[top,parent,opener].each(function(w){
 if(w!==window&&zen.isAccessible(w)&&w.zen){
 w.zen._subwinLoad(window);
}
});
},

 _subwinLoad:function(w){

 this._subwins=this._subwins.findAll(function(o){
 return o.w==w?o.f(true)&&false:(new Date()-o.t)>6e4;
});
},


 observeSubwindowLoad:function(w,f){
 this._subwins.push({
 w:w.contentWindow||w,
 f:f,
 t:new Date()
});
}
};


 Event.observe(window,'load',function(){setTimeout(zen._subwinNotify,0)});


 zen.cookie={

 get:function(name){
 var nameEQ=name+"=";
 var ca=document.cookie.split(';');
 for(var i=0;i<ca.length;i++){
 var c=ca[i];
 while(c.charAt(0)==' ')c=c.substring(1,c.length);
 if(c.indexOf(nameEQ)==0)return c.substring(nameEQ.length,c.length);
}
 return null;
},

 set:function(name,value,keep){
 var expires=keep?new Date():null;
 if(expires)expires.setYear(expires.getFullYear()+5);
 document.cookie=name+"="+value+"; path=/"+
(!expires?'':"; expires="+expires.toGMTString());
}
};


 Object.extend(window,{

 $unique:function(pattern){
 var c=arguments.callee;
 c._i=(c._i||0)+1;
 return pattern?pattern.replace(/#/g,c._i):c._i;
},


 $to_a:function(obj){
 return Object.isArray(obj)?obj:[obj];
},


 $px:function(o){
 return parseInt(o)+'px';
},



 $cid:function(elementId){
 var match=elementId.match(/(c\d*)/);
 return match?match[0]:false;
}

});








 var makeWrapper=function(s){
 var f=console[s];
 console[s]=function(){
 var a=arguments;
 a[0]=typeof(a[0])=='string'?'['+zen.getWindowName()+'] '+a[0]:a[0];
 f.apply(console,arguments);
};
 console[s+'Trace']=function(){
 console.group();
 var a=arguments;
 a[0]=typeof(a[0])=='string'?'['+zen.getWindowName()+'] '+a[0]:a[0];
 f.apply(console,arguments);
 console.trace();
 console.groupEnd();
}
};
['debug','error','info','log','warn'].each(function(o){
 makeWrapper(o);
});


 if(!Prototype.Browser.IE){
 if(document.activeElement===undefined){
 document.addEventListener('focus',
 function(e){document.activeElement=e.target;},true);
 document.addEventListener('blur',
 function(e){document.activeElement=null;},true);
};
};




 Event.observe(document,'click',function(e){
 var el=Event.element(e=e||event);
 while(el){
 if(el.nodeName=='A'){



 var href=(el.href+'').replace(/#$/,'');
 var loc=(window.location.href+'').replace(/#$/,'');
 if(href===''||href==loc)Event.stop(e);
}
 el=el.parentNode;
}
});



 window.SafeString=function(s,isEscaped){
 s=s||'';

 this._safe=isEscaped?s:s.escapeHTML();

 this._unsafe=!isEscaped?s:s.unescapeHTML();

 this.length=this._safe.length;
}

 Object.extend(SafeString,{

 safe:function(x){
 return(x&&x.safe&&x.safe())||x;
},


 unsafe:function(x){
 return(x&&x.unsafe&&x.unsafe())||x;
},


 _addMethods:function(names){
 names.each(function(name){
 var m=String.prototype[name];
 SafeString.prototype[name]=function(){
 return m.apply(this._safe,arguments);
}
});
}
});

 SafeString.prototype={

 isSafe:true,


 unsafe:function(){return this._unsafe;},


 safe:function(){return this},

 toString:function(){return this._safe},
 valueOf:function(){return this._safe}
};


 SafeString._addMethods(['charAt','charCodeAt','concat','indexOf',
'lastIndexOf','localeCompare','match','replace','search','slice',
'split','substr','substring','toLowerCase','toUpperCase']);




 SafeString._addMethods(['blank','camelize','capitalize','dasherize',
'empty','endsWith','escapeHTML','gsub','include','inspect',
'interpolate','scan','startsWith','strip','sub','succ','times',
'toArray','toJSON','truncate','underscore','unescapeHTML']);


 Object.extend(String.prototype,{

 safe:function(){return new SafeString(this);},


 unsafe:function(){return this}
});







 Ajax.Responders.register({

 onCreate:function(request,xmlHttp){
 var indicator=request.options.indicator;
 if(!indicator)return;
 if(typeof(indicator)=='function')return indicator(true);

 try{
 indicator=$(indicator);
 console.assert(indicator&&indicator.nodeName,'indicator must be either a function or an element.');
 if(indicator){
 var t=request.options.indicatorText;
 if(t)indicator.update(t);



(indicator.up('.wait_indicator_container')||indicator).show();
}
}catch(e){
 zen.logException(e);
}
},


 onComplete:function(request,xmlHttp){
 var indicator=request.options.indicator;
 if(!indicator)return;
 if(typeof(indicator)=='function')return indicator(false);

 try{
 indicator=$(indicator);
 if(!indicator||!indicator.nodeName){
 console.errorTrace('indicator for '+request.url+' must be either a function or an element.');
}
(indicator.up('.wait_indicator_container')||indicator).hide();
}catch(e){
 zen.logException(e);
}
},


 onException:function(request,e){
 zen.logException(e,'Exception during '+request.method+' to '
+request.url+'?'
+unescape(Object.toQueryString(request.options.parameters)));
}
});


[
{key:'bind'},
{key:'escapeHTML'},
{key:'isAccessible'},
{key:'locate'},
{key:'logException'},
{key:'open_download',value:'openDownload'},
{key:'preload'},
{key:'proxy'},
{key:'readCookie',value:'cookie.get'},
{key:'title',value:'setTitle'},
{key:'window_name',value:'getWindowName'},
{key:'writeCookie',value:'cookie.set'}
].each(function(pair){
 pair.value=pair.value||pair.key;
 var tmpl="zen.deprecate('$#{key}()', 'zen.#{value}()'); return zen.#{value}.apply(zen, arguments);"
 window['$'+pair.key]=new Function(tmpl.interpolate(pair));
});

 window.$require=function(){
 zen.deprecate('!$require()','zen.require()');
}


 window.$addCallback=function(options,name,f){
 zen.deprecate('$addCallback','Object.extendOptions or Function#before/after');
 options[name]=options[name]?options[name].before(f):f;
}

 window.ReadyState={
 observe:function(){
 zen.deprecate('ReadyState.observe','zen.observeSubwindowLoad');
 return zen.observeSubwindowLoad.apply(zen,arguments);
}
}

})();



function isIE6OrLess(){
 var rv=false;
 if(navigator.appName=='Microsoft Internet Explorer'){
 var ua=navigator.userAgent;
 var re=new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
 if(re.exec(ua)!=null)rv=parseFloat(RegExp.$1);
}
 return(rv&&rv<7);
}