var Prototype ={version:1.6.0.3, Browser: { IE: !!(window.attachEvent&&navigator.userAgent.indexOf('Opera') === -1), Opera: navigator.userAgent.indexOf(Opera) > -1, 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, SelectorsAPI: !!document.querySelector, ElementExtensions: !!window.HTMLElement, SpecificElementExtensions: document.createElement(div)[__proto__] && document.createElement(div)[__proto__] !== document.createElement(form)[__proto__]}
,evalJSON: function(sanitize){varjson:this.unfilterJSON()}
,startsWith: function(pattern){returnthisindexofpattern:== 0}
,endsWith: function(pattern){vard:this.length 0 pattern.length;returnd:0 && this.lastIndexOf(pattern) === d}
,empty: function(){returnthis:=}
);
if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype,{escapehtml:function() { return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')}
);
String.prototype.gsub.prepareReplacement = function(replacement){vartemplate:new Template(replacement)}
;
String.prototype.parseQuery = String.prototype.toQueryParams;
Object.extend(String.prototype.escapeHTML,{div:document.createElement(div), text: document.createTextNode()}
);
String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
var Template = Class.create({initialize:function(template,pattern) { this.template = template.toString();thispattern:pattern || Template.Pattern}
,evaluate: function(object){ifobjectisfunctionobjecttotemplatereplacementsobject:object.toTemplateReplacements();returnthistemplategsubthispatternfunctionmatchifobject:= null) return;varbefore:match[1] ||;ifbefore:= \\) return match[2];varctx:object, expr = match[3];varpattern:/^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;ifmatch:= null) return before;whilematch:null) { var comp = match[1].startsWith([) ? match[2].gsub(\\\\]',']) : match[1];ctx:ctx[comp];ifnull:= ctx || == match[3]) break;expr:expr.substring(['==match[3]?match[1].length:match[0].lengt);match:pattern.exec(expr)}
;
var Enumerable ={each:function(iterator,context) { var index = 0}
catch (e){ife:$break) throw e}
,eachSlice: function(number,iterator,context){varindex:0 slices = [], array = this.toArray();whileindex:number) < array.length) slices.push(array.slice(index,index+number))}
,all: function(iterator,context){iterator:iterator || Prototype.K;varresult:true;thiseachfunctionvalueindexresult:result && !!iterator.call(context,value,index)}
,any: function(iterator,context){iterator:iterator || Prototype.K;varresult:false;thiseachfunctionvalueindexifresult:!!iterator.call(context,value,index)) throw $break}
,collect: function(iterator,context){iterator:iterator || Prototype.K;varresults:[]}
,detect: function(iterator,context){thiseachfunctionvalueindexifiteratorcallcontextvalueindexresult:value}
,grep: function(filter,iterator,context){iterator:iterator || Prototype.K;varresults:[];ifobjectisstringfilterfilter:new RegExp(filter)}
,include: function(object){ifobjectisfunctionthisindexofifthisindexofobject:-1) return true;varfound:false;thiseachfunctionvalueifvalue:= object) { found = true}
,inGroupsOf: function(number,fillWith){fillwith:Object.isUndefined(fillWith) ? null : fillWith}
,inject: function(memo,iterator,context){thiseachfunctionvalueindexmemo:iterator.call(context,memo,value,index)}
,invoke: function(method){varargs:$A(arguments).slice(1)}
,max: function(iterator,context){iterator:iterator || Prototype.K;thiseachfunctionvalueindexvalue:iterator.call(context,value,index);ifresult:= null || value >= result) result = value}
,min: function(iterator,context){iterator:iterator || Prototype.K;thiseachfunctionvalueindexvalue:iterator.call(context,value,index);ifresult:= null || value < result) result = value}
,partition: function(iterator,context){iterator:iterator || Prototype.K;vartrues:[], falses = [];thiseachfunctionvalueindexiteratorcallcontextvalueindextrues:falses).push(value)}
,sortBy: function(iterator,context){returnthismapfunctionvalueindexreturnvalue:value, criteria: iterator.call(context,value,index)}
).sort(function(left,right){vara:left.criteria, b = right.criteria;returnab-1:a > b ? 1 : 0}
,zip: function(){variterator:Prototype.K, args = $A(arguments);ifobjectisfunctionargslastiterator:args.pop();varcollections:[this].concat(args).map($A)}
,inspect: function(){return#enumerable:' + this.toArray().inspect() + '>';\A   }\A };\A \A Object.extend(Enumerable, {\A   map:     Enumerable.collect,\A   find:    Enumerable.detect,\A   select:  Enumerable.findAll,\A   filter:  Enumerable.findAll,\A   member:  Enumerable.include,\A   entries: Enumerable.toArray,\A   every:   Enumerable.all,\A   some:    Enumerable.any\A });\A function $A(iterable) {\A   if (!iterable) return [];\A   if (iterable.toArray) return iterable.toArray();\A   var length = iterable.length || 0, results = new Array(length);\A   while (length--) results[length] = iterable[length];\A   return results;\A }\A \A if (Prototype.Browser.WebKit) {\A   $A = function(iterable) {\A     if (!iterable) return [];\A     // In Safari, only use the `toArray` method if it's not a NodeList. // A NodeList is a function, has an function `item` property, and a numeric // `length` property. Adapted from Google Doctype. if (!(typeofiterable==='function'&&typeofiterable.length==='number'&&typeofiterable.item==='function') && iterable.toArray) return iterable.toArray();varlength:iterable.length || 0 results = new Array(length);whilelength--resultslength:iterable[length]}
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 (vari=0,length=this.length;i<length;i++) iterator(this[i])}
,clear: function(){thislength:0}
,compact: function(){returnthisselectfunctionvaluereturnvalue:null}
,flatten: function(){returnthisinjectfunctionarrayvaluereturnarrayconcatobjectisarrayvaluevalueflatten:[value])}
,without: function(){varvalues:$A(arguments)}
,reverse: function(inline){returninline:= false ? this : this.toArray())._reverse()}
,reduce: function(){returnthislength1this:this[0]}
,uniq: function(sorted){returnthisinjectfunctionarrayvalueindexif0:= index || (sorted?array.last() != value : !array.include(value))) array.push(value)}
,intersect: function(array){returnthisuniqfindallfunctionitemreturnarraydetectfunctionvaluereturnitem:== value}
,toJSON: function(){varresults:[];thiseachfunctionobjectvarvalue:Object.toJSON(object);returnisfinitethisthistostring:null}
);
// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
Array.prototype._each = Array.prototype.forEach;
if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item,i){ii:0;varlength:this.length;ifi0i:length 0 i;iifthisi:== item) return i}
;
if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item,i){i:isNaN(i) ? this.length : (i<0?this.length+i:i) 0 1;varn:this.slice(0,i).reverse().indexOf(item);returnn0n:i 0 n 0 1}
;
Array.prototype.toArray = Array.prototype.clone;
function $w(string){string:string.strip();returnstringstringsplits:[]}
if (Prototype.Browser.Opera){arrayprototypeconcat:function() { var array = [];forvari:0 length = arguments.length;iifobjectisarrayargumentsiforvarj:0 arrayLength = arguments[i].length}
Object.extend(Number.prototype,{tocolorpart:function() { return this.toPaddedString(2,16)}
,toPaddedString: function(length,radix){varstring:this.toString(radix||10)}
);
$w('abs round ceil floor').each(function(method){numberprototypemethod:Math[method].methodize()}
;
var Hash = Class.create(Enumerable,(function(){returnkey:' + encodeURIComponent(String.interpret(value));\A   }\A \A   return {\A     initialize: function(object) {\A       this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);\A     },\A \A     _each: function(iterator) {\A       for (var key in this._object) {\A         var value = this._object[key], pair = [key, value];\A         pair.key = key;\A         pair.value = value;\A         iterator(pair);\A       }\A     },\A \A     set: function(key, value) {\A       return this._object[key] = value;\A     },\A \A     get: function(key) {\A       // simulating poorly supported hasOwnProperty\A       if (this._object[key] !== Object.prototype[key])\A         return this._object[key];\A     },\A \A     unset: function(key) {\A       var value = this._object[key];\A       delete this._object[key];\A       return value;\A     },\A \A     toObject: function() {\A       return Object.clone(this._object);\A     },\A \A     keys: function() {\A       return this.pluck('key');\A     },\A \A     values: function() {\A       return this.pluck('value');\A     },\A \A     index: function(value) {\A       var match = this.detect(function(pair) {\A         return pair.value === value;\A       });\A       return match && match.key;\A     },\A \A     merge: function(object) {\A       return this.clone().update(object);\A     },\A \A     update: function(object) {\A       return new Hash(object).inject(this, function(result, pair) {\A         result.set(pair.key, pair.value);\A         return result;\A       });\A     },\A \A     toQueryString: function() {\A       return this.inject([], function(results, pair) {\A         var key = encodeURIComponent(pair.key), values = pair.value;\A \A         if (values && typeof values == 'object') {\A           if (Object.isArray(values))\A             return results.concat(values.map(toQueryPair.curry(key)));\A         } else results.push(toQueryPair(key, values));\A         return results;\A       }).join('&');\A     },\A \A     inspect: function() {\A       return '#<Hash:{' + this.map(function(pair) {\A         return pair.map(Object.inspect).join(': ');\A       }).join(', ') + '}
'.interpolate({\A       protocol: location.protocol,\A       domain: document.domain,\A       port: location.port ? ':' + location.port : ''\A     }));\A   },\A \A   getHeader: function(name) {\A     try {\A       return this.transport.getResponseHeader(name) || null;\A     } catch (e) { return null }\A   },\A \A   evalResponse: function() {\A     try {\A       return eval((this.transport.responseText || '').unfilterJSON());\A     } catch (e) {\A       this.dispatchException(e);\A     }\A   },\A \A   dispatchException: function(exception) {\A     (this.options.onException || Prototype.emptyFunction)(this, exception);\A     Ajax.Responders.dispatch('onException', this, exception);\A   }\A });\A \A Ajax.Request.Events =\A   ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];\A \A Ajax.Response = Class.create({\A   initialize: function(request){\A     this.request = request;\A     var transport  = this.transport  = request.transport,\A         readyState = this.readyState = transport.readyState;\A \A     if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {\A       this.status       = this.getStatus();\A       this.statusText   = this.getStatusText();\A       this.responseText = String.interpret(transport.responseText);\A       this.headerJSON   = this._getHeaderJSON();\A     }\A \A     if(readyState == 4) {\A       var xml = transport.responseXML;\A       this.responseXML  = Object.isUndefined(xml) ? null : xml;\A       this.responseJSON = this._getResponseJSON();\A     }\A   },\A \A   status:      0,\A   statusText: '',\A \A   getStatus: Ajax.Request.prototype.getStatus,\A \A   getStatusText: function() {\A     try {\A       return this.transport.statusText || '';\A     } catch (e) { return '' }\A   },\A \A   getHeader: Ajax.Request.prototype.getHeader,\A \A   getAllHeaders: function() {\A     try {\A       return this.getAllResponseHeaders();\A     } catch (e) { return null }\A   },\A \A   getResponseHeader: function(name) {\A     return this.transport.getResponseHeader(name);\A   },\A \A   getAllResponseHeaders: function() {\A     return this.transport.getAllResponseHeaders();\A   },\A \A   _getHeaderJSON: function() {\A     var json = this.getHeader('X-JSON');\A     if (!json) return null;\A     json = decodeURIComponent(escape(json));\A     try {\A       return json.evalJSON(this.request.options.sanitizeJSON ||\A         !this.request.isSameOrigin());\A     } catch (e) {\A       this.request.dispatchException(e);\A     }\A   },\A \A   _getResponseJSON: function() {\A     var options = this.request.options;\A     if (!options.evalJSON || (options.evalJSON != 'force' &&\A       !(this.getHeader('Content-type') || ').include(application/json')) ||\A         this.responseText.blank())\A           return null;\A     try {\A       return this.responseText.evalJSON(options.sanitizeJSON ||\A         !this.request.isSameOrigin());\A     } catch (e) {\A       this.request.dispatchException(e);\A     }\A   }\A });\A \A Ajax.Updater = Class.create(Ajax.Request, {\A   initialize: function($super, container, url, options) {\A     this.container = {\A       success: (container.success || container),\A       failure: (container.failure || (container.success ? null : container))\A     };\A \A     options = Object.clone(options);\A     var onComplete = options.onComplete;\A     options.onComplete = (function(response, json) {\A       this.updateContent(response.responseText);\A       if (Object.isFunction(onComplete)) onComplete(response, json);\A     }).bind(this);\A \A     $super(url, options);\A   },\A \A   updateContent: function(responseText) {\A     var receiver = this.container[this.success() ? 'success' : 'failure'],\A         options = this.options;\A \A     if (!options.evalScripts) responseText = responseText.stripScripts();\A \A     if (receiver = $(receiver)) {\A       if (options.insertion) {\A         if (Object.isString(options.insertion)) {\A           var insertion = { }; insertion[options.insertion] = responseText;\A           receiver.insert(insertion);\A         }\A         else options.insertion(receiver, responseText);\A       }\A       else receiver.update(responseText);\A     }\A   }\A });\A \A Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {\A   initialize: function($super, container, url, options) {\A     $super(options);\A     this.onComplete = this.options.onComplete;\A \A     this.frequency = (this.options.frequency || 2);\A     this.decay = (this.options.decay || 1);\A \A     this.updater = { };\A     this.container = container;\A     this.url = url;\A \A     this.start();\A   },\A \A   start: function() {\A     this.options.onComplete = this.updateComplete.bind(this);\A     this.onTimerEvent();\A   },\A \A   stop: function() {\A     this.updater.options.onComplete = undefined;\A     clearTimeout(this.timer);\A     (this.onComplete || Prototype.emptyFunction).apply(this, arguments);\A   },\A \A   updateComplete: function(response) {\A     if (this.options.decay) {\A       this.decay = (response.responseText == this.lastText ?\A         this.decay * this.options.decay : 1);\A \A       this.lastText = response.responseText;\A     }\A     this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);\A   },\A \A   onTimerEvent: function() {\A     this.updater = new Ajax.Updater(this.container, this.url, this.options);\A   }\A });\A function $(element) {\A   if (arguments.length > 1) {\A     for (var i = 0, elements = [], length = arguments.length; i < length; i++)\A       elements.push($(arguments[i]));\A     return elements;\A   }\A   if (Object.isString(element))\A     element = document.getElementById(element);\A   return Element.extend(element);\A }\A \A if (Prototype.BrowserFeatures.XPath) {\A   document._getElementsByXPath = function(expression, parentElement) {\A     var results = [];\A     var query = document.evaluate(expression, $(parentElement) || document,\A       null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);\A     for (var i = 0, length = query.snapshotLength; i < length; i++)\A       results.push(Element.extend(query.snapshotItem(i)));\A     return results;\A   };\A }\A \A /*--------------------------------------------------------------------------*/\A \A if (!window.Node) var Node = { };\A \A if (!Node.ELEMENT_NODE) {\A   // DOM level 2 ECMAScript Language Binding\A   Object.extend(Node, {\A     ELEMENT_NODE: 1,\A     ATTRIBUTE_NODE: 2,\A     TEXT_NODE: 3,\A     CDATA_SECTION_NODE: 4,\A     ENTITY_REFERENCE_NODE: 5,\A     ENTITY_NODE: 6,\A     PROCESSING_INSTRUCTION_NODE: 7,\A     COMMENT_NODE: 8,\A     DOCUMENT_NODE: 9,\A     DOCUMENT_TYPE_NODE: 10,\A     DOCUMENT_FRAGMENT_NODE: 11,\A     NOTATION_NODE: 12\A   });\A }\A \A (function() {\A   var element = this.Element;\A   this.Element = function(tagName, attributes) {\A     attributes = attributes || { };\A     tagName = tagName.toLowerCase();\A     var cache = Element.cache;\A     if (Prototype.Browser.IE && attributes.name) {\A       tagName = '<' + tagName + ' name="' + attributes.name + '">';\A       delete attributes.name;\A       return Element.writeAttribute(document.createElement(tagName), attributes);\A     }\A     if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));\A     return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);\A   };\A   Object.extend(this.Element, element || { });\A   if (element) this.Element.prototype = element.prototype;\A }).call(window);\A \A Element.cache = { };\A \A Element.Methods = {\A   visible: function(element) {\A     return $(element).style.display != 'none';\A   },\A \A   toggle: function(element) {\A     element = $(element);\A     Element[Element.visible(element) ? 'hide' : 'show'](element);\A     return element;\A   },\A \A   hide: function(element) {\A     element = $(element);\A     element.style.display = 'none';\A     return element;\A   },\A \A   show: function(element) {\A     element = $(element);\A     element.style.display = '';\A     return element;\A   },\A \A   remove: function(element) {\A     element = $(element);\A     element.parentNode.removeChild(element);\A     return element;\A   },\A \A   update: function(element, content) {\A     element = $(element);\A     if (content && content.toElement) content = content.toElement();\A     if (Object.isElement(content)) return element.update().insert(content);\A     content = Object.toHTML(content);\A     element.innerHTML = content.stripScripts();\A     content.evalScripts.bind(content).defer();\A     return element;\A   },\A \A   replace: function(element, content) {\A     element = $(element);\A     if (content && content.toElement) content = content.toElement();\A     else if (!Object.isElement(content)) {\A       content = Object.toHTML(content);\A       var range = element.ownerDocument.createRange();\A       range.selectNode(element);\A       content.evalScripts.bind(content).defer();\A       content = range.createContextualFragment(content.stripScripts());\A     }\A     element.parentNode.replaceChild(content, element);\A     return element;\A   },\A \A   insert: function(element, insertions) {\A     element = $(element);\A \A     if (Object.isString(insertions) || Object.isNumber(insertions) ||\A         Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))\A           insertions = {bottom:insertions};\A \A     var content, insert, tagName, childNodes;\A \A     for (var position in insertions) {\A       content  = insertions[position];\A       position = position.toLowerCase();\A       insert = Element._insertionTranslations[position];\A \A       if (content && content.toElement) content = content.toElement();\A       if (Object.isElement(content)) {\A         insert(element, content);\A         continue;\A       }\A \A       content = Object.toHTML(content);\A \A       tagName = ((position == 'before' || position == 'after')\A         ? element.parentNode : element).tagName.toUpperCase();\A \A       childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());\A \A       if (position == 'top' || position == 'after') childNodes.reverse();\A       childNodes.each(insert.curry(element));\A \A       content.evalScripts.bind(content).defer();\A     }\A \A     return element;\A   },\A \A   wrap: function(element, wrapper, attributes) {\A     element = $(element);\A     if (Object.isElement(wrapper))\A       $(wrapper).writeAttribute(attributes || { });\A     else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);\A     else wrapper = new Element('div', wrapper);\A     if (element.parentNode)\A       element.parentNode.replaceChild(wrapper, element);\A     wrapper.appendChild(element);\A     return wrapper;\A   },\A \A   inspect: function(element) {\A     element = $(element);\A     var result = '<' + element.tagName.toLowerCase();\A     $H({'id': 'id', 'className': 'class'}).each(function(pair) {\A       var property = pair.first(), attribute = pair.last();\A       var value = (element[property] || '').toString();\A       if (value) result += ' ' + attribute + '=' + value.inspect(true);\A     });\A     return result + '>';\A   },\A \A   recursivelyCollect: function(element, property) {\A     element = $(element);\A     var elements = [];\A     while (element = element[property])\A       if (element.nodeType == 1)\A         elements.push(Element.extend(element));\A     return elements;\A   },\A \A   ancestors: function(element) {\A     return $(element).recursivelyCollect('parentNode');\A   },\A \A   descendants: function(element) {\A     return $(element).select("*");\A   },\A \A   firstDescendant: function(element) {\A     element = $(element).firstChild;\A     while (element && element.nodeType != 1) element = element.nextSibling;\A     return $(element);\A   },\A \A   immediateDescendants: function(element) {\A     if (!(element = $(element).firstChild)) return [];\A     while (element && element.nodeType != 1) element = element.nextSibling;\A     if (element) return [element].concat($(element).nextSiblings());\A     return [];\A   },\A \A   previousSiblings: function(element) {\A     return $(element).recursivelyCollect('previousSibling');\A   },\A \A   nextSiblings: function(element) {\A     return $(element).recursivelyCollect('nextSibling');\A   },\A \A   siblings: function(element) {\A     element = $(element);\A     return element.previousSiblings().reverse().concat(element.nextSiblings());\A   },\A \A   match: function(element, selector) {\A     if (Object.isString(selector))\A       selector = new Selector(selector);\A     return selector.match($(element));\A   },\A \A   up: function(element, expression, index) {\A     element = $(element);\A     if (arguments.length == 1) return $(element.parentNode);\A     var ancestors = element.ancestors();\A     return Object.isNumber(expression) ? ancestors[expression] :\A       Selector.findElement(ancestors, expression, index);\A   },\A \A   down: function(element, expression, index) {\A     element = $(element);\A     if (arguments.length == 1) return element.firstDescendant();\A     return Object.isNumber(expression) ? element.descendants()[expression] :\A       Element.select(element, expression)[index || 0];\A   },\A \A   previous: function(element, expression, index) {\A     element = $(element);\A     if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));\A     var previousSiblings = element.previousSiblings();\A     return Object.isNumber(expression) ? previousSiblings[expression] :\A       Selector.findElement(previousSiblings, expression, index);\A   },\A \A   next: function(element, expression, index) {\A     element = $(element);\A     if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));\A     var nextSiblings = element.nextSiblings();\A     return Object.isNumber(expression) ? nextSiblings[expression] :\A       Selector.findElement(nextSiblings, expression, index);\A   },\A \A   select: function() {\A     var args = $A(arguments), element = $(args.shift());\A     return Selector.findChildElements(element, args);\A   },\A \A   adjacent: function() {\A     var args = $A(arguments), element = $(args.shift());\A     return Selector.findChildElements(element.parentNode, args).without(element);\A   },\A \A   identify: function(element) {\A     element = $(element);\A     var id = element.readAttribute('id'), self = arguments.callee;\A     if (id) return id;\A     do { id = 'anonymous_element_' + self.counter++ } while ($(id));\A     element.writeAttribute('id', id);\A     return id;\A   },\A \A   readAttribute: function(element, name) {\A     element = $(element);\A     if (Prototype.Browser.IE) {\A       var t = Element._attributeTranslations.read;\A       if (t.values[name]) return t.values[name](element, name);\A       if (t.names[name]) name = t.names[name];\A       if (name.include(':')) {\A         return (!element.attributes || !element.attributes[name]) ? null :\A          element.attributes[name].value;\A       }\A     }\A     return element.getAttribute(name);\A   },\A \A   writeAttribute: function(element, name, value) {\A     element = $(element);\A     var attributes = { }, t = Element._attributeTranslations.write;\A \A     if (typeof name == 'object') attributes = name;\A     else attributes[name] = Object.isUndefined(value) ? true : value;\A \A     for (var attr in attributes) {\A       name = t.names[attr] || attr;\A       value = attributes[attr];\A       if (t.values[attr]) name = t.values[attr](element, value);\A       if (value === false || value === null)\A         element.removeAttribute(name);\A       else if (value === true)\A         element.setAttribute(name, name);\A       else element.setAttribute(name, value);\A     }\A     return element;\A   },\A \A   getHeight: function(element) {\A     return $(element).getDimensions().height;\A   },\A \A   getWidth: function(element) {\A     return $(element).getDimensions().width;\A   },\A \A   classNames: function(element) {\A     return new Element.ClassNames(element);\A   },\A \A   hasClassName: function(element, className) {\A     if (!(element = $(element))) return;\A     var elementClassName = element.className;\A     return (elementClassName.length > 0 && (elementClassName == className ||\A       new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));\A   },\A \A   addClassName: function(element, className) {\A     if (!(element = $(element))) return;\A     if (!element.hasClassName(className))\A       element.className += (element.className ? ' ' : '') + className;\A     return element;\A   },\A \A   removeClassName: function(element, className) {\A     if (!(element = $(element))) return;\A     element.className = element.className.replace(\A       new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();\A     return element;\A   },\A \A   toggleClassName: function(element, className) {\A     if (!(element = $(element))) return;\A     return element[element.hasClassName(className) ?\A       'removeClassName' : 'addClassName'](className);\A   },\A \A   // removes whitespace-only text node children\A   cleanWhitespace: function(element) {\A     element = $(element);\A     var node = element.firstChild;\A     while (node) {\A       var nextNode = node.nextSibling;\A       if (node.nodeType == 3 && !/\S/.test(node.nodeValue))\A         element.removeChild(node);\A       node = nextNode;\A     }\A     return element;\A   },\A \A   empty: function(element) {\A     return $(element).innerHTML.blank();\A   },\A \A   descendantOf: function(element, ancestor) {\A     element = $(element), ancestor = $(ancestor);\A \A     if (element.compareDocumentPosition)\A       return (element.compareDocumentPosition(ancestor) & 8) === 8;\A \A     if (ancestor.contains)\A       return ancestor.contains(element) && ancestor !== element;\A \A     while (element = element.parentNode)\A       if (element == ancestor) return true;\A \A     return false;\A   },\A \A   scrollTo: function(element) {\A     element = $(element);\A     var pos = element.cumulativeOffset();\A     window.scrollTo(pos[0], pos[1]);\A     return element;\A   },\A \A   getStyle: function(element, style) {\A     element = $(element);\A     style = style == 'float' ? 'cssFloat' : style.camelize();\A     var value = element.style[style];\A     if (!value || value == 'auto') {\A       var css = document.defaultView.getComputedStyle(element, null);\A       value = css ? css[style] : null;\A     }\A     if (style == 'opacity') return value ? parseFloat(value) : 1.0;\A     return value == 'auto' ? null : value;\A   },\A \A   getOpacity: function(element) {\A     return $(element).getStyle('opacity');\A   },\A \A   setStyle: function(element, styles) {\A     element = $(element);\A     var elementStyle = element.style, match;\A     if (Object.isString(styles)) {\A       element.style.cssText += ';' + styles;\A       return styles.include('opacity') ?\A         element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;\A     }\A     for (var property in styles)\A       if (property == 'opacity') element.setOpacity(styles[property]);\A       else\A         elementStyle[(property == 'float' || property == 'cssFloat') ?\A           (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :\A             property] = styles[property];\A \A     return element;\A   },\A \A   setOpacity: function(element, value) {\A     element = $(element);\A     element.style.opacity = (value == 1 || value === '') ? '' :\A       (value < 0.00001) ? 0 : value;\A     return element;\A   },\A \A   getDimensions: function(element) {\A     element = $(element);\A     var display = element.getStyle('display');\A     if (display != 'none' && display != null) // Safari bug\A       return {width: element.offsetWidth, height: element.offsetHeight};\A \A     // All *Width and *Height properties give 0 on elements with display none,\A     // so enable the element temporarily\A     var els = element.style;\A     var originalVisibility = els.visibility;\A     var originalPosition = els.position;\A     var originalDisplay = els.display;\A     els.visibility = 'hidden';\A     els.position = 'absolute';\A     els.display = 'block';\A     var originalWidth = element.clientWidth;\A     var originalHeight = element.clientHeight;\A     els.display = originalDisplay;\A     els.position = originalPosition;\A     els.visibility = originalVisibility;\A     return {width: originalWidth, height: originalHeight};\A   },\A \A   makePositioned: function(element) {\A     element = $(element);\A     var pos = Element.getStyle(element, 'position');\A     if (pos == 'static' || !pos) {\A       element._madePositioned = true;\A       element.style.position = 'relative';\A       // Opera returns the offset relative to the positioning context, when an\A       // element is position relative but top and left have not been defined\A       if (Prototype.Browser.Opera) {\A         element.style.top = 0;\A         element.style.left = 0;\A       }\A     }\A     return element;\A   },\A \A   undoPositioned: function(element) {\A     element = $(element);\A     if (element._madePositioned) {\A       element._madePositioned = undefined;\A       element.style.position =\A         element.style.top =\A         element.style.left =\A         element.style.bottom =\A         element.style.right = '';\A     }\A     return element;\A   },\A \A   makeClipping: function(element) {\A     element = $(element);\A     if (element._overflow) return element;\A     element._overflow = Element.getStyle(element, 'overflow') || 'auto';\A     if (element._overflow !== 'hidden')\A       element.style.overflow = 'hidden';\A     return element;\A   },\A \A   undoClipping: function(element) {\A     element = $(element);\A     if (!element._overflow) return element;\A     element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;\A     element._overflow = null;\A     return element;\A   },\A \A   cumulativeOffset: function(element) {\A     var valueT = 0, valueL = 0;\A     do {\A       valueT += element.offsetTop  || 0;\A       valueL += element.offsetLeft || 0;\A       element = element.offsetParent;\A     } while (element);\A     return Element._returnOffset(valueL, valueT);\A   },\A \A   positionedOffset: function(element) {\A     var valueT = 0, valueL = 0;\A     do {\A       valueT += element.offsetTop  || 0;\A       valueL += element.offsetLeft || 0;\A       element = element.offsetParent;\A       if (element) {\A         if (element.tagName.toUpperCase() == 'BODY') break;\A         var p = Element.getStyle(element, 'position');\A         if (p !== 'static') break;\A       }\A     } while (element);\A     return Element._returnOffset(valueL, valueT);\A   },\A \A   absolutize: function(element) {\A     element = $(element);\A     if (element.getStyle('position') == 'absolute') return element;\A     // Position.prepare(); // To be done manually by Scripty when it needs it.\A \A     var offsets = element.positionedOffset();\A     var top     = offsets[1];\A     var left    = offsets[0];\A     var width   = element.clientWidth;\A     var height  = element.clientHeight;\A \A     element._originalLeft   = left - parseFloat(element.style.left  || 0);\A     element._originalTop    = top  - parseFloat(element.style.top || 0);\A     element._originalWidth  = element.style.width;\A     element._originalHeight = element.style.height;\A \A     element.style.position = 'absolute';\A     element.style.top    = top + 'px';\A     element.style.left   = left + 'px';\A     element.style.width  = width + 'px';\A     element.style.height = height + 'px';\A     return element;\A   },\A \A   relativize: function(element) {\A     element = $(element);\A     if (element.getStyle('position') == 'relative') return element;\A     // Position.prepare(); // To be done manually by Scripty when it needs it.\A \A     element.style.position = 'relative';\A     var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);\A     var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);\A \A     element.style.top    = top + 'px';\A     element.style.left   = left + 'px';\A     element.style.height = element._originalHeight;\A     element.style.width  = element._originalWidth;\A     return element;\A   },\A \A   cumulativeScrollOffset: function(element) {\A     var valueT = 0, valueL = 0;\A     do {\A       valueT += element.scrollTop  || 0;\A       valueL += element.scrollLeft || 0;\A       element = element.parentNode;\A     } while (element);\A     return Element._returnOffset(valueL, valueT);\A   },\A \A   getOffsetParent: function(element) {\A     if (element.offsetParent) return $(element.offsetParent);\A     if (element == document.body) return $(element);\A \A     while ((element = element.parentNode) && element != document.body)\A       if (Element.getStyle(element, 'position') != 'static')\A         return $(element);\A \A     return $(document.body);\A   },\A \A   viewportOffset: function(forElement) {\A     var valueT = 0, valueL = 0;\A \A     var element = forElement;\A     do {\A       valueT += element.offsetTop  || 0;\A       valueL += element.offsetLeft || 0;\A \A       // Safari fix\A       if (element.offsetParent == document.body &&\A         Element.getStyle(element, 'position') == 'absolute') break;\A \A     } while (element = element.offsetParent);\A \A     element = forElement;\A     do {\A       if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {\A         valueT -= element.scrollTop  || 0;\A         valueL -= element.scrollLeft || 0;\A       }\A     } while (element = element.parentNode);\A \A     return Element._returnOffset(valueL, valueT);\A   },\A \A   clonePosition: function(element, source) {\A     var options = Object.extend({\A       setLeft:    true,\A       setTop:     true,\A       setWidth:   true,\A       setHeight:  true,\A       offsetTop:  0,\A       offsetLeft: 0\A     }, arguments[2] || { });\A \A     // find page position of source\A     source = $(source);\A     var p = source.viewportOffset();\A \A     // find coordinate system to use\A     element = $(element);\A     var delta = [0, 0];\A     var parent = null;\A     // delta [0,0] will do fine with position: fixed elements,\A     // position:absolute needs offsetParent deltas\A     if (Element.getStyle(element, 'position') == 'absolute') {\A       parent = element.getOffsetParent();\A       delta = parent.viewportOffset();\A     }\A \A     // correct by body offsets (fixes Safari)\A     if (parent == document.body) {\A       delta[0] -= document.body.offsetLeft;\A       delta[1] -= document.body.offsetTop;\A     }\A \A     // set position\A     if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';\A     if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';\A     if (options.setWidth)  element.style.width = source.offsetWidth + 'px';\A     if (options.setHeight) element.style.height = source.offsetHeight + 'px';\A     return element;\A   }\A };\A \A Element.Methods.identify.counter = 1;\A \A Object.extend(Element.Methods, {\A   getElementsBySelector: Element.Methods.select,\A   childElements: Element.Methods.immediateDescendants\A });\A \A Element._attributeTranslations = {\A   write: {\A     names: {\A       className: 'class',\A       htmlFor:   'for'\A     },\A     values: { }\A   }\A };\A \A if (Prototype.Browser.Opera) {\A   Element.Methods.getStyle = Element.Methods.getStyle.wrap(\A     function(proceed, element, style) {\A       switch (style) {\A         case 'left': case 'top': case 'right': case 'bottom':\A           if (proceed(element, 'position') === 'static') return null;\A         case 'height': case 'width':\A           // returns '0px' for hidden elements; we want it to return null\A           if (!Element.visible(element)) return null;\A \A           // returns the border-box dimensions rather than the content-box\A           // dimensions, so we subtract padding and borders from the value\A           var dim = parseInt(proceed(element, style), 10);\A \A           if (dim !== element['offset' + style.capitalize()])\A             return dim + 'px';\A \A           var properties;\A           if (style === 'height') {\A             properties = ['border-top-width', 'padding-top',\A              'padding-bottom', 'border-bottom-width'];\A           }\A           else {\A             properties = ['border-left-width', 'padding-left',\A              'padding-right', 'border-right-width'];\A           }\A           return properties.inject(dim, function(memo, property) {\A             var val = proceed(element, property);\A             return val === null ? memo : memo - parseInt(val, 10);\A           }) + 'px';\A         default: return proceed(element, style);\A       }\A     }\A   );\A \A   Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(\A     function(proceed, element, attribute) {\A       if (attribute === 'title') return element.title;\A       return proceed(element, attribute);\A     }\A   );\A }\A \A else if (Prototype.Browser.IE) {\A   // IE doesn't report offsets correctly for static elements,so we change them
// to relative to get the values,then change them back.
Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
function(proceed,element){element:$(element)}
);
var value = proceed(element);
element.setStyle({position:position}
);
$w('positionedOffset viewportOffset').each(function(method){elementmethodsmethod:Element.Methods[method].wrap(function(proceed,element) { element = $(element)}
var position = element.getStyle(position);
if (position !== static) return proceed(element);
// Trigger hasLayout on the offset parent so that IE6 reports
// accurate offsetTop and offsetLeft values for position: fixed.
var offsetParent = element.getOffsetParent();
if (offsetParent && offsetParent.getStyle(position) === fixed)
offsetParent.setStyle({zoom:1}
);
Element.Methods.getStyle = function(element,style){element:$(element);style:(style=='float'||style=='cssFloat') ? styleFloat : style.camelize();varvalue:element.style[style];ifvalueelementcurrentstylevalue:element.currentStyle[style];ifstyle:= opacity) { if (value=(element.getStyle('filter') || ).match(/alpha\(opacity=(.*)\)/)) if (value[1]) return parseFloat(value[1]) / 100}
if (value == auto){ifstyle:= width || style == height) && (element.getStyle('display') != none)) return element[offset 0 style.capitalize()] 0 px}
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)}
;
Element._attributeTranslations ={read:{ names: { class: className, for: htmlFor}
,values:{_getattr:function(element,attribute) { return element.getAttribute(attribute,2)}
,_getAttrNode: function(element,attribute){varnode:element.getAttributeNode(attribute)}
,_getEv: function(element,attribute){attribute:element.getAttribute(attribute);returnattributeattributetostringslice23-2:null}
,_flag: function(element,attribute){returnelementhasattributeattributeattribute:null}
;
Element._attributeTranslations.write ={names:Object.extend({cellpadding:'cellPadding',cellspacing:'cellSpacing'},Element._attributeTranslations.read.names), values: { checked: function(element,value) { element.checked = !!value}
,style: function(element,value){elementstylecsstext:value ? value :}
;
$w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
'encType maxLength readOnly longDesc frameBorder').each(function(attr){element_attributetranslationswritenamesattrtolowercase:attr;element_attributetranslationshasattrtolowercase:attr}
);
(function(v){objectextendvhref: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}
else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)){elementmethodssetopacity:function(element,value) { element = $(element);elementstyleopacity:(value==1) ? 0.999999 : (value==='') ? : (value<0.00001) ? 0 : value}
else if (Prototype.Browser.WebKit){elementmethodssetopacity:function(element,value) { element = $(element);elementstyleopacity:(value==1||value==='') ? : (value<0.00001) ? 0 : value;ifvalue:= 1) if(element.tagName.toUpperCase() == IMG && element.width) { element.width++;isbutton:function(event,code) { switch (code) { case 0 return event.which == 1 && !event.metaKey;case1:return event.which == 1 && event.metaKey;default:return false}
else try{varn:document.createTextNode(' ')}
;
// Safari returns margins on body which is incorrect if the child is absolutely
// positioned. For performance reasons,redefine Element#cumulativeOffset for
// KHTML/WebKit only.
Element.Methods.cumulativeOffset = function(element){varvaluet:0 valueL = 0;dovaluet:element.offsetTop || 0;valuel:element.offsetLeft || 0;ifelementoffsetparent:= document.body) if (Element.getStyle(element,'position') == absolute) break;element:element.offsetParent}
if (Prototype.Browser.IE || Prototype.Browser.Opera){ieandoperaaremissinginnerhtmlsupportfortable-relatedandselectelementselementmethodsupdate:function(element,content) { element = $(element);ifcontentcontenttoelementcontent:content.toElement();content:Object.toHTML(content);vartagname:element.tagName.toUpperCase()}
if (outerHTML in document.createElement(div)){elementmethodsreplace:function(element,content) { element = $(element);ifcontentcontenttoelementcontent:content.toElement()}
content = Object.toHTML(content);
var parent = element.parentNode,tagName = parent.tagName.toUpperCase();
if (Element._insertionTranslations.tags[tagName]){varnextsibling:element.next();varfragments:Element._getContentFromAnonymousElement(tagName,content.stripScripts())}
Element._returnOffset = function(l,t){varresult:[l, t];resultleft:l;resulttop:t}
;
Element._getContentFromAnonymousElement = function(tagName,html){vardiv:new Element(div), t = Element._insertionTranslations.tags[tagName];iftdivinnerhtml:t[0] 0 html 0 t[1];t2timesfunctiondiv:div.firstChild}
;
Element._insertionTranslations ={before:function(element,node) { element.parentNode.insertBefore(node,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(){objectextendthistagsthead: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;varnode:$(element).getAttributeNode(attribute)}
;
Object.extend(Element,Element.Methods);
if (!Prototype.BrowserFeatures.ElementExtensions &&
document.createElement(div)[__proto__]){windowhtmlelement:{}
Element.extend = (function(){varmethods:{}
,ByTag = Element.Methods.ByTag;
var extend = Object.extend(function(element){ifelementelement_extendedbyprototypeelementnodetype:1 || element == window) return element;varmethods:Object.clone(Methods), tagName = element.tagName.toUpperCase(), property, value;forpropertyinmethodsvalue:methods[property];ifobjectisfunctionvaluepropertyinelementelementproperty:value.methodize()}
,{refresh:function() { // extend methods for all tags (Safaridoesn't need this)\A       if (!Prototype.BrowserFeatures.ElementExtensions) {\A         Object.extend(Methods, Element.Methods);\A         Object.extend(Methods, Element.Methods.Simulated);\A       }\A     }\A   });\A \A   extend.refresh();\A   return extend;\A })();\A \A Element.hasAttribute = function(element, attribute) {\A   if (element.hasAttribute) return element.hasAttribute(attribute);\A   return Element.Methods.Simulated.hasAttribute(element, attribute);\A };\A \A Element.addMethods = function(methods) {\A   var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;\A \A   if (!methods) {\A     Object.extend(Form, Form.Methods);\A     Object.extend(Form.Element, Form.Element.Methods);\A     Object.extend(Element.Methods.ByTag, {\A       "FORM":     Object.clone(Form.Methods),\A       "INPUT":    Object.clone(Form.Element.Methods),\A       "SELECT":   Object.clone(Form.Element.Methods),\A       "TEXTAREA": Object.clone(Form.Element.Methods)\A     });\A   }\A \A   if (arguments.length == 2) {\A     var tagName = methods;\A     methods = arguments[1];\A   }\A \A   if (!tagName) Object.extend(Element.Methods, methods || { });\A   else {\A     if (Object.isArray(tagName)) tagName.each(extend);\A     else extend(tagName);\A   }\A \A   function extend(tagName) {\A     tagName = tagName.toUpperCase();\A     if (!Element.Methods.ByTag[tagName])\A       Element.Methods.ByTag[tagName] = { };\A     Object.extend(Element.Methods.ByTag[tagName], methods);\A   }\A \A   function copy(methods, destination, onlyIfAbsent) {\A     onlyIfAbsent = onlyIfAbsent || false;\A     for (var property in methods) {\A       var value = methods[property];\A       if (!Object.isFunction(value)) continue;\A       if (!onlyIfAbsent || !(property in destination))\A         destination[property] = value.methodize();\A     }\A   }\A \A   function findDOMClass(tagName) {\A     var klass;\A     var trans = {\A       "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",\A       "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",\A       "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",\A       "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",\A       "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":\A       "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":\A       "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":\A       "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":\A       "FrameSet", "IFRAME": "IFrame"\A     };\A     if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';\A     if (window[klass]) return window[klass];\A     klass = 'HTML' + tagName + 'Element';\A     if (window[klass]) return window[klass];\A     klass = 'HTML' + tagName.capitalize() + 'Element';\A     if (window[klass]) return window[klass];\A \A     window[klass] = { };\A     window[klass].prototype = document.createElement(tagName)['__proto__'];\A     return window[klass];\A   }\A \A   if (F.ElementExtensions) {\A     copy(Element.Methods, HTMLElement.prototype);\A     copy(Element.Methods.Simulated, HTMLElement.prototype, true);\A   }\A \A   if (F.SpecificElementExtensions) {\A     for (var tag in Element.Methods.ByTag) {\A       var klass = findDOMClass(tag);\A       if (Object.isUndefined(klass)) continue;\A       copy(T[tag], klass.prototype);\A     }\A   }\A \A   Object.extend(Element, Element.Methods);\A   delete Element.ByTag;\A \A   if (Element.extend.refresh) Element.extend.refresh();\A   Element.cache = { };\A };\A \A document.viewport = {\A   getDimensions: function() {\A     var dimensions = { }, B = Prototype.Browser;\A     $w('widthheight').each(function(d) {\A       var D = d.capitalize();\A       if (B.WebKit && !document.evaluate) {\A         // Safari <3.0 needs self.innerWidth/Height\A         dimensions[d] = self['inner' + D];\A       } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {\A         // Opera <9.5 needs document.body.clientWidth/Height\A         dimensions[d] = document.body['client' + D]\A       } else {\A         dimensions[d] = document.documentElement['client' + D];\A       }\A     });\A     return dimensions;\A   },\A \A   getWidth: function() {\A     return this.getDimensions().width;\A   },\A \A   getHeight: function() {\A     return this.getDimensions().height;\A   },\A \A   getScrollOffsets: function() {\A     return Element._returnOffset(\A       window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,\A       window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);\A   }\A };\A /* Portions of the Selector class are derived from Jack Slocum'sDomQuery,*partofYUI-Extversion0.40,distributedunderthetermsofanMIT-style*license.Pleaseseehttp://www.yui-ext.com/formoreinformation.*/varSelector=Class.create({initialize:function(expression) { this.expression = expression.strip();ifthisshoulduseselectorsapithismode:selectorsAPI}
else if (this.shouldUseXPath()){thismode:xpath}
else{thismode:normal;forvari:0 j = 1, nodes = parentNode.childNodes;node:nodes[i];iifnodenodetype:= 1 && (!ofType||node._countedByPrototype)) node.nodeIndex = j++;isbutton:function(event,code) { return event.which ? (event.which===code+1) : (event.button===code);eventprototype:Event.prototype || document.createEvent(HTMLEvents)[__proto__];event:document.createEventObject();eventeventtype:ondataavailable}
,shouldUseXPath: function(){vare:this.expression;safari3chokeson:*-of-type and :empty if (Prototype.Browser.WebKit&&(e.include("-of-type") || e.include(:empty))) return false;xpathcantdonamespacedattributesnorcanitreadthecheckedpropertyfromdomnodesif\[w-:|:checked)/).test(e)) return false}
,shouldUseSelectorsAPI: function(){ifselector_divselector_div:new Element(div)}
,compileMatcher: function(){vare:this.expression, ps = Selector.patterns, h = Selector.handlers, c = Selector.criteria, le, p, m;ifselector_cacheethismatcher:Selector._cache[e]}
this.matcher = ["this.matcher = function(root) {","var r = root, h = Selector.handlers, c = false, n;"];
while (e && le != e && (/S/).test(e)){le:e;forvariinpsp:ps[i];ifm:e.match(p)) { this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : new Template(c[i]).evaluate(m));e:e.replace(m[0],'')}
,compileXPathMatcher: function(){vare:this.expression, ps = Selector.patterns, x = Selector.xpath, le, m;ifselector_cacheethisxpath:Selector._cache[e]}
this.matcher = [.//*];
while (e && le != e && (/S/).test(e)){le:e;forvariinpsifm: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],'')}
,findElements: function(root){root:root || document;vare:this.expression, results;switchthismodecaseselectorsapi:// querySelectorAll queries document-wide, then filters to descendants // of the context element. That's not what we want.\A         // Add an explicit context to the selector if necessary.\A         if (root !== document) {\A           var oldId = root.id, id = $(root).identify();\A           e = "#" + id + " " + e;\A         }\A \A         results = $A(root.querySelectorAll(e)).map(Element.extend);\A         root.id = oldId;\A \A         return results;\A       case 'xpath':\A         return document._getElementsByXPath(this.xpath, root);\A       default:\A        return this.matcher(root);\A     }\A   },\A \A   match: function(element) {\A     this.tokens = [];\A \A     var e = this.expression, ps = Selector.patterns, as = Selector.assertions;\A     var le, p, m;\A \A     while (e && le !== e && (/\S/).test(e)) {\A       le = e;\A       for (var i in ps) {\A         p = ps[i];\A         if (m = e.match(p)) {\A           // use the Selector.assertions methods unless the selector\A           // is too complex.\A           if (as[i]) {\A             this.tokens.push([i, Object.clone(m)]);\A             e = e.replace(m[0], '');\A           } else {\A             // reluctantly do a document-wide search\A             // and look for a match in the array\A             return this.findElements(document).include(element);\A           }\A         }\A       }\A     }\A \A     var match = true, name, matches;\A     for (var i = 0, token; token = this.tokens[i]; i++) {\A       name = token[0], matches = token[1];\A       if (!Selector.assertions[name](element, matches)) {\A         match = false; break;\A       }\A     }\A \A     return match;\A   },\A \A   toString: function() {\A     return this.expression;\A   },\A \A   inspect: function() {\A     return "#<Selector:" + this.expression.inspect() + ">";\A   }\A });\A \A Object.extend(Selector, {\A   _cache: { },\A \A   xpath: {\A     descendant:   "//*",\A     child:        "/*",\A     adjacent:     "/following-sibling::*[1]",\A     laterSibling: '/following-sibling::*',\A     tagName:      function(m) {\A       if (m[1] == '*') return '';\A       return "[local-name()='" + m[1].toLowerCase() +\A              "' or local-name()='" + m[1].toUpperCase() + "']";\A     },\A     className:    "[contains(concat(' ', @class, ' '), ' #{1}
", r, c); c = false;').evaluate(m);\A     },\A     descendant:   'c = "descendant";',\A     child:        'c = "child";',\A     adjacent:     'c = "adjacent";',\A     laterSibling: 'c = "laterSibling";'\A   },\A \A   patterns: {\A     // combinators must be listed first\A     // (and descendant needs to be last combinator)\A     laterSibling: /^\s*~\s*/,\A     child:        /^\s*>\s*/,\A     adjacent:     /^\s*\+\s*/,\A     descendant:   /^\s/,\A \A     // selectors follow\A     tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,\A     id:           /^#([\w\-\*]+)(\b|$)/,\A     className:    /^\.([\w\-\*]+)(\b|$)/,\A     pseudo:\A /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,\A     attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,\A     attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/\A   },\A \A   // for Selector.match and Element#match\A   assertions: {\A     tagName: function(element, matches) {\A       return matches[1].toUpperCase() == element.tagName.toUpperCase();\A     },\A \A     className: function(element, matches) {\A       return Element.hasClassName(element, matches[1]);\A     },\A \A     id: function(element, matches) {\A       return element.id === matches[1];\A     },\A \A     attrPresence: function(element, matches) {\A       return Element.hasAttribute(element, matches[1]);\A     },\A \A     attr: function(element, matches) {\A       var nodeValue = Element.readAttribute(element, matches[1]);\A       return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);\A     }\A   },\A \A   handlers: {\A     // UTILITY FUNCTIONS\A     // joins two collections\A     concat: function(a, b) {\A       for (var i = 0, node; node = b[i]; i++)\A         a.push(node);\A       return a;\A     },\A \A     // marks an array of nodes for counting\A     mark: function(nodes) {\A       var _true = Prototype.emptyFunction;\A       for (var i = 0, node; node = nodes[i]; i++)\A         node._countedByPrototype = _true;\A       return nodes;\A     },\A \A     unmark: function(nodes) {\A       for (var i = 0, node; node = nodes[i]; i++)\A         node._countedByPrototype = undefined;\A       return nodes;\A     },\A \A     // mark each child node with its position (for nth calls)\A     // "ofType" flag indicates whether we're indexing for nth-of-type
// rather than nth-child
index: function(parentNode,reverse,ofType){parentnode_countedbyprototype:Prototype.emptyFunction;ifreverseforvarnodes:parentNode.childNodes, i = nodes.length 0 1, j = 1;i:0;i--varnode:nodes[i];ifnodenodetype:= 1 && (!ofType||node._countedByPrototype)) node.nodeIndex = j++}
,// filters out duplicates and extends all nodes
unique: function(nodes){ifnodeslength:= 0 return nodes;varresults:[], n;forvari:0 l = nodes.length;iifn:nodes[i])._countedByPrototype) { n._countedByPrototype = Prototype.emptyFunction}
,child: function(nodes){varh:Selector.handlers;forvari:0 results = [], node;node:nodes[i];iforvarj:0 child;child:node.childNodes[j];jifchildnodetype:= 1 && child.tagName != !) results.push(child)}
,adjacent: function(nodes){forvari:0 results = [], node;node:nodes[i];ivarnext:this.nextElementSibling(node)}
,nextElementSibling: function(node){whilenode:node.nextSibling) if (node.nodeType==1) return node}
,previousElementSibling: function(node){whilenode:node.previousSibling) if (node.nodeType==1) return node}
,// TOKEN FUNCTIONS
tagName: function(nodes,root,tagName,combinator){varutagname:tagName.toUpperCase();varresults:[], h = Selector.handlers;ifnodesifcombinatorfastlaneforordinarydescendantcombinatorsifcombinator:= descendant) { for (vari=0,node;node=nodes[i];i++) h.concat(results,node.getElementsByTagName(tagName))}
,id: function(nodes,root,id,combinator){vartargetnode:$(id), h = Selector.handlers;ifnodesroot:= document) return [targetNode];ifnodesifcombinatorifcombinator:= child) { for (vari=0,node;node=nodes[i];i++) if (targetNode.parentNode==node) return [targetNode]}
else if (combinator == adjacent){forvari:0 node;node:nodes[i];iifselectorhandlerspreviouselementsiblingtargetnode:= node) return [targetNode]}
,className: function(nodes,root,className,combinator){ifnodescombinatornodes:this[combinator](nodes)}
,byClassName: function(nodes,root,className){ifnodesnodes:Selector.handlers.descendant([root]);varneedle:' ' 0 className 0 ' ';forvari:0 results = [], node, nodeClassName;node:nodes[i];inodeclassname:node.className;ifnodeclassnamelength:= 0 continue;ifnodeclassname:= className || (' '+nodeClassName+' ').include(needle)) results.push(node)}
,attrPresence: function(nodes,root,attr,combinator){ifnodesnodes:root.getElementsByTagName(*);ifnodescombinatornodes:this[combinator](nodes);varresults:[];forvari:0 node;node:nodes[i]}
,attr: function(nodes,root,attr,value,operator,combinator){ifnodesnodes:root.getElementsByTagName(*);ifnodescombinatornodes:this[combinator](nodes);varhandler:Selector.operators[operator], results = [];forvari:0 node;node:nodes[i];ivarnodevalue:Element.readAttribute(node,attr);ifnodevalue:== null) continue}
,pseudo: function(nodes,name,value,root,combinator){ifnodescombinatornodes:this[combinator](nodes);ifnodesnodes:root.getElementsByTagName(*)}
,pseudos:{first-child:function(nodes,value,root) { for (vari=0,results=[],node;node=nodes[i];i++) { if (Selector.handlers.previousElementSibling(node)) continue}
,only-of-type: function(nodes,formula,root){varp:Selector.pseudos}
,// handles the an+b logic
getIndices: function(a,b,total){ifa:= 0 return b > 0 ? [b] : [];returnr1totalinjectfunctionmemoiif0:= (i-b) % a && (i-b) / a >= 0 memo.push(i)}
,// handles nth(-last)-child,nth(-last)-of-type,and (first|last)-of-type
nth: function(nodes,formula,root,reverse,ofType){ifnodeslength:= 0 return [];ifformula:= odd) formula = 2n+1;varh:Selector.handlers, results = [], indexed = [], m;forvari:0 node;node:nodes[i]}
if (formula.match(/^\d+$/)){justanumberformula:Number(formula);forvari:0 node;node:nodes[i];iifnodenodeindex:= formula) results.push(node)}
else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)){anbifm1:= 0 m[1] = -1;vara:m[1] ? Number(m[1]) : 1;varb:m[2] ? Number(m[2]) : 0;varindices:Selector.pseudos.getIndices(a,b,nodes.length);forvari:0 node, l = indices.length;node:nodes[i];iforvarj:0;jifnodenodeindex:= indices[j]) results.push(node)}
,empty: function(nodes,value,root){forvari:0 results = [], node;node:nodes[i];iietreatscommentsaselementnodesifnodetagname:= ! || node.firstChild) continue}
,not: function(nodes,selector,root){varh:Selector.handlers, selectorType, m;varexclusions:new Selector(selector).findElements(root);forvari:0 results = [], node;node:nodes[i]}
,enabled: function(nodes,value,root){forvari:0 results = [], node;node:nodes[i];iifnodedisablednodetypenodetype:= hidden)) results.push(node)}
,operators:{functionnvvreturnnv:= v}
,!=: function(nv,v){returnnv:v}
,^=: function(nv,v){returnnv:= v || nv && nv.startsWith(v)}
,$=: function(nv,v){returnnv:= v || nv && nv.endsWith(v)}
,*=: function(nv,v){returnnv:= v || nv && nv.include(v)}
,split: function(expression){varexpressions:[];expressionscanw#:.~>+()s-]+|\*|\[.*?\])+)s*(,|$)/, function(m) { expressions.push(m[1].strip())}
,matchElements: function(elements,expression){varmatches:$$(expression), h = Selector.handlers;forvari:0 results = [], element;element:elements[i]}
,findElement: function(elements,expression,index){ifobjectisnumberexpressionindex:expression;expression:false}
,findChildElements: function(element,expressions){expressions:Selector.split(expressions.join(','));varresults:[], h = Selector.handlers;forvari:0 l = expressions.length, selector;iselector:new Selector(expressions[i].strip())}
);
if (Prototype.Browser.IE){objectextendselectorhandlersiereturnscommentnodesongetelementsbytagnamefilterthemoutconcat:function(a,b) { for (vari=0,node;node=b[i];i++) if (node.tagName!=="!") a.push(node);objectextendmethodsstoppropagation:function() { this.cancelBubble = true}
var Form ={reset:function(form) { $(form).reset()}
,serializeElements: function(elements,options){iftypeofoptions:object) options = { hash: !!options}
,function(result,element){ifelementdisabledelementnamekey:element.name;value:$(element).getValue();ifvalue:null && element.type != file && (element.type!='submit'||(!submitted&&submit!==false&&(!submit||key==submit) && (submitted=true)))) { if (keyinresult) { // a key is already present;constructanarrayofvaluesifobjectisarrayresultkeyresultkey:[result[key]]}
;
Form.Methods ={serialize:function(form,options) { return Form.serializeElements(Form.getElements(form), options)}
,getInputs: function(form,typeName,name){form:$(form);varinputs:form.getElementsByTagName(input);forvari:0 matchingInputs = [], length = inputs.length;ivarinput:inputs[i];iftypenameinputtype:typeName) || (name&&input.name!=name)) continue}
,findFirstElement: function(form){varelements:$(form).getElements().findAll(function(element) { return hidden != element.type && !element.disabled}
);
var firstByIndex = elements.findAll(function(element){returnelementhasattributetabindexelementtabindex:0}
,request: function(form,options){form:$(form), options = Object.clone(options||{});varparams:options.parameters, action = form.readAttribute(action) ||;ifactionblankaction:window.location.href;optionsparameters:form.serialize(true);ifparamsifobjectisstringparamsparams:params.toQueryParams()}
;
/*--------------------------------------------------------------------------*/
Form.Element ={focus:function(element) { $(element).focus()}
;
Form.Element.Methods ={serialize:function(element) { element = $(element);ifelementdisabledelementnamevarvalue:element.getValue();ifvalue:undefined) { var pair = {}
,activate: function(element){element:$(element);ifelementselectelementtagnametolowercase:input || ![button, reset, submit].include(element.type))) element.select()}
,disable: function(element){element:$(element);elementdisabled:true}
,enable: function(element){element:$(element);elementdisabled:false}
;
/*--------------------------------------------------------------------------*/
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){ifobjectisundefinedvaluereturnelementcheckedelementvalue:null;elseelementchecked:!!value}
,textarea: function(element,value){elseelementvalue:value}
,select: function(element,value){ifobjectisundefinedvaluereturnthiselementtype:= select-one ? selectOne : selectMany](element);elsevaroptcurrentvaluesingle:!Object.isArray(value);forvari:0 length = element.length;iopt:element.options[i];currentvalue:this.optionValue(opt);ifsingleifcurrentvalue:= value) { opt.selected = true}
,selectOne: function(element){varindex:element.selectedIndex;returnindex:0 ? this.optionValue(element.options[index]) : null}
,selectMany: function(element){varvalueslength:element.length;forvari:0 values = [];ivaropt:element.options[i]}
,optionValue: function(opt){extendelementbecausehasattributemaynotbenativereturnelementextendopthasattributevalueoptvalue:opt.text}
;
/*--------------------------------------------------------------------------*/
Abstract.TimedObserver = Class.create(PeriodicalExecuter,{initialize:function($super,element,frequency,callback) { $super(callback,frequency);thiselement:$(element);thislastvalue:this.getValue()}
,execute: function(){varvalue:this.getValue();ifobjectisstringthislastvalueobjectisstringvaluethislastvalue:value : String(this.lastValue) != String(value)) { this.callback(this.element,value);thislastvalue:value}
);
/*--------------------------------------------------------------------------*/
Abstract.EventObserver = Class.create({initialize:function(element,callback) { this.element = $(element);thiscallback:callback;thislastvalue:this.getValue();ifthiselementtagnametolowercase:= form) this.registerFormCallbacks()}
,onElementEvent: function(){varvalue:this.getValue();ifthislastvalue:value) { this.callback(this.element,value);thislastvalue:value}
,registerCallback: function(element){ifelementtypeswitchelementtypetolowercasecasecheckbox:case radio: Event.observe(element,'click',this.onElementEvent.bind(this));default:Event.observe(element,'change',this.onElementEvent.bind(this))}
;
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){switcheventtypecasemouseover:element = event.fromElement;casemouseout:element = event.toElement;default:return null}
);
Event.Methods = (function(){ifprototypebrowserievarbuttonmap:{ 0 1, 1: 4, 2: 2}
;
isButton = function(event,code){returneventbutton:= buttonMap[code]}
return{isleftclick:function(event) { return isButton(event,0);observe:function(element,eventName,handler) { element = $(element);varname:getDOMEventName(eventName);varwrapper:createWrapper(element,eventName,handler)}
,element: function(event){event:Event.extend(event);varnode:event.target, type = event.type, currentTarget = event.currentTarget;ifcurrenttargetcurrenttargettagnamefirefoxscrewsuptheclickeventwhenmovingbetweenradiobuttonsviaarrowkeysitalsoscrewsuptheloadanderroreventsonimagesreportingthedocumentasthetargetinsteadoftheoriginalimageiftype:== load || type === error || (type==='click'&&currentTarget.tagName.toLowerCase() === input && currentTarget.type === radio)) node = currentTarget}
,findElement: function(event,expression){varelement:Event.element(event);varelements:[element].concat(element.ancestors())}
,pointer: function(event){vardocelement:document.documentElement, body = document.body || { scrollLeft: 0 scrollTop: 0}
;
return{x:event.pageX || (event.clientX+(docElement.scrollLeft||body.scrollLeft) 0 (docElement.clientLeft||0)), y: event.pageY || (event.clientY+(docElement.scrollTop||body.scrollTop) 0 (docElement.clientTop||0))}
,stop: function(event){eventstopped:true}
)();
Event.extend = (function(){varmethods:Object.keys(Event.Methods).inject({},function(m,name) { m[name] = Event.Methods[name].methodize()}
,preventDefault: function(){thisreturnvalue:false}
);
return function(event){event_extendedbyprototype:Prototype.emptyFunction;varpointer:Event.pointer(event);objectextendeventtarget:event.srcElement, relatedTarget: Event.relatedTarget(event), pageX: pointer.x, pageY: pointer.y}
)();
Object.extend(Event,(function(){varcache:Event.cache;argumentscalleeid:arguments.callee.id || 1;returnelement_prototypeeventid:[++arguments.callee.id]}
function getDOMEventName(eventName){ifeventnameeventnameinclude:')) return "dataavailable";\A     return eventName;\A   }\A \A   function getCacheForID(id) {\A     return cache[id] = cache[id] || { };\A   }\A \A   function getWrappersForEventName(id, eventName) {\A     var c = getCacheForID(id);\A     return c[eventName] = c[eventName] || [];\A   }\A \A   function createWrapper(element, eventName, handler) {\A     var id = getEventID(element);\A     var c = getWrappersForEventName(id, eventName);\A     if (c.pluck("handler").include(handler)) return false;\A \A     var wrapper = function(event) {\A       if (!Event || !Event.extend ||\A         (event.eventName && event.eventName != eventName))\A           return false;\A \A       Event.extend(event);\A       handler.call(element, event);\A     };\A \A     wrapper.handler = handler;\A     c.push(wrapper);\A     return wrapper;\A   }\A \A   function findWrapper(id, eventName, handler) {\A     var c = getWrappersForEventName(id, eventName);\A     return c.find(function(wrapper) { return wrapper.handler == handler });\A   }\A \A   function destroyWrapper(id, eventName, handler) {\A     var c = getCacheForID(id);\A     if (!c[eventName]) return false;\A     c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));\A   }\A \A   function destroyCache() {\A     for (var id in cache)\A       for (var eventName in cache[id])\A         cache[id][eventName] = null;\A   }\A \A \A   // Internet Explorer needs to remove event handlers on page unload\A   // in order to avoid memory leaks.\A   if (window.attachEvent) {\A     window.attachEvent("onunload", destroyCache);\A   }\A \A   // Safari has a dummy event handler on page unload so that it won't // use its bfcache. Safari <= 3.1 has an issue with restoring the document // object when page is returned to via the back button using its bfcache. if (Prototype.Browser.WebKit) { window.addEventListener(unload',Prototype.emptyFunction,fals)}
,stopObserving: function(element,eventName,handler){element:$(element);varid:getEventID(element), name = getDOMEventName(eventName)}
,fire: function(element,eventName,memo){element:$(element);ifelement:= document && document.createEvent && !element.dispatchEvent) element = document.documentElement;ifdocumentcreateeventevent:document.createEvent(HTMLEvents)}
)());
Object.extend(Event,Event.Methods);
Element.addMethods({fire:Event.fire, observe: Event.observe, stopObserving: Event.stopObserving}
);
Object.extend(document,{fire:Element.Methods.fire.methodize(), observe: Element.Methods.observe.methodize(), stopObserving: Element.Methods.stopObserving.methodize(), loaded: false}
,findAll: function(iterator,context),,pluck: function(property),,reject: function(iterator,context){varresults:[]}
var position = element.getStyle(position);
if (position !== static) return proceed(element);
element.setStyle(,);
element.setStyle({position:relative}
,// COMBINATOR FUNCTIONS
descendant: function(nodes),,laterSibling: function(nodes),,only-child: function(nodes,value,root){varh:Selector.handlers;forvari:0 results = [], node;node:nodes[i]}
else if (combinator == descendant),,// IE improperly serializes _countedByPrototype in (inner|outer)HTML.
unmark: function(nodes){forvari:0 node;node:nodes[i]}
,last-child: function(nodes,value,root),,disabled: function(nodes,value,root),,checked: function(nodes,value,root){forvari:0 results = [], node;node:nodes[i]}
,disable: function(form),,enable: function(form),,focusFirstElement: function(form){form:$(form)}
,getValue: function(element),,setValue: function(element,value){element:$(element);varmethod:element.tagName.toLowerCase()}
);
Form.Element.Observer = Class.create(Abstract.TimedObserver,,);
Form.Element.EventObserver = Class.create(Abstract.EventObserver,{getvalue:function() { return Form.Element.getValue(this.element)}
);
Form.Observer = Class.create(Abstract.TimedObserver,,);
Form.EventObserver = Class.create(Abstract.EventObserver,{getvalue:function() { return Form.serialize(this.element)}