var Prototype={Version:"1.6.0",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;
}
if(Prototype.Browser.WebKit){
  Prototype.BrowserFeatures.XPath=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===undefined){
        return "undefined";
      }
      if(object===null){
        return "null";
      }
      return object.inspect?object.inspect():object.toString();
    }
    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(value!==undefined){
        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.constructor===Array;
  },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(){
    if(arguments.length<2&&arguments[0]===undefined){
      return this;
    }
    var __method=this,args=$A(arguments),object=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=count===undefined?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=truncation===undefined?"...":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.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);
    }.bind(this));
  }});
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){
    }
    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=fillWith===undefined?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==undefined||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==undefined||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,results=new Array(length);
  while(length--){
    results[length]=iterable[length];
  }
  return results;
}
if(Prototype.Browser.WebKit){
  function $A(iterable){
    if(!iterable){
      return [];
    }
    if(!(Object.isFunction(iterable)&&iterable=="[object NodeList]")&&iterable.toArray){
      return iterable.toArray();
    }
    var length=iterable.length,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(value!==undefined){
        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(){
  if(function(){
    var i=0,Test=function(value){
      this.key=value;
    };
    Test.prototype.key="foo";
    for(var property in new Test("bar")){
      i++;
    }
    return i>1;
  }()){
    function each(iterator){
      var cache=[];
      for(var key in this._object){
        var value=this._object[key];
        if(cache.include(key)){
          continue ;
        }
        cache.push(key);
        var pair=[key,value];
        pair.key=key;
        pair.value=value;
        iterator(pair);
      }
    }
  }else {
    function each(iterator){
      for(var key in this._object){
        var value=this._object[key],pair=[key,value];
        pair.key=key;
        pair.value=value;
        iterator(pair);
      }
    }
  }
  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:each,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();
    }
  }});
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||0;
    }
    catch(e){
      return 0;
    }
  },respondToReadyState:function(readyState){
    var state=Ajax.Request.Events[readyState],response=new Ajax.Response(this);
    if(state=="Complete"){
      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);
      }
      var contentType=response.getHeader("Content-type");
      if(this.options.evalJS=="force"||(this.options.evalJS&&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;
    }
  },getHeader:function(name){
    try{
      return this.transport.getResponseHeader(name);
    }
    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=xml===undefined?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);
    }
    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"))){
      return null;
    }
    try{
      return this.transport.responseText.evalJSON(options.sanitizeJSON);
    }
    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=options||{};
    var onComplete=options.onComplete;
    options.onComplete=(function(response,param){
      this.updateContent(response.responseText);
      if(Object.isFunction(onComplete)){
        onComplete(response,param);
      }
    }).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);
      }
    }
    if(this.success()){
      if(this.onComplete){
        this.onComplete.bind(this).defer();
      }
    }
  }});
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,t,range;
    for(position in insertions){
      content=insertions[position];
      position=position.toLowerCase();
      t=Element._insertionTranslations[position];
      if(content&&content.toElement){
        content=content.toElement();
      }
      if(Object.isElement(content)){
        t.insert(element,content);
        continue ;
      }
      content=Object.toHTML(content);
      range=element.ownerDocument.createRange();
      t.initializeRange(element,range);
      t.insert(element,range.createContextualFragment(content.stripScripts()));
      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 $A($(element).getElementsByTagName("*")).each(Element.extend);
  },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 expression?Selector.findElement(ancestors,expression,index):ancestors[index||0];
  },down:function(element,expression,index){
    element=$(element);
    if(arguments.length==1){
      return element.firstDescendant();
    }
    var descendants=element.descendants();
    return expression?Selector.findElement(descendants,expression,index):descendants[index||0];
  },previous:function(element,expression,index){
    element=$(element);
    if(arguments.length==1){
      return $(Selector.handlers.previousElementSibling(element));
    }
    var previousSiblings=element.previousSiblings();
    return expression?Selector.findElement(previousSiblings,expression,index):previousSiblings[index||0];
  },next:function(element,expression,index){
    element=$(element);
    if(arguments.length==1){
      return $(Selector.handlers.nextElementSibling(element));
    }
    var nextSiblings=element.nextSiblings();
    return expression?Selector.findElement(nextSiblings,expression,index):nextSiblings[index||0];
  },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]=value===undefined?true:value;
    }
    for(var attr in attributes){
      var 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);
    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){
        return (e>a&&e<nextAncestor.sourceIndex);
      }
    }
    while(element=element.parentNode){
      if(element==ancestor){
        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;
    }
    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")?(elementStyle.styleFloat===undefined?"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=="relative"||p=="absolute"){
          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(!document.createRange||Prototype.Browser.Opera){
  Element.Methods.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 t=Element._insertionTranslations,content,position,pos,tagName;
    for(position in insertions){
      content=insertions[position];
      position=position.toLowerCase();
      pos=t[position];
      if(content&&content.toElement){
        content=content.toElement();
      }
      if(Object.isElement(content)){
        pos.insert(element,content);
        continue ;
      }
      content=Object.toHTML(content);
      tagName=((position=="before"||position=="after")?element.parentNode:element).tagName.toUpperCase();
      if(t.tags[tagName]){
        var fragments=Element._getContentFromAnonymousElement(tagName,content.stripScripts());
        if(position=="top"||position=="after"){
          fragments.reverse();
        }
        fragments.each(pos.insert.curry(element));
      }else {
        element.insertAdjacentHTML(pos.adjacency,content.stripScripts());
      }
      content.evalScripts.bind(content).defer();
    }
    return element;
  };
}
if(Prototype.Browser.Opera){
  Element.Methods._getStyle=Element.Methods.getStyle;
  Element.Methods.getStyle=function(element,style){
    switch(style){
    case "left":
    case "top":
    case "right":
    case "bottom":
      if(Element._getStyle(element,"position")=="static"){
        return null;
      }
    default:
      return Element._getStyle(element,style);
    }
  };
  Element.Methods._readAttribute=Element.Methods.readAttribute;
  Element.Methods.readAttribute=function(element,attribute){
    if(attribute=="title"){
      return element.title;
    }
    return Element._readAttribute(element,attribute);
  };
}else {
  if(Prototype.Browser.IE){
    $w("positionedOffset getOffsetParent 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);
        }
        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;
      }
      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){
            var 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.clone(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(document.createElement("div").outerHTML){
  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];
  div.innerHTML=t[0]+html+t[1];
  t[2].times(function(){
    div=div.firstChild;
  });
  return $A(div.childNodes);
};
Element._insertionTranslations={before:{adjacency:"beforeBegin",insert:function(element,node){
      element.parentNode.insertBefore(node,element);
    },initializeRange:function(element,range){
      range.setStartBefore(element);
    }},top:{adjacency:"afterBegin",insert:function(element,node){
      element.insertBefore(node,element.firstChild);
    },initializeRange:function(element,range){
      range.selectNodeContents(element);
      range.collapse(true);
    }},bottom:{adjacency:"beforeEnd",insert:function(element,node){
      element.appendChild(node);
    }},after:{adjacency:"afterEnd",insert:function(element,node){
      element.parentNode.insertBefore(node,element.nextSibling);
    },initializeRange:function(element,range){
      range.setStartAfter(element);
    }},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(){
  this.bottom.initializeRange=this.top.initializeRange;
  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={};
    $w("width height").each(function(d){
      var D=d.capitalize();
      dimensions[d]=self["inner"+D]||(document.documentElement["client"+D]||document.body["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();
  },compileMatcher:function(){
    if(Prototype.BrowserFeatures.XPath&&!(/(\[[\w-]*?:|:checked)/).test(this.expression)){
      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:"[@#{1}]",attr:function(m){
      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,m,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 = false;",attr:function(m){
      m[3]=(m[5]||m[6]);
      return new Template("n = h.attr(n, r, \"#{1}\", \"#{3}\", \"#{2}\"); 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 Selector.operators[matches[2]](nodeValue,matches[3]);
    }},handlers:{concat:function(a,b){
      for(var i=0,node;node=b[i];i++){
        a.push(node);
      }
      return a;
    },mark:function(nodes){
      for(var i=0,node;node=nodes[i];i++){
        node._counted=true;
      }
      return nodes;
    },unmark:function(nodes){
      for(var i=0,node;node=nodes[i];i++){
        node._counted=undefined;
      }
      return nodes;
    },index:function(parentNode,reverse,ofType){
      parentNode._counted=true;
      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._counted)){
            node.nodeIndex=j++;
          }
        }
      }else {
        for(var i=0,j=1,nodes=parentNode.childNodes;node=nodes[i];i++){
          if(node.nodeType==1&&(!ofType||node._counted)){
            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])._counted){
          n._counted=true;
          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,children=[],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){
      tagName=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()==tagName){
            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){
      if(!nodes){
        nodes=root.getElementsByTagName("*");
      }
      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){
      if(!nodes){
        nodes=root.getElementsByTagName("*");
      }
      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._counted){
          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._counted){
          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()+"-");
    }},matchElements:function(elements,expression){
    var matches=new Selector(expression).findElements(),h=Selector.handlers;
    h.mark(matches);
    for(var i=0,results=[],element;element=elements[i];i++){
      if(element._counted){
        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){
    var exprs=expressions.join(","),expressions=[];
    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/,function(m){
      expressions.push(m[1].strip());
    });
    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;
  }});
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(options.hash===undefined){
        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(value===undefined){
      return element.checked?element.value:null;
    }else {
      element.checked=!!value;
    }
  },textarea:function(element,value){
    if(value===undefined){
      return element.value;
    }else {
      element.value=value;
    }
  },select:function(element,index){
    if(index===undefined){
      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);
      return element.match(expression)?element:element.up(expression);
    },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._eventID){
      return element._eventID;
    }
    arguments.callee.id=arguments.callee.id||1;
    return element._eventID=++arguments.callee.id;
  }
  function getDOMEventName(eventName){
    if(eventName&&eventName.include(":")){
      return "dataavailable";
    }
    return eventName;
  }
  function getCacheForID(id){
    return cache[id]=cache[id]||{};
  }
  function getWrappersForEventName(id,eventName){
    var c=getCacheForID(id);
    return c[eventName]=c[eventName]||[];
  }
  function createWrapper(element,eventName,handler){
    var id=getEventID(element);
    var c=getWrappersForEventName(id,eventName);
    if(c.pluck("handler").include(handler)){
      return false;
    }
    var wrapper=function(event){
      if(!Event||!Event.extend||(event.eventName&&event.eventName!=eventName)){
        return false;
      }
      Event.extend(event);
      handler.call(element,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;
      }
      if(document.createEvent){
        var event=document.createEvent("HTMLEvents");
        event.initEvent("dataavailable",true,true);
      }else {
        var 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;
    }};
})());
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()});
(function(){
  var timer,fired=false;
  function fireContentLoadedEvent(){
    if(fired){
      return ;
    }
    if(timer){
      window.clearInterval(timer);
    }
    document.fire("dom:loaded");
    fired=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();
