[BACK]Return to prototype.js CVS log [TXT][DIR] Up to [local] / todotxt / Text-Todo-REST-API / example / htdocs

Annotation of todotxt/Text-Todo-REST-API/example/htdocs/prototype.js, Revision 1.1

1.1     ! andrew      1: /*  Prototype JavaScript framework, version 1.6.1
        !             2:  *  (c) 2005-2009 Sam Stephenson
        !             3:  *
        !             4:  *  Prototype is freely distributable under the terms of an MIT-style license.
        !             5:  *  For details, see the Prototype web site: http://www.prototypejs.org/
        !             6:  *
        !             7:  *--------------------------------------------------------------------------*/
        !             8:
        !             9: var Prototype = {
        !            10:   Version: '1.6.1',
        !            11:
        !            12:   Browser: (function(){
        !            13:     var ua = navigator.userAgent;
        !            14:     var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
        !            15:     return {
        !            16:       IE:             !!window.attachEvent && !isOpera,
        !            17:       Opera:          isOpera,
        !            18:       WebKit:         ua.indexOf('AppleWebKit/') > -1,
        !            19:       Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
        !            20:       MobileSafari:   /Apple.*Mobile.*Safari/.test(ua)
        !            21:     }
        !            22:   })(),
        !            23:
        !            24:   BrowserFeatures: {
        !            25:     XPath: !!document.evaluate,
        !            26:     SelectorsAPI: !!document.querySelector,
        !            27:     ElementExtensions: (function() {
        !            28:       var constructor = window.Element || window.HTMLElement;
        !            29:       return !!(constructor && constructor.prototype);
        !            30:     })(),
        !            31:     SpecificElementExtensions: (function() {
        !            32:       if (typeof window.HTMLDivElement !== 'undefined')
        !            33:         return true;
        !            34:
        !            35:       var div = document.createElement('div');
        !            36:       var form = document.createElement('form');
        !            37:       var isSupported = false;
        !            38:
        !            39:       if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
        !            40:         isSupported = true;
        !            41:       }
        !            42:
        !            43:       div = form = null;
        !            44:
        !            45:       return isSupported;
        !            46:     })()
        !            47:   },
        !            48:
        !            49:   ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
        !            50:   JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
        !            51:
        !            52:   emptyFunction: function() { },
        !            53:   K: function(x) { return x }
        !            54: };
        !            55:
        !            56: if (Prototype.Browser.MobileSafari)
        !            57:   Prototype.BrowserFeatures.SpecificElementExtensions = false;
        !            58:
        !            59:
        !            60: var Abstract = { };
        !            61:
        !            62:
        !            63: var Try = {
        !            64:   these: function() {
        !            65:     var returnValue;
        !            66:
        !            67:     for (var i = 0, length = arguments.length; i < length; i++) {
        !            68:       var lambda = arguments[i];
        !            69:       try {
        !            70:         returnValue = lambda();
        !            71:         break;
        !            72:       } catch (e) { }
        !            73:     }
        !            74:
        !            75:     return returnValue;
        !            76:   }
        !            77: };
        !            78:
        !            79: /* Based on Alex Arnell's inheritance implementation. */
        !            80:
        !            81: var Class = (function() {
        !            82:   function subclass() {};
        !            83:   function create() {
        !            84:     var parent = null, properties = $A(arguments);
        !            85:     if (Object.isFunction(properties[0]))
        !            86:       parent = properties.shift();
        !            87:
        !            88:     function klass() {
        !            89:       this.initialize.apply(this, arguments);
        !            90:     }
        !            91:
        !            92:     Object.extend(klass, Class.Methods);
        !            93:     klass.superclass = parent;
        !            94:     klass.subclasses = [];
        !            95:
        !            96:     if (parent) {
        !            97:       subclass.prototype = parent.prototype;
        !            98:       klass.prototype = new subclass;
        !            99:       parent.subclasses.push(klass);
        !           100:     }
        !           101:
        !           102:     for (var i = 0; i < properties.length; i++)
        !           103:       klass.addMethods(properties[i]);
        !           104:
        !           105:     if (!klass.prototype.initialize)
        !           106:       klass.prototype.initialize = Prototype.emptyFunction;
        !           107:
        !           108:     klass.prototype.constructor = klass;
        !           109:     return klass;
        !           110:   }
        !           111:
        !           112:   function addMethods(source) {
        !           113:     var ancestor   = this.superclass && this.superclass.prototype;
        !           114:     var properties = Object.keys(source);
        !           115:
        !           116:     if (!Object.keys({ toString: true }).length) {
        !           117:       if (source.toString != Object.prototype.toString)
        !           118:         properties.push("toString");
        !           119:       if (source.valueOf != Object.prototype.valueOf)
        !           120:         properties.push("valueOf");
        !           121:     }
        !           122:
        !           123:     for (var i = 0, length = properties.length; i < length; i++) {
        !           124:       var property = properties[i], value = source[property];
        !           125:       if (ancestor && Object.isFunction(value) &&
        !           126:           value.argumentNames().first() == "$super") {
        !           127:         var method = value;
        !           128:         value = (function(m) {
        !           129:           return function() { return ancestor[m].apply(this, arguments); };
        !           130:         })(property).wrap(method);
        !           131:
        !           132:         value.valueOf = method.valueOf.bind(method);
        !           133:         value.toString = method.toString.bind(method);
        !           134:       }
        !           135:       this.prototype[property] = value;
        !           136:     }
        !           137:
        !           138:     return this;
        !           139:   }
        !           140:
        !           141:   return {
        !           142:     create: create,
        !           143:     Methods: {
        !           144:       addMethods: addMethods
        !           145:     }
        !           146:   };
        !           147: })();
        !           148: (function() {
        !           149:
        !           150:   var _toString = Object.prototype.toString;
        !           151:
        !           152:   function extend(destination, source) {
        !           153:     for (var property in source)
        !           154:       destination[property] = source[property];
        !           155:     return destination;
        !           156:   }
        !           157:
        !           158:   function inspect(object) {
        !           159:     try {
        !           160:       if (isUndefined(object)) return 'undefined';
        !           161:       if (object === null) return 'null';
        !           162:       return object.inspect ? object.inspect() : String(object);
        !           163:     } catch (e) {
        !           164:       if (e instanceof RangeError) return '...';
        !           165:       throw e;
        !           166:     }
        !           167:   }
        !           168:
        !           169:   function toJSON(object) {
        !           170:     var type = typeof object;
        !           171:     switch (type) {
        !           172:       case 'undefined':
        !           173:       case 'function':
        !           174:       case 'unknown': return;
        !           175:       case 'boolean': return object.toString();
        !           176:     }
        !           177:
        !           178:     if (object === null) return 'null';
        !           179:     if (object.toJSON) return object.toJSON();
        !           180:     if (isElement(object)) return;
        !           181:
        !           182:     var results = [];
        !           183:     for (var property in object) {
        !           184:       var value = toJSON(object[property]);
        !           185:       if (!isUndefined(value))
        !           186:         results.push(property.toJSON() + ': ' + value);
        !           187:     }
        !           188:
        !           189:     return '{' + results.join(', ') + '}';
        !           190:   }
        !           191:
        !           192:   function toQueryString(object) {
        !           193:     return $H(object).toQueryString();
        !           194:   }
        !           195:
        !           196:   function toHTML(object) {
        !           197:     return object && object.toHTML ? object.toHTML() : String.interpret(object);
        !           198:   }
        !           199:
        !           200:   function keys(object) {
        !           201:     var results = [];
        !           202:     for (var property in object)
        !           203:       results.push(property);
        !           204:     return results;
        !           205:   }
        !           206:
        !           207:   function values(object) {
        !           208:     var results = [];
        !           209:     for (var property in object)
        !           210:       results.push(object[property]);
        !           211:     return results;
        !           212:   }
        !           213:
        !           214:   function clone(object) {
        !           215:     return extend({ }, object);
        !           216:   }
        !           217:
        !           218:   function isElement(object) {
        !           219:     return !!(object && object.nodeType == 1);
        !           220:   }
        !           221:
        !           222:   function isArray(object) {
        !           223:     return _toString.call(object) == "[object Array]";
        !           224:   }
        !           225:
        !           226:
        !           227:   function isHash(object) {
        !           228:     return object instanceof Hash;
        !           229:   }
        !           230:
        !           231:   function isFunction(object) {
        !           232:     return typeof object === "function";
        !           233:   }
        !           234:
        !           235:   function isString(object) {
        !           236:     return _toString.call(object) == "[object String]";
        !           237:   }
        !           238:
        !           239:   function isNumber(object) {
        !           240:     return _toString.call(object) == "[object Number]";
        !           241:   }
        !           242:
        !           243:   function isUndefined(object) {
        !           244:     return typeof object === "undefined";
        !           245:   }
        !           246:
        !           247:   extend(Object, {
        !           248:     extend:        extend,
        !           249:     inspect:       inspect,
        !           250:     toJSON:        toJSON,
        !           251:     toQueryString: toQueryString,
        !           252:     toHTML:        toHTML,
        !           253:     keys:          keys,
        !           254:     values:        values,
        !           255:     clone:         clone,
        !           256:     isElement:     isElement,
        !           257:     isArray:       isArray,
        !           258:     isHash:        isHash,
        !           259:     isFunction:    isFunction,
        !           260:     isString:      isString,
        !           261:     isNumber:      isNumber,
        !           262:     isUndefined:   isUndefined
        !           263:   });
        !           264: })();
        !           265: Object.extend(Function.prototype, (function() {
        !           266:   var slice = Array.prototype.slice;
        !           267:
        !           268:   function update(array, args) {
        !           269:     var arrayLength = array.length, length = args.length;
        !           270:     while (length--) array[arrayLength + length] = args[length];
        !           271:     return array;
        !           272:   }
        !           273:
        !           274:   function merge(array, args) {
        !           275:     array = slice.call(array, 0);
        !           276:     return update(array, args);
        !           277:   }
        !           278:
        !           279:   function argumentNames() {
        !           280:     var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
        !           281:       .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
        !           282:       .replace(/\s+/g, '').split(',');
        !           283:     return names.length == 1 && !names[0] ? [] : names;
        !           284:   }
        !           285:
        !           286:   function bind(context) {
        !           287:     if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
        !           288:     var __method = this, args = slice.call(arguments, 1);
        !           289:     return function() {
        !           290:       var a = merge(args, arguments);
        !           291:       return __method.apply(context, a);
        !           292:     }
        !           293:   }
        !           294:
        !           295:   function bindAsEventListener(context) {
        !           296:     var __method = this, args = slice.call(arguments, 1);
        !           297:     return function(event) {
        !           298:       var a = update([event || window.event], args);
        !           299:       return __method.apply(context, a);
        !           300:     }
        !           301:   }
        !           302:
        !           303:   function curry() {
        !           304:     if (!arguments.length) return this;
        !           305:     var __method = this, args = slice.call(arguments, 0);
        !           306:     return function() {
        !           307:       var a = merge(args, arguments);
        !           308:       return __method.apply(this, a);
        !           309:     }
        !           310:   }
        !           311:
        !           312:   function delay(timeout) {
        !           313:     var __method = this, args = slice.call(arguments, 1);
        !           314:     timeout = timeout * 1000
        !           315:     return window.setTimeout(function() {
        !           316:       return __method.apply(__method, args);
        !           317:     }, timeout);
        !           318:   }
        !           319:
        !           320:   function defer() {
        !           321:     var args = update([0.01], arguments);
        !           322:     return this.delay.apply(this, args);
        !           323:   }
        !           324:
        !           325:   function wrap(wrapper) {
        !           326:     var __method = this;
        !           327:     return function() {
        !           328:       var a = update([__method.bind(this)], arguments);
        !           329:       return wrapper.apply(this, a);
        !           330:     }
        !           331:   }
        !           332:
        !           333:   function methodize() {
        !           334:     if (this._methodized) return this._methodized;
        !           335:     var __method = this;
        !           336:     return this._methodized = function() {
        !           337:       var a = update([this], arguments);
        !           338:       return __method.apply(null, a);
        !           339:     };
        !           340:   }
        !           341:
        !           342:   return {
        !           343:     argumentNames:       argumentNames,
        !           344:     bind:                bind,
        !           345:     bindAsEventListener: bindAsEventListener,
        !           346:     curry:               curry,
        !           347:     delay:               delay,
        !           348:     defer:               defer,
        !           349:     wrap:                wrap,
        !           350:     methodize:           methodize
        !           351:   }
        !           352: })());
        !           353:
        !           354:
        !           355: Date.prototype.toJSON = function() {
        !           356:   return '"' + this.getUTCFullYear() + '-' +
        !           357:     (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
        !           358:     this.getUTCDate().toPaddedString(2) + 'T' +
        !           359:     this.getUTCHours().toPaddedString(2) + ':' +
        !           360:     this.getUTCMinutes().toPaddedString(2) + ':' +
        !           361:     this.getUTCSeconds().toPaddedString(2) + 'Z"';
        !           362: };
        !           363:
        !           364:
        !           365: RegExp.prototype.match = RegExp.prototype.test;
        !           366:
        !           367: RegExp.escape = function(str) {
        !           368:   return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
        !           369: };
        !           370: var PeriodicalExecuter = Class.create({
        !           371:   initialize: function(callback, frequency) {
        !           372:     this.callback = callback;
        !           373:     this.frequency = frequency;
        !           374:     this.currentlyExecuting = false;
        !           375:
        !           376:     this.registerCallback();
        !           377:   },
        !           378:
        !           379:   registerCallback: function() {
        !           380:     this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
        !           381:   },
        !           382:
        !           383:   execute: function() {
        !           384:     this.callback(this);
        !           385:   },
        !           386:
        !           387:   stop: function() {
        !           388:     if (!this.timer) return;
        !           389:     clearInterval(this.timer);
        !           390:     this.timer = null;
        !           391:   },
        !           392:
        !           393:   onTimerEvent: function() {
        !           394:     if (!this.currentlyExecuting) {
        !           395:       try {
        !           396:         this.currentlyExecuting = true;
        !           397:         this.execute();
        !           398:         this.currentlyExecuting = false;
        !           399:       } catch(e) {
        !           400:         this.currentlyExecuting = false;
        !           401:         throw e;
        !           402:       }
        !           403:     }
        !           404:   }
        !           405: });
        !           406: Object.extend(String, {
        !           407:   interpret: function(value) {
        !           408:     return value == null ? '' : String(value);
        !           409:   },
        !           410:   specialChar: {
        !           411:     '\b': '\\b',
        !           412:     '\t': '\\t',
        !           413:     '\n': '\\n',
        !           414:     '\f': '\\f',
        !           415:     '\r': '\\r',
        !           416:     '\\': '\\\\'
        !           417:   }
        !           418: });
        !           419:
        !           420: Object.extend(String.prototype, (function() {
        !           421:
        !           422:   function prepareReplacement(replacement) {
        !           423:     if (Object.isFunction(replacement)) return replacement;
        !           424:     var template = new Template(replacement);
        !           425:     return function(match) { return template.evaluate(match) };
        !           426:   }
        !           427:
        !           428:   function gsub(pattern, replacement) {
        !           429:     var result = '', source = this, match;
        !           430:     replacement = prepareReplacement(replacement);
        !           431:
        !           432:     if (Object.isString(pattern))
        !           433:       pattern = RegExp.escape(pattern);
        !           434:
        !           435:     if (!(pattern.length || pattern.source)) {
        !           436:       replacement = replacement('');
        !           437:       return replacement + source.split('').join(replacement) + replacement;
        !           438:     }
        !           439:
        !           440:     while (source.length > 0) {
        !           441:       if (match = source.match(pattern)) {
        !           442:         result += source.slice(0, match.index);
        !           443:         result += String.interpret(replacement(match));
        !           444:         source  = source.slice(match.index + match[0].length);
        !           445:       } else {
        !           446:         result += source, source = '';
        !           447:       }
        !           448:     }
        !           449:     return result;
        !           450:   }
        !           451:
        !           452:   function sub(pattern, replacement, count) {
        !           453:     replacement = prepareReplacement(replacement);
        !           454:     count = Object.isUndefined(count) ? 1 : count;
        !           455:
        !           456:     return this.gsub(pattern, function(match) {
        !           457:       if (--count < 0) return match[0];
        !           458:       return replacement(match);
        !           459:     });
        !           460:   }
        !           461:
        !           462:   function scan(pattern, iterator) {
        !           463:     this.gsub(pattern, iterator);
        !           464:     return String(this);
        !           465:   }
        !           466:
        !           467:   function truncate(length, truncation) {
        !           468:     length = length || 30;
        !           469:     truncation = Object.isUndefined(truncation) ? '...' : truncation;
        !           470:     return this.length > length ?
        !           471:       this.slice(0, length - truncation.length) + truncation : String(this);
        !           472:   }
        !           473:
        !           474:   function strip() {
        !           475:     return this.replace(/^\s+/, '').replace(/\s+$/, '');
        !           476:   }
        !           477:
        !           478:   function stripTags() {
        !           479:     return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
        !           480:   }
        !           481:
        !           482:   function stripScripts() {
        !           483:     return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
        !           484:   }
        !           485:
        !           486:   function extractScripts() {
        !           487:     var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
        !           488:     var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
        !           489:     return (this.match(matchAll) || []).map(function(scriptTag) {
        !           490:       return (scriptTag.match(matchOne) || ['', ''])[1];
        !           491:     });
        !           492:   }
        !           493:
        !           494:   function evalScripts() {
        !           495:     return this.extractScripts().map(function(script) { return eval(script) });
        !           496:   }
        !           497:
        !           498:   function escapeHTML() {
        !           499:     return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
        !           500:   }
        !           501:
        !           502:   function unescapeHTML() {
        !           503:     return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
        !           504:   }
        !           505:
        !           506:
        !           507:   function toQueryParams(separator) {
        !           508:     var match = this.strip().match(/([^?#]*)(#.*)?$/);
        !           509:     if (!match) return { };
        !           510:
        !           511:     return match[1].split(separator || '&').inject({ }, function(hash, pair) {
        !           512:       if ((pair = pair.split('='))[0]) {
        !           513:         var key = decodeURIComponent(pair.shift());
        !           514:         var value = pair.length > 1 ? pair.join('=') : pair[0];
        !           515:         if (value != undefined) value = decodeURIComponent(value);
        !           516:
        !           517:         if (key in hash) {
        !           518:           if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
        !           519:           hash[key].push(value);
        !           520:         }
        !           521:         else hash[key] = value;
        !           522:       }
        !           523:       return hash;
        !           524:     });
        !           525:   }
        !           526:
        !           527:   function toArray() {
        !           528:     return this.split('');
        !           529:   }
        !           530:
        !           531:   function succ() {
        !           532:     return this.slice(0, this.length - 1) +
        !           533:       String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
        !           534:   }
        !           535:
        !           536:   function times(count) {
        !           537:     return count < 1 ? '' : new Array(count + 1).join(this);
        !           538:   }
        !           539:
        !           540:   function camelize() {
        !           541:     var parts = this.split('-'), len = parts.length;
        !           542:     if (len == 1) return parts[0];
        !           543:
        !           544:     var camelized = this.charAt(0) == '-'
        !           545:       ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
        !           546:       : parts[0];
        !           547:
        !           548:     for (var i = 1; i < len; i++)
        !           549:       camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
        !           550:
        !           551:     return camelized;
        !           552:   }
        !           553:
        !           554:   function capitalize() {
        !           555:     return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
        !           556:   }
        !           557:
        !           558:   function underscore() {
        !           559:     return this.replace(/::/g, '/')
        !           560:                .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
        !           561:                .replace(/([a-z\d])([A-Z])/g, '$1_$2')
        !           562:                .replace(/-/g, '_')
        !           563:                .toLowerCase();
        !           564:   }
        !           565:
        !           566:   function dasherize() {
        !           567:     return this.replace(/_/g, '-');
        !           568:   }
        !           569:
        !           570:   function inspect(useDoubleQuotes) {
        !           571:     var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
        !           572:       if (character in String.specialChar) {
        !           573:         return String.specialChar[character];
        !           574:       }
        !           575:       return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
        !           576:     });
        !           577:     if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
        !           578:     return "'" + escapedString.replace(/'/g, '\\\'') + "'";
        !           579:   }
        !           580:
        !           581:   function toJSON() {
        !           582:     return this.inspect(true);
        !           583:   }
        !           584:
        !           585:   function unfilterJSON(filter) {
        !           586:     return this.replace(filter || Prototype.JSONFilter, '$1');
        !           587:   }
        !           588:
        !           589:   function isJSON() {
        !           590:     var str = this;
        !           591:     if (str.blank()) return false;
        !           592:     str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
        !           593:     return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
        !           594:   }
        !           595:
        !           596:   function evalJSON(sanitize) {
        !           597:     var json = this.unfilterJSON();
        !           598:     try {
        !           599:       if (!sanitize || json.isJSON()) return eval('(' + json + ')');
        !           600:     } catch (e) { }
        !           601:     throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
        !           602:   }
        !           603:
        !           604:   function include(pattern) {
        !           605:     return this.indexOf(pattern) > -1;
        !           606:   }
        !           607:
        !           608:   function startsWith(pattern) {
        !           609:     return this.indexOf(pattern) === 0;
        !           610:   }
        !           611:
        !           612:   function endsWith(pattern) {
        !           613:     var d = this.length - pattern.length;
        !           614:     return d >= 0 && this.lastIndexOf(pattern) === d;
        !           615:   }
        !           616:
        !           617:   function empty() {
        !           618:     return this == '';
        !           619:   }
        !           620:
        !           621:   function blank() {
        !           622:     return /^\s*$/.test(this);
        !           623:   }
        !           624:
        !           625:   function interpolate(object, pattern) {
        !           626:     return new Template(this, pattern).evaluate(object);
        !           627:   }
        !           628:
        !           629:   return {
        !           630:     gsub:           gsub,
        !           631:     sub:            sub,
        !           632:     scan:           scan,
        !           633:     truncate:       truncate,
        !           634:     strip:          String.prototype.trim ? String.prototype.trim : strip,
        !           635:     stripTags:      stripTags,
        !           636:     stripScripts:   stripScripts,
        !           637:     extractScripts: extractScripts,
        !           638:     evalScripts:    evalScripts,
        !           639:     escapeHTML:     escapeHTML,
        !           640:     unescapeHTML:   unescapeHTML,
        !           641:     toQueryParams:  toQueryParams,
        !           642:     parseQuery:     toQueryParams,
        !           643:     toArray:        toArray,
        !           644:     succ:           succ,
        !           645:     times:          times,
        !           646:     camelize:       camelize,
        !           647:     capitalize:     capitalize,
        !           648:     underscore:     underscore,
        !           649:     dasherize:      dasherize,
        !           650:     inspect:        inspect,
        !           651:     toJSON:         toJSON,
        !           652:     unfilterJSON:   unfilterJSON,
        !           653:     isJSON:         isJSON,
        !           654:     evalJSON:       evalJSON,
        !           655:     include:        include,
        !           656:     startsWith:     startsWith,
        !           657:     endsWith:       endsWith,
        !           658:     empty:          empty,
        !           659:     blank:          blank,
        !           660:     interpolate:    interpolate
        !           661:   };
        !           662: })());
        !           663:
        !           664: var Template = Class.create({
        !           665:   initialize: function(template, pattern) {
        !           666:     this.template = template.toString();
        !           667:     this.pattern = pattern || Template.Pattern;
        !           668:   },
        !           669:
        !           670:   evaluate: function(object) {
        !           671:     if (object && Object.isFunction(object.toTemplateReplacements))
        !           672:       object = object.toTemplateReplacements();
        !           673:
        !           674:     return this.template.gsub(this.pattern, function(match) {
        !           675:       if (object == null) return (match[1] + '');
        !           676:
        !           677:       var before = match[1] || '';
        !           678:       if (before == '\\') return match[2];
        !           679:
        !           680:       var ctx = object, expr = match[3];
        !           681:       var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
        !           682:       match = pattern.exec(expr);
        !           683:       if (match == null) return before;
        !           684:
        !           685:       while (match != null) {
        !           686:         var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
        !           687:         ctx = ctx[comp];
        !           688:         if (null == ctx || '' == match[3]) break;
        !           689:         expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
        !           690:         match = pattern.exec(expr);
        !           691:       }
        !           692:
        !           693:       return before + String.interpret(ctx);
        !           694:     });
        !           695:   }
        !           696: });
        !           697: Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
        !           698:
        !           699: var $break = { };
        !           700:
        !           701: var Enumerable = (function() {
        !           702:   function each(iterator, context) {
        !           703:     var index = 0;
        !           704:     try {
        !           705:       this._each(function(value) {
        !           706:         iterator.call(context, value, index++);
        !           707:       });
        !           708:     } catch (e) {
        !           709:       if (e != $break) throw e;
        !           710:     }
        !           711:     return this;
        !           712:   }
        !           713:
        !           714:   function eachSlice(number, iterator, context) {
        !           715:     var index = -number, slices = [], array = this.toArray();
        !           716:     if (number < 1) return array;
        !           717:     while ((index += number) < array.length)
        !           718:       slices.push(array.slice(index, index+number));
        !           719:     return slices.collect(iterator, context);
        !           720:   }
        !           721:
        !           722:   function all(iterator, context) {
        !           723:     iterator = iterator || Prototype.K;
        !           724:     var result = true;
        !           725:     this.each(function(value, index) {
        !           726:       result = result && !!iterator.call(context, value, index);
        !           727:       if (!result) throw $break;
        !           728:     });
        !           729:     return result;
        !           730:   }
        !           731:
        !           732:   function any(iterator, context) {
        !           733:     iterator = iterator || Prototype.K;
        !           734:     var result = false;
        !           735:     this.each(function(value, index) {
        !           736:       if (result = !!iterator.call(context, value, index))
        !           737:         throw $break;
        !           738:     });
        !           739:     return result;
        !           740:   }
        !           741:
        !           742:   function collect(iterator, context) {
        !           743:     iterator = iterator || Prototype.K;
        !           744:     var results = [];
        !           745:     this.each(function(value, index) {
        !           746:       results.push(iterator.call(context, value, index));
        !           747:     });
        !           748:     return results;
        !           749:   }
        !           750:
        !           751:   function detect(iterator, context) {
        !           752:     var result;
        !           753:     this.each(function(value, index) {
        !           754:       if (iterator.call(context, value, index)) {
        !           755:         result = value;
        !           756:         throw $break;
        !           757:       }
        !           758:     });
        !           759:     return result;
        !           760:   }
        !           761:
        !           762:   function findAll(iterator, context) {
        !           763:     var results = [];
        !           764:     this.each(function(value, index) {
        !           765:       if (iterator.call(context, value, index))
        !           766:         results.push(value);
        !           767:     });
        !           768:     return results;
        !           769:   }
        !           770:
        !           771:   function grep(filter, iterator, context) {
        !           772:     iterator = iterator || Prototype.K;
        !           773:     var results = [];
        !           774:
        !           775:     if (Object.isString(filter))
        !           776:       filter = new RegExp(RegExp.escape(filter));
        !           777:
        !           778:     this.each(function(value, index) {
        !           779:       if (filter.match(value))
        !           780:         results.push(iterator.call(context, value, index));
        !           781:     });
        !           782:     return results;
        !           783:   }
        !           784:
        !           785:   function include(object) {
        !           786:     if (Object.isFunction(this.indexOf))
        !           787:       if (this.indexOf(object) != -1) return true;
        !           788:
        !           789:     var found = false;
        !           790:     this.each(function(value) {
        !           791:       if (value == object) {
        !           792:         found = true;
        !           793:         throw $break;
        !           794:       }
        !           795:     });
        !           796:     return found;
        !           797:   }
        !           798:
        !           799:   function inGroupsOf(number, fillWith) {
        !           800:     fillWith = Object.isUndefined(fillWith) ? null : fillWith;
        !           801:     return this.eachSlice(number, function(slice) {
        !           802:       while(slice.length < number) slice.push(fillWith);
        !           803:       return slice;
        !           804:     });
        !           805:   }
        !           806:
        !           807:   function inject(memo, iterator, context) {
        !           808:     this.each(function(value, index) {
        !           809:       memo = iterator.call(context, memo, value, index);
        !           810:     });
        !           811:     return memo;
        !           812:   }
        !           813:
        !           814:   function invoke(method) {
        !           815:     var args = $A(arguments).slice(1);
        !           816:     return this.map(function(value) {
        !           817:       return value[method].apply(value, args);
        !           818:     });
        !           819:   }
        !           820:
        !           821:   function max(iterator, context) {
        !           822:     iterator = iterator || Prototype.K;
        !           823:     var result;
        !           824:     this.each(function(value, index) {
        !           825:       value = iterator.call(context, value, index);
        !           826:       if (result == null || value >= result)
        !           827:         result = value;
        !           828:     });
        !           829:     return result;
        !           830:   }
        !           831:
        !           832:   function min(iterator, context) {
        !           833:     iterator = iterator || Prototype.K;
        !           834:     var result;
        !           835:     this.each(function(value, index) {
        !           836:       value = iterator.call(context, value, index);
        !           837:       if (result == null || value < result)
        !           838:         result = value;
        !           839:     });
        !           840:     return result;
        !           841:   }
        !           842:
        !           843:   function partition(iterator, context) {
        !           844:     iterator = iterator || Prototype.K;
        !           845:     var trues = [], falses = [];
        !           846:     this.each(function(value, index) {
        !           847:       (iterator.call(context, value, index) ?
        !           848:         trues : falses).push(value);
        !           849:     });
        !           850:     return [trues, falses];
        !           851:   }
        !           852:
        !           853:   function pluck(property) {
        !           854:     var results = [];
        !           855:     this.each(function(value) {
        !           856:       results.push(value[property]);
        !           857:     });
        !           858:     return results;
        !           859:   }
        !           860:
        !           861:   function reject(iterator, context) {
        !           862:     var results = [];
        !           863:     this.each(function(value, index) {
        !           864:       if (!iterator.call(context, value, index))
        !           865:         results.push(value);
        !           866:     });
        !           867:     return results;
        !           868:   }
        !           869:
        !           870:   function sortBy(iterator, context) {
        !           871:     return this.map(function(value, index) {
        !           872:       return {
        !           873:         value: value,
        !           874:         criteria: iterator.call(context, value, index)
        !           875:       };
        !           876:     }).sort(function(left, right) {
        !           877:       var a = left.criteria, b = right.criteria;
        !           878:       return a < b ? -1 : a > b ? 1 : 0;
        !           879:     }).pluck('value');
        !           880:   }
        !           881:
        !           882:   function toArray() {
        !           883:     return this.map();
        !           884:   }
        !           885:
        !           886:   function zip() {
        !           887:     var iterator = Prototype.K, args = $A(arguments);
        !           888:     if (Object.isFunction(args.last()))
        !           889:       iterator = args.pop();
        !           890:
        !           891:     var collections = [this].concat(args).map($A);
        !           892:     return this.map(function(value, index) {
        !           893:       return iterator(collections.pluck(index));
        !           894:     });
        !           895:   }
        !           896:
        !           897:   function size() {
        !           898:     return this.toArray().length;
        !           899:   }
        !           900:
        !           901:   function inspect() {
        !           902:     return '#<Enumerable:' + this.toArray().inspect() + '>';
        !           903:   }
        !           904:
        !           905:
        !           906:
        !           907:
        !           908:
        !           909:
        !           910:
        !           911:
        !           912:
        !           913:   return {
        !           914:     each:       each,
        !           915:     eachSlice:  eachSlice,
        !           916:     all:        all,
        !           917:     every:      all,
        !           918:     any:        any,
        !           919:     some:       any,
        !           920:     collect:    collect,
        !           921:     map:        collect,
        !           922:     detect:     detect,
        !           923:     findAll:    findAll,
        !           924:     select:     findAll,
        !           925:     filter:     findAll,
        !           926:     grep:       grep,
        !           927:     include:    include,
        !           928:     member:     include,
        !           929:     inGroupsOf: inGroupsOf,
        !           930:     inject:     inject,
        !           931:     invoke:     invoke,
        !           932:     max:        max,
        !           933:     min:        min,
        !           934:     partition:  partition,
        !           935:     pluck:      pluck,
        !           936:     reject:     reject,
        !           937:     sortBy:     sortBy,
        !           938:     toArray:    toArray,
        !           939:     entries:    toArray,
        !           940:     zip:        zip,
        !           941:     size:       size,
        !           942:     inspect:    inspect,
        !           943:     find:       detect
        !           944:   };
        !           945: })();
        !           946: function $A(iterable) {
        !           947:   if (!iterable) return [];
        !           948:   if ('toArray' in Object(iterable)) return iterable.toArray();
        !           949:   var length = iterable.length || 0, results = new Array(length);
        !           950:   while (length--) results[length] = iterable[length];
        !           951:   return results;
        !           952: }
        !           953:
        !           954: function $w(string) {
        !           955:   if (!Object.isString(string)) return [];
        !           956:   string = string.strip();
        !           957:   return string ? string.split(/\s+/) : [];
        !           958: }
        !           959:
        !           960: Array.from = $A;
        !           961:
        !           962:
        !           963: (function() {
        !           964:   var arrayProto = Array.prototype,
        !           965:       slice = arrayProto.slice,
        !           966:       _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
        !           967:
        !           968:   function each(iterator) {
        !           969:     for (var i = 0, length = this.length; i < length; i++)
        !           970:       iterator(this[i]);
        !           971:   }
        !           972:   if (!_each) _each = each;
        !           973:
        !           974:   function clear() {
        !           975:     this.length = 0;
        !           976:     return this;
        !           977:   }
        !           978:
        !           979:   function first() {
        !           980:     return this[0];
        !           981:   }
        !           982:
        !           983:   function last() {
        !           984:     return this[this.length - 1];
        !           985:   }
        !           986:
        !           987:   function compact() {
        !           988:     return this.select(function(value) {
        !           989:       return value != null;
        !           990:     });
        !           991:   }
        !           992:
        !           993:   function flatten() {
        !           994:     return this.inject([], function(array, value) {
        !           995:       if (Object.isArray(value))
        !           996:         return array.concat(value.flatten());
        !           997:       array.push(value);
        !           998:       return array;
        !           999:     });
        !          1000:   }
        !          1001:
        !          1002:   function without() {
        !          1003:     var values = slice.call(arguments, 0);
        !          1004:     return this.select(function(value) {
        !          1005:       return !values.include(value);
        !          1006:     });
        !          1007:   }
        !          1008:
        !          1009:   function reverse(inline) {
        !          1010:     return (inline !== false ? this : this.toArray())._reverse();
        !          1011:   }
        !          1012:
        !          1013:   function uniq(sorted) {
        !          1014:     return this.inject([], function(array, value, index) {
        !          1015:       if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        !          1016:         array.push(value);
        !          1017:       return array;
        !          1018:     });
        !          1019:   }
        !          1020:
        !          1021:   function intersect(array) {
        !          1022:     return this.uniq().findAll(function(item) {
        !          1023:       return array.detect(function(value) { return item === value });
        !          1024:     });
        !          1025:   }
        !          1026:
        !          1027:
        !          1028:   function clone() {
        !          1029:     return slice.call(this, 0);
        !          1030:   }
        !          1031:
        !          1032:   function size() {
        !          1033:     return this.length;
        !          1034:   }
        !          1035:
        !          1036:   function inspect() {
        !          1037:     return '[' + this.map(Object.inspect).join(', ') + ']';
        !          1038:   }
        !          1039:
        !          1040:   function toJSON() {
        !          1041:     var results = [];
        !          1042:     this.each(function(object) {
        !          1043:       var value = Object.toJSON(object);
        !          1044:       if (!Object.isUndefined(value)) results.push(value);
        !          1045:     });
        !          1046:     return '[' + results.join(', ') + ']';
        !          1047:   }
        !          1048:
        !          1049:   function indexOf(item, i) {
        !          1050:     i || (i = 0);
        !          1051:     var length = this.length;
        !          1052:     if (i < 0) i = length + i;
        !          1053:     for (; i < length; i++)
        !          1054:       if (this[i] === item) return i;
        !          1055:     return -1;
        !          1056:   }
        !          1057:
        !          1058:   function lastIndexOf(item, i) {
        !          1059:     i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
        !          1060:     var n = this.slice(0, i).reverse().indexOf(item);
        !          1061:     return (n < 0) ? n : i - n - 1;
        !          1062:   }
        !          1063:
        !          1064:   function concat() {
        !          1065:     var array = slice.call(this, 0), item;
        !          1066:     for (var i = 0, length = arguments.length; i < length; i++) {
        !          1067:       item = arguments[i];
        !          1068:       if (Object.isArray(item) && !('callee' in item)) {
        !          1069:         for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
        !          1070:           array.push(item[j]);
        !          1071:       } else {
        !          1072:         array.push(item);
        !          1073:       }
        !          1074:     }
        !          1075:     return array;
        !          1076:   }
        !          1077:
        !          1078:   Object.extend(arrayProto, Enumerable);
        !          1079:
        !          1080:   if (!arrayProto._reverse)
        !          1081:     arrayProto._reverse = arrayProto.reverse;
        !          1082:
        !          1083:   Object.extend(arrayProto, {
        !          1084:     _each:     _each,
        !          1085:     clear:     clear,
        !          1086:     first:     first,
        !          1087:     last:      last,
        !          1088:     compact:   compact,
        !          1089:     flatten:   flatten,
        !          1090:     without:   without,
        !          1091:     reverse:   reverse,
        !          1092:     uniq:      uniq,
        !          1093:     intersect: intersect,
        !          1094:     clone:     clone,
        !          1095:     toArray:   clone,
        !          1096:     size:      size,
        !          1097:     inspect:   inspect,
        !          1098:     toJSON:    toJSON
        !          1099:   });
        !          1100:
        !          1101:   var CONCAT_ARGUMENTS_BUGGY = (function() {
        !          1102:     return [].concat(arguments)[0][0] !== 1;
        !          1103:   })(1,2)
        !          1104:
        !          1105:   if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
        !          1106:
        !          1107:   if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
        !          1108:   if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
        !          1109: })();
        !          1110: function $H(object) {
        !          1111:   return new Hash(object);
        !          1112: };
        !          1113:
        !          1114: var Hash = Class.create(Enumerable, (function() {
        !          1115:   function initialize(object) {
        !          1116:     this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
        !          1117:   }
        !          1118:
        !          1119:   function _each(iterator) {
        !          1120:     for (var key in this._object) {
        !          1121:       var value = this._object[key], pair = [key, value];
        !          1122:       pair.key = key;
        !          1123:       pair.value = value;
        !          1124:       iterator(pair);
        !          1125:     }
        !          1126:   }
        !          1127:
        !          1128:   function set(key, value) {
        !          1129:     return this._object[key] = value;
        !          1130:   }
        !          1131:
        !          1132:   function get(key) {
        !          1133:     if (this._object[key] !== Object.prototype[key])
        !          1134:       return this._object[key];
        !          1135:   }
        !          1136:
        !          1137:   function unset(key) {
        !          1138:     var value = this._object[key];
        !          1139:     delete this._object[key];
        !          1140:     return value;
        !          1141:   }
        !          1142:
        !          1143:   function toObject() {
        !          1144:     return Object.clone(this._object);
        !          1145:   }
        !          1146:
        !          1147:   function keys() {
        !          1148:     return this.pluck('key');
        !          1149:   }
        !          1150:
        !          1151:   function values() {
        !          1152:     return this.pluck('value');
        !          1153:   }
        !          1154:
        !          1155:   function index(value) {
        !          1156:     var match = this.detect(function(pair) {
        !          1157:       return pair.value === value;
        !          1158:     });
        !          1159:     return match && match.key;
        !          1160:   }
        !          1161:
        !          1162:   function merge(object) {
        !          1163:     return this.clone().update(object);
        !          1164:   }
        !          1165:
        !          1166:   function update(object) {
        !          1167:     return new Hash(object).inject(this, function(result, pair) {
        !          1168:       result.set(pair.key, pair.value);
        !          1169:       return result;
        !          1170:     });
        !          1171:   }
        !          1172:
        !          1173:   function toQueryPair(key, value) {
        !          1174:     if (Object.isUndefined(value)) return key;
        !          1175:     return key + '=' + encodeURIComponent(String.interpret(value));
        !          1176:   }
        !          1177:
        !          1178:   function toQueryString() {
        !          1179:     return this.inject([], function(results, pair) {
        !          1180:       var key = encodeURIComponent(pair.key), values = pair.value;
        !          1181:
        !          1182:       if (values && typeof values == 'object') {
        !          1183:         if (Object.isArray(values))
        !          1184:           return results.concat(values.map(toQueryPair.curry(key)));
        !          1185:       } else results.push(toQueryPair(key, values));
        !          1186:       return results;
        !          1187:     }).join('&');
        !          1188:   }
        !          1189:
        !          1190:   function inspect() {
        !          1191:     return '#<Hash:{' + this.map(function(pair) {
        !          1192:       return pair.map(Object.inspect).join(': ');
        !          1193:     }).join(', ') + '}>';
        !          1194:   }
        !          1195:
        !          1196:   function toJSON() {
        !          1197:     return Object.toJSON(this.toObject());
        !          1198:   }
        !          1199:
        !          1200:   function clone() {
        !          1201:     return new Hash(this);
        !          1202:   }
        !          1203:
        !          1204:   return {
        !          1205:     initialize:             initialize,
        !          1206:     _each:                  _each,
        !          1207:     set:                    set,
        !          1208:     get:                    get,
        !          1209:     unset:                  unset,
        !          1210:     toObject:               toObject,
        !          1211:     toTemplateReplacements: toObject,
        !          1212:     keys:                   keys,
        !          1213:     values:                 values,
        !          1214:     index:                  index,
        !          1215:     merge:                  merge,
        !          1216:     update:                 update,
        !          1217:     toQueryString:          toQueryString,
        !          1218:     inspect:                inspect,
        !          1219:     toJSON:                 toJSON,
        !          1220:     clone:                  clone
        !          1221:   };
        !          1222: })());
        !          1223:
        !          1224: Hash.from = $H;
        !          1225: Object.extend(Number.prototype, (function() {
        !          1226:   function toColorPart() {
        !          1227:     return this.toPaddedString(2, 16);
        !          1228:   }
        !          1229:
        !          1230:   function succ() {
        !          1231:     return this + 1;
        !          1232:   }
        !          1233:
        !          1234:   function times(iterator, context) {
        !          1235:     $R(0, this, true).each(iterator, context);
        !          1236:     return this;
        !          1237:   }
        !          1238:
        !          1239:   function toPaddedString(length, radix) {
        !          1240:     var string = this.toString(radix || 10);
        !          1241:     return '0'.times(length - string.length) + string;
        !          1242:   }
        !          1243:
        !          1244:   function toJSON() {
        !          1245:     return isFinite(this) ? this.toString() : 'null';
        !          1246:   }
        !          1247:
        !          1248:   function abs() {
        !          1249:     return Math.abs(this);
        !          1250:   }
        !          1251:
        !          1252:   function round() {
        !          1253:     return Math.round(this);
        !          1254:   }
        !          1255:
        !          1256:   function ceil() {
        !          1257:     return Math.ceil(this);
        !          1258:   }
        !          1259:
        !          1260:   function floor() {
        !          1261:     return Math.floor(this);
        !          1262:   }
        !          1263:
        !          1264:   return {
        !          1265:     toColorPart:    toColorPart,
        !          1266:     succ:           succ,
        !          1267:     times:          times,
        !          1268:     toPaddedString: toPaddedString,
        !          1269:     toJSON:         toJSON,
        !          1270:     abs:            abs,
        !          1271:     round:          round,
        !          1272:     ceil:           ceil,
        !          1273:     floor:          floor
        !          1274:   };
        !          1275: })());
        !          1276:
        !          1277: function $R(start, end, exclusive) {
        !          1278:   return new ObjectRange(start, end, exclusive);
        !          1279: }
        !          1280:
        !          1281: var ObjectRange = Class.create(Enumerable, (function() {
        !          1282:   function initialize(start, end, exclusive) {
        !          1283:     this.start = start;
        !          1284:     this.end = end;
        !          1285:     this.exclusive = exclusive;
        !          1286:   }
        !          1287:
        !          1288:   function _each(iterator) {
        !          1289:     var value = this.start;
        !          1290:     while (this.include(value)) {
        !          1291:       iterator(value);
        !          1292:       value = value.succ();
        !          1293:     }
        !          1294:   }
        !          1295:
        !          1296:   function include(value) {
        !          1297:     if (value < this.start)
        !          1298:       return false;
        !          1299:     if (this.exclusive)
        !          1300:       return value < this.end;
        !          1301:     return value <= this.end;
        !          1302:   }
        !          1303:
        !          1304:   return {
        !          1305:     initialize: initialize,
        !          1306:     _each:      _each,
        !          1307:     include:    include
        !          1308:   };
        !          1309: })());
        !          1310:
        !          1311:
        !          1312:
        !          1313: var Ajax = {
        !          1314:   getTransport: function() {
        !          1315:     return Try.these(
        !          1316:       function() {return new XMLHttpRequest()},
        !          1317:       function() {return new ActiveXObject('Msxml2.XMLHTTP')},
        !          1318:       function() {return new ActiveXObject('Microsoft.XMLHTTP')}
        !          1319:     ) || false;
        !          1320:   },
        !          1321:
        !          1322:   activeRequestCount: 0
        !          1323: };
        !          1324:
        !          1325: Ajax.Responders = {
        !          1326:   responders: [],
        !          1327:
        !          1328:   _each: function(iterator) {
        !          1329:     this.responders._each(iterator);
        !          1330:   },
        !          1331:
        !          1332:   register: function(responder) {
        !          1333:     if (!this.include(responder))
        !          1334:       this.responders.push(responder);
        !          1335:   },
        !          1336:
        !          1337:   unregister: function(responder) {
        !          1338:     this.responders = this.responders.without(responder);
        !          1339:   },
        !          1340:
        !          1341:   dispatch: function(callback, request, transport, json) {
        !          1342:     this.each(function(responder) {
        !          1343:       if (Object.isFunction(responder[callback])) {
        !          1344:         try {
        !          1345:           responder[callback].apply(responder, [request, transport, json]);
        !          1346:         } catch (e) { }
        !          1347:       }
        !          1348:     });
        !          1349:   }
        !          1350: };
        !          1351:
        !          1352: Object.extend(Ajax.Responders, Enumerable);
        !          1353:
        !          1354: Ajax.Responders.register({
        !          1355:   onCreate:   function() { Ajax.activeRequestCount++ },
        !          1356:   onComplete: function() { Ajax.activeRequestCount-- }
        !          1357: });
        !          1358: Ajax.Base = Class.create({
        !          1359:   initialize: function(options) {
        !          1360:     this.options = {
        !          1361:       method:       'post',
        !          1362:       asynchronous: true,
        !          1363:       contentType:  'application/x-www-form-urlencoded',
        !          1364:       encoding:     'UTF-8',
        !          1365:       parameters:   '',
        !          1366:       evalJSON:     true,
        !          1367:       evalJS:       true
        !          1368:     };
        !          1369:     Object.extend(this.options, options || { });
        !          1370:
        !          1371:     this.options.method = this.options.method.toLowerCase();
        !          1372:
        !          1373:     if (Object.isString(this.options.parameters))
        !          1374:       this.options.parameters = this.options.parameters.toQueryParams();
        !          1375:     else if (Object.isHash(this.options.parameters))
        !          1376:       this.options.parameters = this.options.parameters.toObject();
        !          1377:   }
        !          1378: });
        !          1379: Ajax.Request = Class.create(Ajax.Base, {
        !          1380:   _complete: false,
        !          1381:
        !          1382:   initialize: function($super, url, options) {
        !          1383:     $super(options);
        !          1384:     this.transport = Ajax.getTransport();
        !          1385:     this.request(url);
        !          1386:   },
        !          1387:
        !          1388:   request: function(url) {
        !          1389:     this.url = url;
        !          1390:     this.method = this.options.method;
        !          1391:     var params = Object.clone(this.options.parameters);
        !          1392:
        !          1393:     if (!['get', 'post'].include(this.method)) {
        !          1394:       params['_method'] = this.method;
        !          1395:       this.method = 'post';
        !          1396:     }
        !          1397:
        !          1398:     this.parameters = params;
        !          1399:
        !          1400:     if (params = Object.toQueryString(params)) {
        !          1401:       if (this.method == 'get')
        !          1402:         this.url += (this.url.include('?') ? '&' : '?') + params;
        !          1403:       else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        !          1404:         params += '&_=';
        !          1405:     }
        !          1406:
        !          1407:     try {
        !          1408:       var response = new Ajax.Response(this);
        !          1409:       if (this.options.onCreate) this.options.onCreate(response);
        !          1410:       Ajax.Responders.dispatch('onCreate', this, response);
        !          1411:
        !          1412:       this.transport.open(this.method.toUpperCase(), this.url,
        !          1413:         this.options.asynchronous);
        !          1414:
        !          1415:       if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
        !          1416:
        !          1417:       this.transport.onreadystatechange = this.onStateChange.bind(this);
        !          1418:       this.setRequestHeaders();
        !          1419:
        !          1420:       this.body = this.method == 'post' ? (this.options.postBody || params) : null;
        !          1421:       this.transport.send(this.body);
        !          1422:
        !          1423:       /* Force Firefox to handle ready state 4 for synchronous requests */
        !          1424:       if (!this.options.asynchronous && this.transport.overrideMimeType)
        !          1425:         this.onStateChange();
        !          1426:
        !          1427:     }
        !          1428:     catch (e) {
        !          1429:       this.dispatchException(e);
        !          1430:     }
        !          1431:   },
        !          1432:
        !          1433:   onStateChange: function() {
        !          1434:     var readyState = this.transport.readyState;
        !          1435:     if (readyState > 1 && !((readyState == 4) && this._complete))
        !          1436:       this.respondToReadyState(this.transport.readyState);
        !          1437:   },
        !          1438:
        !          1439:   setRequestHeaders: function() {
        !          1440:     var headers = {
        !          1441:       'X-Requested-With': 'XMLHttpRequest',
        !          1442:       'X-Prototype-Version': Prototype.Version,
        !          1443:       'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
        !          1444:     };
        !          1445:
        !          1446:     if (this.method == 'post') {
        !          1447:       headers['Content-type'] = this.options.contentType +
        !          1448:         (this.options.encoding ? '; charset=' + this.options.encoding : '');
        !          1449:
        !          1450:       /* Force "Connection: close" for older Mozilla browsers to work
        !          1451:        * around a bug where XMLHttpRequest sends an incorrect
        !          1452:        * Content-length header. See Mozilla Bugzilla #246651.
        !          1453:        */
        !          1454:       if (this.transport.overrideMimeType &&
        !          1455:           (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
        !          1456:             headers['Connection'] = 'close';
        !          1457:     }
        !          1458:
        !          1459:     if (typeof this.options.requestHeaders == 'object') {
        !          1460:       var extras = this.options.requestHeaders;
        !          1461:
        !          1462:       if (Object.isFunction(extras.push))
        !          1463:         for (var i = 0, length = extras.length; i < length; i += 2)
        !          1464:           headers[extras[i]] = extras[i+1];
        !          1465:       else
        !          1466:         $H(extras).each(function(pair) { headers[pair.key] = pair.value });
        !          1467:     }
        !          1468:
        !          1469:     for (var name in headers)
        !          1470:       this.transport.setRequestHeader(name, headers[name]);
        !          1471:   },
        !          1472:
        !          1473:   success: function() {
        !          1474:     var status = this.getStatus();
        !          1475:     return !status || (status >= 200 && status < 300);
        !          1476:   },
        !          1477:
        !          1478:   getStatus: function() {
        !          1479:     try {
        !          1480:       return this.transport.status || 0;
        !          1481:     } catch (e) { return 0 }
        !          1482:   },
        !          1483:
        !          1484:   respondToReadyState: function(readyState) {
        !          1485:     var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
        !          1486:
        !          1487:     if (state == 'Complete') {
        !          1488:       try {
        !          1489:         this._complete = true;
        !          1490:         (this.options['on' + response.status]
        !          1491:          || this.options['on' + (this.success() ? 'Success' : 'Failure')]
        !          1492:          || Prototype.emptyFunction)(response, response.headerJSON);
        !          1493:       } catch (e) {
        !          1494:         this.dispatchException(e);
        !          1495:       }
        !          1496:
        !          1497:       var contentType = response.getHeader('Content-type');
        !          1498:       if (this.options.evalJS == 'force'
        !          1499:           || (this.options.evalJS && this.isSameOrigin() && contentType
        !          1500:           && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
        !          1501:         this.evalResponse();
        !          1502:     }
        !          1503:
        !          1504:     try {
        !          1505:       (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
        !          1506:       Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
        !          1507:     } catch (e) {
        !          1508:       this.dispatchException(e);
        !          1509:     }
        !          1510:
        !          1511:     if (state == 'Complete') {
        !          1512:       this.transport.onreadystatechange = Prototype.emptyFunction;
        !          1513:     }
        !          1514:   },
        !          1515:
        !          1516:   isSameOrigin: function() {
        !          1517:     var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
        !          1518:     return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
        !          1519:       protocol: location.protocol,
        !          1520:       domain: document.domain,
        !          1521:       port: location.port ? ':' + location.port : ''
        !          1522:     }));
        !          1523:   },
        !          1524:
        !          1525:   getHeader: function(name) {
        !          1526:     try {
        !          1527:       return this.transport.getResponseHeader(name) || null;
        !          1528:     } catch (e) { return null; }
        !          1529:   },
        !          1530:
        !          1531:   evalResponse: function() {
        !          1532:     try {
        !          1533:       return eval((this.transport.responseText || '').unfilterJSON());
        !          1534:     } catch (e) {
        !          1535:       this.dispatchException(e);
        !          1536:     }
        !          1537:   },
        !          1538:
        !          1539:   dispatchException: function(exception) {
        !          1540:     (this.options.onException || Prototype.emptyFunction)(this, exception);
        !          1541:     Ajax.Responders.dispatch('onException', this, exception);
        !          1542:   }
        !          1543: });
        !          1544:
        !          1545: Ajax.Request.Events =
        !          1546:   ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
        !          1547:
        !          1548:
        !          1549:
        !          1550:
        !          1551:
        !          1552:
        !          1553:
        !          1554:
        !          1555: Ajax.Response = Class.create({
        !          1556:   initialize: function(request){
        !          1557:     this.request = request;
        !          1558:     var transport  = this.transport  = request.transport,
        !          1559:         readyState = this.readyState = transport.readyState;
        !          1560:
        !          1561:     if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
        !          1562:       this.status       = this.getStatus();
        !          1563:       this.statusText   = this.getStatusText();
        !          1564:       this.responseText = String.interpret(transport.responseText);
        !          1565:       this.headerJSON   = this._getHeaderJSON();
        !          1566:     }
        !          1567:
        !          1568:     if(readyState == 4) {
        !          1569:       var xml = transport.responseXML;
        !          1570:       this.responseXML  = Object.isUndefined(xml) ? null : xml;
        !          1571:       this.responseJSON = this._getResponseJSON();
        !          1572:     }
        !          1573:   },
        !          1574:
        !          1575:   status:      0,
        !          1576:
        !          1577:   statusText: '',
        !          1578:
        !          1579:   getStatus: Ajax.Request.prototype.getStatus,
        !          1580:
        !          1581:   getStatusText: function() {
        !          1582:     try {
        !          1583:       return this.transport.statusText || '';
        !          1584:     } catch (e) { return '' }
        !          1585:   },
        !          1586:
        !          1587:   getHeader: Ajax.Request.prototype.getHeader,
        !          1588:
        !          1589:   getAllHeaders: function() {
        !          1590:     try {
        !          1591:       return this.getAllResponseHeaders();
        !          1592:     } catch (e) { return null }
        !          1593:   },
        !          1594:
        !          1595:   getResponseHeader: function(name) {
        !          1596:     return this.transport.getResponseHeader(name);
        !          1597:   },
        !          1598:
        !          1599:   getAllResponseHeaders: function() {
        !          1600:     return this.transport.getAllResponseHeaders();
        !          1601:   },
        !          1602:
        !          1603:   _getHeaderJSON: function() {
        !          1604:     var json = this.getHeader('X-JSON');
        !          1605:     if (!json) return null;
        !          1606:     json = decodeURIComponent(escape(json));
        !          1607:     try {
        !          1608:       return json.evalJSON(this.request.options.sanitizeJSON ||
        !          1609:         !this.request.isSameOrigin());
        !          1610:     } catch (e) {
        !          1611:       this.request.dispatchException(e);
        !          1612:     }
        !          1613:   },
        !          1614:
        !          1615:   _getResponseJSON: function() {
        !          1616:     var options = this.request.options;
        !          1617:     if (!options.evalJSON || (options.evalJSON != 'force' &&
        !          1618:       !(this.getHeader('Content-type') || '').include('application/json')) ||
        !          1619:         this.responseText.blank())
        !          1620:           return null;
        !          1621:     try {
        !          1622:       return this.responseText.evalJSON(options.sanitizeJSON ||
        !          1623:         !this.request.isSameOrigin());
        !          1624:     } catch (e) {
        !          1625:       this.request.dispatchException(e);
        !          1626:     }
        !          1627:   }
        !          1628: });
        !          1629:
        !          1630: Ajax.Updater = Class.create(Ajax.Request, {
        !          1631:   initialize: function($super, container, url, options) {
        !          1632:     this.container = {
        !          1633:       success: (container.success || container),
        !          1634:       failure: (container.failure || (container.success ? null : container))
        !          1635:     };
        !          1636:
        !          1637:     options = Object.clone(options);
        !          1638:     var onComplete = options.onComplete;
        !          1639:     options.onComplete = (function(response, json) {
        !          1640:       this.updateContent(response.responseText);
        !          1641:       if (Object.isFunction(onComplete)) onComplete(response, json);
        !          1642:     }).bind(this);
        !          1643:
        !          1644:     $super(url, options);
        !          1645:   },
        !          1646:
        !          1647:   updateContent: function(responseText) {
        !          1648:     var receiver = this.container[this.success() ? 'success' : 'failure'],
        !          1649:         options = this.options;
        !          1650:
        !          1651:     if (!options.evalScripts) responseText = responseText.stripScripts();
        !          1652:
        !          1653:     if (receiver = $(receiver)) {
        !          1654:       if (options.insertion) {
        !          1655:         if (Object.isString(options.insertion)) {
        !          1656:           var insertion = { }; insertion[options.insertion] = responseText;
        !          1657:           receiver.insert(insertion);
        !          1658:         }
        !          1659:         else options.insertion(receiver, responseText);
        !          1660:       }
        !          1661:       else receiver.update(responseText);
        !          1662:     }
        !          1663:   }
        !          1664: });
        !          1665:
        !          1666: Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
        !          1667:   initialize: function($super, container, url, options) {
        !          1668:     $super(options);
        !          1669:     this.onComplete = this.options.onComplete;
        !          1670:
        !          1671:     this.frequency = (this.options.frequency || 2);
        !          1672:     this.decay = (this.options.decay || 1);
        !          1673:
        !          1674:     this.updater = { };
        !          1675:     this.container = container;
        !          1676:     this.url = url;
        !          1677:
        !          1678:     this.start();
        !          1679:   },
        !          1680:
        !          1681:   start: function() {
        !          1682:     this.options.onComplete = this.updateComplete.bind(this);
        !          1683:     this.onTimerEvent();
        !          1684:   },
        !          1685:
        !          1686:   stop: function() {
        !          1687:     this.updater.options.onComplete = undefined;
        !          1688:     clearTimeout(this.timer);
        !          1689:     (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
        !          1690:   },
        !          1691:
        !          1692:   updateComplete: function(response) {
        !          1693:     if (this.options.decay) {
        !          1694:       this.decay = (response.responseText == this.lastText ?
        !          1695:         this.decay * this.options.decay : 1);
        !          1696:
        !          1697:       this.lastText = response.responseText;
        !          1698:     }
        !          1699:     this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
        !          1700:   },
        !          1701:
        !          1702:   onTimerEvent: function() {
        !          1703:     this.updater = new Ajax.Updater(this.container, this.url, this.options);
        !          1704:   }
        !          1705: });
        !          1706:
        !          1707:
        !          1708:
        !          1709: function $(element) {
        !          1710:   if (arguments.length > 1) {
        !          1711:     for (var i = 0, elements = [], length = arguments.length; i < length; i++)
        !          1712:       elements.push($(arguments[i]));
        !          1713:     return elements;
        !          1714:   }
        !          1715:   if (Object.isString(element))
        !          1716:     element = document.getElementById(element);
        !          1717:   return Element.extend(element);
        !          1718: }
        !          1719:
        !          1720: if (Prototype.BrowserFeatures.XPath) {
        !          1721:   document._getElementsByXPath = function(expression, parentElement) {
        !          1722:     var results = [];
        !          1723:     var query = document.evaluate(expression, $(parentElement) || document,
        !          1724:       null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        !          1725:     for (var i = 0, length = query.snapshotLength; i < length; i++)
        !          1726:       results.push(Element.extend(query.snapshotItem(i)));
        !          1727:     return results;
        !          1728:   };
        !          1729: }
        !          1730:
        !          1731: /*--------------------------------------------------------------------------*/
        !          1732:
        !          1733: if (!window.Node) var Node = { };
        !          1734:
        !          1735: if (!Node.ELEMENT_NODE) {
        !          1736:   Object.extend(Node, {
        !          1737:     ELEMENT_NODE: 1,
        !          1738:     ATTRIBUTE_NODE: 2,
        !          1739:     TEXT_NODE: 3,
        !          1740:     CDATA_SECTION_NODE: 4,
        !          1741:     ENTITY_REFERENCE_NODE: 5,
        !          1742:     ENTITY_NODE: 6,
        !          1743:     PROCESSING_INSTRUCTION_NODE: 7,
        !          1744:     COMMENT_NODE: 8,
        !          1745:     DOCUMENT_NODE: 9,
        !          1746:     DOCUMENT_TYPE_NODE: 10,
        !          1747:     DOCUMENT_FRAGMENT_NODE: 11,
        !          1748:     NOTATION_NODE: 12
        !          1749:   });
        !          1750: }
        !          1751:
        !          1752:
        !          1753: (function(global) {
        !          1754:
        !          1755:   var SETATTRIBUTE_IGNORES_NAME = (function(){
        !          1756:     var elForm = document.createElement("form");
        !          1757:     var elInput = document.createElement("input");
        !          1758:     var root = document.documentElement;
        !          1759:     elInput.setAttribute("name", "test");
        !          1760:     elForm.appendChild(elInput);
        !          1761:     root.appendChild(elForm);
        !          1762:     var isBuggy = elForm.elements
        !          1763:       ? (typeof elForm.elements.test == "undefined")
        !          1764:       : null;
        !          1765:     root.removeChild(elForm);
        !          1766:     elForm = elInput = null;
        !          1767:     return isBuggy;
        !          1768:   })();
        !          1769:
        !          1770:   var element = global.Element;
        !          1771:   global.Element = function(tagName, attributes) {
        !          1772:     attributes = attributes || { };
        !          1773:     tagName = tagName.toLowerCase();
        !          1774:     var cache = Element.cache;
        !          1775:     if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
        !          1776:       tagName = '<' + tagName + ' name="' + attributes.name + '">';
        !          1777:       delete attributes.name;
        !          1778:       return Element.writeAttribute(document.createElement(tagName), attributes);
        !          1779:     }
        !          1780:     if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
        !          1781:     return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
        !          1782:   };
        !          1783:   Object.extend(global.Element, element || { });
        !          1784:   if (element) global.Element.prototype = element.prototype;
        !          1785: })(this);
        !          1786:
        !          1787: Element.cache = { };
        !          1788: Element.idCounter = 1;
        !          1789:
        !          1790: Element.Methods = {
        !          1791:   visible: function(element) {
        !          1792:     return $(element).style.display != 'none';
        !          1793:   },
        !          1794:
        !          1795:   toggle: function(element) {
        !          1796:     element = $(element);
        !          1797:     Element[Element.visible(element) ? 'hide' : 'show'](element);
        !          1798:     return element;
        !          1799:   },
        !          1800:
        !          1801:
        !          1802:   hide: function(element) {
        !          1803:     element = $(element);
        !          1804:     element.style.display = 'none';
        !          1805:     return element;
        !          1806:   },
        !          1807:
        !          1808:   show: function(element) {
        !          1809:     element = $(element);
        !          1810:     element.style.display = '';
        !          1811:     return element;
        !          1812:   },
        !          1813:
        !          1814:   remove: function(element) {
        !          1815:     element = $(element);
        !          1816:     element.parentNode.removeChild(element);
        !          1817:     return element;
        !          1818:   },
        !          1819:
        !          1820:   update: (function(){
        !          1821:
        !          1822:     var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
        !          1823:       var el = document.createElement("select"),
        !          1824:           isBuggy = true;
        !          1825:       el.innerHTML = "<option value=\"test\">test</option>";
        !          1826:       if (el.options && el.options[0]) {
        !          1827:         isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
        !          1828:       }
        !          1829:       el = null;
        !          1830:       return isBuggy;
        !          1831:     })();
        !          1832:
        !          1833:     var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
        !          1834:       try {
        !          1835:         var el = document.createElement("table");
        !          1836:         if (el && el.tBodies) {
        !          1837:           el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
        !          1838:           var isBuggy = typeof el.tBodies[0] == "undefined";
        !          1839:           el = null;
        !          1840:           return isBuggy;
        !          1841:         }
        !          1842:       } catch (e) {
        !          1843:         return true;
        !          1844:       }
        !          1845:     })();
        !          1846:
        !          1847:     var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
        !          1848:       var s = document.createElement("script"),
        !          1849:           isBuggy = false;
        !          1850:       try {
        !          1851:         s.appendChild(document.createTextNode(""));
        !          1852:         isBuggy = !s.firstChild ||
        !          1853:           s.firstChild && s.firstChild.nodeType !== 3;
        !          1854:       } catch (e) {
        !          1855:         isBuggy = true;
        !          1856:       }
        !          1857:       s = null;
        !          1858:       return isBuggy;
        !          1859:     })();
        !          1860:
        !          1861:     function update(element, content) {
        !          1862:       element = $(element);
        !          1863:
        !          1864:       if (content && content.toElement)
        !          1865:         content = content.toElement();
        !          1866:
        !          1867:       if (Object.isElement(content))
        !          1868:         return element.update().insert(content);
        !          1869:
        !          1870:       content = Object.toHTML(content);
        !          1871:
        !          1872:       var tagName = element.tagName.toUpperCase();
        !          1873:
        !          1874:       if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
        !          1875:         element.text = content;
        !          1876:         return element;
        !          1877:       }
        !          1878:
        !          1879:       if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
        !          1880:         if (tagName in Element._insertionTranslations.tags) {
        !          1881:           while (element.firstChild) {
        !          1882:             element.removeChild(element.firstChild);
        !          1883:           }
        !          1884:           Element._getContentFromAnonymousElement(tagName, content.stripScripts())
        !          1885:             .each(function(node) {
        !          1886:               element.appendChild(node)
        !          1887:             });
        !          1888:         }
        !          1889:         else {
        !          1890:           element.innerHTML = content.stripScripts();
        !          1891:         }
        !          1892:       }
        !          1893:       else {
        !          1894:         element.innerHTML = content.stripScripts();
        !          1895:       }
        !          1896:
        !          1897:       content.evalScripts.bind(content).defer();
        !          1898:       return element;
        !          1899:     }
        !          1900:
        !          1901:     return update;
        !          1902:   })(),
        !          1903:
        !          1904:   replace: function(element, content) {
        !          1905:     element = $(element);
        !          1906:     if (content && content.toElement) content = content.toElement();
        !          1907:     else if (!Object.isElement(content)) {
        !          1908:       content = Object.toHTML(content);
        !          1909:       var range = element.ownerDocument.createRange();
        !          1910:       range.selectNode(element);
        !          1911:       content.evalScripts.bind(content).defer();
        !          1912:       content = range.createContextualFragment(content.stripScripts());
        !          1913:     }
        !          1914:     element.parentNode.replaceChild(content, element);
        !          1915:     return element;
        !          1916:   },
        !          1917:
        !          1918:   insert: function(element, insertions) {
        !          1919:     element = $(element);
        !          1920:
        !          1921:     if (Object.isString(insertions) || Object.isNumber(insertions) ||
        !          1922:         Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
        !          1923:           insertions = {bottom:insertions};
        !          1924:
        !          1925:     var content, insert, tagName, childNodes;
        !          1926:
        !          1927:     for (var position in insertions) {
        !          1928:       content  = insertions[position];
        !          1929:       position = position.toLowerCase();
        !          1930:       insert = Element._insertionTranslations[position];
        !          1931:
        !          1932:       if (content && content.toElement) content = content.toElement();
        !          1933:       if (Object.isElement(content)) {
        !          1934:         insert(element, content);
        !          1935:         continue;
        !          1936:       }
        !          1937:
        !          1938:       content = Object.toHTML(content);
        !          1939:
        !          1940:       tagName = ((position == 'before' || position == 'after')
        !          1941:         ? element.parentNode : element).tagName.toUpperCase();
        !          1942:
        !          1943:       childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
        !          1944:
        !          1945:       if (position == 'top' || position == 'after') childNodes.reverse();
        !          1946:       childNodes.each(insert.curry(element));
        !          1947:
        !          1948:       content.evalScripts.bind(content).defer();
        !          1949:     }
        !          1950:
        !          1951:     return element;
        !          1952:   },
        !          1953:
        !          1954:   wrap: function(element, wrapper, attributes) {
        !          1955:     element = $(element);
        !          1956:     if (Object.isElement(wrapper))
        !          1957:       $(wrapper).writeAttribute(attributes || { });
        !          1958:     else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
        !          1959:     else wrapper = new Element('div', wrapper);
        !          1960:     if (element.parentNode)
        !          1961:       element.parentNode.replaceChild(wrapper, element);
        !          1962:     wrapper.appendChild(element);
        !          1963:     return wrapper;
        !          1964:   },
        !          1965:
        !          1966:   inspect: function(element) {
        !          1967:     element = $(element);
        !          1968:     var result = '<' + element.tagName.toLowerCase();
        !          1969:     $H({'id': 'id', 'className': 'class'}).each(function(pair) {
        !          1970:       var property = pair.first(), attribute = pair.last();
        !          1971:       var value = (element[property] || '').toString();
        !          1972:       if (value) result += ' ' + attribute + '=' + value.inspect(true);
        !          1973:     });
        !          1974:     return result + '>';
        !          1975:   },
        !          1976:
        !          1977:   recursivelyCollect: function(element, property) {
        !          1978:     element = $(element);
        !          1979:     var elements = [];
        !          1980:     while (element = element[property])
        !          1981:       if (element.nodeType == 1)
        !          1982:         elements.push(Element.extend(element));
        !          1983:     return elements;
        !          1984:   },
        !          1985:
        !          1986:   ancestors: function(element) {
        !          1987:     return Element.recursivelyCollect(element, 'parentNode');
        !          1988:   },
        !          1989:
        !          1990:   descendants: function(element) {
        !          1991:     return Element.select(element, "*");
        !          1992:   },
        !          1993:
        !          1994:   firstDescendant: function(element) {
        !          1995:     element = $(element).firstChild;
        !          1996:     while (element && element.nodeType != 1) element = element.nextSibling;
        !          1997:     return $(element);
        !          1998:   },
        !          1999:
        !          2000:   immediateDescendants: function(element) {
        !          2001:     if (!(element = $(element).firstChild)) return [];
        !          2002:     while (element && element.nodeType != 1) element = element.nextSibling;
        !          2003:     if (element) return [element].concat($(element).nextSiblings());
        !          2004:     return [];
        !          2005:   },
        !          2006:
        !          2007:   previousSiblings: function(element) {
        !          2008:     return Element.recursivelyCollect(element, 'previousSibling');
        !          2009:   },
        !          2010:
        !          2011:   nextSiblings: function(element) {
        !          2012:     return Element.recursivelyCollect(element, 'nextSibling');
        !          2013:   },
        !          2014:
        !          2015:   siblings: function(element) {
        !          2016:     element = $(element);
        !          2017:     return Element.previousSiblings(element).reverse()
        !          2018:       .concat(Element.nextSiblings(element));
        !          2019:   },
        !          2020:
        !          2021:   match: function(element, selector) {
        !          2022:     if (Object.isString(selector))
        !          2023:       selector = new Selector(selector);
        !          2024:     return selector.match($(element));
        !          2025:   },
        !          2026:
        !          2027:   up: function(element, expression, index) {
        !          2028:     element = $(element);
        !          2029:     if (arguments.length == 1) return $(element.parentNode);
        !          2030:     var ancestors = Element.ancestors(element);
        !          2031:     return Object.isNumber(expression) ? ancestors[expression] :
        !          2032:       Selector.findElement(ancestors, expression, index);
        !          2033:   },
        !          2034:
        !          2035:   down: function(element, expression, index) {
        !          2036:     element = $(element);
        !          2037:     if (arguments.length == 1) return Element.firstDescendant(element);
        !          2038:     return Object.isNumber(expression) ? Element.descendants(element)[expression] :
        !          2039:       Element.select(element, expression)[index || 0];
        !          2040:   },
        !          2041:
        !          2042:   previous: function(element, expression, index) {
        !          2043:     element = $(element);
        !          2044:     if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
        !          2045:     var previousSiblings = Element.previousSiblings(element);
        !          2046:     return Object.isNumber(expression) ? previousSiblings[expression] :
        !          2047:       Selector.findElement(previousSiblings, expression, index);
        !          2048:   },
        !          2049:
        !          2050:   next: function(element, expression, index) {
        !          2051:     element = $(element);
        !          2052:     if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
        !          2053:     var nextSiblings = Element.nextSiblings(element);
        !          2054:     return Object.isNumber(expression) ? nextSiblings[expression] :
        !          2055:       Selector.findElement(nextSiblings, expression, index);
        !          2056:   },
        !          2057:
        !          2058:
        !          2059:   select: function(element) {
        !          2060:     var args = Array.prototype.slice.call(arguments, 1);
        !          2061:     return Selector.findChildElements(element, args);
        !          2062:   },
        !          2063:
        !          2064:   adjacent: function(element) {
        !          2065:     var args = Array.prototype.slice.call(arguments, 1);
        !          2066:     return Selector.findChildElements(element.parentNode, args).without(element);
        !          2067:   },
        !          2068:
        !          2069:   identify: function(element) {
        !          2070:     element = $(element);
        !          2071:     var id = Element.readAttribute(element, 'id');
        !          2072:     if (id) return id;
        !          2073:     do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
        !          2074:     Element.writeAttribute(element, 'id', id);
        !          2075:     return id;
        !          2076:   },
        !          2077:
        !          2078:   readAttribute: function(element, name) {
        !          2079:     element = $(element);
        !          2080:     if (Prototype.Browser.IE) {
        !          2081:       var t = Element._attributeTranslations.read;
        !          2082:       if (t.values[name]) return t.values[name](element, name);
        !          2083:       if (t.names[name]) name = t.names[name];
        !          2084:       if (name.include(':')) {
        !          2085:         return (!element.attributes || !element.attributes[name]) ? null :
        !          2086:          element.attributes[name].value;
        !          2087:       }
        !          2088:     }
        !          2089:     return element.getAttribute(name);
        !          2090:   },
        !          2091:
        !          2092:   writeAttribute: function(element, name, value) {
        !          2093:     element = $(element);
        !          2094:     var attributes = { }, t = Element._attributeTranslations.write;
        !          2095:
        !          2096:     if (typeof name == 'object') attributes = name;
        !          2097:     else attributes[name] = Object.isUndefined(value) ? true : value;
        !          2098:
        !          2099:     for (var attr in attributes) {
        !          2100:       name = t.names[attr] || attr;
        !          2101:       value = attributes[attr];
        !          2102:       if (t.values[attr]) name = t.values[attr](element, value);
        !          2103:       if (value === false || value === null)
        !          2104:         element.removeAttribute(name);
        !          2105:       else if (value === true)
        !          2106:         element.setAttribute(name, name);
        !          2107:       else element.setAttribute(name, value);
        !          2108:     }
        !          2109:     return element;
        !          2110:   },
        !          2111:
        !          2112:   getHeight: function(element) {
        !          2113:     return Element.getDimensions(element).height;
        !          2114:   },
        !          2115:
        !          2116:   getWidth: function(element) {
        !          2117:     return Element.getDimensions(element).width;
        !          2118:   },
        !          2119:
        !          2120:   classNames: function(element) {
        !          2121:     return new Element.ClassNames(element);
        !          2122:   },
        !          2123:
        !          2124:   hasClassName: function(element, className) {
        !          2125:     if (!(element = $(element))) return;
        !          2126:     var elementClassName = element.className;
        !          2127:     return (elementClassName.length > 0 && (elementClassName == className ||
        !          2128:       new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
        !          2129:   },
        !          2130:
        !          2131:   addClassName: function(element, className) {
        !          2132:     if (!(element = $(element))) return;
        !          2133:     if (!Element.hasClassName(element, className))
        !          2134:       element.className += (element.className ? ' ' : '') + className;
        !          2135:     return element;
        !          2136:   },
        !          2137:
        !          2138:   removeClassName: function(element, className) {
        !          2139:     if (!(element = $(element))) return;
        !          2140:     element.className = element.className.replace(
        !          2141:       new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
        !          2142:     return element;
        !          2143:   },
        !          2144:
        !          2145:   toggleClassName: function(element, className) {
        !          2146:     if (!(element = $(element))) return;
        !          2147:     return Element[Element.hasClassName(element, className) ?
        !          2148:       'removeClassName' : 'addClassName'](element, className);
        !          2149:   },
        !          2150:
        !          2151:   cleanWhitespace: function(element) {
        !          2152:     element = $(element);
        !          2153:     var node = element.firstChild;
        !          2154:     while (node) {
        !          2155:       var nextNode = node.nextSibling;
        !          2156:       if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        !          2157:         element.removeChild(node);
        !          2158:       node = nextNode;
        !          2159:     }
        !          2160:     return element;
        !          2161:   },
        !          2162:
        !          2163:   empty: function(element) {
        !          2164:     return $(element).innerHTML.blank();
        !          2165:   },
        !          2166:
        !          2167:   descendantOf: function(element, ancestor) {
        !          2168:     element = $(element), ancestor = $(ancestor);
        !          2169:
        !          2170:     if (element.compareDocumentPosition)
        !          2171:       return (element.compareDocumentPosition(ancestor) & 8) === 8;
        !          2172:
        !          2173:     if (ancestor.contains)
        !          2174:       return ancestor.contains(element) && ancestor !== element;
        !          2175:
        !          2176:     while (element = element.parentNode)
        !          2177:       if (element == ancestor) return true;
        !          2178:
        !          2179:     return false;
        !          2180:   },
        !          2181:
        !          2182:   scrollTo: function(element) {
        !          2183:     element = $(element);
        !          2184:     var pos = Element.cumulativeOffset(element);
        !          2185:     window.scrollTo(pos[0], pos[1]);
        !          2186:     return element;
        !          2187:   },
        !          2188:
        !          2189:   getStyle: function(element, style) {
        !          2190:     element = $(element);
        !          2191:     style = style == 'float' ? 'cssFloat' : style.camelize();
        !          2192:     var value = element.style[style];
        !          2193:     if (!value || value == 'auto') {
        !          2194:       var css = document.defaultView.getComputedStyle(element, null);
        !          2195:       value = css ? css[style] : null;
        !          2196:     }
        !          2197:     if (style == 'opacity') return value ? parseFloat(value) : 1.0;
        !          2198:     return value == 'auto' ? null : value;
        !          2199:   },
        !          2200:
        !          2201:   getOpacity: function(element) {
        !          2202:     return $(element).getStyle('opacity');
        !          2203:   },
        !          2204:
        !          2205:   setStyle: function(element, styles) {
        !          2206:     element = $(element);
        !          2207:     var elementStyle = element.style, match;
        !          2208:     if (Object.isString(styles)) {
        !          2209:       element.style.cssText += ';' + styles;
        !          2210:       return styles.include('opacity') ?
        !          2211:         element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
        !          2212:     }
        !          2213:     for (var property in styles)
        !          2214:       if (property == 'opacity') element.setOpacity(styles[property]);
        !          2215:       else
        !          2216:         elementStyle[(property == 'float' || property == 'cssFloat') ?
        !          2217:           (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
        !          2218:             property] = styles[property];
        !          2219:
        !          2220:     return element;
        !          2221:   },
        !          2222:
        !          2223:   setOpacity: function(element, value) {
        !          2224:     element = $(element);
        !          2225:     element.style.opacity = (value == 1 || value === '') ? '' :
        !          2226:       (value < 0.00001) ? 0 : value;
        !          2227:     return element;
        !          2228:   },
        !          2229:
        !          2230:   getDimensions: function(element) {
        !          2231:     element = $(element);
        !          2232:     var display = Element.getStyle(element, 'display');
        !          2233:     if (display != 'none' && display != null) // Safari bug
        !          2234:       return {width: element.offsetWidth, height: element.offsetHeight};
        !          2235:
        !          2236:     var els = element.style;
        !          2237:     var originalVisibility = els.visibility;
        !          2238:     var originalPosition = els.position;
        !          2239:     var originalDisplay = els.display;
        !          2240:     els.visibility = 'hidden';
        !          2241:     if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
        !          2242:       els.position = 'absolute';
        !          2243:     els.display = 'block';
        !          2244:     var originalWidth = element.clientWidth;
        !          2245:     var originalHeight = element.clientHeight;
        !          2246:     els.display = originalDisplay;
        !          2247:     els.position = originalPosition;
        !          2248:     els.visibility = originalVisibility;
        !          2249:     return {width: originalWidth, height: originalHeight};
        !          2250:   },
        !          2251:
        !          2252:   makePositioned: function(element) {
        !          2253:     element = $(element);
        !          2254:     var pos = Element.getStyle(element, 'position');
        !          2255:     if (pos == 'static' || !pos) {
        !          2256:       element._madePositioned = true;
        !          2257:       element.style.position = 'relative';
        !          2258:       if (Prototype.Browser.Opera) {
        !          2259:         element.style.top = 0;
        !          2260:         element.style.left = 0;
        !          2261:       }
        !          2262:     }
        !          2263:     return element;
        !          2264:   },
        !          2265:
        !          2266:   undoPositioned: function(element) {
        !          2267:     element = $(element);
        !          2268:     if (element._madePositioned) {
        !          2269:       element._madePositioned = undefined;
        !          2270:       element.style.position =
        !          2271:         element.style.top =
        !          2272:         element.style.left =
        !          2273:         element.style.bottom =
        !          2274:         element.style.right = '';
        !          2275:     }
        !          2276:     return element;
        !          2277:   },
        !          2278:
        !          2279:   makeClipping: function(element) {
        !          2280:     element = $(element);
        !          2281:     if (element._overflow) return element;
        !          2282:     element._overflow = Element.getStyle(element, 'overflow') || 'auto';
        !          2283:     if (element._overflow !== 'hidden')
        !          2284:       element.style.overflow = 'hidden';
        !          2285:     return element;
        !          2286:   },
        !          2287:
        !          2288:   undoClipping: function(element) {
        !          2289:     element = $(element);
        !          2290:     if (!element._overflow) return element;
        !          2291:     element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
        !          2292:     element._overflow = null;
        !          2293:     return element;
        !          2294:   },
        !          2295:
        !          2296:   cumulativeOffset: function(element) {
        !          2297:     var valueT = 0, valueL = 0;
        !          2298:     do {
        !          2299:       valueT += element.offsetTop  || 0;
        !          2300:       valueL += element.offsetLeft || 0;
        !          2301:       element = element.offsetParent;
        !          2302:     } while (element);
        !          2303:     return Element._returnOffset(valueL, valueT);
        !          2304:   },
        !          2305:
        !          2306:   positionedOffset: function(element) {
        !          2307:     var valueT = 0, valueL = 0;
        !          2308:     do {
        !          2309:       valueT += element.offsetTop  || 0;
        !          2310:       valueL += element.offsetLeft || 0;
        !          2311:       element = element.offsetParent;
        !          2312:       if (element) {
        !          2313:         if (element.tagName.toUpperCase() == 'BODY') break;
        !          2314:         var p = Element.getStyle(element, 'position');
        !          2315:         if (p !== 'static') break;
        !          2316:       }
        !          2317:     } while (element);
        !          2318:     return Element._returnOffset(valueL, valueT);
        !          2319:   },
        !          2320:
        !          2321:   absolutize: function(element) {
        !          2322:     element = $(element);
        !          2323:     if (Element.getStyle(element, 'position') == 'absolute') return element;
        !          2324:
        !          2325:     var offsets = Element.positionedOffset(element);
        !          2326:     var top     = offsets[1];
        !          2327:     var left    = offsets[0];
        !          2328:     var width   = element.clientWidth;
        !          2329:     var height  = element.clientHeight;
        !          2330:
        !          2331:     element._originalLeft   = left - parseFloat(element.style.left  || 0);
        !          2332:     element._originalTop    = top  - parseFloat(element.style.top || 0);
        !          2333:     element._originalWidth  = element.style.width;
        !          2334:     element._originalHeight = element.style.height;
        !          2335:
        !          2336:     element.style.position = 'absolute';
        !          2337:     element.style.top    = top + 'px';
        !          2338:     element.style.left   = left + 'px';
        !          2339:     element.style.width  = width + 'px';
        !          2340:     element.style.height = height + 'px';
        !          2341:     return element;
        !          2342:   },
        !          2343:
        !          2344:   relativize: function(element) {
        !          2345:     element = $(element);
        !          2346:     if (Element.getStyle(element, 'position') == 'relative') return element;
        !          2347:
        !          2348:     element.style.position = 'relative';
        !          2349:     var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
        !          2350:     var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
        !          2351:
        !          2352:     element.style.top    = top + 'px';
        !          2353:     element.style.left   = left + 'px';
        !          2354:     element.style.height = element._originalHeight;
        !          2355:     element.style.width  = element._originalWidth;
        !          2356:     return element;
        !          2357:   },
        !          2358:
        !          2359:   cumulativeScrollOffset: function(element) {
        !          2360:     var valueT = 0, valueL = 0;
        !          2361:     do {
        !          2362:       valueT += element.scrollTop  || 0;
        !          2363:       valueL += element.scrollLeft || 0;
        !          2364:       element = element.parentNode;
        !          2365:     } while (element);
        !          2366:     return Element._returnOffset(valueL, valueT);
        !          2367:   },
        !          2368:
        !          2369:   getOffsetParent: function(element) {
        !          2370:     if (element.offsetParent) return $(element.offsetParent);
        !          2371:     if (element == document.body) return $(element);
        !          2372:
        !          2373:     while ((element = element.parentNode) && element != document.body)
        !          2374:       if (Element.getStyle(element, 'position') != 'static')
        !          2375:         return $(element);
        !          2376:
        !          2377:     return $(document.body);
        !          2378:   },
        !          2379:
        !          2380:   viewportOffset: function(forElement) {
        !          2381:     var valueT = 0, valueL = 0;
        !          2382:
        !          2383:     var element = forElement;
        !          2384:     do {
        !          2385:       valueT += element.offsetTop  || 0;
        !          2386:       valueL += element.offsetLeft || 0;
        !          2387:
        !          2388:       if (element.offsetParent == document.body &&
        !          2389:         Element.getStyle(element, 'position') == 'absolute') break;
        !          2390:
        !          2391:     } while (element = element.offsetParent);
        !          2392:
        !          2393:     element = forElement;
        !          2394:     do {
        !          2395:       if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
        !          2396:         valueT -= element.scrollTop  || 0;
        !          2397:         valueL -= element.scrollLeft || 0;
        !          2398:       }
        !          2399:     } while (element = element.parentNode);
        !          2400:
        !          2401:     return Element._returnOffset(valueL, valueT);
        !          2402:   },
        !          2403:
        !          2404:   clonePosition: function(element, source) {
        !          2405:     var options = Object.extend({
        !          2406:       setLeft:    true,
        !          2407:       setTop:     true,
        !          2408:       setWidth:   true,
        !          2409:       setHeight:  true,
        !          2410:       offsetTop:  0,
        !          2411:       offsetLeft: 0
        !          2412:     }, arguments[2] || { });
        !          2413:
        !          2414:     source = $(source);
        !          2415:     var p = Element.viewportOffset(source);
        !          2416:
        !          2417:     element = $(element);
        !          2418:     var delta = [0, 0];
        !          2419:     var parent = null;
        !          2420:     if (Element.getStyle(element, 'position') == 'absolute') {
        !          2421:       parent = Element.getOffsetParent(element);
        !          2422:       delta = Element.viewportOffset(parent);
        !          2423:     }
        !          2424:
        !          2425:     if (parent == document.body) {
        !          2426:       delta[0] -= document.body.offsetLeft;
        !          2427:       delta[1] -= document.body.offsetTop;
        !          2428:     }
        !          2429:
        !          2430:     if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
        !          2431:     if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
        !          2432:     if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
        !          2433:     if (options.setHeight) element.style.height = source.offsetHeight + 'px';
        !          2434:     return element;
        !          2435:   }
        !          2436: };
        !          2437:
        !          2438: Object.extend(Element.Methods, {
        !          2439:   getElementsBySelector: Element.Methods.select,
        !          2440:
        !          2441:   childElements: Element.Methods.immediateDescendants
        !          2442: });
        !          2443:
        !          2444: Element._attributeTranslations = {
        !          2445:   write: {
        !          2446:     names: {
        !          2447:       className: 'class',
        !          2448:       htmlFor:   'for'
        !          2449:     },
        !          2450:     values: { }
        !          2451:   }
        !          2452: };
        !          2453:
        !          2454: if (Prototype.Browser.Opera) {
        !          2455:   Element.Methods.getStyle = Element.Methods.getStyle.wrap(
        !          2456:     function(proceed, element, style) {
        !          2457:       switch (style) {
        !          2458:         case 'left': case 'top': case 'right': case 'bottom':
        !          2459:           if (proceed(element, 'position') === 'static') return null;
        !          2460:         case 'height': case 'width':
        !          2461:           if (!Element.visible(element)) return null;
        !          2462:
        !          2463:           var dim = parseInt(proceed(element, style), 10);
        !          2464:
        !          2465:           if (dim !== element['offset' + style.capitalize()])
        !          2466:             return dim + 'px';
        !          2467:
        !          2468:           var properties;
        !          2469:           if (style === 'height') {
        !          2470:             properties = ['border-top-width', 'padding-top',
        !          2471:              'padding-bottom', 'border-bottom-width'];
        !          2472:           }
        !          2473:           else {
        !          2474:             properties = ['border-left-width', 'padding-left',
        !          2475:              'padding-right', 'border-right-width'];
        !          2476:           }
        !          2477:           return properties.inject(dim, function(memo, property) {
        !          2478:             var val = proceed(element, property);
        !          2479:             return val === null ? memo : memo - parseInt(val, 10);
        !          2480:           }) + 'px';
        !          2481:         default: return proceed(element, style);
        !          2482:       }
        !          2483:     }
        !          2484:   );
        !          2485:
        !          2486:   Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
        !          2487:     function(proceed, element, attribute) {
        !          2488:       if (attribute === 'title') return element.title;
        !          2489:       return proceed(element, attribute);
        !          2490:     }
        !          2491:   );
        !          2492: }
        !          2493:
        !          2494: else if (Prototype.Browser.IE) {
        !          2495:   Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
        !          2496:     function(proceed, element) {
        !          2497:       element = $(element);
        !          2498:       try { element.offsetParent }
        !          2499:       catch(e) { return $(document.body) }
        !          2500:       var position = element.getStyle('position');
        !          2501:       if (position !== 'static') return proceed(element);
        !          2502:       element.setStyle({ position: 'relative' });
        !          2503:       var value = proceed(element);
        !          2504:       element.setStyle({ position: position });
        !          2505:       return value;
        !          2506:     }
        !          2507:   );
        !          2508:
        !          2509:   $w('positionedOffset viewportOffset').each(function(method) {
        !          2510:     Element.Methods[method] = Element.Methods[method].wrap(
        !          2511:       function(proceed, element) {
        !          2512:         element = $(element);
        !          2513:         try { element.offsetParent }
        !          2514:         catch(e) { return Element._returnOffset(0,0) }
        !          2515:         var position = element.getStyle('position');
        !          2516:         if (position !== 'static') return proceed(element);
        !          2517:         var offsetParent = element.getOffsetParent();
        !          2518:         if (offsetParent && offsetParent.getStyle('position') === 'fixed')
        !          2519:           offsetParent.setStyle({ zoom: 1 });
        !          2520:         element.setStyle({ position: 'relative' });
        !          2521:         var value = proceed(element);
        !          2522:         element.setStyle({ position: position });
        !          2523:         return value;
        !          2524:       }
        !          2525:     );
        !          2526:   });
        !          2527:
        !          2528:   Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
        !          2529:     function(proceed, element) {
        !          2530:       try { element.offsetParent }
        !          2531:       catch(e) { return Element._returnOffset(0,0) }
        !          2532:       return proceed(element);
        !          2533:     }
        !          2534:   );
        !          2535:
        !          2536:   Element.Methods.getStyle = function(element, style) {
        !          2537:     element = $(element);
        !          2538:     style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
        !          2539:     var value = element.style[style];
        !          2540:     if (!value && element.currentStyle) value = element.currentStyle[style];
        !          2541:
        !          2542:     if (style == 'opacity') {
        !          2543:       if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        !          2544:         if (value[1]) return parseFloat(value[1]) / 100;
        !          2545:       return 1.0;
        !          2546:     }
        !          2547:
        !          2548:     if (value == 'auto') {
        !          2549:       if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        !          2550:         return element['offset' + style.capitalize()] + 'px';
        !          2551:       return null;
        !          2552:     }
        !          2553:     return value;
        !          2554:   };
        !          2555:
        !          2556:   Element.Methods.setOpacity = function(element, value) {
        !          2557:     function stripAlpha(filter){
        !          2558:       return filter.replace(/alpha\([^\)]*\)/gi,'');
        !          2559:     }
        !          2560:     element = $(element);
        !          2561:     var currentStyle = element.currentStyle;
        !          2562:     if ((currentStyle && !currentStyle.hasLayout) ||
        !          2563:       (!currentStyle && element.style.zoom == 'normal'))
        !          2564:         element.style.zoom = 1;
        !          2565:
        !          2566:     var filter = element.getStyle('filter'), style = element.style;
        !          2567:     if (value == 1 || value === '') {
        !          2568:       (filter = stripAlpha(filter)) ?
        !          2569:         style.filter = filter : style.removeAttribute('filter');
        !          2570:       return element;
        !          2571:     } else if (value < 0.00001) value = 0;
        !          2572:     style.filter = stripAlpha(filter) +
        !          2573:       'alpha(opacity=' + (value * 100) + ')';
        !          2574:     return element;
        !          2575:   };
        !          2576:
        !          2577:   Element._attributeTranslations = (function(){
        !          2578:
        !          2579:     var classProp = 'className';
        !          2580:     var forProp = 'for';
        !          2581:
        !          2582:     var el = document.createElement('div');
        !          2583:
        !          2584:     el.setAttribute(classProp, 'x');
        !          2585:
        !          2586:     if (el.className !== 'x') {
        !          2587:       el.setAttribute('class', 'x');
        !          2588:       if (el.className === 'x') {
        !          2589:         classProp = 'class';
        !          2590:       }
        !          2591:     }
        !          2592:     el = null;
        !          2593:
        !          2594:     el = document.createElement('label');
        !          2595:     el.setAttribute(forProp, 'x');
        !          2596:     if (el.htmlFor !== 'x') {
        !          2597:       el.setAttribute('htmlFor', 'x');
        !          2598:       if (el.htmlFor === 'x') {
        !          2599:         forProp = 'htmlFor';
        !          2600:       }
        !          2601:     }
        !          2602:     el = null;
        !          2603:
        !          2604:     return {
        !          2605:       read: {
        !          2606:         names: {
        !          2607:           'class':      classProp,
        !          2608:           'className':  classProp,
        !          2609:           'for':        forProp,
        !          2610:           'htmlFor':    forProp
        !          2611:         },
        !          2612:         values: {
        !          2613:           _getAttr: function(element, attribute) {
        !          2614:             return element.getAttribute(attribute);
        !          2615:           },
        !          2616:           _getAttr2: function(element, attribute) {
        !          2617:             return element.getAttribute(attribute, 2);
        !          2618:           },
        !          2619:           _getAttrNode: function(element, attribute) {
        !          2620:             var node = element.getAttributeNode(attribute);
        !          2621:             return node ? node.value : "";
        !          2622:           },
        !          2623:           _getEv: (function(){
        !          2624:
        !          2625:             var el = document.createElement('div');
        !          2626:             el.onclick = Prototype.emptyFunction;
        !          2627:             var value = el.getAttribute('onclick');
        !          2628:             var f;
        !          2629:
        !          2630:             if (String(value).indexOf('{') > -1) {
        !          2631:               f = function(element, attribute) {
        !          2632:                 attribute = element.getAttribute(attribute);
        !          2633:                 if (!attribute) return null;
        !          2634:                 attribute = attribute.toString();
        !          2635:                 attribute = attribute.split('{')[1];
        !          2636:                 attribute = attribute.split('}')[0];
        !          2637:                 return attribute.strip();
        !          2638:               };
        !          2639:             }
        !          2640:             else if (value === '') {
        !          2641:               f = function(element, attribute) {
        !          2642:                 attribute = element.getAttribute(attribute);
        !          2643:                 if (!attribute) return null;
        !          2644:                 return attribute.strip();
        !          2645:               };
        !          2646:             }
        !          2647:             el = null;
        !          2648:             return f;
        !          2649:           })(),
        !          2650:           _flag: function(element, attribute) {
        !          2651:             return $(element).hasAttribute(attribute) ? attribute : null;
        !          2652:           },
        !          2653:           style: function(element) {
        !          2654:             return element.style.cssText.toLowerCase();
        !          2655:           },
        !          2656:           title: function(element) {
        !          2657:             return element.title;
        !          2658:           }
        !          2659:         }
        !          2660:       }
        !          2661:     }
        !          2662:   })();
        !          2663:
        !          2664:   Element._attributeTranslations.write = {
        !          2665:     names: Object.extend({
        !          2666:       cellpadding: 'cellPadding',
        !          2667:       cellspacing: 'cellSpacing'
        !          2668:     }, Element._attributeTranslations.read.names),
        !          2669:     values: {
        !          2670:       checked: function(element, value) {
        !          2671:         element.checked = !!value;
        !          2672:       },
        !          2673:
        !          2674:       style: function(element, value) {
        !          2675:         element.style.cssText = value ? value : '';
        !          2676:       }
        !          2677:     }
        !          2678:   };
        !          2679:
        !          2680:   Element._attributeTranslations.has = {};
        !          2681:
        !          2682:   $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
        !          2683:       'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
        !          2684:     Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
        !          2685:     Element._attributeTranslations.has[attr.toLowerCase()] = attr;
        !          2686:   });
        !          2687:
        !          2688:   (function(v) {
        !          2689:     Object.extend(v, {
        !          2690:       href:        v._getAttr2,
        !          2691:       src:         v._getAttr2,
        !          2692:       type:        v._getAttr,
        !          2693:       action:      v._getAttrNode,
        !          2694:       disabled:    v._flag,
        !          2695:       checked:     v._flag,
        !          2696:       readonly:    v._flag,
        !          2697:       multiple:    v._flag,
        !          2698:       onload:      v._getEv,
        !          2699:       onunload:    v._getEv,
        !          2700:       onclick:     v._getEv,
        !          2701:       ondblclick:  v._getEv,
        !          2702:       onmousedown: v._getEv,
        !          2703:       onmouseup:   v._getEv,
        !          2704:       onmouseover: v._getEv,
        !          2705:       onmousemove: v._getEv,
        !          2706:       onmouseout:  v._getEv,
        !          2707:       onfocus:     v._getEv,
        !          2708:       onblur:      v._getEv,
        !          2709:       onkeypress:  v._getEv,
        !          2710:       onkeydown:   v._getEv,
        !          2711:       onkeyup:     v._getEv,
        !          2712:       onsubmit:    v._getEv,
        !          2713:       onreset:     v._getEv,
        !          2714:       onselect:    v._getEv,
        !          2715:       onchange:    v._getEv
        !          2716:     });
        !          2717:   })(Element._attributeTranslations.read.values);
        !          2718:
        !          2719:   if (Prototype.BrowserFeatures.ElementExtensions) {
        !          2720:     (function() {
        !          2721:       function _descendants(element) {
        !          2722:         var nodes = element.getElementsByTagName('*'), results = [];
        !          2723:         for (var i = 0, node; node = nodes[i]; i++)
        !          2724:           if (node.tagName !== "!") // Filter out comment nodes.
        !          2725:             results.push(node);
        !          2726:         return results;
        !          2727:       }
        !          2728:
        !          2729:       Element.Methods.down = function(element, expression, index) {
        !          2730:         element = $(element);
        !          2731:         if (arguments.length == 1) return element.firstDescendant();
        !          2732:         return Object.isNumber(expression) ? _descendants(element)[expression] :
        !          2733:           Element.select(element, expression)[index || 0];
        !          2734:       }
        !          2735:     })();
        !          2736:   }
        !          2737:
        !          2738: }
        !          2739:
        !          2740: else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
        !          2741:   Element.Methods.setOpacity = function(element, value) {
        !          2742:     element = $(element);
        !          2743:     element.style.opacity = (value == 1) ? 0.999999 :
        !          2744:       (value === '') ? '' : (value < 0.00001) ? 0 : value;
        !          2745:     return element;
        !          2746:   };
        !          2747: }
        !          2748:
        !          2749: else if (Prototype.Browser.WebKit) {
        !          2750:   Element.Methods.setOpacity = function(element, value) {
        !          2751:     element = $(element);
        !          2752:     element.style.opacity = (value == 1 || value === '') ? '' :
        !          2753:       (value < 0.00001) ? 0 : value;
        !          2754:
        !          2755:     if (value == 1)
        !          2756:       if(element.tagName.toUpperCase() == 'IMG' && element.width) {
        !          2757:         element.width++; element.width--;
        !          2758:       } else try {
        !          2759:         var n = document.createTextNode(' ');
        !          2760:         element.appendChild(n);
        !          2761:         element.removeChild(n);
        !          2762:       } catch (e) { }
        !          2763:
        !          2764:     return element;
        !          2765:   };
        !          2766:
        !          2767:   Element.Methods.cumulativeOffset = function(element) {
        !          2768:     var valueT = 0, valueL = 0;
        !          2769:     do {
        !          2770:       valueT += element.offsetTop  || 0;
        !          2771:       valueL += element.offsetLeft || 0;
        !          2772:       if (element.offsetParent == document.body)
        !          2773:         if (Element.getStyle(element, 'position') == 'absolute') break;
        !          2774:
        !          2775:       element = element.offsetParent;
        !          2776:     } while (element);
        !          2777:
        !          2778:     return Element._returnOffset(valueL, valueT);
        !          2779:   };
        !          2780: }
        !          2781:
        !          2782: if ('outerHTML' in document.documentElement) {
        !          2783:   Element.Methods.replace = function(element, content) {
        !          2784:     element = $(element);
        !          2785:
        !          2786:     if (content && content.toElement) content = content.toElement();
        !          2787:     if (Object.isElement(content)) {
        !          2788:       element.parentNode.replaceChild(content, element);
        !          2789:       return element;
        !          2790:     }
        !          2791:
        !          2792:     content = Object.toHTML(content);
        !          2793:     var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
        !          2794:
        !          2795:     if (Element._insertionTranslations.tags[tagName]) {
        !          2796:       var nextSibling = element.next();
        !          2797:       var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
        !          2798:       parent.removeChild(element);
        !          2799:       if (nextSibling)
        !          2800:         fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
        !          2801:       else
        !          2802:         fragments.each(function(node) { parent.appendChild(node) });
        !          2803:     }
        !          2804:     else element.outerHTML = content.stripScripts();
        !          2805:
        !          2806:     content.evalScripts.bind(content).defer();
        !          2807:     return element;
        !          2808:   };
        !          2809: }
        !          2810:
        !          2811: Element._returnOffset = function(l, t) {
        !          2812:   var result = [l, t];
        !          2813:   result.left = l;
        !          2814:   result.top = t;
        !          2815:   return result;
        !          2816: };
        !          2817:
        !          2818: Element._getContentFromAnonymousElement = function(tagName, html) {
        !          2819:   var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
        !          2820:   if (t) {
        !          2821:     div.innerHTML = t[0] + html + t[1];
        !          2822:     t[2].times(function() { div = div.firstChild });
        !          2823:   } else div.innerHTML = html;
        !          2824:   return $A(div.childNodes);
        !          2825: };
        !          2826:
        !          2827: Element._insertionTranslations = {
        !          2828:   before: function(element, node) {
        !          2829:     element.parentNode.insertBefore(node, element);
        !          2830:   },
        !          2831:   top: function(element, node) {
        !          2832:     element.insertBefore(node, element.firstChild);
        !          2833:   },
        !          2834:   bottom: function(element, node) {
        !          2835:     element.appendChild(node);
        !          2836:   },
        !          2837:   after: function(element, node) {
        !          2838:     element.parentNode.insertBefore(node, element.nextSibling);
        !          2839:   },
        !          2840:   tags: {
        !          2841:     TABLE:  ['<table>',                '</table>',                   1],
        !          2842:     TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
        !          2843:     TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
        !          2844:     TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
        !          2845:     SELECT: ['<select>',               '</select>',                  1]
        !          2846:   }
        !          2847: };
        !          2848:
        !          2849: (function() {
        !          2850:   var tags = Element._insertionTranslations.tags;
        !          2851:   Object.extend(tags, {
        !          2852:     THEAD: tags.TBODY,
        !          2853:     TFOOT: tags.TBODY,
        !          2854:     TH:    tags.TD
        !          2855:   });
        !          2856: })();
        !          2857:
        !          2858: Element.Methods.Simulated = {
        !          2859:   hasAttribute: function(element, attribute) {
        !          2860:     attribute = Element._attributeTranslations.has[attribute] || attribute;
        !          2861:     var node = $(element).getAttributeNode(attribute);
        !          2862:     return !!(node && node.specified);
        !          2863:   }
        !          2864: };
        !          2865:
        !          2866: Element.Methods.ByTag = { };
        !          2867:
        !          2868: Object.extend(Element, Element.Methods);
        !          2869:
        !          2870: (function(div) {
        !          2871:
        !          2872:   if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
        !          2873:     window.HTMLElement = { };
        !          2874:     window.HTMLElement.prototype = div['__proto__'];
        !          2875:     Prototype.BrowserFeatures.ElementExtensions = true;
        !          2876:   }
        !          2877:
        !          2878:   div = null;
        !          2879:
        !          2880: })(document.createElement('div'))
        !          2881:
        !          2882: Element.extend = (function() {
        !          2883:
        !          2884:   function checkDeficiency(tagName) {
        !          2885:     if (typeof window.Element != 'undefined') {
        !          2886:       var proto = window.Element.prototype;
        !          2887:       if (proto) {
        !          2888:         var id = '_' + (Math.random()+'').slice(2);
        !          2889:         var el = document.createElement(tagName);
        !          2890:         proto[id] = 'x';
        !          2891:         var isBuggy = (el[id] !== 'x');
        !          2892:         delete proto[id];
        !          2893:         el = null;
        !          2894:         return isBuggy;
        !          2895:       }
        !          2896:     }
        !          2897:     return false;
        !          2898:   }
        !          2899:
        !          2900:   function extendElementWith(element, methods) {
        !          2901:     for (var property in methods) {
        !          2902:       var value = methods[property];
        !          2903:       if (Object.isFunction(value) && !(property in element))
        !          2904:         element[property] = value.methodize();
        !          2905:     }
        !          2906:   }
        !          2907:
        !          2908:   var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
        !          2909:
        !          2910:   if (Prototype.BrowserFeatures.SpecificElementExtensions) {
        !          2911:     if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
        !          2912:       return function(element) {
        !          2913:         if (element && typeof element._extendedByPrototype == 'undefined') {
        !          2914:           var t = element.tagName;
        !          2915:           if (t && (/^(?:object|applet|embed)$/i.test(t))) {
        !          2916:             extendElementWith(element, Element.Methods);
        !          2917:             extendElementWith(element, Element.Methods.Simulated);
        !          2918:             extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
        !          2919:           }
        !          2920:         }
        !          2921:         return element;
        !          2922:       }
        !          2923:     }
        !          2924:     return Prototype.K;
        !          2925:   }
        !          2926:
        !          2927:   var Methods = { }, ByTag = Element.Methods.ByTag;
        !          2928:
        !          2929:   var extend = Object.extend(function(element) {
        !          2930:     if (!element || typeof element._extendedByPrototype != 'undefined' ||
        !          2931:         element.nodeType != 1 || element == window) return element;
        !          2932:
        !          2933:     var methods = Object.clone(Methods),
        !          2934:         tagName = element.tagName.toUpperCase();
        !          2935:
        !          2936:     if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
        !          2937:
        !          2938:     extendElementWith(element, methods);
        !          2939:
        !          2940:     element._extendedByPrototype = Prototype.emptyFunction;
        !          2941:     return element;
        !          2942:
        !          2943:   }, {
        !          2944:     refresh: function() {
        !          2945:       if (!Prototype.BrowserFeatures.ElementExtensions) {
        !          2946:         Object.extend(Methods, Element.Methods);
        !          2947:         Object.extend(Methods, Element.Methods.Simulated);
        !          2948:       }
        !          2949:     }
        !          2950:   });
        !          2951:
        !          2952:   extend.refresh();
        !          2953:   return extend;
        !          2954: })();
        !          2955:
        !          2956: Element.hasAttribute = function(element, attribute) {
        !          2957:   if (element.hasAttribute) return element.hasAttribute(attribute);
        !          2958:   return Element.Methods.Simulated.hasAttribute(element, attribute);
        !          2959: };
        !          2960:
        !          2961: Element.addMethods = function(methods) {
        !          2962:   var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
        !          2963:
        !          2964:   if (!methods) {
        !          2965:     Object.extend(Form, Form.Methods);
        !          2966:     Object.extend(Form.Element, Form.Element.Methods);
        !          2967:     Object.extend(Element.Methods.ByTag, {
        !          2968:       "FORM":     Object.clone(Form.Methods),
        !          2969:       "INPUT":    Object.clone(Form.Element.Methods),
        !          2970:       "SELECT":   Object.clone(Form.Element.Methods),
        !          2971:       "TEXTAREA": Object.clone(Form.Element.Methods)
        !          2972:     });
        !          2973:   }
        !          2974:
        !          2975:   if (arguments.length == 2) {
        !          2976:     var tagName = methods;
        !          2977:     methods = arguments[1];
        !          2978:   }
        !          2979:
        !          2980:   if (!tagName) Object.extend(Element.Methods, methods || { });
        !          2981:   else {
        !          2982:     if (Object.isArray(tagName)) tagName.each(extend);
        !          2983:     else extend(tagName);
        !          2984:   }
        !          2985:
        !          2986:   function extend(tagName) {
        !          2987:     tagName = tagName.toUpperCase();
        !          2988:     if (!Element.Methods.ByTag[tagName])
        !          2989:       Element.Methods.ByTag[tagName] = { };
        !          2990:     Object.extend(Element.Methods.ByTag[tagName], methods);
        !          2991:   }
        !          2992:
        !          2993:   function copy(methods, destination, onlyIfAbsent) {
        !          2994:     onlyIfAbsent = onlyIfAbsent || false;
        !          2995:     for (var property in methods) {
        !          2996:       var value = methods[property];
        !          2997:       if (!Object.isFunction(value)) continue;
        !          2998:       if (!onlyIfAbsent || !(property in destination))
        !          2999:         destination[property] = value.methodize();
        !          3000:     }
        !          3001:   }
        !          3002:
        !          3003:   function findDOMClass(tagName) {
        !          3004:     var klass;
        !          3005:     var trans = {
        !          3006:       "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
        !          3007:       "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
        !          3008:       "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
        !          3009:       "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
        !          3010:       "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
        !          3011:       "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
        !          3012:       "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
        !          3013:       "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
        !          3014:       "FrameSet", "IFRAME": "IFrame"
        !          3015:     };
        !          3016:     if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
        !          3017:     if (window[klass]) return window[klass];
        !          3018:     klass = 'HTML' + tagName + 'Element';
        !          3019:     if (window[klass]) return window[klass];
        !          3020:     klass = 'HTML' + tagName.capitalize() + 'Element';
        !          3021:     if (window[klass]) return window[klass];
        !          3022:
        !          3023:     var element = document.createElement(tagName);
        !          3024:     var proto = element['__proto__'] || element.constructor.prototype;
        !          3025:     element = null;
        !          3026:     return proto;
        !          3027:   }
        !          3028:
        !          3029:   var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
        !          3030:    Element.prototype;
        !          3031:
        !          3032:   if (F.ElementExtensions) {
        !          3033:     copy(Element.Methods, elementPrototype);
        !          3034:     copy(Element.Methods.Simulated, elementPrototype, true);
        !          3035:   }
        !          3036:
        !          3037:   if (F.SpecificElementExtensions) {
        !          3038:     for (var tag in Element.Methods.ByTag) {
        !          3039:       var klass = findDOMClass(tag);
        !          3040:       if (Object.isUndefined(klass)) continue;
        !          3041:       copy(T[tag], klass.prototype);
        !          3042:     }
        !          3043:   }
        !          3044:
        !          3045:   Object.extend(Element, Element.Methods);
        !          3046:   delete Element.ByTag;
        !          3047:
        !          3048:   if (Element.extend.refresh) Element.extend.refresh();
        !          3049:   Element.cache = { };
        !          3050: };
        !          3051:
        !          3052:
        !          3053: document.viewport = {
        !          3054:
        !          3055:   getDimensions: function() {
        !          3056:     return { width: this.getWidth(), height: this.getHeight() };
        !          3057:   },
        !          3058:
        !          3059:   getScrollOffsets: function() {
        !          3060:     return Element._returnOffset(
        !          3061:       window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
        !          3062:       window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
        !          3063:   }
        !          3064: };
        !          3065:
        !          3066: (function(viewport) {
        !          3067:   var B = Prototype.Browser, doc = document, element, property = {};
        !          3068:
        !          3069:   function getRootElement() {
        !          3070:     if (B.WebKit && !doc.evaluate)
        !          3071:       return document;
        !          3072:
        !          3073:     if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
        !          3074:       return document.body;
        !          3075:
        !          3076:     return document.documentElement;
        !          3077:   }
        !          3078:
        !          3079:   function define(D) {
        !          3080:     if (!element) element = getRootElement();
        !          3081:
        !          3082:     property[D] = 'client' + D;
        !          3083:
        !          3084:     viewport['get' + D] = function() { return element[property[D]] };
        !          3085:     return viewport['get' + D]();
        !          3086:   }
        !          3087:
        !          3088:   viewport.getWidth  = define.curry('Width');
        !          3089:
        !          3090:   viewport.getHeight = define.curry('Height');
        !          3091: })(document.viewport);
        !          3092:
        !          3093:
        !          3094: Element.Storage = {
        !          3095:   UID: 1
        !          3096: };
        !          3097:
        !          3098: Element.addMethods({
        !          3099:   getStorage: function(element) {
        !          3100:     if (!(element = $(element))) return;
        !          3101:
        !          3102:     var uid;
        !          3103:     if (element === window) {
        !          3104:       uid = 0;
        !          3105:     } else {
        !          3106:       if (typeof element._prototypeUID === "undefined")
        !          3107:         element._prototypeUID = [Element.Storage.UID++];
        !          3108:       uid = element._prototypeUID[0];
        !          3109:     }
        !          3110:
        !          3111:     if (!Element.Storage[uid])
        !          3112:       Element.Storage[uid] = $H();
        !          3113:
        !          3114:     return Element.Storage[uid];
        !          3115:   },
        !          3116:
        !          3117:   store: function(element, key, value) {
        !          3118:     if (!(element = $(element))) return;
        !          3119:
        !          3120:     if (arguments.length === 2) {
        !          3121:       Element.getStorage(element).update(key);
        !          3122:     } else {
        !          3123:       Element.getStorage(element).set(key, value);
        !          3124:     }
        !          3125:
        !          3126:     return element;
        !          3127:   },
        !          3128:
        !          3129:   retrieve: function(element, key, defaultValue) {
        !          3130:     if (!(element = $(element))) return;
        !          3131:     var hash = Element.getStorage(element), value = hash.get(key);
        !          3132:
        !          3133:     if (Object.isUndefined(value)) {
        !          3134:       hash.set(key, defaultValue);
        !          3135:       value = defaultValue;
        !          3136:     }
        !          3137:
        !          3138:     return value;
        !          3139:   },
        !          3140:
        !          3141:   clone: function(element, deep) {
        !          3142:     if (!(element = $(element))) return;
        !          3143:     var clone = element.cloneNode(deep);
        !          3144:     clone._prototypeUID = void 0;
        !          3145:     if (deep) {
        !          3146:       var descendants = Element.select(clone, '*'),
        !          3147:           i = descendants.length;
        !          3148:       while (i--) {
        !          3149:         descendants[i]._prototypeUID = void 0;
        !          3150:       }
        !          3151:     }
        !          3152:     return Element.extend(clone);
        !          3153:   }
        !          3154: });
        !          3155: /* Portions of the Selector class are derived from Jack Slocum's DomQuery,
        !          3156:  * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
        !          3157:  * license.  Please see http://www.yui-ext.com/ for more information. */
        !          3158:
        !          3159: var Selector = Class.create({
        !          3160:   initialize: function(expression) {
        !          3161:     this.expression = expression.strip();
        !          3162:
        !          3163:     if (this.shouldUseSelectorsAPI()) {
        !          3164:       this.mode = 'selectorsAPI';
        !          3165:     } else if (this.shouldUseXPath()) {
        !          3166:       this.mode = 'xpath';
        !          3167:       this.compileXPathMatcher();
        !          3168:     } else {
        !          3169:       this.mode = "normal";
        !          3170:       this.compileMatcher();
        !          3171:     }
        !          3172:
        !          3173:   },
        !          3174:
        !          3175:   shouldUseXPath: (function() {
        !          3176:
        !          3177:     var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
        !          3178:       var isBuggy = false;
        !          3179:       if (document.evaluate && window.XPathResult) {
        !          3180:         var el = document.createElement('div');
        !          3181:         el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
        !          3182:
        !          3183:         var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
        !          3184:           "//*[local-name()='li' or local-name()='LI']";
        !          3185:
        !          3186:         var result = document.evaluate(xpath, el, null,
        !          3187:           XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
        !          3188:
        !          3189:         isBuggy = (result.snapshotLength !== 2);
        !          3190:         el = null;
        !          3191:       }
        !          3192:       return isBuggy;
        !          3193:     })();
        !          3194:
        !          3195:     return function() {
        !          3196:       if (!Prototype.BrowserFeatures.XPath) return false;
        !          3197:
        !          3198:       var e = this.expression;
        !          3199:
        !          3200:       if (Prototype.Browser.WebKit &&
        !          3201:        (e.include("-of-type") || e.include(":empty")))
        !          3202:         return false;
        !          3203:
        !          3204:       if ((/(\[[\w-]*?:|:checked)/).test(e))
        !          3205:         return false;
        !          3206:
        !          3207:       if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
        !          3208:
        !          3209:       return true;
        !          3210:     }
        !          3211:
        !          3212:   })(),
        !          3213:
        !          3214:   shouldUseSelectorsAPI: function() {
        !          3215:     if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
        !          3216:
        !          3217:     if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;
        !          3218:
        !          3219:     if (!Selector._div) Selector._div = new Element('div');
        !          3220:
        !          3221:     try {
        !          3222:       Selector._div.querySelector(this.expression);
        !          3223:     } catch(e) {
        !          3224:       return false;
        !          3225:     }
        !          3226:
        !          3227:     return true;
        !          3228:   },
        !          3229:
        !          3230:   compileMatcher: function() {
        !          3231:     var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        !          3232:         c = Selector.criteria, le, p, m, len = ps.length, name;
        !          3233:
        !          3234:     if (Selector._cache[e]) {
        !          3235:       this.matcher = Selector._cache[e];
        !          3236:       return;
        !          3237:     }
        !          3238:
        !          3239:     this.matcher = ["this.matcher = function(root) {",
        !          3240:                     "var r = root, h = Selector.handlers, c = false, n;"];
        !          3241:
        !          3242:     while (e && le != e && (/\S/).test(e)) {
        !          3243:       le = e;
        !          3244:       for (var i = 0; i<len; i++) {
        !          3245:         p = ps[i].re;
        !          3246:         name = ps[i].name;
        !          3247:         if (m = e.match(p)) {
        !          3248:           this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
        !          3249:             new Template(c[name]).evaluate(m));
        !          3250:           e = e.replace(m[0], '');
        !          3251:           break;
        !          3252:         }
        !          3253:       }
        !          3254:     }
        !          3255:
        !          3256:     this.matcher.push("return h.unique(n);\n}");
        !          3257:     eval(this.matcher.join('\n'));
        !          3258:     Selector._cache[this.expression] = this.matcher;
        !          3259:   },
        !          3260:
        !          3261:   compileXPathMatcher: function() {
        !          3262:     var e = this.expression, ps = Selector.patterns,
        !          3263:         x = Selector.xpath, le, m, len = ps.length, name;
        !          3264:
        !          3265:     if (Selector._cache[e]) {
        !          3266:       this.xpath = Selector._cache[e]; return;
        !          3267:     }
        !          3268:
        !          3269:     this.matcher = ['.//*'];
        !          3270:     while (e && le != e && (/\S/).test(e)) {
        !          3271:       le = e;
        !          3272:       for (var i = 0; i<len; i++) {
        !          3273:         name = ps[i].name;
        !          3274:         if (m = e.match(ps[i].re)) {
        !          3275:           this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
        !          3276:             new Template(x[name]).evaluate(m));
        !          3277:           e = e.replace(m[0], '');
        !          3278:           break;
        !          3279:         }
        !          3280:       }
        !          3281:     }
        !          3282:
        !          3283:     this.xpath = this.matcher.join('');
        !          3284:     Selector._cache[this.expression] = this.xpath;
        !          3285:   },
        !          3286:
        !          3287:   findElements: function(root) {
        !          3288:     root = root || document;
        !          3289:     var e = this.expression, results;
        !          3290:
        !          3291:     switch (this.mode) {
        !          3292:       case 'selectorsAPI':
        !          3293:         if (root !== document) {
        !          3294:           var oldId = root.id, id = $(root).identify();
        !          3295:           id = id.replace(/([\.:])/g, "\\$1");
        !          3296:           e = "#" + id + " " + e;
        !          3297:         }
        !          3298:
        !          3299:         results = $A(root.querySelectorAll(e)).map(Element.extend);
        !          3300:         root.id = oldId;
        !          3301:
        !          3302:         return results;
        !          3303:       case 'xpath':
        !          3304:         return document._getElementsByXPath(this.xpath, root);
        !          3305:       default:
        !          3306:        return this.matcher(root);
        !          3307:     }
        !          3308:   },
        !          3309:
        !          3310:   match: function(element) {
        !          3311:     this.tokens = [];
        !          3312:
        !          3313:     var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
        !          3314:     var le, p, m, len = ps.length, name;
        !          3315:
        !          3316:     while (e && le !== e && (/\S/).test(e)) {
        !          3317:       le = e;
        !          3318:       for (var i = 0; i<len; i++) {
        !          3319:         p = ps[i].re;
        !          3320:         name = ps[i].name;
        !          3321:         if (m = e.match(p)) {
        !          3322:           if (as[name]) {
        !          3323:             this.tokens.push([name, Object.clone(m)]);
        !          3324:             e = e.replace(m[0], '');
        !          3325:           } else {
        !          3326:             return this.findElements(document).include(element);
        !          3327:           }
        !          3328:         }
        !          3329:       }
        !          3330:     }
        !          3331:
        !          3332:     var match = true, name, matches;
        !          3333:     for (var i = 0, token; token = this.tokens[i]; i++) {
        !          3334:       name = token[0], matches = token[1];
        !          3335:       if (!Selector.assertions[name](element, matches)) {
        !          3336:         match = false; break;
        !          3337:       }
        !          3338:     }
        !          3339:
        !          3340:     return match;
        !          3341:   },
        !          3342:
        !          3343:   toString: function() {
        !          3344:     return this.expression;
        !          3345:   },
        !          3346:
        !          3347:   inspect: function() {
        !          3348:     return "#<Selector:" + this.expression.inspect() + ">";
        !          3349:   }
        !          3350: });
        !          3351:
        !          3352: if (Prototype.BrowserFeatures.SelectorsAPI &&
        !          3353:  document.compatMode === 'BackCompat') {
        !          3354:   Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
        !          3355:     var div = document.createElement('div'),
        !          3356:      span = document.createElement('span');
        !          3357:
        !          3358:     div.id = "prototype_test_id";
        !          3359:     span.className = 'Test';
        !          3360:     div.appendChild(span);
        !          3361:     var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
        !          3362:     div = span = null;
        !          3363:     return isIgnored;
        !          3364:   })();
        !          3365: }
        !          3366:
        !          3367: Object.extend(Selector, {
        !          3368:   _cache: { },
        !          3369:
        !          3370:   xpath: {
        !          3371:     descendant:   "//*",
        !          3372:     child:        "/*",
        !          3373:     adjacent:     "/following-sibling::*[1]",
        !          3374:     laterSibling: '/following-sibling::*',
        !          3375:     tagName:      function(m) {
        !          3376:       if (m[1] == '*') return '';
        !          3377:       return "[local-name()='" + m[1].toLowerCase() +
        !          3378:              "' or local-name()='" + m[1].toUpperCase() + "']";
        !          3379:     },
        !          3380:     className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
        !          3381:     id:           "[@id='#{1}']",
        !          3382:     attrPresence: function(m) {
        !          3383:       m[1] = m[1].toLowerCase();
        !          3384:       return new Template("[@#{1}]").evaluate(m);
        !          3385:     },
        !          3386:     attr: function(m) {
        !          3387:       m[1] = m[1].toLowerCase();
        !          3388:       m[3] = m[5] || m[6];
        !          3389:       return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
        !          3390:     },
        !          3391:     pseudo: function(m) {
        !          3392:       var h = Selector.xpath.pseudos[m[1]];
        !          3393:       if (!h) return '';
        !          3394:       if (Object.isFunction(h)) return h(m);
        !          3395:       return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
        !          3396:     },
        !          3397:     operators: {
        !          3398:       '=':  "[@#{1}='#{3}']",
        !          3399:       '!=': "[@#{1}!='#{3}']",
        !          3400:       '^=': "[starts-with(@#{1}, '#{3}')]",
        !          3401:       '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
        !          3402:       '*=': "[contains(@#{1}, '#{3}')]",
        !          3403:       '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
        !          3404:       '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
        !          3405:     },
        !          3406:     pseudos: {
        !          3407:       'first-child': '[not(preceding-sibling::*)]',
        !          3408:       'last-child':  '[not(following-sibling::*)]',
        !          3409:       'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
        !          3410:       'empty':       "[count(*) = 0 and (count(text()) = 0)]",
        !          3411:       'checked':     "[@checked]",
        !          3412:       'disabled':    "[(@disabled) and (@type!='hidden')]",
        !          3413:       'enabled':     "[not(@disabled) and (@type!='hidden')]",
        !          3414:       'not': function(m) {
        !          3415:         var e = m[6], p = Selector.patterns,
        !          3416:             x = Selector.xpath, le, v, len = p.length, name;
        !          3417:
        !          3418:         var exclusion = [];
        !          3419:         while (e && le != e && (/\S/).test(e)) {
        !          3420:           le = e;
        !          3421:           for (var i = 0; i<len; i++) {
        !          3422:             name = p[i].name
        !          3423:             if (m = e.match(p[i].re)) {
        !          3424:               v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
        !          3425:               exclusion.push("(" + v.substring(1, v.length - 1) + ")");
        !          3426:               e = e.replace(m[0], '');
        !          3427:               break;
        !          3428:             }
        !          3429:           }
        !          3430:         }
        !          3431:         return "[not(" + exclusion.join(" and ") + ")]";
        !          3432:       },
        !          3433:       'nth-child':      function(m) {
        !          3434:         return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
        !          3435:       },
        !          3436:       'nth-last-child': function(m) {
        !          3437:         return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
        !          3438:       },
        !          3439:       'nth-of-type':    function(m) {
        !          3440:         return Selector.xpath.pseudos.nth("position() ", m);
        !          3441:       },
        !          3442:       'nth-last-of-type': function(m) {
        !          3443:         return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
        !          3444:       },
        !          3445:       'first-of-type':  function(m) {
        !          3446:         m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
        !          3447:       },
        !          3448:       'last-of-type':   function(m) {
        !          3449:         m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
        !          3450:       },
        !          3451:       'only-of-type':   function(m) {
        !          3452:         var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
        !          3453:       },
        !          3454:       nth: function(fragment, m) {
        !          3455:         var mm, formula = m[6], predicate;
        !          3456:         if (formula == 'even') formula = '2n+0';
        !          3457:         if (formula == 'odd')  formula = '2n+1';
        !          3458:         if (mm = formula.match(/^(\d+)$/)) // digit only
        !          3459:           return '[' + fragment + "= " + mm[1] + ']';
        !          3460:         if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        !          3461:           if (mm[1] == "-") mm[1] = -1;
        !          3462:           var a = mm[1] ? Number(mm[1]) : 1;
        !          3463:           var b = mm[2] ? Number(mm[2]) : 0;
        !          3464:           predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
        !          3465:           "((#{fragment} - #{b}) div #{a} >= 0)]";
        !          3466:           return new Template(predicate).evaluate({
        !          3467:             fragment: fragment, a: a, b: b });
        !          3468:         }
        !          3469:       }
        !          3470:     }
        !          3471:   },
        !          3472:
        !          3473:   criteria: {
        !          3474:     tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
        !          3475:     className:    'n = h.className(n, r, "#{1}", c);    c = false;',
        !          3476:     id:           'n = h.id(n, r, "#{1}", c);           c = false;',
        !          3477:     attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
        !          3478:     attr: function(m) {
        !          3479:       m[3] = (m[5] || m[6]);
        !          3480:       return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
        !          3481:     },
        !          3482:     pseudo: function(m) {
        !          3483:       if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
        !          3484:       return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
        !          3485:     },
        !          3486:     descendant:   'c = "descendant";',
        !          3487:     child:        'c = "child";',
        !          3488:     adjacent:     'c = "adjacent";',
        !          3489:     laterSibling: 'c = "laterSibling";'
        !          3490:   },
        !          3491:
        !          3492:   patterns: [
        !          3493:     { name: 'laterSibling', re: /^\s*~\s*/ },
        !          3494:     { name: 'child',        re: /^\s*>\s*/ },
        !          3495:     { name: 'adjacent',     re: /^\s*\+\s*/ },
        !          3496:     { name: 'descendant',   re: /^\s/ },
        !          3497:
        !          3498:     { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
        !          3499:     { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ },
        !          3500:     { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ },
        !          3501:     { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
        !          3502:     { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
        !          3503:     { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
        !          3504:   ],
        !          3505:
        !          3506:   assertions: {
        !          3507:     tagName: function(element, matches) {
        !          3508:       return matches[1].toUpperCase() == element.tagName.toUpperCase();
        !          3509:     },
        !          3510:
        !          3511:     className: function(element, matches) {
        !          3512:       return Element.hasClassName(element, matches[1]);
        !          3513:     },
        !          3514:
        !          3515:     id: function(element, matches) {
        !          3516:       return element.id === matches[1];
        !          3517:     },
        !          3518:
        !          3519:     attrPresence: function(element, matches) {
        !          3520:       return Element.hasAttribute(element, matches[1]);
        !          3521:     },
        !          3522:
        !          3523:     attr: function(element, matches) {
        !          3524:       var nodeValue = Element.readAttribute(element, matches[1]);
        !          3525:       return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
        !          3526:     }
        !          3527:   },
        !          3528:
        !          3529:   handlers: {
        !          3530:     concat: function(a, b) {
        !          3531:       for (var i = 0, node; node = b[i]; i++)
        !          3532:         a.push(node);
        !          3533:       return a;
        !          3534:     },
        !          3535:
        !          3536:     mark: function(nodes) {
        !          3537:       var _true = Prototype.emptyFunction;
        !          3538:       for (var i = 0, node; node = nodes[i]; i++)
        !          3539:         node._countedByPrototype = _true;
        !          3540:       return nodes;
        !          3541:     },
        !          3542:
        !          3543:     unmark: (function(){
        !          3544:
        !          3545:       var PROPERTIES_ATTRIBUTES_MAP = (function(){
        !          3546:         var el = document.createElement('div'),
        !          3547:             isBuggy = false,
        !          3548:             propName = '_countedByPrototype',
        !          3549:             value = 'x'
        !          3550:         el[propName] = value;
        !          3551:         isBuggy = (el.getAttribute(propName) === value);
        !          3552:         el = null;
        !          3553:         return isBuggy;
        !          3554:       })();
        !          3555:
        !          3556:       return PROPERTIES_ATTRIBUTES_MAP ?
        !          3557:         function(nodes) {
        !          3558:           for (var i = 0, node; node = nodes[i]; i++)
        !          3559:             node.removeAttribute('_countedByPrototype');
        !          3560:           return nodes;
        !          3561:         } :
        !          3562:         function(nodes) {
        !          3563:           for (var i = 0, node; node = nodes[i]; i++)
        !          3564:             node._countedByPrototype = void 0;
        !          3565:           return nodes;
        !          3566:         }
        !          3567:     })(),
        !          3568:
        !          3569:     index: function(parentNode, reverse, ofType) {
        !          3570:       parentNode._countedByPrototype = Prototype.emptyFunction;
        !          3571:       if (reverse) {
        !          3572:         for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
        !          3573:           var node = nodes[i];
        !          3574:           if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
        !          3575:         }
        !          3576:       } else {
        !          3577:         for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
        !          3578:           if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
        !          3579:       }
        !          3580:     },
        !          3581:
        !          3582:     unique: function(nodes) {
        !          3583:       if (nodes.length == 0) return nodes;
        !          3584:       var results = [], n;
        !          3585:       for (var i = 0, l = nodes.length; i < l; i++)
        !          3586:         if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
        !          3587:           n._countedByPrototype = Prototype.emptyFunction;
        !          3588:           results.push(Element.extend(n));
        !          3589:         }
        !          3590:       return Selector.handlers.unmark(results);
        !          3591:     },
        !          3592:
        !          3593:     descendant: function(nodes) {
        !          3594:       var h = Selector.handlers;
        !          3595:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3596:         h.concat(results, node.getElementsByTagName('*'));
        !          3597:       return results;
        !          3598:     },
        !          3599:
        !          3600:     child: function(nodes) {
        !          3601:       var h = Selector.handlers;
        !          3602:       for (var i = 0, results = [], node; node = nodes[i]; i++) {
        !          3603:         for (var j = 0, child; child = node.childNodes[j]; j++)
        !          3604:           if (child.nodeType == 1 && child.tagName != '!') results.push(child);
        !          3605:       }
        !          3606:       return results;
        !          3607:     },
        !          3608:
        !          3609:     adjacent: function(nodes) {
        !          3610:       for (var i = 0, results = [], node; node = nodes[i]; i++) {
        !          3611:         var next = this.nextElementSibling(node);
        !          3612:         if (next) results.push(next);
        !          3613:       }
        !          3614:       return results;
        !          3615:     },
        !          3616:
        !          3617:     laterSibling: function(nodes) {
        !          3618:       var h = Selector.handlers;
        !          3619:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3620:         h.concat(results, Element.nextSiblings(node));
        !          3621:       return results;
        !          3622:     },
        !          3623:
        !          3624:     nextElementSibling: function(node) {
        !          3625:       while (node = node.nextSibling)
        !          3626:         if (node.nodeType == 1) return node;
        !          3627:       return null;
        !          3628:     },
        !          3629:
        !          3630:     previousElementSibling: function(node) {
        !          3631:       while (node = node.previousSibling)
        !          3632:         if (node.nodeType == 1) return node;
        !          3633:       return null;
        !          3634:     },
        !          3635:
        !          3636:     tagName: function(nodes, root, tagName, combinator) {
        !          3637:       var uTagName = tagName.toUpperCase();
        !          3638:       var results = [], h = Selector.handlers;
        !          3639:       if (nodes) {
        !          3640:         if (combinator) {
        !          3641:           if (combinator == "descendant") {
        !          3642:             for (var i = 0, node; node = nodes[i]; i++)
        !          3643:               h.concat(results, node.getElementsByTagName(tagName));
        !          3644:             return results;
        !          3645:           } else nodes = this[combinator](nodes);
        !          3646:           if (tagName == "*") return nodes;
        !          3647:         }
        !          3648:         for (var i = 0, node; node = nodes[i]; i++)
        !          3649:           if (node.tagName.toUpperCase() === uTagName) results.push(node);
        !          3650:         return results;
        !          3651:       } else return root.getElementsByTagName(tagName);
        !          3652:     },
        !          3653:
        !          3654:     id: function(nodes, root, id, combinator) {
        !          3655:       var targetNode = $(id), h = Selector.handlers;
        !          3656:
        !          3657:       if (root == document) {
        !          3658:         if (!targetNode) return [];
        !          3659:         if (!nodes) return [targetNode];
        !          3660:       } else {
        !          3661:         if (!root.sourceIndex || root.sourceIndex < 1) {
        !          3662:           var nodes = root.getElementsByTagName('*');
        !          3663:           for (var j = 0, node; node = nodes[j]; j++) {
        !          3664:             if (node.id === id) return [node];
        !          3665:           }
        !          3666:         }
        !          3667:       }
        !          3668:
        !          3669:       if (nodes) {
        !          3670:         if (combinator) {
        !          3671:           if (combinator == 'child') {
        !          3672:             for (var i = 0, node; node = nodes[i]; i++)
        !          3673:               if (targetNode.parentNode == node) return [targetNode];
        !          3674:           } else if (combinator == 'descendant') {
        !          3675:             for (var i = 0, node; node = nodes[i]; i++)
        !          3676:               if (Element.descendantOf(targetNode, node)) return [targetNode];
        !          3677:           } else if (combinator == 'adjacent') {
        !          3678:             for (var i = 0, node; node = nodes[i]; i++)
        !          3679:               if (Selector.handlers.previousElementSibling(targetNode) == node)
        !          3680:                 return [targetNode];
        !          3681:           } else nodes = h[combinator](nodes);
        !          3682:         }
        !          3683:         for (var i = 0, node; node = nodes[i]; i++)
        !          3684:           if (node == targetNode) return [targetNode];
        !          3685:         return [];
        !          3686:       }
        !          3687:       return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
        !          3688:     },
        !          3689:
        !          3690:     className: function(nodes, root, className, combinator) {
        !          3691:       if (nodes && combinator) nodes = this[combinator](nodes);
        !          3692:       return Selector.handlers.byClassName(nodes, root, className);
        !          3693:     },
        !          3694:
        !          3695:     byClassName: function(nodes, root, className) {
        !          3696:       if (!nodes) nodes = Selector.handlers.descendant([root]);
        !          3697:       var needle = ' ' + className + ' ';
        !          3698:       for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        !          3699:         nodeClassName = node.className;
        !          3700:         if (nodeClassName.length == 0) continue;
        !          3701:         if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
        !          3702:           results.push(node);
        !          3703:       }
        !          3704:       return results;
        !          3705:     },
        !          3706:
        !          3707:     attrPresence: function(nodes, root, attr, combinator) {
        !          3708:       if (!nodes) nodes = root.getElementsByTagName("*");
        !          3709:       if (nodes && combinator) nodes = this[combinator](nodes);
        !          3710:       var results = [];
        !          3711:       for (var i = 0, node; node = nodes[i]; i++)
        !          3712:         if (Element.hasAttribute(node, attr)) results.push(node);
        !          3713:       return results;
        !          3714:     },
        !          3715:
        !          3716:     attr: function(nodes, root, attr, value, operator, combinator) {
        !          3717:       if (!nodes) nodes = root.getElementsByTagName("*");
        !          3718:       if (nodes && combinator) nodes = this[combinator](nodes);
        !          3719:       var handler = Selector.operators[operator], results = [];
        !          3720:       for (var i = 0, node; node = nodes[i]; i++) {
        !          3721:         var nodeValue = Element.readAttribute(node, attr);
        !          3722:         if (nodeValue === null) continue;
        !          3723:         if (handler(nodeValue, value)) results.push(node);
        !          3724:       }
        !          3725:       return results;
        !          3726:     },
        !          3727:
        !          3728:     pseudo: function(nodes, name, value, root, combinator) {
        !          3729:       if (nodes && combinator) nodes = this[combinator](nodes);
        !          3730:       if (!nodes) nodes = root.getElementsByTagName("*");
        !          3731:       return Selector.pseudos[name](nodes, value, root);
        !          3732:     }
        !          3733:   },
        !          3734:
        !          3735:   pseudos: {
        !          3736:     'first-child': function(nodes, value, root) {
        !          3737:       for (var i = 0, results = [], node; node = nodes[i]; i++) {
        !          3738:         if (Selector.handlers.previousElementSibling(node)) continue;
        !          3739:           results.push(node);
        !          3740:       }
        !          3741:       return results;
        !          3742:     },
        !          3743:     'last-child': function(nodes, value, root) {
        !          3744:       for (var i = 0, results = [], node; node = nodes[i]; i++) {
        !          3745:         if (Selector.handlers.nextElementSibling(node)) continue;
        !          3746:           results.push(node);
        !          3747:       }
        !          3748:       return results;
        !          3749:     },
        !          3750:     'only-child': function(nodes, value, root) {
        !          3751:       var h = Selector.handlers;
        !          3752:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3753:         if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
        !          3754:           results.push(node);
        !          3755:       return results;
        !          3756:     },
        !          3757:     'nth-child':        function(nodes, formula, root) {
        !          3758:       return Selector.pseudos.nth(nodes, formula, root);
        !          3759:     },
        !          3760:     'nth-last-child':   function(nodes, formula, root) {
        !          3761:       return Selector.pseudos.nth(nodes, formula, root, true);
        !          3762:     },
        !          3763:     'nth-of-type':      function(nodes, formula, root) {
        !          3764:       return Selector.pseudos.nth(nodes, formula, root, false, true);
        !          3765:     },
        !          3766:     'nth-last-of-type': function(nodes, formula, root) {
        !          3767:       return Selector.pseudos.nth(nodes, formula, root, true, true);
        !          3768:     },
        !          3769:     'first-of-type':    function(nodes, formula, root) {
        !          3770:       return Selector.pseudos.nth(nodes, "1", root, false, true);
        !          3771:     },
        !          3772:     'last-of-type':     function(nodes, formula, root) {
        !          3773:       return Selector.pseudos.nth(nodes, "1", root, true, true);
        !          3774:     },
        !          3775:     'only-of-type':     function(nodes, formula, root) {
        !          3776:       var p = Selector.pseudos;
        !          3777:       return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
        !          3778:     },
        !          3779:
        !          3780:     getIndices: function(a, b, total) {
        !          3781:       if (a == 0) return b > 0 ? [b] : [];
        !          3782:       return $R(1, total).inject([], function(memo, i) {
        !          3783:         if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        !          3784:         return memo;
        !          3785:       });
        !          3786:     },
        !          3787:
        !          3788:     nth: function(nodes, formula, root, reverse, ofType) {
        !          3789:       if (nodes.length == 0) return [];
        !          3790:       if (formula == 'even') formula = '2n+0';
        !          3791:       if (formula == 'odd')  formula = '2n+1';
        !          3792:       var h = Selector.handlers, results = [], indexed = [], m;
        !          3793:       h.mark(nodes);
        !          3794:       for (var i = 0, node; node = nodes[i]; i++) {
        !          3795:         if (!node.parentNode._countedByPrototype) {
        !          3796:           h.index(node.parentNode, reverse, ofType);
        !          3797:           indexed.push(node.parentNode);
        !          3798:         }
        !          3799:       }
        !          3800:       if (formula.match(/^\d+$/)) { // just a number
        !          3801:         formula = Number(formula);
        !          3802:         for (var i = 0, node; node = nodes[i]; i++)
        !          3803:           if (node.nodeIndex == formula) results.push(node);
        !          3804:       } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        !          3805:         if (m[1] == "-") m[1] = -1;
        !          3806:         var a = m[1] ? Number(m[1]) : 1;
        !          3807:         var b = m[2] ? Number(m[2]) : 0;
        !          3808:         var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        !          3809:         for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
        !          3810:           for (var j = 0; j < l; j++)
        !          3811:             if (node.nodeIndex == indices[j]) results.push(node);
        !          3812:         }
        !          3813:       }
        !          3814:       h.unmark(nodes);
        !          3815:       h.unmark(indexed);
        !          3816:       return results;
        !          3817:     },
        !          3818:
        !          3819:     'empty': function(nodes, value, root) {
        !          3820:       for (var i = 0, results = [], node; node = nodes[i]; i++) {
        !          3821:         if (node.tagName == '!' || node.firstChild) continue;
        !          3822:         results.push(node);
        !          3823:       }
        !          3824:       return results;
        !          3825:     },
        !          3826:
        !          3827:     'not': function(nodes, selector, root) {
        !          3828:       var h = Selector.handlers, selectorType, m;
        !          3829:       var exclusions = new Selector(selector).findElements(root);
        !          3830:       h.mark(exclusions);
        !          3831:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3832:         if (!node._countedByPrototype) results.push(node);
        !          3833:       h.unmark(exclusions);
        !          3834:       return results;
        !          3835:     },
        !          3836:
        !          3837:     'enabled': function(nodes, value, root) {
        !          3838:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3839:         if (!node.disabled && (!node.type || node.type !== 'hidden'))
        !          3840:           results.push(node);
        !          3841:       return results;
        !          3842:     },
        !          3843:
        !          3844:     'disabled': function(nodes, value, root) {
        !          3845:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3846:         if (node.disabled) results.push(node);
        !          3847:       return results;
        !          3848:     },
        !          3849:
        !          3850:     'checked': function(nodes, value, root) {
        !          3851:       for (var i = 0, results = [], node; node = nodes[i]; i++)
        !          3852:         if (node.checked) results.push(node);
        !          3853:       return results;
        !          3854:     }
        !          3855:   },
        !          3856:
        !          3857:   operators: {
        !          3858:     '=':  function(nv, v) { return nv == v; },
        !          3859:     '!=': function(nv, v) { return nv != v; },
        !          3860:     '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
        !          3861:     '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
        !          3862:     '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
        !          3863:     '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
        !          3864:     '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
        !          3865:      '-').include('-' + (v || "").toUpperCase() + '-'); }
        !          3866:   },
        !          3867:
        !          3868:   split: function(expression) {
        !          3869:     var expressions = [];
        !          3870:     expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
        !          3871:       expressions.push(m[1].strip());
        !          3872:     });
        !          3873:     return expressions;
        !          3874:   },
        !          3875:
        !          3876:   matchElements: function(elements, expression) {
        !          3877:     var matches = $$(expression), h = Selector.handlers;
        !          3878:     h.mark(matches);
        !          3879:     for (var i = 0, results = [], element; element = elements[i]; i++)
        !          3880:       if (element._countedByPrototype) results.push(element);
        !          3881:     h.unmark(matches);
        !          3882:     return results;
        !          3883:   },
        !          3884:
        !          3885:   findElement: function(elements, expression, index) {
        !          3886:     if (Object.isNumber(expression)) {
        !          3887:       index = expression; expression = false;
        !          3888:     }
        !          3889:     return Selector.matchElements(elements, expression || '*')[index || 0];
        !          3890:   },
        !          3891:
        !          3892:   findChildElements: function(element, expressions) {
        !          3893:     expressions = Selector.split(expressions.join(','));
        !          3894:     var results = [], h = Selector.handlers;
        !          3895:     for (var i = 0, l = expressions.length, selector; i < l; i++) {
        !          3896:       selector = new Selector(expressions[i].strip());
        !          3897:       h.concat(results, selector.findElements(element));
        !          3898:     }
        !          3899:     return (l > 1) ? h.unique(results) : results;
        !          3900:   }
        !          3901: });
        !          3902:
        !          3903: if (Prototype.Browser.IE) {
        !          3904:   Object.extend(Selector.handlers, {
        !          3905:     concat: function(a, b) {
        !          3906:       for (var i = 0, node; node = b[i]; i++)
        !          3907:         if (node.tagName !== "!") a.push(node);
        !          3908:       return a;
        !          3909:     }
        !          3910:   });
        !          3911: }
        !          3912:
        !          3913: function $$() {
        !          3914:   return Selector.findChildElements(document, $A(arguments));
        !          3915: }
        !          3916:
        !          3917: var Form = {
        !          3918:   reset: function(form) {
        !          3919:     form = $(form);
        !          3920:     form.reset();
        !          3921:     return form;
        !          3922:   },
        !          3923:
        !          3924:   serializeElements: function(elements, options) {
        !          3925:     if (typeof options != 'object') options = { hash: !!options };
        !          3926:     else if (Object.isUndefined(options.hash)) options.hash = true;
        !          3927:     var key, value, submitted = false, submit = options.submit;
        !          3928:
        !          3929:     var data = elements.inject({ }, function(result, element) {
        !          3930:       if (!element.disabled && element.name) {
        !          3931:         key = element.name; value = $(element).getValue();
        !          3932:         if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
        !          3933:             submit !== false && (!submit || key == submit) && (submitted = true)))) {
        !          3934:           if (key in result) {
        !          3935:             if (!Object.isArray(result[key])) result[key] = [result[key]];
        !          3936:             result[key].push(value);
        !          3937:           }
        !          3938:           else result[key] = value;
        !          3939:         }
        !          3940:       }
        !          3941:       return result;
        !          3942:     });
        !          3943:
        !          3944:     return options.hash ? data : Object.toQueryString(data);
        !          3945:   }
        !          3946: };
        !          3947:
        !          3948: Form.Methods = {
        !          3949:   serialize: function(form, options) {
        !          3950:     return Form.serializeElements(Form.getElements(form), options);
        !          3951:   },
        !          3952:
        !          3953:   getElements: function(form) {
        !          3954:     var elements = $(form).getElementsByTagName('*'),
        !          3955:         element,
        !          3956:         arr = [ ],
        !          3957:         serializers = Form.Element.Serializers;
        !          3958:     for (var i = 0; element = elements[i]; i++) {
        !          3959:       arr.push(element);
        !          3960:     }
        !          3961:     return arr.inject([], function(elements, child) {
        !          3962:       if (serializers[child.tagName.toLowerCase()])
        !          3963:         elements.push(Element.extend(child));
        !          3964:       return elements;
        !          3965:     })
        !          3966:   },
        !          3967:
        !          3968:   getInputs: function(form, typeName, name) {
        !          3969:     form = $(form);
        !          3970:     var inputs = form.getElementsByTagName('input');
        !          3971:
        !          3972:     if (!typeName && !name) return $A(inputs).map(Element.extend);
        !          3973:
        !          3974:     for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
        !          3975:       var input = inputs[i];
        !          3976:       if ((typeName && input.type != typeName) || (name && input.name != name))
        !          3977:         continue;
        !          3978:       matchingInputs.push(Element.extend(input));
        !          3979:     }
        !          3980:
        !          3981:     return matchingInputs;
        !          3982:   },
        !          3983:
        !          3984:   disable: function(form) {
        !          3985:     form = $(form);
        !          3986:     Form.getElements(form).invoke('disable');
        !          3987:     return form;
        !          3988:   },
        !          3989:
        !          3990:   enable: function(form) {
        !          3991:     form = $(form);
        !          3992:     Form.getElements(form).invoke('enable');
        !          3993:     return form;
        !          3994:   },
        !          3995:
        !          3996:   findFirstElement: function(form) {
        !          3997:     var elements = $(form).getElements().findAll(function(element) {
        !          3998:       return 'hidden' != element.type && !element.disabled;
        !          3999:     });
        !          4000:     var firstByIndex = elements.findAll(function(element) {
        !          4001:       return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
        !          4002:     }).sortBy(function(element) { return element.tabIndex }).first();
        !          4003:
        !          4004:     return firstByIndex ? firstByIndex : elements.find(function(element) {
        !          4005:       return /^(?:input|select|textarea)$/i.test(element.tagName);
        !          4006:     });
        !          4007:   },
        !          4008:
        !          4009:   focusFirstElement: function(form) {
        !          4010:     form = $(form);
        !          4011:     form.findFirstElement().activate();
        !          4012:     return form;
        !          4013:   },
        !          4014:
        !          4015:   request: function(form, options) {
        !          4016:     form = $(form), options = Object.clone(options || { });
        !          4017:
        !          4018:     var params = options.parameters, action = form.readAttribute('action') || '';
        !          4019:     if (action.blank()) action = window.location.href;
        !          4020:     options.parameters = form.serialize(true);
        !          4021:
        !          4022:     if (params) {
        !          4023:       if (Object.isString(params)) params = params.toQueryParams();
        !          4024:       Object.extend(options.parameters, params);
        !          4025:     }
        !          4026:
        !          4027:     if (form.hasAttribute('method') && !options.method)
        !          4028:       options.method = form.method;
        !          4029:
        !          4030:     return new Ajax.Request(action, options);
        !          4031:   }
        !          4032: };
        !          4033:
        !          4034: /*--------------------------------------------------------------------------*/
        !          4035:
        !          4036:
        !          4037: Form.Element = {
        !          4038:   focus: function(element) {
        !          4039:     $(element).focus();
        !          4040:     return element;
        !          4041:   },
        !          4042:
        !          4043:   select: function(element) {
        !          4044:     $(element).select();
        !          4045:     return element;
        !          4046:   }
        !          4047: };
        !          4048:
        !          4049: Form.Element.Methods = {
        !          4050:
        !          4051:   serialize: function(element) {
        !          4052:     element = $(element);
        !          4053:     if (!element.disabled && element.name) {
        !          4054:       var value = element.getValue();
        !          4055:       if (value != undefined) {
        !          4056:         var pair = { };
        !          4057:         pair[element.name] = value;
        !          4058:         return Object.toQueryString(pair);
        !          4059:       }
        !          4060:     }
        !          4061:     return '';
        !          4062:   },
        !          4063:
        !          4064:   getValue: function(element) {
        !          4065:     element = $(element);
        !          4066:     var method = element.tagName.toLowerCase();
        !          4067:     return Form.Element.Serializers[method](element);
        !          4068:   },
        !          4069:
        !          4070:   setValue: function(element, value) {
        !          4071:     element = $(element);
        !          4072:     var method = element.tagName.toLowerCase();
        !          4073:     Form.Element.Serializers[method](element, value);
        !          4074:     return element;
        !          4075:   },
        !          4076:
        !          4077:   clear: function(element) {
        !          4078:     $(element).value = '';
        !          4079:     return element;
        !          4080:   },
        !          4081:
        !          4082:   present: function(element) {
        !          4083:     return $(element).value != '';
        !          4084:   },
        !          4085:
        !          4086:   activate: function(element) {
        !          4087:     element = $(element);
        !          4088:     try {
        !          4089:       element.focus();
        !          4090:       if (element.select && (element.tagName.toLowerCase() != 'input' ||
        !          4091:           !(/^(?:button|reset|submit)$/i.test(element.type))))
        !          4092:         element.select();
        !          4093:     } catch (e) { }
        !          4094:     return element;
        !          4095:   },
        !          4096:
        !          4097:   disable: function(element) {
        !          4098:     element = $(element);
        !          4099:     element.disabled = true;
        !          4100:     return element;
        !          4101:   },
        !          4102:
        !          4103:   enable: function(element) {
        !          4104:     element = $(element);
        !          4105:     element.disabled = false;
        !          4106:     return element;
        !          4107:   }
        !          4108: };
        !          4109:
        !          4110: /*--------------------------------------------------------------------------*/
        !          4111:
        !          4112: var Field = Form.Element;
        !          4113:
        !          4114: var $F = Form.Element.Methods.getValue;
        !          4115:
        !          4116: /*--------------------------------------------------------------------------*/
        !          4117:
        !          4118: Form.Element.Serializers = {
        !          4119:   input: function(element, value) {
        !          4120:     switch (element.type.toLowerCase()) {
        !          4121:       case 'checkbox':
        !          4122:       case 'radio':
        !          4123:         return Form.Element.Serializers.inputSelector(element, value);
        !          4124:       default:
        !          4125:         return Form.Element.Serializers.textarea(element, value);
        !          4126:     }
        !          4127:   },
        !          4128:
        !          4129:   inputSelector: function(element, value) {
        !          4130:     if (Object.isUndefined(value)) return element.checked ? element.value : null;
        !          4131:     else element.checked = !!value;
        !          4132:   },
        !          4133:
        !          4134:   textarea: function(element, value) {
        !          4135:     if (Object.isUndefined(value)) return element.value;
        !          4136:     else element.value = value;
        !          4137:   },
        !          4138:
        !          4139:   select: function(element, value) {
        !          4140:     if (Object.isUndefined(value))
        !          4141:       return this[element.type == 'select-one' ?
        !          4142:         'selectOne' : 'selectMany'](element);
        !          4143:     else {
        !          4144:       var opt, currentValue, single = !Object.isArray(value);
        !          4145:       for (var i = 0, length = element.length; i < length; i++) {
        !          4146:         opt = element.options[i];
        !          4147:         currentValue = this.optionValue(opt);
        !          4148:         if (single) {
        !          4149:           if (currentValue == value) {
        !          4150:             opt.selected = true;
        !          4151:             return;
        !          4152:           }
        !          4153:         }
        !          4154:         else opt.selected = value.include(currentValue);
        !          4155:       }
        !          4156:     }
        !          4157:   },
        !          4158:
        !          4159:   selectOne: function(element) {
        !          4160:     var index = element.selectedIndex;
        !          4161:     return index >= 0 ? this.optionValue(element.options[index]) : null;
        !          4162:   },
        !          4163:
        !          4164:   selectMany: function(element) {
        !          4165:     var values, length = element.length;
        !          4166:     if (!length) return null;
        !          4167:
        !          4168:     for (var i = 0, values = []; i < length; i++) {
        !          4169:       var opt = element.options[i];
        !          4170:       if (opt.selected) values.push(this.optionValue(opt));
        !          4171:     }
        !          4172:     return values;
        !          4173:   },
        !          4174:
        !          4175:   optionValue: function(opt) {
        !          4176:     return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
        !          4177:   }
        !          4178: };
        !          4179:
        !          4180: /*--------------------------------------------------------------------------*/
        !          4181:
        !          4182:
        !          4183: Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
        !          4184:   initialize: function($super, element, frequency, callback) {
        !          4185:     $super(callback, frequency);
        !          4186:     this.element   = $(element);
        !          4187:     this.lastValue = this.getValue();
        !          4188:   },
        !          4189:
        !          4190:   execute: function() {
        !          4191:     var value = this.getValue();
        !          4192:     if (Object.isString(this.lastValue) && Object.isString(value) ?
        !          4193:         this.lastValue != value : String(this.lastValue) != String(value)) {
        !          4194:       this.callback(this.element, value);
        !          4195:       this.lastValue = value;
        !          4196:     }
        !          4197:   }
        !          4198: });
        !          4199:
        !          4200: Form.Element.Observer = Class.create(Abstract.TimedObserver, {
        !          4201:   getValue: function() {
        !          4202:     return Form.Element.getValue(this.element);
        !          4203:   }
        !          4204: });
        !          4205:
        !          4206: Form.Observer = Class.create(Abstract.TimedObserver, {
        !          4207:   getValue: function() {
        !          4208:     return Form.serialize(this.element);
        !          4209:   }
        !          4210: });
        !          4211:
        !          4212: /*--------------------------------------------------------------------------*/
        !          4213:
        !          4214: Abstract.EventObserver = Class.create({
        !          4215:   initialize: function(element, callback) {
        !          4216:     this.element  = $(element);
        !          4217:     this.callback = callback;
        !          4218:
        !          4219:     this.lastValue = this.getValue();
        !          4220:     if (this.element.tagName.toLowerCase() == 'form')
        !          4221:       this.registerFormCallbacks();
        !          4222:     else
        !          4223:       this.registerCallback(this.element);
        !          4224:   },
        !          4225:
        !          4226:   onElementEvent: function() {
        !          4227:     var value = this.getValue();
        !          4228:     if (this.lastValue != value) {
        !          4229:       this.callback(this.element, value);
        !          4230:       this.lastValue = value;
        !          4231:     }
        !          4232:   },
        !          4233:
        !          4234:   registerFormCallbacks: function() {
        !          4235:     Form.getElements(this.element).each(this.registerCallback, this);
        !          4236:   },
        !          4237:
        !          4238:   registerCallback: function(element) {
        !          4239:     if (element.type) {
        !          4240:       switch (element.type.toLowerCase()) {
        !          4241:         case 'checkbox':
        !          4242:         case 'radio':
        !          4243:           Event.observe(element, 'click', this.onElementEvent.bind(this));
        !          4244:           break;
        !          4245:         default:
        !          4246:           Event.observe(element, 'change', this.onElementEvent.bind(this));
        !          4247:           break;
        !          4248:       }
        !          4249:     }
        !          4250:   }
        !          4251: });
        !          4252:
        !          4253: Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
        !          4254:   getValue: function() {
        !          4255:     return Form.Element.getValue(this.element);
        !          4256:   }
        !          4257: });
        !          4258:
        !          4259: Form.EventObserver = Class.create(Abstract.EventObserver, {
        !          4260:   getValue: function() {
        !          4261:     return Form.serialize(this.element);
        !          4262:   }
        !          4263: });
        !          4264: (function() {
        !          4265:
        !          4266:   var Event = {
        !          4267:     KEY_BACKSPACE: 8,
        !          4268:     KEY_TAB:       9,
        !          4269:     KEY_RETURN:   13,
        !          4270:     KEY_ESC:      27,
        !          4271:     KEY_LEFT:     37,
        !          4272:     KEY_UP:       38,
        !          4273:     KEY_RIGHT:    39,
        !          4274:     KEY_DOWN:     40,
        !          4275:     KEY_DELETE:   46,
        !          4276:     KEY_HOME:     36,
        !          4277:     KEY_END:      35,
        !          4278:     KEY_PAGEUP:   33,
        !          4279:     KEY_PAGEDOWN: 34,
        !          4280:     KEY_INSERT:   45,
        !          4281:
        !          4282:     cache: {}
        !          4283:   };
        !          4284:
        !          4285:   var docEl = document.documentElement;
        !          4286:   var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
        !          4287:     && 'onmouseleave' in docEl;
        !          4288:
        !          4289:   var _isButton;
        !          4290:   if (Prototype.Browser.IE) {
        !          4291:     var buttonMap = { 0: 1, 1: 4, 2: 2 };
        !          4292:     _isButton = function(event, code) {
        !          4293:       return event.button === buttonMap[code];
        !          4294:     };
        !          4295:   } else if (Prototype.Browser.WebKit) {
        !          4296:     _isButton = function(event, code) {
        !          4297:       switch (code) {
        !          4298:         case 0: return event.which == 1 && !event.metaKey;
        !          4299:         case 1: return event.which == 1 && event.metaKey;
        !          4300:         default: return false;
        !          4301:       }
        !          4302:     };
        !          4303:   } else {
        !          4304:     _isButton = function(event, code) {
        !          4305:       return event.which ? (event.which === code + 1) : (event.button === code);
        !          4306:     };
        !          4307:   }
        !          4308:
        !          4309:   function isLeftClick(event)   { return _isButton(event, 0) }
        !          4310:
        !          4311:   function isMiddleClick(event) { return _isButton(event, 1) }
        !          4312:
        !          4313:   function isRightClick(event)  { return _isButton(event, 2) }
        !          4314:
        !          4315:   function element(event) {
        !          4316:     event = Event.extend(event);
        !          4317:
        !          4318:     var node = event.target, type = event.type,
        !          4319:      currentTarget = event.currentTarget;
        !          4320:
        !          4321:     if (currentTarget && currentTarget.tagName) {
        !          4322:       if (type === 'load' || type === 'error' ||
        !          4323:         (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
        !          4324:           && currentTarget.type === 'radio'))
        !          4325:             node = currentTarget;
        !          4326:     }
        !          4327:
        !          4328:     if (node.nodeType == Node.TEXT_NODE)
        !          4329:       node = node.parentNode;
        !          4330:
        !          4331:     return Element.extend(node);
        !          4332:   }
        !          4333:
        !          4334:   function findElement(event, expression) {
        !          4335:     var element = Event.element(event);
        !          4336:     if (!expression) return element;
        !          4337:     var elements = [element].concat(element.ancestors());
        !          4338:     return Selector.findElement(elements, expression, 0);
        !          4339:   }
        !          4340:
        !          4341:   function pointer(event) {
        !          4342:     return { x: pointerX(event), y: pointerY(event) };
        !          4343:   }
        !          4344:
        !          4345:   function pointerX(event) {
        !          4346:     var docElement = document.documentElement,
        !          4347:      body = document.body || { scrollLeft: 0 };
        !          4348:
        !          4349:     return event.pageX || (event.clientX +
        !          4350:       (docElement.scrollLeft || body.scrollLeft) -
        !          4351:       (docElement.clientLeft || 0));
        !          4352:   }
        !          4353:
        !          4354:   function pointerY(event) {
        !          4355:     var docElement = document.documentElement,
        !          4356:      body = document.body || { scrollTop: 0 };
        !          4357:
        !          4358:     return  event.pageY || (event.clientY +
        !          4359:        (docElement.scrollTop || body.scrollTop) -
        !          4360:        (docElement.clientTop || 0));
        !          4361:   }
        !          4362:
        !          4363:
        !          4364:   function stop(event) {
        !          4365:     Event.extend(event);
        !          4366:     event.preventDefault();
        !          4367:     event.stopPropagation();
        !          4368:
        !          4369:     event.stopped = true;
        !          4370:   }
        !          4371:
        !          4372:   Event.Methods = {
        !          4373:     isLeftClick: isLeftClick,
        !          4374:     isMiddleClick: isMiddleClick,
        !          4375:     isRightClick: isRightClick,
        !          4376:
        !          4377:     element: element,
        !          4378:     findElement: findElement,
        !          4379:
        !          4380:     pointer: pointer,
        !          4381:     pointerX: pointerX,
        !          4382:     pointerY: pointerY,
        !          4383:
        !          4384:     stop: stop
        !          4385:   };
        !          4386:
        !          4387:
        !          4388:   var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
        !          4389:     m[name] = Event.Methods[name].methodize();
        !          4390:     return m;
        !          4391:   });
        !          4392:
        !          4393:   if (Prototype.Browser.IE) {
        !          4394:     function _relatedTarget(event) {
        !          4395:       var element;
        !          4396:       switch (event.type) {
        !          4397:         case 'mouseover': element = event.fromElement; break;
        !          4398:         case 'mouseout':  element = event.toElement;   break;
        !          4399:         default: return null;
        !          4400:       }
        !          4401:       return Element.extend(element);
        !          4402:     }
        !          4403:
        !          4404:     Object.extend(methods, {
        !          4405:       stopPropagation: function() { this.cancelBubble = true },
        !          4406:       preventDefault:  function() { this.returnValue = false },
        !          4407:       inspect: function() { return '[object Event]' }
        !          4408:     });
        !          4409:
        !          4410:     Event.extend = function(event, element) {
        !          4411:       if (!event) return false;
        !          4412:       if (event._extendedByPrototype) return event;
        !          4413:
        !          4414:       event._extendedByPrototype = Prototype.emptyFunction;
        !          4415:       var pointer = Event.pointer(event);
        !          4416:
        !          4417:       Object.extend(event, {
        !          4418:         target: event.srcElement || element,
        !          4419:         relatedTarget: _relatedTarget(event),
        !          4420:         pageX:  pointer.x,
        !          4421:         pageY:  pointer.y
        !          4422:       });
        !          4423:
        !          4424:       return Object.extend(event, methods);
        !          4425:     };
        !          4426:   } else {
        !          4427:     Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
        !          4428:     Object.extend(Event.prototype, methods);
        !          4429:     Event.extend = Prototype.K;
        !          4430:   }
        !          4431:
        !          4432:   function _createResponder(element, eventName, handler) {
        !          4433:     var registry = Element.retrieve(element, 'prototype_event_registry');
        !          4434:
        !          4435:     if (Object.isUndefined(registry)) {
        !          4436:       CACHE.push(element);
        !          4437:       registry = Element.retrieve(element, 'prototype_event_registry', $H());
        !          4438:     }
        !          4439:
        !          4440:     var respondersForEvent = registry.get(eventName);
        !          4441:     if (Object.isUndefined(respondersForEvent)) {
        !          4442:       respondersForEvent = [];
        !          4443:       registry.set(eventName, respondersForEvent);
        !          4444:     }
        !          4445:
        !          4446:     if (respondersForEvent.pluck('handler').include(handler)) return false;
        !          4447:
        !          4448:     var responder;
        !          4449:     if (eventName.include(":")) {
        !          4450:       responder = function(event) {
        !          4451:         if (Object.isUndefined(event.eventName))
        !          4452:           return false;
        !          4453:
        !          4454:         if (event.eventName !== eventName)
        !          4455:           return false;
        !          4456:
        !          4457:         Event.extend(event, element);
        !          4458:         handler.call(element, event);
        !          4459:       };
        !          4460:     } else {
        !          4461:       if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
        !          4462:        (eventName === "mouseenter" || eventName === "mouseleave")) {
        !          4463:         if (eventName === "mouseenter" || eventName === "mouseleave") {
        !          4464:           responder = function(event) {
        !          4465:             Event.extend(event, element);
        !          4466:
        !          4467:             var parent = event.relatedTarget;
        !          4468:             while (parent && parent !== element) {
        !          4469:               try { parent = parent.parentNode; }
        !          4470:               catch(e) { parent = element; }
        !          4471:             }
        !          4472:
        !          4473:             if (parent === element) return;
        !          4474:
        !          4475:             handler.call(element, event);
        !          4476:           };
        !          4477:         }
        !          4478:       } else {
        !          4479:         responder = function(event) {
        !          4480:           Event.extend(event, element);
        !          4481:           handler.call(element, event);
        !          4482:         };
        !          4483:       }
        !          4484:     }
        !          4485:
        !          4486:     responder.handler = handler;
        !          4487:     respondersForEvent.push(responder);
        !          4488:     return responder;
        !          4489:   }
        !          4490:
        !          4491:   function _destroyCache() {
        !          4492:     for (var i = 0, length = CACHE.length; i < length; i++) {
        !          4493:       Event.stopObserving(CACHE[i]);
        !          4494:       CACHE[i] = null;
        !          4495:     }
        !          4496:   }
        !          4497:
        !          4498:   var CACHE = [];
        !          4499:
        !          4500:   if (Prototype.Browser.IE)
        !          4501:     window.attachEvent('onunload', _destroyCache);
        !          4502:
        !          4503:   if (Prototype.Browser.WebKit)
        !          4504:     window.addEventListener('unload', Prototype.emptyFunction, false);
        !          4505:
        !          4506:
        !          4507:   var _getDOMEventName = Prototype.K;
        !          4508:
        !          4509:   if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
        !          4510:     _getDOMEventName = function(eventName) {
        !          4511:       var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
        !          4512:       return eventName in translations ? translations[eventName] : eventName;
        !          4513:     };
        !          4514:   }
        !          4515:
        !          4516:   function observe(element, eventName, handler) {
        !          4517:     element = $(element);
        !          4518:
        !          4519:     var responder = _createResponder(element, eventName, handler);
        !          4520:
        !          4521:     if (!responder) return element;
        !          4522:
        !          4523:     if (eventName.include(':')) {
        !          4524:       if (element.addEventListener)
        !          4525:         element.addEventListener("dataavailable", responder, false);
        !          4526:       else {
        !          4527:         element.attachEvent("ondataavailable", responder);
        !          4528:         element.attachEvent("onfilterchange", responder);
        !          4529:       }
        !          4530:     } else {
        !          4531:       var actualEventName = _getDOMEventName(eventName);
        !          4532:
        !          4533:       if (element.addEventListener)
        !          4534:         element.addEventListener(actualEventName, responder, false);
        !          4535:       else
        !          4536:         element.attachEvent("on" + actualEventName, responder);
        !          4537:     }
        !          4538:
        !          4539:     return element;
        !          4540:   }
        !          4541:
        !          4542:   function stopObserving(element, eventName, handler) {
        !          4543:     element = $(element);
        !          4544:
        !          4545:     var registry = Element.retrieve(element, 'prototype_event_registry');
        !          4546:
        !          4547:     if (Object.isUndefined(registry)) return element;
        !          4548:
        !          4549:     if (eventName && !handler) {
        !          4550:       var responders = registry.get(eventName);
        !          4551:
        !          4552:       if (Object.isUndefined(responders)) return element;
        !          4553:
        !          4554:       responders.each( function(r) {
        !          4555:         Element.stopObserving(element, eventName, r.handler);
        !          4556:       });
        !          4557:       return element;
        !          4558:     } else if (!eventName) {
        !          4559:       registry.each( function(pair) {
        !          4560:         var eventName = pair.key, responders = pair.value;
        !          4561:
        !          4562:         responders.each( function(r) {
        !          4563:           Element.stopObserving(element, eventName, r.handler);
        !          4564:         });
        !          4565:       });
        !          4566:       return element;
        !          4567:     }
        !          4568:
        !          4569:     var responders = registry.get(eventName);
        !          4570:
        !          4571:     if (!responders) return;
        !          4572:
        !          4573:     var responder = responders.find( function(r) { return r.handler === handler; });
        !          4574:     if (!responder) return element;
        !          4575:
        !          4576:     var actualEventName = _getDOMEventName(eventName);
        !          4577:
        !          4578:     if (eventName.include(':')) {
        !          4579:       if (element.removeEventListener)
        !          4580:         element.removeEventListener("dataavailable", responder, false);
        !          4581:       else {
        !          4582:         element.detachEvent("ondataavailable", responder);
        !          4583:         element.detachEvent("onfilterchange",  responder);
        !          4584:       }
        !          4585:     } else {
        !          4586:       if (element.removeEventListener)
        !          4587:         element.removeEventListener(actualEventName, responder, false);
        !          4588:       else
        !          4589:         element.detachEvent('on' + actualEventName, responder);
        !          4590:     }
        !          4591:
        !          4592:     registry.set(eventName, responders.without(responder));
        !          4593:
        !          4594:     return element;
        !          4595:   }
        !          4596:
        !          4597:   function fire(element, eventName, memo, bubble) {
        !          4598:     element = $(element);
        !          4599:
        !          4600:     if (Object.isUndefined(bubble))
        !          4601:       bubble = true;
        !          4602:
        !          4603:     if (element == document && document.createEvent && !element.dispatchEvent)
        !          4604:       element = document.documentElement;
        !          4605:
        !          4606:     var event;
        !          4607:     if (document.createEvent) {
        !          4608:       event = document.createEvent('HTMLEvents');
        !          4609:       event.initEvent('dataavailable', true, true);
        !          4610:     } else {
        !          4611:       event = document.createEventObject();
        !          4612:       event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
        !          4613:     }
        !          4614:
        !          4615:     event.eventName = eventName;
        !          4616:     event.memo = memo || { };
        !          4617:
        !          4618:     if (document.createEvent)
        !          4619:       element.dispatchEvent(event);
        !          4620:     else
        !          4621:       element.fireEvent(event.eventType, event);
        !          4622:
        !          4623:     return Event.extend(event);
        !          4624:   }
        !          4625:
        !          4626:
        !          4627:   Object.extend(Event, Event.Methods);
        !          4628:
        !          4629:   Object.extend(Event, {
        !          4630:     fire:          fire,
        !          4631:     observe:       observe,
        !          4632:     stopObserving: stopObserving
        !          4633:   });
        !          4634:
        !          4635:   Element.addMethods({
        !          4636:     fire:          fire,
        !          4637:
        !          4638:     observe:       observe,
        !          4639:
        !          4640:     stopObserving: stopObserving
        !          4641:   });
        !          4642:
        !          4643:   Object.extend(document, {
        !          4644:     fire:          fire.methodize(),
        !          4645:
        !          4646:     observe:       observe.methodize(),
        !          4647:
        !          4648:     stopObserving: stopObserving.methodize(),
        !          4649:
        !          4650:     loaded:        false
        !          4651:   });
        !          4652:
        !          4653:   if (window.Event) Object.extend(window.Event, Event);
        !          4654:   else window.Event = Event;
        !          4655: })();
        !          4656:
        !          4657: (function() {
        !          4658:   /* Support for the DOMContentLoaded event is based on work by Dan Webb,
        !          4659:      Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
        !          4660:
        !          4661:   var timer;
        !          4662:
        !          4663:   function fireContentLoadedEvent() {
        !          4664:     if (document.loaded) return;
        !          4665:     if (timer) window.clearTimeout(timer);
        !          4666:     document.loaded = true;
        !          4667:     document.fire('dom:loaded');
        !          4668:   }
        !          4669:
        !          4670:   function checkReadyState() {
        !          4671:     if (document.readyState === 'complete') {
        !          4672:       document.stopObserving('readystatechange', checkReadyState);
        !          4673:       fireContentLoadedEvent();
        !          4674:     }
        !          4675:   }
        !          4676:
        !          4677:   function pollDoScroll() {
        !          4678:     try { document.documentElement.doScroll('left'); }
        !          4679:     catch(e) {
        !          4680:       timer = pollDoScroll.defer();
        !          4681:       return;
        !          4682:     }
        !          4683:     fireContentLoadedEvent();
        !          4684:   }
        !          4685:
        !          4686:   if (document.addEventListener) {
        !          4687:     document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
        !          4688:   } else {
        !          4689:     document.observe('readystatechange', checkReadyState);
        !          4690:     if (window == top)
        !          4691:       timer = pollDoScroll.defer();
        !          4692:   }
        !          4693:
        !          4694:   Event.observe(window, 'load', fireContentLoadedEvent);
        !          4695: })();
        !          4696:
        !          4697: Element.addMethods();
        !          4698:
        !          4699: /*------------------------------- DEPRECATED -------------------------------*/
        !          4700:
        !          4701: Hash.toQueryString = Object.toQueryString;
        !          4702:
        !          4703: var Toggle = { display: Element.toggle };
        !          4704:
        !          4705: Element.Methods.childOf = Element.Methods.descendantOf;
        !          4706:
        !          4707: var Insertion = {
        !          4708:   Before: function(element, content) {
        !          4709:     return Element.insert(element, {before:content});
        !          4710:   },
        !          4711:
        !          4712:   Top: function(element, content) {
        !          4713:     return Element.insert(element, {top:content});
        !          4714:   },
        !          4715:
        !          4716:   Bottom: function(element, content) {
        !          4717:     return Element.insert(element, {bottom:content});
        !          4718:   },
        !          4719:
        !          4720:   After: function(element, content) {
        !          4721:     return Element.insert(element, {after:content});
        !          4722:   }
        !          4723: };
        !          4724:
        !          4725: var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
        !          4726:
        !          4727: var Position = {
        !          4728:   includeScrollOffsets: false,
        !          4729:
        !          4730:   prepare: function() {
        !          4731:     this.deltaX =  window.pageXOffset
        !          4732:                 || document.documentElement.scrollLeft
        !          4733:                 || document.body.scrollLeft
        !          4734:                 || 0;
        !          4735:     this.deltaY =  window.pageYOffset
        !          4736:                 || document.documentElement.scrollTop
        !          4737:                 || document.body.scrollTop
        !          4738:                 || 0;
        !          4739:   },
        !          4740:
        !          4741:   within: function(element, x, y) {
        !          4742:     if (this.includeScrollOffsets)
        !          4743:       return this.withinIncludingScrolloffsets(element, x, y);
        !          4744:     this.xcomp = x;
        !          4745:     this.ycomp = y;
        !          4746:     this.offset = Element.cumulativeOffset(element);
        !          4747:
        !          4748:     return (y >= this.offset[1] &&
        !          4749:             y <  this.offset[1] + element.offsetHeight &&
        !          4750:             x >= this.offset[0] &&
        !          4751:             x <  this.offset[0] + element.offsetWidth);
        !          4752:   },
        !          4753:
        !          4754:   withinIncludingScrolloffsets: function(element, x, y) {
        !          4755:     var offsetcache = Element.cumulativeScrollOffset(element);
        !          4756:
        !          4757:     this.xcomp = x + offsetcache[0] - this.deltaX;
        !          4758:     this.ycomp = y + offsetcache[1] - this.deltaY;
        !          4759:     this.offset = Element.cumulativeOffset(element);
        !          4760:
        !          4761:     return (this.ycomp >= this.offset[1] &&
        !          4762:             this.ycomp <  this.offset[1] + element.offsetHeight &&
        !          4763:             this.xcomp >= this.offset[0] &&
        !          4764:             this.xcomp <  this.offset[0] + element.offsetWidth);
        !          4765:   },
        !          4766:
        !          4767:   overlap: function(mode, element) {
        !          4768:     if (!mode) return 0;
        !          4769:     if (mode == 'vertical')
        !          4770:       return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        !          4771:         element.offsetHeight;
        !          4772:     if (mode == 'horizontal')
        !          4773:       return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        !          4774:         element.offsetWidth;
        !          4775:   },
        !          4776:
        !          4777:
        !          4778:   cumulativeOffset: Element.Methods.cumulativeOffset,
        !          4779:
        !          4780:   positionedOffset: Element.Methods.positionedOffset,
        !          4781:
        !          4782:   absolutize: function(element) {
        !          4783:     Position.prepare();
        !          4784:     return Element.absolutize(element);
        !          4785:   },
        !          4786:
        !          4787:   relativize: function(element) {
        !          4788:     Position.prepare();
        !          4789:     return Element.relativize(element);
        !          4790:   },
        !          4791:
        !          4792:   realOffset: Element.Methods.cumulativeScrollOffset,
        !          4793:
        !          4794:   offsetParent: Element.Methods.getOffsetParent,
        !          4795:
        !          4796:   page: Element.Methods.viewportOffset,
        !          4797:
        !          4798:   clone: function(source, target, options) {
        !          4799:     options = options || { };
        !          4800:     return Element.clonePosition(target, source, options);
        !          4801:   }
        !          4802: };
        !          4803:
        !          4804: /*--------------------------------------------------------------------------*/
        !          4805:
        !          4806: if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
        !          4807:   function iter(name) {
        !          4808:     return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
        !          4809:   }
        !          4810:
        !          4811:   instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
        !          4812:   function(element, className) {
        !          4813:     className = className.toString().strip();
        !          4814:     var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
        !          4815:     return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
        !          4816:   } : function(element, className) {
        !          4817:     className = className.toString().strip();
        !          4818:     var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
        !          4819:     if (!classNames && !className) return elements;
        !          4820:
        !          4821:     var nodes = $(element).getElementsByTagName('*');
        !          4822:     className = ' ' + className + ' ';
        !          4823:
        !          4824:     for (var i = 0, child, cn; child = nodes[i]; i++) {
        !          4825:       if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
        !          4826:           (classNames && classNames.all(function(name) {
        !          4827:             return !name.toString().blank() && cn.include(' ' + name + ' ');
        !          4828:           }))))
        !          4829:         elements.push(Element.extend(child));
        !          4830:     }
        !          4831:     return elements;
        !          4832:   };
        !          4833:
        !          4834:   return function(className, parentElement) {
        !          4835:     return $(parentElement || document.body).getElementsByClassName(className);
        !          4836:   };
        !          4837: }(Element.Methods);
        !          4838:
        !          4839: /*--------------------------------------------------------------------------*/
        !          4840:
        !          4841: Element.ClassNames = Class.create();
        !          4842: Element.ClassNames.prototype = {
        !          4843:   initialize: function(element) {
        !          4844:     this.element = $(element);
        !          4845:   },
        !          4846:
        !          4847:   _each: function(iterator) {
        !          4848:     this.element.className.split(/\s+/).select(function(name) {
        !          4849:       return name.length > 0;
        !          4850:     })._each(iterator);
        !          4851:   },
        !          4852:
        !          4853:   set: function(className) {
        !          4854:     this.element.className = className;
        !          4855:   },
        !          4856:
        !          4857:   add: function(classNameToAdd) {
        !          4858:     if (this.include(classNameToAdd)) return;
        !          4859:     this.set($A(this).concat(classNameToAdd).join(' '));
        !          4860:   },
        !          4861:
        !          4862:   remove: function(classNameToRemove) {
        !          4863:     if (!this.include(classNameToRemove)) return;
        !          4864:     this.set($A(this).without(classNameToRemove).join(' '));
        !          4865:   },
        !          4866:
        !          4867:   toString: function() {
        !          4868:     return $A(this).join(' ');
        !          4869:   }
        !          4870: };
        !          4871:
        !          4872: Object.extend(Element.ClassNames.prototype, Enumerable);
        !          4873:
        !          4874: /*--------------------------------------------------------------------------*/

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>