PageSourceSearch

https://japanstep.jp/_administrator/js/slibs.js

js japanstep.jp collected 2026-10-02 10:59:52 UTC 263,298 bytes, 10,216 lines download raw bytes

1/* Prototype JavaScript framework, version 1.7.1
2 * (c) 2005-2010 Sam Stephenson
3 * Prototype is freely distributable under the terms of an MIT-style license.
4 * For details, see the Prototype web site: http://www.prototypejs.org/
5 *--------------------------------------------------------------------------*/
6
7var Prototype = {
8
9 Version: '1.7.1',
10
11 Browser: (function(){
12 var ua = navigator.userAgent;
13 var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
14 return {
15 IE: !!window.attachEvent && !isOpera,
16 Opera: isOpera,
17 WebKit: ua.indexOf('AppleWebKit/') > -1,
18 Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
19 MobileSafari: /Apple.*Mobile/.test(ua)
20 }
21 })(),
22
23 BrowserFeatures: {
24 XPath: !!document.evaluate,
25
26 SelectorsAPI: !!document.querySelector,
27
28 ElementExtensions: (function() {
29 var constructor = window.Element || window.HTMLElement;
30 return !!(constructor && constructor.prototype);
31 })(),
32 SpecificElementExtensions: (function() {
33 if (typeof window.HTMLDivElement !== 'undefined')
34 return true;
35
36 var div = document.createElement('div'),
37 form = document.createElement('form'),
38 isSupported = false;
39
40 if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
41 isSupported = true;
42 }
43
44 div = form = null;
45
46 return isSupported;
47 })()
48 },
49
50 ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script\\s*>',
51 JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
52
53 emptyFunction: function() { },
54
55 K: function(x) { return x }
56};
57
58if (Prototype.Browser.MobileSafari)
59 Prototype.BrowserFeatures.SpecificElementExtensions = false;
60/* Based on Alex Arnell's inheritance implementation. */
61
62var Class = (function() {
63
64 var IS_DONTENUM_BUGGY = (function(){
65 for (var p in { toString: 1 }) {
66 if (p === 'toString') return false;
67 }
68 return true;
69 })();
70
71 function subclass() {};
72 function create() {
73 var parent = null, properties = $A(arguments);
74 if (Object.isFunction(properties[0]))
75 parent = properties.shift();
76
77 function klass() {
78 this.initialize.apply(this, arguments);
79 }
80
81 Object.extend(klass, Class.Methods);
82 klass.superclass = parent;
83 klass.subclasses = [];
84
85 if (parent) {
86 subclass.prototype = parent.prototype;
87 klass.prototype = new subclass;
88 parent.subclasses.push(klass);
89 }
90
91 for (var i = 0, length = properties.length; i < length; i++)
92 klass.addMethods(properties[i]);
93
94 if (!klass.prototype.initialize)
95 klass.prototype.initialize = Prototype.emptyFunction;
96
97 klass.prototype.constructor = klass;
98 return klass;
99 }
100
101 function addMethods(source) {
102 var ancestor = this.superclass && this.superclass.prototype,
103 properties = Object.keys(source);
104
105 if (IS_DONTENUM_BUGGY) {
106 if (source.toString != Object.prototype.toString)
107 properties.push("toString");
108 if (source.valueOf != Object.prototype.valueOf)
109 properties.push("valueOf");
110 }
111
112 for (var i = 0, length = properties.length; i < length; i++) {
113 var property = properties[i], value = source[property];
114 if (ancestor && Object.isFunction(value) &&
115 value.argumentNames()[0] == "$super") {
116 var method = value;
117 value = (function(m) {
118 return function() { return ancestor[m].apply(this, arguments); };
119 })(property).wrap(method);
120
121 value.valueOf = (function(method) {
122 return function() { return method.valueOf.call(method); };
123 })(method);
124
125 value.toString = (function(method) {
126 return function() { return method.toString.call(method); };
127 })(method);
128 }
129 this.prototype[property] = value;
130 }
131
132 return this;
133 }
134
135 return {
136 create: create,
137 Methods: {
138 addMethods: addMethods
139 }
140 };
141})();
142(function() {
143
144 var _toString = Object.prototype.toString,
145 _hasOwnProperty = Object.prototype.hasOwnProperty,
146 NULL_TYPE = 'Null',
147 UNDEFINED_TYPE = 'Undefined',
148 BOOLEAN_TYPE = 'Boolean',
149 NUMBER_TYPE = 'Number',
150 STRING_TYPE = 'String',
151 OBJECT_TYPE = 'Object',
152 FUNCTION_CLASS = '[object Function]',
153 BOOLEAN_CLASS = '[object Boolean]',
154 NUMBER_CLASS = '[object Number]',
155 STRING_CLASS = '[object String]',
156 ARRAY_CLASS = '[object Array]',
157 DATE_CLASS = '[object Date]',
158 NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
159 typeof JSON.stringify === 'function' &&
160 JSON.stringify(0) === '0' &&
161 typeof JSON.stringify(Prototype.K) === 'undefined';
162
163
164
165 var DONT_ENUMS = ['toString', 'toLocaleString', 'valueOf',
166 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'];
167
168 var IS_DONTENUM_BUGGY = (function(){
169 for (var p in { toString: 1 }) {
170 if (p === 'toString') return false;
171 }
172 return true;
173 })();
174
175 function Type(o) {
176 switch(o) {
177 case null: return NULL_TYPE;
178 case (void 0): return UNDEFINED_TYPE;
179 }
180 var type = typeof o;
181 switch(type) {
182 case 'boolean': return BOOLEAN_TYPE;
183 case 'number': return NUMBER_TYPE;
184 case 'string': return STRING_TYPE;
185 }
186 return OBJECT_TYPE;
187 }
188
189 function extend(destination, source) {
190 for (var property in source)
191 destination[property] = source[property];
192 return destination;
193 }
194
195 function inspect(object) {
196 try {
197 if (isUndefined(object)) return 'undefined';
198 if (object === null) return 'null';
199 return object.inspect ? object.inspect() : String(object);
200 } catch (e) {
201 if (e instanceof RangeError) return '...';
202 throw e;
203 }
204 }
205
206 function toJSON(value) {
207 return Str('', { '': value }, []);
208 }
209
210 function Str(key, holder, stack) {
211 var value = holder[key];
212 if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
213 value = value.toJSON(key);
214 }
215
216 var _class = _toString.call(value);
217
218 switch (_class) {
219 case NUMBER_CLASS:
220 case BOOLEAN_CLASS:
221 case STRING_CLASS:
222 value = value.valueOf();
223 }
224
225 switch (value) {
226 case null: return 'null';
227 case true: return 'true';
228 case false: return 'false';
229 }
230
231 var type = typeof value;
232 switch (type) {
233 case 'string':
234 return value.inspect(true);
235 case 'number':
236 return isFinite(value) ? String(value) : 'null';
237 case 'object':
238
239 for (var i = 0, length = stack.length; i < length; i++) {
240 if (stack[i] === value) {
241 throw new TypeError("Cyclic reference to '" + value + "' in object");
242 }
243 }
244 stack.push(value);
245
246 var partial = [];
247 if (_class === ARRAY_CLASS) {
248 for (var i = 0, length = value.length; i < length; i++) {
249 var str = Str(i, value, stack);
250 partial.push(typeof str === 'undefined' ? 'null' : str);
251 }
252 partial = '[' + partial.join(',') + ']';
253 } else {
254 var keys = Object.keys(value);
255 for (var i = 0, length = keys.length; i < length; i++) {
256 var key = keys[i], str = Str(key, value, stack);
257 if (typeof str !== "undefined") {
258 partial.push(key.inspect(true)+ ':' + str);
259 }
260 }
261 partial = '{' + partial.join(',') + '}';
262 }
263 stack.pop();
264 return partial;
265 }
266 }
267
268 function stringify(object) {
269 return JSON.stringify(object);
270 }
271
272 function toQueryString(object) {
273 return $H(object).toQueryString();
274 }
275
276 function toHTML(object) {
277 return object && object.toHTML ? object.toHTML() : String.interpret(object);
278 }
279
280 function keys(object) {
281 if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
282 var results = [];
283 for (var property in object) {
284 if (_hasOwnProperty.call(object, property))
285 results.push(property);
286 }
287
288 if (IS_DONTENUM_BUGGY) {
289 for (var i = 0; property = DONT_ENUMS[i]; i++) {
290 if (_hasOwnProperty.call(object, property))
291 results.push(property);
292 }
293 }
294
295 return results;
296 }
297
298 function values(object) {
299 var results = [];
300 for (var property in object)
301 results.push(object[property]);
302 return results;
303 }
304
305 function clone(object) {
306 return extend({ }, object);
307 }
308
309 function isElement(object) {
310 return !!(object && object.nodeType == 1);
311 }
312
313 function isArray(object) {
314 return _toString.call(object) === ARRAY_CLASS;
315 }
316
317 var hasNativeIsArray = (typeof Array.isArray == 'function')
318 && Array.isArray([]) && !Array.isArray({});
319
320 if (hasNativeIsArray) {
321 isArray = Array.isArray;
322 }
323
324 function isHash(object) {
325 return object instanceof Hash;
326 }
327
328 function isFunction(object) {
329 return _toString.call(object) === FUNCTION_CLASS;
330 }
331
332 function isString(object) {
333 return _toString.call(object) === STRING_CLASS;
334 }
335
336 function isNumber(object) {
337 return _toString.call(object) === NUMBER_CLASS;
338 }
339
340 function isDate(object) {
341 return _toString.call(object) === DATE_CLASS;
342 }
343
344 function isUndefined(object) {
345 return typeof object === "undefined";
346 }
347
348 extend(Object, {
349 extend: extend,
350 inspect: inspect,
351 toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
352 toQueryString: toQueryString,
353 toHTML: toHTML,
354 keys: Object.keys || keys,
355 values: values,
356 clone: clone,
357 isElement: isElement,
358 isArray: isArray,
359 isHash: isHash,
360 isFunction: isFunction,
361 isString: isString,
362 isNumber: isNumber,
363 isDate: isDate,
364 isUndefined: isUndefined
365 });
366})();
367Object.extend(Function.prototype, (function() {
368 var slice = Array.prototype.slice;
369
370 function update(array, args) {
371 var arrayLength = array.length, length = args.length;
372 while (length--) array[arrayLength + length] = args[length];
373 return array;
374 }
375
376 function merge(array, args) {
377 array = slice.call(array, 0);
378 return update(array, args);
379 }
380
381 function argumentNames() {
382 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
383 .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
384 .replace(/\s+/g, '').split(',');
385 return names.length == 1 && !names[0] ? [] : names;
386 }
387
388
389 function bind(context) {
390 if (arguments.length < 2 && Object.isUndefined(arguments[0]))
391 return this;
392
393 if (!Object.isFunction(this))
394 throw new TypeError("The object is not callable.");
395
396 var nop = function() {};
397 var __method = this, args = slice.call(arguments, 1);
398
399 var bound = function() {
400 var a = merge(args, arguments), c = context;
401 var c = this instanceof bound ? this : context;
402 return __method.apply(c, a);
403 };
404
405 nop.prototype = this.prototype;
406 bound.prototype = new nop();
407
408 return bound;
409 }
410
411 function bindAsEventListener(context) {
412 var __method = this, args = slice.call(arguments, 1);
413 return function(event) {
414 var a = update([event || window.event], args);
415 return __method.apply(context, a);
416 }
417 }
418
419 function curry() {
420 if (!arguments.length) return this;
421 var __method = this, args = slice.call(arguments, 0);
422 return function() {
423 var a = merge(args, arguments);
424 return __method.apply(this, a);
425 }
426 }
427
428 function delay(timeout) {
429 var __method = this, args = slice.call(arguments, 1);
430 timeout = timeout * 1000;
431 return window.setTimeout(function() {
432 return __method.apply(__method, args);
433 }, timeout);
434 }
435
436 function defer() {
437 var args = update([0.01], arguments);
438 return this.delay.apply(this, args);
439 }
440
441 function wrap(wrapper) {
442 var __method = this;
443 return function() {
444 var a = update([__method.bind(this)], arguments);
445 return wrapper.apply(this, a);
446 }
447 }
448
449 function methodize() {
450 if (this._methodized) return this._methodized;
451 var __method = this;
452 return this._methodized = function() {
453 var a = update([this], arguments);
454 return __method.apply(null, a);
455 };
456 }
457
458 var extensions = {
459 argumentNames: argumentNames,
460 bindAsEventListener: bindAsEventListener,
461 curry: curry,
462 delay: delay,
463 defer: defer,
464 wrap: wrap,
465 methodize: methodize
466 };
467
468 if (!Function.prototype.bind)
469 extensions.bind = bind;
470
471 return extensions;
472})());
473
474
475
476(function(proto) {
477
478
479 function toISOString() {
480 return this.getUTCFullYear() + '-' +
481 (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
482 this.getUTCDate().toPaddedString(2) + 'T' +
483 this.getUTCHours().toPaddedString(2) + ':' +
484 this.getUTCMinutes().toPaddedString(2) + ':' +
485 this.getUTCSeconds().toPaddedString(2) + 'Z';
486 }
487
488
489 function toJSON() {
490 return this.toISOString();
491 }
492
493 if (!proto.toISOString) proto.toISOString = toISOString;
494 if (!proto.toJSON) proto.toJSON = toJSON;
495
496})(Date.prototype);
497
498
499RegExp.prototype.match = RegExp.prototype.test;
500
501RegExp.escape = function(str) {
502 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
503};
504var PeriodicalExecuter = Class.create({
505 initialize: function(callback, frequency) {
506 this.callback = callback;
507 this.frequency = frequency;
508 this.currentlyExecuting = false;
509
510 this.registerCallback();
511 },
512
513 registerCallback: function() {
514 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
515 },
516
517 execute: function() {
518 this.callback(this);
519 },
520
521 stop: function() {
522 if (!this.timer) return;
523 clearInterval(this.timer);
524 this.timer = null;
525 },
526
527 onTimerEvent: function() {
528 if (!this.currentlyExecuting) {
529 try {
530 this.currentlyExecuting = true;
531 this.execute();
532 this.currentlyExecuting = false;
533 } catch(e) {
534 this.currentlyExecuting = false;
535 throw e;
536 }
537 }
538 }
539});
540Object.extend(String, {
541 interpret: function(value) {
542 return value == null ? '' : String(value);
543 },
544 specialChar: {
545 '\b': '\\b',
546 '\t': '\\t',
547 '\n': '\\n',
548 '\f': '\\f',
549 '\r': '\\r',
550 '\\': '\\\\'
551 }
552});
553
554Object.extend(String.prototype, (function() {
555 var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
556 typeof JSON.parse === 'function' &&
557 JSON.parse('{"test": true}').test;
558
559 function prepareReplacement(replacement) {
560 if (Object.isFunction(replacement)) return replacement;
561 var template = new Template(replacement);
562 return function(match) { return template.evaluate(match) };
563 }
564
565 function gsub(pattern, replacement) {
566 var result = '', source = this, match;
567 replacement = prepareReplacement(replacement);
568
569 if (Object.isString(pattern))
570 pattern = RegExp.escape(pattern);
571
572 if (!(pattern.length || pattern.source)) {
573 replacement = replacement('');
574 return replacement + source.split('').join(replacement) + replacement;
575 }
576
577 while (source.length > 0) {
578 if (match = source.match(pattern)) {
579 result += source.slice(0, match.index);
580 result += String.interpret(replacement(match));
581 source = source.slice(match.index + match[0].length);
582 } else {
583 result += source, source = '';
584 }
585 }
586 return result;
587 }
588
589 function sub(pattern, replacement, count) {
590 replacement = prepareReplacement(replacement);
591 count = Object.isUndefined(count) ? 1 : count;
592
593 return this.gsub(pattern, function(match) {
594 if (--count < 0) return match[0];
595 return replacement(match);
596 });
597 }
598
599 function scan(pattern, iterator) {
600 this.gsub(pattern, iterator);
601 return String(this);
602 }
603
604 function truncate(length, truncation) {
605 length = length || 30;
606 truncation = Object.isUndefined(truncation) ? '...' : truncation;
607 return this.length > length ?
608 this.slice(0, length - truncation.length) + truncation : String(this);
609 }
610
611 function strip() {
612 return this.replace(/^\s+/, '').replace(/\s+$/, '');
613 }
614
615 function stripTags() {
616 return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
617 }
618
619 function stripScripts() {
620 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
621 }
622
623 function extractScripts() {
624 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
625 matchOne = new RegExp(Prototype.ScriptFragment, 'im');
626 return (this.match(matchAll) || []).map(function(scriptTag) {
627 return (scriptTag.match(matchOne) || ['', ''])[1];
628 });
629 }
630
631 function evalScripts() {
632 return this.extractScripts().map(function(script) { return eval(script); });
633 }
634
635 function escapeHTML() {
636 return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
637 }
638
639 function unescapeHTML() {
640 return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
641 }
642
643
644 function toQueryParams(separator) {
645 var match = this.strip().match(/([^?#]*)(#.*)?$/);
646 if (!match) return { };
647
648 return match[1].split(separator || '&').inject({ }, function(hash, pair) {
649 if ((pair = pair.split('='))[0]) {
650 var key = decodeURIComponent(pair.shift()),
651 value = pair.length > 1 ? pair.join('=') : pair[0];
652
653 if (value != undefined) value = decodeURIComponent(value);
654
655 if (key in hash) {
656 if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
657 hash[key].push(value);
658 }
659 else hash[key] = value;
660 }
661 return hash;
662 });
663 }
664
665 function toArray() {
666 return this.split('');
667 }
668
669 function succ() {
670 return this.slice(0, this.length - 1) +
671 String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
672 }
673
674 function times(count) {
675 return count < 1 ? '' : new Array(count + 1).join(this);
676 }
677
678 function camelize() {
679 return this.replace(/-+(.)?/g, function(match, chr) {
680 return chr ? chr.toUpperCase() : '';
681 });
682 }
683
684 function capitalize() {
685 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
686 }
687
688 function underscore() {
689 return this.replace(/::/g, '/')
690 .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
691 .replace(/([a-z\d])([A-Z])/g, '$1_$2')
692 .replace(/-/g, '_')
693 .toLowerCase();
694 }
695
696 function dasherize() {
697 return this.replace(/_/g, '-');
698 }
699
700 function inspect(useDoubleQuotes) {
701 var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
702 if (character in String.specialChar) {
703 return String.specialChar[character];
704 }
705 return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
706 });
707 if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
708 return "'" + escapedString.replace(/'/g, '\\\'') + "'";
709 }
710
711 function unfilterJSON(filter) {
712 return this.replace(filter || Prototype.JSONFilter, '$1');
713 }
714
715 function isJSON() {
716 var str = this;
717 if (str.blank()) return false;
718 str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
719 str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
720 str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
721 return (/^[\],:{}\s]*$/).test(str);
722 }
723
724 function evalJSON(sanitize) {
725 var json = this.unfilterJSON(),
726 cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
727 if (cx.test(json)) {
728 json = json.replace(cx, function (a) {
729 return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
730 });
731 }
732 try {
733 if (!sanitize || json.isJSON()) return eval('(' + json + ')');
734 } catch (e) { }
735 throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
736 }
737
738 function parseJSON() {
739 var json = this.unfilterJSON();
740 return JSON.parse(json);
741 }
742
743 function include(pattern) {
744 return this.indexOf(pattern) > -1;
745 }
746
747 function startsWith(pattern) {
748 return this.lastIndexOf(pattern, 0) === 0;
749 }
750
751 function endsWith(pattern) {
752 var d = this.length - pattern.length;
753 return d >= 0 && this.indexOf(pattern, d) === d;
754 }
755
756 function empty() {
757 return this == '';
758 }
759
760 function blank() {
761 return /^\s*$/.test(this);
762 }
763
764 function interpolate(object, pattern) {
765 return new Template(this, pattern).evaluate(object);
766 }
767
768 return {
769 gsub: gsub,
770 sub: sub,
771 scan: scan,
772 truncate: truncate,
773 strip: String.prototype.trim || strip,
774 stripTags: stripTags,
775 stripScripts: stripScripts,
776 extractScripts: extractScripts,
777 evalScripts: evalScripts,
778 escapeHTML: escapeHTML,
779 unescapeHTML: unescapeHTML,
780 toQueryParams: toQueryParams,
781 parseQuery: toQueryParams,
782 toArray: toArray,
783 succ: succ,
784 times: times,
785 camelize: camelize,
786 capitalize: capitalize,
787 underscore: underscore,
788 dasherize: dasherize,
789 inspect: inspect,
790 unfilterJSON: unfilterJSON,
791 isJSON: isJSON,
792 evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
793 include: include,
794 startsWith: startsWith,
795 endsWith: endsWith,
796 empty: empty,
797 blank: blank,
798 interpolate: interpolate
799 };
800})());
801
802var Template = Class.create({
803 initialize: function(template, pattern) {
804 this.template = template.toString();
805 this.pattern = pattern || Template.Pattern;
806 },
807
808 evaluate: function(object) {
809 if (object && Object.isFunction(object.toTemplateReplacements))
810 object = object.toTemplateReplacements();
811
812 return this.template.gsub(this.pattern, function(match) {
813 if (object == null) return (match[1] + '');
814
815 var before = match[1] || '';
816 if (before == '\\') return match[2];
817
818 var ctx = object, expr = match[3],
819 pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
820
821 match = pattern.exec(expr);
822 if (match == null) return before;
823
824 while (match != null) {
825 var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
826 ctx = ctx[comp];
827 if (null == ctx || '' == match[3]) break;
828 expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
829 match = pattern.exec(expr);
830 }
831
832 return before + String.interpret(ctx);
833 });
834 }
835});
836Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
837
838var $break = { };
839
840var Enumerable = (function() {
841 function each(iterator, context) {
842 try {
843 this._each(iterator, context);
844 } catch (e) {
845 if (e != $break) throw e;
846 }
847 return this;
848 }
849
850 function eachSlice(number, iterator, context) {
851 var index = -number, slices = [], array = this.toArray();
852 if (number < 1) return array;
853 while ((index += number) < array.length)
854 slices.push(array.slice(index, index+number));
855 return slices.collect(iterator, context);
856 }
857
858 function all(iterator, context) {
859 iterator = iterator || Prototype.K;
860 var result = true;
861 this.each(function(value, index) {
862 result = result && !!iterator.call(context, value, index, this);
863 if (!result) throw $break;
864 }, this);
865 return result;
866 }
867
868 function any(iterator, context) {
869 iterator = iterator || Prototype.K;
870 var result = false;
871 this.each(function(value, index) {
872 if (result = !!iterator.call(context, value, index, this))
873 throw $break;
874 }, this);
875 return result;
876 }
877
878 function collect(iterator, context) {
879 iterator = iterator || Prototype.K;
880 var results = [];
881 this.each(function(value, index) {
882 results.push(iterator.call(context, value, index, this));
883 }, this);
884 return results;
885 }
886
887 function detect(iterator, context) {
888 var result;
889 this.each(function(value, index) {
890 if (iterator.call(context, value, index, this)) {
891 result = value;
892 throw $break;
893 }
894 }, this);
895 return result;
896 }
897
898 function findAll(iterator, context) {
899 var results = [];
900 this.each(function(value, index) {
901 if (iterator.call(context, value, index, this))
902 results.push(value);
903 }, this);
904 return results;
905 }
906
907 function grep(filter, iterator, context) {
908 iterator = iterator || Prototype.K;
909 var results = [];
910
911 if (Object.isString(filter))
912 filter = new RegExp(RegExp.escape(filter));
913
914 this.each(function(value, index) {
915 if (filter.match(value))
916 results.push(iterator.call(context, value, index, this));
917 }, this);
918 return results;
919 }
920
921 function include(object) {
922 if (Object.isFunction(this.indexOf))
923 if (this.indexOf(object) != -1) return true;
924
925 var found = false;
926 this.each(function(value) {
927 if (value == object) {
928 found = true;
929 throw $break;
930 }
931 });
932 return found;
933 }
934
935 function inGroupsOf(number, fillWith) {
936 fillWith = Object.isUndefined(fillWith) ? null : fillWith;
937 return this.eachSlice(number, function(slice) {
938 while(slice.length < number) slice.push(fillWith);
939 return slice;
940 });
941 }
942
943 function inject(memo, iterator, context) {
944 this.each(function(value, index) {
945 memo = iterator.call(context, memo, value, index, this);
946 }, this);
947 return memo;
948 }
949
950 function invoke(method) {
951 var args = $A(arguments).slice(1);
952 return this.map(function(value) {
953 return value[method].apply(value, args);
954 });
955 }
956
957 function max(iterator, context) {
958 iterator = iterator || Prototype.K;
959 var result;
960 this.each(function(value, index) {
961 value = iterator.call(context, value, index, this);
962 if (result == null || value >= result)
963 result = value;
964 }, this);
965 return result;
966 }
967
968 function min(iterator, context) {
969 iterator = iterator || Prototype.K;
970 var result;
971 this.each(function(value, index) {
972 value = iterator.call(context, value, index, this);
973 if (result == null || value < result)
974 result = value;
975 }, this);
976 return result;
977 }
978
979 function partition(iterator, context) {
980 iterator = iterator || Prototype.K;
981 var trues = [], falses = [];
982 this.each(function(value, index) {
983 (iterator.call(context, value, index, this) ?
984 trues : falses).push(value);
985 }, this);
986 return [trues, falses];
987 }
988
989 function pluck(property) {
990 var results = [];
991 this.each(function(value) {
992 results.push(value[property]);
993 });
994 return results;
995 }
996
997 function reject(iterator, context) {
998 var results = [];
999 this.each(function(value, index) {
1000 if (!iterator.call(context, value, index, this))
1001 results.push(value);
1002 }, this);
1003 return results;
1004 }
1005
1006 function sortBy(iterator, context) {
1007 return this.map(function(value, index) {
1008 return {
1009 value: value,
1010 criteria: iterator.call(context, value, index, this)
1011 };
1012 }, this).sort(function(left, right) {
1013 var a = left.criteria, b = right.criteria;
1014 return a < b ? -1 : a > b ? 1 : 0;
1015 }).pluck('value');
1016 }
1017
1018 function toArray() {
1019 return this.map();
1020 }
1021
1022 function zip() {
1023 var iterator = Prototype.K, args = $A(arguments);
1024 if (Object.isFunction(args.last()))
1025 iterator = args.pop();
1026
1027 var collections = [this].concat(args).map($A);
1028 return this.map(function(value, index) {
1029 return iterator(collections.pluck(index));
1030 });
1031 }
1032
1033 function size() {
1034 return this.toArray().length;
1035 }
1036
1037 function inspect() {
1038 return '#<Enumerable:' + this.toArray().inspect() + '>';
1039 }
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 return {
1050 each: each,
1051 eachSlice: eachSlice,
1052 all: all,
1053 every: all,
1054 any: any,
1055 some: any,
1056 collect: collect,
1057 map: collect,
1058 detect: detect,
1059 findAll: findAll,
1060 select: findAll,
1061 filter: findAll,
1062 grep: grep,
1063 include: include,
1064 member: include,
1065 inGroupsOf: inGroupsOf,
1066 inject: inject,
1067 invoke: invoke,
1068 max: max,
1069 min: min,
1070 partition: partition,
1071 pluck: pluck,
1072 reject: reject,
1073 sortBy: sortBy,
1074 toArray: toArray,
1075 entries: toArray,
1076 zip: zip,
1077 size: size,
1078 inspect: inspect,
1079 find: detect
1080 };
1081})();
1082
1083function $A(iterable) {
1084 if (!iterable) return [];
1085 if ('toArray' in Object(iterable)) return iterable.toArray();
1086 var length = iterable.length || 0, results = new Array(length);
1087 while (length--) results[length] = iterable[length];
1088 return results;
1089}
1090
1091
1092function $w(string) {
1093 if (!Object.isString(string)) return [];
1094 string = string.strip();
1095 return string ? string.split(/\s+/) : [];
1096}
1097
1098const orgArrayFrom = Array.from;
1099Array.from = $A;
1100
1101(function() {
1102 var arrayProto = Array.prototype,
1103 slice = arrayProto.slice,
1104 _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
1105
1106 function each(iterator, context) {
1107 for (var i = 0, length = this.length >>> 0; i < length; i++) {
1108 if (i in this) iterator.call(context, this[i], i, this);
1109 }
1110 }
1111 if (!_each) _each = each;
1112
1113 function clear() {
1114 this.length = 0;
1115 return this;
1116 }
1117
1118 function first() {
1119 return this[0];
1120 }
1121
1122 function last() {
1123 return this[this.length - 1];
1124 }
1125
1126 function compact() {
1127 return this.select(function(value) {
1128 return value != null;
1129 });
1130 }
1131
1132 function flatten() {
1133 return this.inject([], function(array, value) {
1134 if (Object.isArray(value))
1135 return array.concat(value.flatten());
1136 array.push(value);
1137 return array;
1138 });
1139 }
1140
1141 function without() {
1142 var values = slice.call(arguments, 0);
1143 return this.select(function(value) {
1144 return !values.include(value);
1145 });
1146 }
1147
1148 function reverse(inline) {
1149 return (inline === false ? this.toArray() : this)._reverse();
1150 }
1151
1152 function uniq(sorted) {
1153 return this.inject([], function(array, value, index) {
1154 if (0 == index || (sorted ? array.last() != value : !array.include(value)))
1155 array.push(value);
1156 return array;
1157 });
1158 }
1159
1160 function intersect(array) {
1161 return this.uniq().findAll(function(item) {
1162 return array.indexOf(item) !== -1;
1163 });
1164 }
1165
1166
1167 function clone() {
1168 return slice.call(this, 0);
1169 }
1170
1171 function size() {
1172 return this.length;
1173 }
1174
1175 function inspect() {
1176 return '[' + this.map(Object.inspect).join(', ') + ']';
1177 }
1178
1179 function indexOf(item, i) {
1180 if (this == null) throw new TypeError();
1181
1182 var array = Object(this), length = array.length >>> 0;
1183 if (length === 0) return -1;
1184
1185 i = Number(i);
1186 if (isNaN(i)) {
1187 i = 0;
1188 } else if (i !== 0 && isFinite(i)) {
1189 i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i));
1190 }
1191
1192 if (i > length) return -1;
1193
1194 var k = i >= 0 ? i : Math.max(length - Math.abs(i), 0);
1195 for (; k < length; k++)
1196 if (k in array && array[k] === item) return k;
1197 return -1;
1198 }
1199
1200
1201 function lastIndexOf(item, i) {
1202 if (this == null) throw new TypeError();
1203
1204 var array = Object(this), length = array.length >>> 0;
1205 if (length === 0) return -1;
1206
1207 if (!Object.isUndefined(i)) {
1208 i = Number(i);
1209 if (isNaN(i)) {
1210 i = 0;
1211 } else if (i !== 0 && isFinite(i)) {
1212 i = (i > 0 ? 1 : -1) * Math.floor(Math.abs(i));
1213 }
1214 } else {
1215 i = length;
1216 }
1217
1218 var k = i >= 0 ? Math.min(i, length - 1) :
1219 length - Math.abs(i);
1220
1221 for (; k >= 0; k--)
1222 if (k in array && array[k] === item) return k;
1223 return -1;
1224 }
1225
1226 function concat(_) {
1227 var array = [], items = slice.call(arguments, 0), item, n = 0;
1228 items.unshift(this);
1229 for (var i = 0, length = items.length; i < length; i++) {
1230 item = items[i];
1231 if (Object.isArray(item) && !('callee' in item)) {
1232 for (var j = 0, arrayLength = item.length; j < arrayLength; j++) {
1233 if (j in item) array[n] = item[j];
1234 n++;
1235 }
1236 } else {
1237 array[n++] = item;
1238 }
1239 }
1240 array.length = n;
1241 return array;
1242 }
1243
1244
1245 function wrapNative(method) {
1246 return function() {
1247 if (arguments.length === 0) {
1248 return method.call(this, Prototype.K);
1249 } else if (arguments[0] === undefined) {
1250 var args = slice.call(arguments, 1);
1251 args.unshift(Prototype.K);
1252 return method.apply(this, args);
1253 } else {
1254 return method.apply(this, arguments);
1255 }
1256 };
1257 }
1258
1259
1260 function map(iterator) {
1261 if (this == null) throw new TypeError();
1262 iterator = iterator || Prototype.K;
1263
1264 var object = Object(this);
1265 var results = [], context = arguments[1], n = 0;
1266
1267 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1268 if (i in object) {
1269 results[n] = iterator.call(context, object[i], i, object);
1270 }
1271 n++;
1272 }
1273 results.length = n;
1274 return results;
1275 }
1276
1277 if (arrayProto.map) {
1278 map = wrapNative(Array.prototype.map);
1279 }
1280
1281 function filter(iterator) {
1282 if (this == null || !Object.isFunction(iterator))
1283 throw new TypeError();
1284
1285 var object = Object(this);
1286 var results = [], context = arguments[1], value;
1287
1288 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1289 if (i in object) {
1290 value = object[i];
1291 if (iterator.call(context, value, i, object)) {
1292 results.push(value);
1293 }
1294 }
1295 }
1296 return results;
1297 }
1298
1299 if (arrayProto.filter) {
1300 filter = Array.prototype.filter;
1301 }
1302
1303 function some(iterator) {
1304 if (this == null) throw new TypeError();
1305 iterator = iterator || Prototype.K;
1306 var context = arguments[1];
1307
1308 var object = Object(this);
1309 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1310 if (i in object && iterator.call(context, object[i], i, object)) {
1311 return true;
1312 }
1313 }
1314
1315 return false;
1316 }
1317
1318 if (arrayProto.some) {
1319 var some = wrapNative(Array.prototype.some);
1320 }
1321
1322
1323 function every(iterator) {
1324 if (this == null) throw new TypeError();
1325 iterator = iterator || Prototype.K;
1326 var context = arguments[1];
1327
1328 var object = Object(this);
1329 for (var i = 0, length = object.length >>> 0; i < length; i++) {
1330 if (i in object && !iterator.call(context, object[i], i, object)) {
1331 return false;
1332 }
1333 }
1334
1335 return true;
1336 }
1337
1338 if (arrayProto.every) {
1339 var every = wrapNative(Array.prototype.every);
1340 }
1341
1342 var _reduce = arrayProto.reduce;
1343 function inject(memo, iterator) {
1344 iterator = iterator || Prototype.K;
1345 var context = arguments[2];
1346 return _reduce.call(this, iterator.bind(context), memo);
1347 }
1348
1349 if (!arrayProto.reduce) {
1350 var inject = Enumerable.inject;
1351 }
1352
1353 Object.extend(arrayProto, Enumerable);
1354
1355 if (!arrayProto._reverse)
1356 arrayProto._reverse = arrayProto.reverse;
1357
1358 Object.extend(arrayProto, {
1359 _each: _each,
1360
1361 map: map,
1362 collect: map,
1363 select: filter,
1364 filter: filter,
1365 findAll: filter,
1366 some: some,
1367 any: some,
1368 every: every,
1369 all: every,
1370 inject: inject,
1371
1372 clear: clear,
1373 first: first,
1374 last: last,
1375 compact: compact,
1376 flatten: flatten,
1377 without: without,
1378 reverse: reverse,
1379 uniq: uniq,
1380 intersect: intersect,
1381 clone: clone,
1382 toArray: clone,
1383 size: size,
1384 inspect: inspect
1385 });
1386
1387 var CONCAT_ARGUMENTS_BUGGY = (function() {
1388 return [].concat(arguments)[0][0] !== 1;
1389 })(1,2);
1390
1391 if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
1392
1393 if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
1394 if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
1395})();
1396function $H(object) {
1397 return new Hash(object);
1398};
1399
1400var Hash = Class.create(Enumerable, (function() {
1401 function initialize(object) {
1402 this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1403 }
1404
1405
1406 function _each(iterator, context) {
1407 for (var key in this._object) {
1408 var value = this._object[key], pair = [key, value];
1409 pair.key = key;
1410 pair.value = value;
1411 iterator.call(context, pair);
1412 }
1413 }
1414
1415 function set(key, value) {
1416 return this._object[key] = value;
1417 }
1418
1419 function get(key) {
1420 if (this._object[key] !== Object.prototype[key])
1421 return this._object[key];
1422 }
1423
1424 function unset(key) {
1425 var value = this._object[key];
1426 delete this._object[key];
1427 return value;
1428 }
1429
1430 function toObject() {
1431 return Object.clone(this._object);
1432 }
1433
1434
1435
1436 function keys() {
1437 return this.pluck('key');
1438 }
1439
1440 function values() {
1441 return this.pluck('value');
1442 }
1443
1444 function index(value) {
1445 var match = this.detect(function(pair) {
1446 return pair.value === value;
1447 });
1448 return match && match.key;
1449 }
1450
1451 function merge(object) {
1452 return this.clone().update(object);
1453 }
1454
1455 function update(object) {
1456 return new Hash(object).inject(this, function(result, pair) {
1457 result.set(pair.key, pair.value);
1458 return result;
1459 });
1460 }
1461
1462 function toQueryPair(key, value) {
1463 if (Object.isUndefined(value)) return key;
1464
1465 var value = String.interpret(value);
1466
1467 value = value.gsub(/(\r)?\n/, '\r\n');
1468 value = encodeURIComponent(value);
1469 value = value.gsub(/%20/, '+');
1470 return key + '=' + value;
1471 }
1472
1473 function toQueryString() {
1474 return this.inject([], function(results, pair) {
1475 var key = encodeURIComponent(pair.key), values = pair.value;
1476
1477 if (values && typeof values == 'object') {
1478 if (Object.isArray(values)) {
1479 var queryValues = [];
1480 for (var i = 0, len = values.length, value; i < len; i++) {
1481 value = values[i];
1482 queryValues.push(toQueryPair(key, value));
1483 }
1484 return results.concat(queryValues);
1485 }
1486 } else results.push(toQueryPair(key, values));
1487 return results;
1488 }).join('&');
1489 }
1490
1491 function inspect() {
1492 return '#<Hash:{' + this.map(function(pair) {
1493 return pair.map(Object.inspect).join(': ');
1494 }).join(', ') + '}>';
1495 }
1496
1497 function clone() {
1498 return new Hash(this);
1499 }
1500
1501 return {
1502 initialize: initialize,
1503 _each: _each,
1504 set: set,
1505 get: get,
1506 unset: unset,
1507 toObject: toObject,
1508 toTemplateReplacements: toObject,
1509 keys: keys,
1510 values: values,
1511 index: index,
1512 merge: merge,
1513 update: update,
1514 toQueryString: toQueryString,
1515 inspect: inspect,
1516 toJSON: toObject,
1517 clone: clone
1518 };
1519})());
1520
1521Hash.from = $H;
1522Object.extend(Number.prototype, (function() {
1523 function toColorPart() {
1524 return this.toPaddedString(2, 16);
1525 }
1526
1527 function succ() {
1528 return this + 1;
1529 }
1530
1531 function times(iterator, context) {
1532 $R(0, this, true).each(iterator, context);
1533 return this;
1534 }
1535
1536 function toPaddedString(length, radix) {
1537 var string = this.toString(radix || 10);
1538 return '0'.times(length - string.length) + string;
1539 }
1540
1541 function abs() {
1542 return Math.abs(this);
1543 }
1544
1545 function round() {
1546 return Math.round(this);
1547 }
1548
1549 function ceil() {
1550 return Math.ceil(this);
1551 }
1552
1553 function floor() {
1554 return Math.floor(this);
1555 }
1556
1557 return {
1558 toColorPart: toColorPart,
1559 succ: succ,
1560 times: times,
1561 toPaddedString: toPaddedString,
1562 abs: abs,
1563 round: round,
1564 ceil: ceil,
1565 floor: floor
1566 };
1567})());
1568
1569function $R(start, end, exclusive) {
1570 return new ObjectRange(start, end, exclusive);
1571}
1572
1573var ObjectRange = Class.create(Enumerable, (function() {
1574 function initialize(start, end, exclusive) {
1575 this.start = start;
1576 this.end = end;
1577 this.exclusive = exclusive;
1578 }
1579
1580 function _each(iterator, context) {
1581 var value = this.start;
1582 while (this.include(value)) {
1583 iterator.call(context, value);
1584 value = value.succ();
1585 }
1586 }
1587
1588 function include(value) {
1589 if (value < this.start)
1590 return false;
1591 if (this.exclusive)
1592 return value < this.end;
1593 return value <= this.end;
1594 }
1595
1596 return {
1597 initialize: initialize,
1598 _each: _each,
1599 include: include
1600 };
1601})());
1602
1603
1604
1605var Abstract = { };
1606
1607
1608var Try = {
1609 these: function() {
1610 var returnValue;
1611
1612 for (var i = 0, length = arguments.length; i < length; i++) {
1613 var lambda = arguments[i];
1614 try {
1615 returnValue = lambda();
1616 break;
1617 } catch (e) { }
1618 }
1619
1620 return returnValue;
1621 }
1622};
1623
1624var Ajax = {
1625 getTransport: function() {
1626 return Try.these(
1627 function() {return new XMLHttpRequest()},
1628 function() {return new ActiveXObject('Msxml2.XMLHTTP')},
1629 function() {return new ActiveXObject('Microsoft.XMLHTTP')}
1630 ) || false;
1631 },
1632
1633 activeRequestCount: 0
1634};
1635
1636Ajax.Responders = {
1637 responders: [],
1638
1639 _each: function(iterator, context) {
1640 this.responders._each(iterator, context);
1641 },
1642
1643 register: function(responder) {
1644 if (!this.include(responder))
1645 this.responders.push(responder);
1646 },
1647
1648 unregister: function(responder) {
1649 this.responders = this.responders.without(responder);
1650 },
1651
1652 dispatch: function(callback, request, transport, json) {
1653 this.each(function(responder) {
1654 if (Object.isFunction(responder[callback])) {
1655 try {
1656 responder[callback].apply(responder, [request, transport, json]);
1657 } catch (e) { }
1658 }
1659 });
1660 }
1661};
1662
1663Object.extend(Ajax.Responders, Enumerable);
1664
1665Ajax.Responders.register({
1666 onCreate: function() { Ajax.activeRequestCount++ },
1667 onComplete: function() { Ajax.activeRequestCount-- }
1668});
1669Ajax.Base = Class.create({
1670 initialize: function(options) {
1671 this.options = {
1672 method: 'post',
1673 asynchronous: true,
1674 contentType: 'application/x-www-form-urlencoded',
1675 encoding: 'UTF-8',
1676 parameters: '',
1677 evalJSON: true,
1678 evalJS: true
1679 };
1680 Object.extend(this.options, options || { });
1681
1682 this.options.method = this.options.method.toLowerCase();
1683
1684 if (Object.isHash(this.options.parameters))
1685 this.options.parameters = this.options.parameters.toObject();
1686 }
1687});
1688Ajax.Request = Class.create(Ajax.Base, {
1689 _complete: false,
1690
1691 initialize: function($super, url, options) {
1692 $super(options);
1693 this.transport = Ajax.getTransport();
1694 this.request(url);
1695 },
1696
1697 request: function(url) {
1698 this.url = url;
1699 this.method = this.options.method;
1700 var params = Object.isString(this.options.parameters) ?
1701 this.options.parameters :
1702 Object.toQueryString(this.options.parameters);
1703
1704 if (!['get', 'post'].include(this.method)) {
1705 params += (params ? '&' : '') + "_method=" + this.method;
1706 this.method = 'post';
1707 }
1708
1709 if (params && this.method === 'get') {
1710 this.url += (this.url.include('?') ? '&' : '?') + params;
1711 }
1712
1713 this.parameters = params.toQueryParams();
1714
1715 try {
1716 var response = new Ajax.Response(this);
1717 if (this.options.onCreate) this.options.onCreate(response);
1718 Ajax.Responders.dispatch('onCreate', this, response);
1719
1720 this.transport.open(this.method.toUpperCase(), this.url,
1721 this.options.asynchronous);
1722
1723 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
1724
1725 this.transport.onreadystatechange = this.onStateChange.bind(this);
1726 this.setRequestHeaders();
1727
1728 this.body = this.method == 'post' ? (this.options.postBody || params) : null;
1729 this.transport.send(this.body);
1730
1731 /* Force Firefox to handle ready state 4 for synchronous requests */
1732 if (!this.options.asynchronous && this.transport.overrideMimeType)
1733 this.onStateChange();
1734
1735 }
1736 catch (e) {
1737 this.dispatchException(e);
1738 }
1739 },
1740
1741 onStateChange: function() {
1742 var readyState = this.transport.readyState;
1743 if (readyState > 1 && !((readyState == 4) && this._complete))
1744 this.respondToReadyState(this.transport.readyState);
1745 },
1746
1747 setRequestHeaders: function() {
1748 var headers = {
1749 'X-Requested-With': 'XMLHttpRequest',
1750 'X-Prototype-Version': Prototype.Version,
1751 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
1752 };
1753
1754 if (this.method == 'post') {
1755 headers['Content-type'] = this.options.contentType +
1756 (this.options.encoding ? '; charset=' + this.options.encoding : '');
1757
1758 /* Force "Connection: close" for older Mozilla browsers to work
1759 * around a bug where XMLHttpRequest sends an incorrect
1760 * Content-length header. See Mozilla Bugzilla #246651.
1761 */
1762 if (this.transport.overrideMimeType &&
1763 (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
1764 headers['Connection'] = 'close';
1765 }
1766
1767 if (typeof this.options.requestHeaders == 'object') {
1768 var extras = this.options.requestHeaders;
1769
1770 if (Object.isFunction(extras.push))
1771 for (var i = 0, length = extras.length; i < length; i += 2)
1772 headers[extras[i]] = extras[i+1];
1773 else
1774 $H(extras).each(function(pair) { headers[pair.key] = pair.value });
1775 }
1776
1777 for (var name in headers)
1778 this.transport.setRequestHeader(name, headers[name]);
1779 },
1780
1781 success: function() {
1782 var status = this.getStatus();
1783 return !status || (status >= 200 && status < 300) || status == 304;
1784 },
1785
1786 getStatus: function() {
1787 try {
1788 if (this.transport.status === 1223) return 204;
1789 return this.transport.status || 0;
1790 } catch (e) { return 0 }
1791 },
1792
1793 respondToReadyState: function(readyState) {
1794 var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
1795
1796 if (state == 'Complete') {
1797 try {
1798 this._complete = true;
1799 (this.options['on' + response.status]
1800 || this.options['on' + (this.success() ? 'Success' : 'Failure')]
1801 || Prototype.emptyFunction)(response, response.headerJSON);
1802 } catch (e) {
1803 this.dispatchException(e);
1804 }
1805
1806 var contentType = response.getHeader('Content-type');
1807 if (this.options.evalJS == 'force'
1808 || (this.options.evalJS && this.isSameOrigin() && contentType
1809 && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1810 this.evalResponse();
1811 }
1812
1813 try {
1814 (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
1815 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
1816 } catch (e) {
1817 this.dispatchException(e);
1818 }
1819
1820 if (state == 'Complete') {
1821 this.transport.onreadystatechange = Prototype.emptyFunction;
1822 }
1823 },
1824
1825 isSameOrigin: function() {
1826 var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
1827 return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
1828 protocol: location.protocol,
1829 domain: document.domain,
1830 port: location.port ? ':' + location.port : ''
1831 }));
1832 },
1833
1834 getHeader: function(name) {
1835 try {
1836 return this.transport.getResponseHeader(name) || null;
1837 } catch (e) { return null; }
1838 },
1839
1840 evalResponse: function() {
1841 try {
1842 return eval((this.transport.responseText || '').unfilterJSON());
1843 } catch (e) {
1844 this.dispatchException(e);
1845 }
1846 },
1847
1848 dispatchException: function(exception) {
1849 (this.options.onException || Prototype.emptyFunction)(this, exception);
1850 Ajax.Responders.dispatch('onException', this, exception);
1851 }
1852});
1853
1854Ajax.Request.Events =
1855 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1856
1857
1858
1859
1860
1861
1862
1863
1864Ajax.Response = Class.create({
1865 initialize: function(request){
1866 this.request = request;
1867 var transport = this.transport = request.transport,
1868 readyState = this.readyState = transport.readyState;
1869
1870 if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1871 this.status = this.getStatus();
1872 this.statusText = this.getStatusText();
1873 this.responseText = String.interpret(transport.responseText);
1874 this.headerJSON = this._getHeaderJSON();
1875 }
1876
1877 if (readyState == 4) {
1878 var xml = transport.responseXML;
1879 this.responseXML = Object.isUndefined(xml) ? null : xml;
1880 this.responseJSON = this._getResponseJSON();
1881 }
1882 },
1883
1884 status: 0,
1885
1886 statusText: '',
1887
1888 getStatus: Ajax.Request.prototype.getStatus,
1889
1890 getStatusText: function() {
1891 try {
1892 return this.transport.statusText || '';
1893 } catch (e) { return '' }
1894 },
1895
1896 getHeader: Ajax.Request.prototype.getHeader,
1897
1898 getAllHeaders: function() {
1899 try {
1900 return this.getAllResponseHeaders();
1901 } catch (e) { return null }
1902 },
1903
1904 getResponseHeader: function(name) {
1905 return this.transport.getResponseHeader(name);
1906 },
1907
1908 getAllResponseHeaders: function() {
1909 return this.transport.getAllResponseHeaders();
1910 },
1911
1912 _getHeaderJSON: function() {
1913 var json = this.getHeader('X-JSON');
1914 if (!json) return null;
1915
1916 try {
1917 json = decodeURIComponent(escape(json));
1918 } catch(e) {
1919 }
1920
1921 try {
1922 return json.evalJSON(this.request.options.sanitizeJSON ||
1923 !this.request.isSameOrigin());
1924 } catch (e) {
1925 this.request.dispatchException(e);
1926 }
1927 },
1928
1929 _getResponseJSON: function() {
1930 var options = this.request.options;
1931 if (!options.evalJSON || (options.evalJSON != 'force' &&
1932 !(this.getHeader('Content-type') || '').include('application/json')) ||
1933 this.responseText.blank())
1934 return null;
1935 try {
1936 return this.responseText.evalJSON(options.sanitizeJSON ||
1937 !this.request.isSameOrigin());
1938 } catch (e) {
1939 this.request.dispatchException(e);
1940 }
1941 }
1942});
1943
1944Ajax.Updater = Class.create(Ajax.Request, {
1945 initialize: function($super, container, url, options) {
1946 this.container = {
1947 success: (container.success || container),
1948 failure: (container.failure || (container.success ? null : container))
1949 };
1950
1951 options = Object.clone(options);
1952 var onComplete = options.onComplete;
1953 options.onComplete = (function(response, json) {
1954 this.updateContent(response.responseText);
1955 if (Object.isFunction(onComplete)) onComplete(response, json);
1956 }).bind(this);
1957
1958 $super(url, options);
1959 },
1960
1961 updateContent: function(responseText) {
1962 var receiver = this.container[this.success() ? 'success' : 'failure'],
1963 options = this.options;
1964
1965 if (!options.evalScripts) responseText = responseText.stripScripts();
1966
1967 if (receiver = $(receiver)) {
1968 if (options.insertion) {
1969 if (Object.isString(options.insertion)) {
1970 var insertion = { }; insertion[options.insertion] = responseText;
1971 receiver.insert(insertion);
1972 }
1973 else options.insertion(receiver, responseText);
1974 }
1975 else receiver.update(responseText);
1976 }
1977 }
1978});
1979
1980Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1981 initialize: function($super, container, url, options) {
1982 $super(options);
1983 this.onComplete = this.options.onComplete;
1984
1985 this.frequency = (this.options.frequency || 2);
1986 this.decay = (this.options.decay || 1);
1987
1988 this.updater = { };
1989 this.container = container;
1990 this.url = url;
1991
1992 this.start();
1993 },
1994
1995 start: function() {
1996 this.options.onComplete = this.updateComplete.bind(this);
1997 this.onTimerEvent();
1998 },
1999
2000 stop: function() {
2001 this.updater.options.onComplete = undefined;
2002 clearTimeout(this.timer);
2003 (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
2004 },
2005
2006 updateComplete: function(response) {
2007 if (this.options.decay) {
2008 this.decay = (response.responseText == this.lastText ?
2009 this.decay * this.options.decay : 1);
2010
2011 this.lastText = response.responseText;
2012 }
2013 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
2014 },
2015
2016 onTimerEvent: function() {
2017 this.updater = new Ajax.Updater(this.container, this.url, this.options);
2018 }
2019});
2020
2021(function(GLOBAL) {
2022
2023 var UNDEFINED;
2024 var SLICE = Array.prototype.slice;
2025
2026 var DIV = document.createElement('div');
2027
2028
2029 function $(element) {
2030 if (arguments.length > 1) {
2031 for (var i = 0, elements = [], length = arguments.length; i < length; i++)
2032 elements.push($(arguments[i]));
2033 return elements;
2034 }
2035
2036 if (Object.isString(element))
2037 element = document.getElementById(element);
2038 return Element.extend(element);
2039 }
2040
2041 GLOBAL.$ = $;
2042
2043
2044 if (!GLOBAL.Node) GLOBAL.Node = {};
2045
2046 if (!GLOBAL.Node.ELEMENT_NODE) {
2047 Object.extend(GLOBAL.Node, {
2048 ELEMENT_NODE: 1,
2049 ATTRIBUTE_NODE: 2,
2050 TEXT_NODE: 3,
2051 CDATA_SECTION_NODE: 4,
2052 ENTITY_REFERENCE_NODE: 5,
2053 ENTITY_NODE: 6,
2054 PROCESSING_INSTRUCTION_NODE: 7,
2055 COMMENT_NODE: 8,
2056 DOCUMENT_NODE: 9,
2057 DOCUMENT_TYPE_NODE: 10,
2058 DOCUMENT_FRAGMENT_NODE: 11,
2059 NOTATION_NODE: 12
2060 });
2061 }
2062
2063 var ELEMENT_CACHE = {};
2064
2065 function shouldUseCreationCache(tagName, attributes) {
2066 if (tagName === 'select') return false;
2067 if ('type' in attributes) return false;
2068 return true;
2069 }
2070
2071 var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
2072 try {
2073 var el = document.createElement('<input name="x">');
2074 return el.tagName.toLowerCase() === 'input' && el.name === 'x';
2075 }
2076 catch(err) {
2077 return false;
2078 }
2079 })();
2080
2081
2082 var oldElement = GLOBAL.Element;
2083 function Element(tagName, attributes) {
2084 attributes = attributes || {};
2085 tagName = tagName.toLowerCase();
2086
2087 if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
2088 tagName = '<' + tagName + ' name="' + attributes.name + '">';
2089 delete attributes.name;
2090 return Element.writeAttribute(document.createElement(tagName), attributes);
2091 }
2092
2093 if (!ELEMENT_CACHE[tagName])
2094 ELEMENT_CACHE[tagName] = Element.extend(document.createElement(tagName));
2095
2096 var node = shouldUseCreationCache(tagName, attributes) ?
2097 ELEMENT_CACHE[tagName].cloneNode(false) : document.createElement(tagName);
2098
2099 return Element.writeAttribute(node, attributes);
2100 }
2101
2102 GLOBAL.Element = Element;
2103
2104 Object.extend(GLOBAL.Element, oldElement || {});
2105 if (oldElement) GLOBAL.Element.prototype = oldElement.prototype;
2106
2107 Element.Methods = { ByTag: {}, Simulated: {} };
2108
2109 var methods = {};
2110
2111 var INSPECT_ATTRIBUTES = { id: 'id', className: 'class' };
2112 function inspect(element) {
2113 element = $(element);
2114 var result = '<' + element.tagName.toLowerCase();
2115
2116 var attribute, value;
2117 for (var property in INSPECT_ATTRIBUTES) {
2118 attribute = INSPECT_ATTRIBUTES[property];
2119 value = (element[property] || '').toString();
2120 if (value) result += ' ' + attribute + '=' + value.inspect(true);
2121 }
2122
2123 return result + '>';
2124 }
2125
2126 methods.inspect = inspect;
2127
2128
2129 function visible(element) {
2130 return $(element).style.display !== 'none';
2131 }
2132
2133 function toggle(element, bool) {
2134 element = $(element);
2135 if (Object.isUndefined(bool))
2136 bool = !Element.visible(element);
2137 Element[bool ? 'show' : 'hide'](element);
2138
2139 return element;
2140 }
2141
2142 function hide(element) {
2143 element = $(element);
2144 element.style.display = 'none';
2145 return element;
2146 }
2147
2148 function show(element) {
2149 element = $(element);
2150 element.style.display = '';
2151 return element;
2152 }
2153
2154
2155 Object.extend(methods, {
2156 visible: visible,
2157 toggle: toggle,
2158 hide: hide,
2159 show: show
2160 });
2161
2162
2163 function remove(element) {
2164 element = $(element);
2165 if(element.parentNode)
2166 element.parentNode.removeChild(element);
2167 return element;
2168 }
2169
2170 var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
2171 var el = document.createElement("select"),
2172 isBuggy = true;
2173 el.innerHTML = "<option value=\"test\">test</option>";
2174 if (el.options && el.options[0]) {
2175 isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
2176 }
2177 el = null;
2178 return isBuggy;
2179 })();
2180
2181 var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
2182 try {
2183 var el = document.createElement("table");
2184 if (el && el.tBodies) {
2185 el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
2186 var isBuggy = typeof el.tBodies[0] == "undefined";
2187 el = null;
2188 return isBuggy;
2189 }
2190 } catch (e) {
2191 return true;
2192 }
2193 })();
2194
2195 var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
2196 try {
2197 var el = document.createElement('div');
2198 el.innerHTML = "<link />";
2199 var isBuggy = (el.childNodes.length === 0);
2200 el = null;
2201 return isBuggy;
2202 } catch(e) {
2203 return true;
2204 }
2205 })();
2206
2207 var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
2208 TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
2209
2210 var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
2211 var s = document.createElement("script"),
2212 isBuggy = false;
2213 try {
2214 s.appendChild(document.createTextNode(""));
2215 isBuggy = !s.firstChild ||
2216 s.firstChild && s.firstChild.nodeType !== 3;
2217 } catch (e) {
2218 isBuggy = true;
2219 }
2220 s = null;
2221 return isBuggy;
2222 })();
2223
2224 function update(element, content) {
2225 element = $(element);
2226
2227 var descendants = element.getElementsByTagName('*'),
2228 i = descendants.length;
2229 while (i--) purgeElement(descendants[i]);
2230
2231 if (content && content.toElement)
2232 content = content.toElement();
2233
2234 if (Object.isElement(content))
2235 return element.update().insert(content);
2236
2237
2238 content = Object.toHTML(content);
2239 var tagName = element.tagName.toUpperCase();
2240
2241 if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
2242 element.text = content;
2243 return element;
2244 }
2245
2246 if (ANY_INNERHTML_BUGGY) {
2247 if (tagName in INSERTION_TRANSLATIONS.tags) {
2248 while (element.firstChild)
2249 element.removeChild(element.firstChild);
2250
2251 var nodes = getContentFromAnonymousElement(tagName, content.stripScripts());
2252 for (var i = 0, node; node = nodes[i]; i++)
2253 element.appendChild(node);
2254
2255 } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
2256 while (element.firstChild)
2257 element.removeChild(element.firstChild);
2258
2259 var nodes = getContentFromAnonymousElement(tagName,
2260 content.stripScripts(), true);
2261
2262 for (var i = 0, node; node = nodes[i]; i++)
2263 element.appendChild(node);
2264 } else {
2265 element.innerHTML = content.stripScripts();
2266 }
2267 } else {
2268 element.innerHTML = content.stripScripts();
2269 }
2270
2271 content.evalScripts.bind(content).defer();
2272 return element;
2273 }
2274
2275 function replace(element, content) {
2276 element = $(element);
2277
2278 if (content && content.toElement) {
2279 content = content.toElement();
2280 } else if (!Object.isElement(content)) {
2281 content = Object.toHTML(content);
2282 var range = element.ownerDocument.createRange();
2283 range.selectNode(element);
2284 content.evalScripts.bind(content).defer();
2285 content = range.createContextualFragment(content.stripScripts());
2286 }
2287
2288 element.parentNode.replaceChild(content, element);
2289 return element;
2290 }
2291
2292 var INSERTION_TRANSLATIONS = {
2293 before: function(element, node) {
2294 element.parentNode.insertBefore(node, element);
2295 },
2296 top: function(element, node) {
2297 element.insertBefore(node, element.firstChild);
2298 },
2299 bottom: function(element, node) {
2300 element.appendChild(node);
2301 },
2302 after: function(element, node) {
2303 element.parentNode.insertBefore(node, element.nextSibling);
2304 },
2305
2306 tags: {
2307 TABLE: ['<table>', '</table>', 1],
2308 TBODY: ['<table><tbody>', '</tbody></table>', 2],
2309 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3],
2310 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
2311 SELECT: ['<select>', '</select>', 1]
2312 }
2313 };
2314
2315 var tags = INSERTION_TRANSLATIONS.tags;
2316
2317 Object.extend(tags, {
2318 THEAD: tags.TBODY,
2319 TFOOT: tags.TBODY,
2320 TH: tags.TD
2321 });
2322
2323 function replace_IE(element, content) {
2324 element = $(element);
2325 if (content && content.toElement)
2326 content = content.toElement();
2327 if (Object.isElement(content)) {
2328 element.parentNode.replaceChild(content, element);
2329 return element;
2330 }
2331
2332 content = Object.toHTML(content);
2333 var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2334
2335 if (tagName in INSERTION_TRANSLATIONS.tags) {
2336 var nextSibling = Element.next(element);
2337 var fragments = getContentFromAnonymousElement(
2338 tagName, content.stripScripts());
2339
2340 parent.removeChild(element);
2341
2342 var iterator;
2343 if (nextSibling)
2344 iterator = function(node) { parent.insertBefore(node, nextSibling) };
2345 else
2346 iterator = function(node) { parent.appendChild(node); }
2347
2348 fragments.each(iterator);
2349 } else {
2350 element.outerHTML = content.stripScripts();
2351 }
2352
2353 content.evalScripts.bind(content).defer();
2354 return element;
2355 }
2356
2357 if ('outerHTML' in document.documentElement)
2358 replace = replace_IE;
2359
2360 function isContent(content) {
2361 if (Object.isUndefined(content) || content === null) return false;
2362
2363 if (Object.isString(content) || Object.isNumber(content)) return true;
2364 if (Object.isElement(content)) return true;
2365 if (content.toElement || content.toHTML) return true;
2366
2367 return false;
2368 }
2369
2370 function insertContentAt(element, content, position) {
2371 position = position.toLowerCase();
2372 var method = INSERTION_TRANSLATIONS[position];
2373
2374 if (content && content.toElement) content = content.toElement();
2375 if (Object.isElement(content)) {
2376 method(element, content);
2377 return element;
2378 }
2379
2380 content = Object.toHTML(content);
2381 var tagName = ((position === 'before' || position === 'after') ?
2382 element.parentNode : element).tagName.toUpperCase();
2383
2384 var childNodes = getContentFromAnonymousElement(tagName, content.stripScripts());
2385
2386 if (position === 'top' || position === 'after') childNodes.reverse();
2387
2388 for (var i = 0, node; node = childNodes[i]; i++)
2389 method(element, node);
2390
2391 content.evalScripts.bind(content).defer();
2392 }
2393
2394 function insert(element, insertions) {
2395 element = $(element);
2396
2397 if (isContent(insertions))
2398 insertions = { bottom: insertions };
2399
2400 for (var position in insertions)
2401 insertContentAt(element, insertions[position], position);
2402
2403 return element;
2404 }
2405
2406 function wrap(element, wrapper, attributes) {
2407 element = $(element);
2408
2409 if (Object.isElement(wrapper)) {
2410 $(wrapper).writeAttribute(attributes || {});
2411 } else if (Object.isString(wrapper)) {
2412 wrapper = new Element(wrapper, attributes);
2413 } else {
2414 wrapper = new Element('div', wrapper);
2415 }
2416
2417 if (element.parentNode)
2418 element.parentNode.replaceChild(wrapper, element);
2419
2420 wrapper.appendChild(element);
2421
2422 return wrapper;
2423 }
2424
2425 function cleanWhitespace(element) {
2426 element = $(element);
2427 var node = element.firstChild;
2428
2429 while (node) {
2430 var nextNode = node.nextSibling;
2431 if (node.nodeType === Node.TEXT_NODE && !/\S/.test(node.nodeValue))
2432 element.removeChild(node);
2433 node = nextNode;
2434 }
2435 return element;
2436 }
2437
2438 function empty(element) {
2439 return $(element).innerHTML.blank();
2440 }
2441
2442 function getContentFromAnonymousElement(tagName, html, force) {
2443 var t = INSERTION_TRANSLATIONS.tags[tagName], div = DIV;
2444
2445 var workaround = !!t;
2446 if (!workaround && force) {
2447 workaround = true;
2448 t = ['', '', 0];
2449 }
2450
2451 if (workaround) {
2452 div.innerHTML = '&#160;' + t[0] + html + t[1];
2453 div.removeChild(div.firstChild);
2454 for (var i = t[2]; i--; )
2455 div = div.firstChild;
2456 } else {
2457 div.innerHTML = html;
2458 }
2459
2460 return $A(div.childNodes);
2461 }
2462
2463 function clone(element, deep) {
2464 if (!(element = $(element))) return;
2465 var clone = element.cloneNode(deep);
2466 if (!HAS_UNIQUE_ID_PROPERTY) {
2467 clone._prototypeUID = UNDEFINED;
2468 if (deep) {
2469 var descendants = Element.select(clone, '*'),
2470 i = descendants.length;
2471 while (i--)
2472 descendants[i]._prototypeUID = UNDEFINED;
2473 }
2474 }
2475 return Element.extend(clone);
2476 }
2477
2478 function purgeElement(element) {
2479 var uid = getUniqueElementID(element);
2480 if (uid) {
2481 Element.stopObserving(element);
2482 if (!HAS_UNIQUE_ID_PROPERTY)
2483 element._prototypeUID = UNDEFINED;
2484 delete Element.Storage[uid];
2485 }
2486 }
2487
2488 function purgeCollection(elements) {
2489 var i = elements.length;
2490 while (i--)
2491 purgeElement(elements[i]);
2492 }
2493
2494 function purgeCollection_IE(elements) {
2495 var i = elements.length, element, uid;
2496 while (i--) {
2497 element = elements[i];
2498 uid = getUniqueElementID(element);
2499 delete Element.Storage[uid];
2500 delete Event.cache[uid];
2501 }
2502 }
2503
2504 if (HAS_UNIQUE_ID_PROPERTY) {
2505 purgeCollection = purgeCollection_IE;
2506 }
2507
2508
2509 function purge(element) {
2510 if (!(element = $(element))) return;
2511 purgeElement(element);
2512
2513 var descendants = element.getElementsByTagName('*'),
2514 i = descendants.length;
2515
2516 while (i--) purgeElement(descendants[i]);
2517
2518 return null;
2519 }
2520
2521 Object.extend(methods, {
2522 remove: remove,
2523 update: update,
2524 replace: replace,
2525 insert: insert,
2526 wrap: wrap,
2527 cleanWhitespace: cleanWhitespace,
2528 empty: empty,
2529 clone: clone,
2530 purge: purge
2531 });
2532
2533
2534
2535 function recursivelyCollect(element, property, maximumLength) {
2536 element = $(element);
2537 maximumLength = maximumLength || -1;
2538 var elements = [];
2539
2540 while (element = element[property]) {
2541 if (element.nodeType === Node.ELEMENT_NODE)
2542 elements.push(Element.extend(element));
2543
2544 if (elements.length === maximumLength) break;
2545 }
2546
2547 return elements;
2548 }
2549
2550
2551 function ancestors(element) {
2552 return recursivelyCollect(element, 'parentNode');
2553 }
2554
2555 function descendants(element) {
2556 return Element.select(element, '*');
2557 }
2558
2559 function firstDescendant(element) {
2560 element = $(element).firstChild;
2561 while (element && element.nodeType !== Node.ELEMENT_NODE)
2562 element = element.nextSibling;
2563
2564 return $(element);
2565 }
2566
2567 function immediateDescendants(element) {
2568 var results = [], child = $(element).firstChild;
2569
2570 while (child) {
2571 if (child.nodeType === Node.ELEMENT_NODE)
2572 results.push(Element.extend(child));
2573
2574 child = child.nextSibling;
2575 }
2576
2577 return results;
2578 }
2579
2580 function previousSiblings(element) {
2581 return recursivelyCollect(element, 'previousSibling');
2582 }
2583
2584 function nextSiblings(element) {
2585 return recursivelyCollect(element, 'nextSibling');
2586 }
2587
2588 function siblings(element) {
2589 element = $(element);
2590 var previous = previousSiblings(element),
2591 next = nextSiblings(element);
2592 return previous.reverse().concat(next);
2593 }
2594
2595 function match(element, selector) {
2596 element = $(element);
2597
2598 if (Object.isString(selector))
2599 return Prototype.Selector.match(element, selector);
2600
2601 return selector.match(element);
2602 }
2603
2604
2605 function _recursivelyFind(element, property, expression, index) {
2606 element = $(element), expression = expression || 0, index = index || 0;
2607 if (Object.isNumber(expression)) {
2608 index = expression, expression = null;
2609 }
2610
2611 while (element = element[property]) {
2612 if (element.nodeType !== 1) continue;
2613 if (expression && !Prototype.Selector.match(element, expression))
2614 continue;
2615 if (--index >= 0) continue;
2616
2617 return Element.extend(element);
2618 }
2619 }
2620
2621
2622 function up(element, expression, index) {
2623 element = $(element);
2624
2625 if (arguments.length === 1) return $(element.parentNode);
2626 return _recursivelyFind(element, 'parentNode', expression, index);
2627 }
2628
2629 function down(element, expression, index) {
2630 element = $(element), expression = expression || 0, index = index || 0;
2631
2632 if (Object.isNumber(expression))
2633 index = expression, expression = '*';
2634
2635 var node = Prototype.Selector.select(expression, element)[index];
2636 return Element.extend(node);
2637 }
2638
2639 function previous(element, expression, index) {
2640 return _recursivelyFind(element, 'previousSibling', expression, index);
2641 }
2642
2643 function next(element, expression, index) {
2644 return _recursivelyFind(element, 'nextSibling', expression, index);
2645 }
2646
2647 function select(element) {
2648 element = $(element);
2649 var expressions = SLICE.call(arguments, 1).join(', ');
2650 return Prototype.Selector.select(expressions, element);
2651 }
2652
2653 function adjacent(element) {
2654 element = $(element);
2655 var expressions = SLICE.call(arguments, 1).join(', ');
2656 var siblings = Element.siblings(element), results = [];
2657 for (var i = 0, sibling; sibling = siblings[i]; i++) {
2658 if (Prototype.Selector.match(sibling, expressions))
2659 results.push(sibling);
2660 }
2661
2662 return results;
2663 }
2664
2665 function descendantOf_DOM(element, ancestor) {
2666 element = $(element), ancestor = $(ancestor);
2667 while (element = element.parentNode)
2668 if (element === ancestor) return true;
2669 return false;
2670 }
2671
2672 function descendantOf_contains(element, ancestor) {
2673 element = $(element), ancestor = $(ancestor);
2674 if (!ancestor.contains) return descendantOf_DOM(element, ancestor);
2675 return ancestor.contains(element) && ancestor !== element;
2676 }
2677
2678 function descendantOf_compareDocumentPosition(element, ancestor) {
2679 element = $(element), ancestor = $(ancestor);
2680 return (element.compareDocumentPosition(ancestor) & 8) === 8;
2681 }
2682
2683 var descendantOf;
2684 if (DIV.compareDocumentPosition) {
2685 descendantOf = descendantOf_compareDocumentPosition;
2686 } else if (DIV.contains) {
2687 descendantOf = descendantOf_contains;
2688 } else {
2689 descendantOf = descendantOf_DOM;
2690 }
2691
2692
2693 Object.extend(methods, {
2694 recursivelyCollect: recursivelyCollect,
2695 ancestors: ancestors,
2696 descendants: descendants,
2697 firstDescendant: firstDescendant,
2698 immediateDescendants: immediateDescendants,
2699 previousSiblings: previousSiblings,
2700 nextSiblings: nextSiblings,
2701 siblings: siblings,
2702 match: match,
2703 up: up,
2704 down: down,
2705 previous: previous,
2706 next: next,
2707 select: select,
2708 adjacent: adjacent,
2709 descendantOf: descendantOf,
2710
2711 getElementsBySelector: select,
2712
2713 childElements: immediateDescendants
2714 });
2715
2716
2717 var idCounter = 1;
2718 function identify(element) {
2719 element = $(element);
2720 var id = Element.readAttribute(element, 'id');
2721 if (id) return id;
2722
2723 do { id = 'anonymous_element_' + idCounter++ } while ($(id));
2724
2725 Element.writeAttribute(element, 'id', id);
2726 return id;
2727 }
2728
2729
2730 function readAttribute(element, name) {
2731 return $(element).getAttribute(name);
2732 }
2733
2734 function readAttribute_IE(element, name) {
2735 element = $(element);
2736
2737 var table = ATTRIBUTE_TRANSLATIONS.read;
2738 if (table.values[name])
2739 return table.values[name](element, name);
2740
2741 if (table.names[name]) name = table.names[name];
2742
2743 if (name.include(':')) {
2744 if (!element.attributes || !element.attributes[name]) return null;
2745 return element.attributes[name].value;
2746 }
2747
2748 return element.getAttribute(name);
2749 }
2750
2751 function readAttribute_Opera(element, name) {
2752 if (name === 'title') return element.title;
2753 return element.getAttribute(name);
2754 }
2755
2756 var PROBLEMATIC_ATTRIBUTE_READING = (function() {
2757 DIV.setAttribute('onclick', Prototype.emptyFunction);
2758 var value = DIV.getAttribute('onclick');
2759 var isFunction = (typeof value === 'function');
2760 DIV.removeAttribute('onclick');
2761 return isFunction;
2762 })();
2763
2764 if (PROBLEMATIC_ATTRIBUTE_READING) {
2765 readAttribute = readAttribute_IE;
2766 } else if (Prototype.Browser.Opera) {
2767 readAttribute = readAttribute_Opera;
2768 }
2769
2770
2771 function writeAttribute(element, name, value) {
2772 element = $(element);
2773 var attributes = {}, table = ATTRIBUTE_TRANSLATIONS.write;
2774
2775 if (typeof name === 'object') {
2776 attributes = name;
2777 } else {
2778 attributes[name] = Object.isUndefined(value) ? true : value;
2779 }
2780
2781 for (var attr in attributes) {
2782 name = table.names[attr] || attr;
2783 value = attributes[attr];
2784 if (table.values[attr])
2785 name = table.values[attr](element, value);
2786 if (value === false || value === null)
2787 element.removeAttribute(name);
2788 else if (value === true)
2789 element.setAttribute(name, name);
2790 else element.setAttribute(name, value);
2791 }
2792
2793 return element;
2794 }
2795
2796 function hasAttribute(element, attribute) {
2797 attribute = ATTRIBUTE_TRANSLATIONS.has[attribute] || attribute;
2798 var node = $(element).getAttributeNode(attribute);
2799 return !!(node && node.specified);
2800 }
2801
2802 GLOBAL.Element.Methods.Simulated.hasAttribute = hasAttribute;
2803
2804 function classNames(element) {
2805 return new Element.ClassNames(element);
2806 }
2807
2808 var regExpCache = {};
2809 function getRegExpForClassName(className) {
2810 if (regExpCache[className]) return regExpCache[className];
2811
2812 var re = new RegExp("(^|\\s+)" + className + "(\\s+|$)");
2813 regExpCache[className] = re;
2814 return re;
2815 }
2816
2817 function hasClassName(element, className) {
2818 if (!(element = $(element))) return;
2819
2820 var elementClassName = element.className;
2821
2822 if (elementClassName.length === 0) return false;
2823 if (elementClassName === className) return true;
2824
2825 return getRegExpForClassName(className).test(elementClassName);
2826 }
2827
2828 function addClassName(element, className) {
2829 if (!(element = $(element))) return;
2830
2831 if (!hasClassName(element, className))
2832 element.className += (element.className ? ' ' : '') + className;
2833
2834 return element;
2835 }
2836
2837 function removeClassName(element, className) {
2838 if (!(element = $(element))) return;
2839
2840 element.className = element.className.replace(
2841 getRegExpForClassName(className), ' ').strip();
2842
2843 return element;
2844 }
2845
2846 function toggleClassName(element, className, bool) {
2847 if (!(element = $(element))) return;
2848
2849 if (Object.isUndefined(bool))
2850 bool = !hasClassName(element, className);
2851
2852 var method = Element[bool ? 'addClassName' : 'removeClassName'];
2853 return method(element, className);
2854 }
2855
2856 var ATTRIBUTE_TRANSLATIONS = {};
2857
2858 var classProp = 'className', forProp = 'for';
2859
2860 DIV.setAttribute(classProp, 'x');
2861 if (DIV.className !== 'x') {
2862 DIV.setAttribute('class', 'x');
2863 if (DIV.className === 'x')
2864 classProp = 'class';
2865 }
2866
2867 var LABEL = document.createElement('label');
2868 LABEL.setAttribute(forProp, 'x');
2869 if (LABEL.htmlFor !== 'x') {
2870 LABEL.setAttribute('htmlFor', 'x');
2871 if (LABEL.htmlFor === 'x')
2872 forProp = 'htmlFor';
2873 }
2874 LABEL = null;
2875
2876 function _getAttr(element, attribute) {
2877 return element.getAttribute(attribute);
2878 }
2879
2880 function _getAttr2(element, attribute) {
2881 return element.getAttribute(attribute, 2);
2882 }
2883
2884 function _getAttrNode(element, attribute) {
2885 var node = element.getAttributeNode(attribute);
2886 return node ? node.value : '';
2887 }
2888
2889 function _getFlag(element, attribute) {
2890 return $(element).hasAttribute(attribute) ? attribute : null;
2891 }
2892
2893 DIV.onclick = Prototype.emptyFunction;
2894 var onclickValue = DIV.getAttribute('onclick');
2895
2896 var _getEv;
2897
2898 if (String(onclickValue).indexOf('{') > -1) {
2899 _getEv = function(element, attribute) {
2900 var value = element.getAttribute(attribute);
2901 if (!value) return null;
2902 value = value.toString();
2903 value = value.split('{')[1];
2904 value = value.split('}')[0];
2905 return value.strip();
2906 };
2907 }
2908 else if (onclickValue === '') {
2909 _getEv = function(element, attribute) {
2910 var value = element.getAttribute(attribute);
2911 if (!value) return null;
2912 return value.strip();
2913 };
2914 }
2915
2916 ATTRIBUTE_TRANSLATIONS.read = {
2917 names: {
2918 'class': classProp,
2919 'className': classProp,
2920 'for': forProp,
2921 'htmlFor': forProp
2922 },
2923
2924 values: {
2925 style: function(element) {
2926 return element.style.cssText.toLowerCase();
2927 },
2928 title: function(element) {
2929 return element.title;
2930 }
2931 }
2932 };
2933
2934 ATTRIBUTE_TRANSLATIONS.write = {
2935 names: {
2936 className: 'class',
2937 htmlFor: 'for',
2938 cellpadding: 'cellPadding',
2939 cellspacing: 'cellSpacing'
2940 },
2941
2942 values: {
2943 checked: function(element, value) {
2944 element.checked = !!value;
2945 },
2946
2947 style: function(element, value) {
2948 element.style.cssText = value ? value : '';
2949 }
2950 }
2951 };
2952
2953 ATTRIBUTE_TRANSLATIONS.has = { names: {} };
2954
2955 Object.extend(ATTRIBUTE_TRANSLATIONS.write.names,
2956 ATTRIBUTE_TRANSLATIONS.read.names);
2957
2958 var CAMEL_CASED_ATTRIBUTE_NAMES = $w('colSpan rowSpan vAlign dateTime ' +
2959 'accessKey tabIndex encType maxLength readOnly longDesc frameBorder');
2960
2961 for (var i = 0, attr; attr = CAMEL_CASED_ATTRIBUTE_NAMES[i]; i++) {
2962 ATTRIBUTE_TRANSLATIONS.write.names[attr.toLowerCase()] = attr;
2963 ATTRIBUTE_TRANSLATIONS.has.names[attr.toLowerCase()] = attr;
2964 }
2965
2966 Object.extend(ATTRIBUTE_TRANSLATIONS.read.values, {
2967 href: _getAttr2,
2968 src: _getAttr2,
2969 type: _getAttr,
2970 action: _getAttrNode,
2971 disabled: _getFlag,
2972 checked: _getFlag,
2973 readonly: _getFlag,
2974 multiple: _getFlag,
2975 onload: _getEv,
2976 onunload: _getEv,
2977 onclick: _getEv,
2978 ondblclick: _getEv,
2979 onmousedown: _getEv,
2980 onmouseup: _getEv,
2981 onmouseover: _getEv,
2982 onmousemove: _getEv,
2983 onmouseout: _getEv,
2984 onfocus: _getEv,
2985 onblur: _getEv,
2986 onkeypress: _getEv,
2987 onkeydown: _getEv,
2988 onkeyup: _getEv,
2989 onsubmit: _getEv,
2990 onreset: _getEv,
2991 onselect: _getEv,
2992 onchange: _getEv
2993 });
2994
2995
2996 Object.extend(methods, {
2997 identify: identify,
2998 readAttribute: readAttribute,
2999 writeAttribute: writeAttribute,
3000 classNames: classNames,
3001 hasClassName: hasClassName,
3002 addClassName: addClassName,
3003 removeClassName: removeClassName,
3004 toggleClassName: toggleClassName
3005 });
3006
3007
3008 function normalizeStyleName(style) {
3009 if (style === 'float' || style === 'styleFloat')
3010 return 'cssFloat';
3011 return style.camelize();
3012 }
3013
3014 function normalizeStyleName_IE(style) {
3015 if (style === 'float' || style === 'cssFloat')
3016 return 'styleFloat';
3017 return style.camelize();
3018 }
3019
3020 function setStyle(element, styles) {
3021 element = $(element);
3022 var elementStyle = element.style, match;
3023
3024 if (Object.isString(styles)) {
3025 elementStyle.cssText += ';' + styles;
3026 if (styles.include('opacity')) {
3027 var opacity = styles.match(/opacity:\s*(\d?\.?\d*)/)[1];
3028 Element.setOpacity(element, opacity);
3029 }
3030 return element;
3031 }
3032
3033 for (var property in styles) {
3034 if (property === 'opacity') {
3035 Element.setOpacity(element, styles[property]);
3036 } else {
3037 var value = styles[property];
3038 if (property === 'float' || property === 'cssFloat') {
3039 property = Object.isUndefined(elementStyle.styleFloat) ?
3040 'cssFloat' : 'styleFloat';
3041 }
3042 elementStyle[property] = value;
3043 }
3044 }
3045
3046 return element;
3047 }
3048
3049
3050 function getStyle(element, style) {
3051 element = $(element);
3052 style = normalizeStyleName(style);
3053
3054 var value = element.style[style];
3055 if (!value || value === 'auto') {
3056 var css = document.defaultView.getComputedStyle(element, null);
3057 value = css ? css[style] : null;
3058 }
3059
3060 if (style === 'opacity') return value ? parseFloat(value) : 1.0;
3061 return value === 'auto' ? null : value;
3062 }
3063
3064 function getStyle_Opera(element, style) {
3065 switch (style) {
3066 case 'height': case 'width':
3067 if (!Element.visible(element)) return null;
3068
3069 var dim = parseInt(getStyle(element, style), 10);
3070
3071 if (dim !== element['offset' + style.capitalize()])
3072 return dim + 'px';
3073
3074 return Element.measure(element, style);
3075
3076 default: return getStyle(element, style);
3077 }
3078 }
3079
3080 function getStyle_IE(element, style) {
3081 element = $(element);
3082 style = normalizeStyleName_IE(style);
3083
3084 var value = element.style[style];
3085 if (!value && element.currentStyle) {
3086 value = element.currentStyle[style];
3087 }
3088
3089 if (style === 'opacity' && !STANDARD_CSS_OPACITY_SUPPORTED)
3090 return getOpacity_IE(element);
3091
3092 if (value === 'auto') {
3093 if ((style === 'width' || style === 'height') && Element.visible(element))
3094 return Element.measure(element, style) + 'px';
3095 return null;
3096 }
3097
3098 return value;
3099 }
3100
3101 function stripAlphaFromFilter_IE(filter) {
3102 return (filter || '').replace(/alpha\([^\)]*\)/gi, '');
3103 }
3104
3105 function hasLayout_IE(element) {
3106 if (!element.currentStyle.hasLayout)
3107 element.style.zoom = 1;
3108 return element;
3109 }
3110
3111 var STANDARD_CSS_OPACITY_SUPPORTED = (function() {
3112 DIV.style.cssText = "opacity:.55";
3113 return /^0.55/.test(DIV.style.opacity);
3114 })();
3115
3116 function setOpacity(element, value) {
3117 element = $(element);
3118 if (value == 1 || value === '') value = '';
3119 else if (value < 0.00001) value = 0;
3120 element.style.opacity = value;
3121 return element;
3122 }
3123
3124 function setOpacity_IE(element, value) {
3125 if (STANDARD_CSS_OPACITY_SUPPORTED)
3126 return setOpacity(element, value);
3127
3128 element = hasLayout_IE($(element));
3129 var filter = Element.getStyle(element, 'filter'),
3130 style = element.style;
3131
3132 if (value == 1 || value === '') {
3133 filter = stripAlphaFromFilter_IE(filter);
3134 if (filter) style.filter = filter;
3135 else style.removeAttribute('filter');
3136 return element;
3137 }
3138
3139 if (value < 0.00001) value = 0;
3140
3141 style.filter = stripAlphaFromFilter_IE(filter) +
3142 'alpha(opacity=' + (value * 100) + ')';
3143
3144 return element;
3145 }
3146
3147
3148 function getOpacity(element) {
3149 return Element.getStyle(element, 'opacity');
3150 }
3151
3152 function getOpacity_IE(element) {
3153 if (STANDARD_CSS_OPACITY_SUPPORTED)
3154 return getOpacity(element);
3155
3156 var filter = Element.getStyle(element, 'filter');
3157 if (filter.length === 0) return 1.0;
3158 var match = (filter || '').match(/alpha\(opacity=(.*)\)/);
3159 if (match[1]) return parseFloat(match[1]) / 100;
3160 return 1.0;
3161 }
3162
3163
3164 Object.extend(methods, {
3165 setStyle: setStyle,
3166 getStyle: getStyle,
3167 setOpacity: setOpacity,
3168 getOpacity: getOpacity
3169 });
3170
3171 if ('styleFloat' in DIV.style) {
3172 methods.getStyle = getStyle_IE;
3173 methods.setOpacity = setOpacity_IE;
3174 methods.getOpacity = getOpacity_IE;
3175 }
3176
3177 var UID = 0;
3178
3179 GLOBAL.Element.Storage = { UID: 1 };
3180
3181 function getUniqueElementID(element) {
3182 if (element === window) return 0;
3183
3184 if (typeof element._prototypeUID === 'undefined')
3185 element._prototypeUID = Element.Storage.UID++;
3186 return element._prototypeUID;
3187 }
3188
3189 function getUniqueElementID_IE(element) {
3190 if (element === window) return 0;
3191 if (element == document) return 1;
3192 return element.uniqueID;
3193 }
3194
3195 var HAS_UNIQUE_ID_PROPERTY = ('uniqueID' in DIV);
3196 if (HAS_UNIQUE_ID_PROPERTY)
3197 getUniqueElementID = getUniqueElementID_IE;
3198
3199 function getStorage(element) {
3200 if (!(element = $(element))) return;
3201
3202 var uid = getUniqueElementID(element);
3203
3204 if (!Element.Storage[uid])
3205 Element.Storage[uid] = $H();
3206
3207 return Element.Storage[uid];
3208 }
3209
3210 function store(element, key, value) {
3211 if (!(element = $(element))) return;
3212 var storage = getStorage(element);
3213 if (arguments.length === 2) {
3214 storage.update(key);
3215 } else {
3216 storage.set(key, value);
3217 }
3218 return element;
3219 }
3220
3221 function retrieve(element, key, defaultValue) {
3222 if (!(element = $(element))) return;
3223 var storage = getStorage(element), value = storage.get(key);
3224
3225 if (Object.isUndefined(value)) {
3226 storage.set(key, defaultValue);
3227 value = defaultValue;
3228 }
3229
3230 return value;
3231 }
3232
3233
3234 Object.extend(methods, {
3235 getStorage: getStorage,
3236 store: store,
3237 retrieve: retrieve
3238 });
3239
3240
3241 var Methods = {}, ByTag = Element.Methods.ByTag,
3242 F = Prototype.BrowserFeatures;
3243
3244 if (!F.ElementExtensions && ('__proto__' in DIV)) {
3245 GLOBAL.HTMLElement = {};
3246 GLOBAL.HTMLElement.prototype = DIV['__proto__'];
3247 F.ElementExtensions = true;
3248 }
3249
3250 function checkElementPrototypeDeficiency(tagName) {
3251 if (typeof window.Element === 'undefined') return false;
3252 var proto = window.Element.prototype;
3253 if (proto) {
3254 var id = '_' + (Math.random() + '').slice(2),
3255 el = document.createElement(tagName);
3256 proto[id] = 'x';
3257 var isBuggy = (el[id] !== 'x');
3258 delete proto[id];
3259 el = null;
3260 return isBuggy;
3261 }
3262
3263 return false;
3264 }
3265
3266 var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY =
3267 checkElementPrototypeDeficiency('object');
3268
3269 function extendElementWith(element, methods) {
3270 for (var property in methods) {
3271 var value = methods[property];
3272 if (Object.isFunction(value) && !(property in element))
3273 element[property] = value.methodize();
3274 }
3275 }
3276
3277 var EXTENDED = {};
3278 function elementIsExtended(element) {
3279 var uid = getUniqueElementID(element);
3280 return (uid in EXTENDED);
3281 }
3282
3283 function extend(element) {
3284 if (!element || elementIsExtended(element)) return element;
3285 if (element.nodeType !== Node.ELEMENT_NODE || element == window)
3286 return element;
3287
3288 var methods = Object.clone(Methods),
3289 tagName = element.tagName.toUpperCase();
3290
3291 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
3292
3293 extendElementWith(element, methods);
3294 EXTENDED[getUniqueElementID(element)] = true;
3295 return element;
3296 }
3297
3298 function extend_IE8(element) {
3299 if (!element || elementIsExtended(element)) return element;
3300
3301 var t = element.tagName;
3302 if (t && (/^(?:object|applet|embed)$/i.test(t))) {
3303 extendElementWith(element, Element.Methods);
3304 extendElementWith(element, Element.Methods.Simulated);
3305 extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
3306 }
3307
3308 return element;
3309 }
3310
3311 if (F.SpecificElementExtensions) {
3312 extend = HTMLOBJECTELEMENT_PROTOTYPE_BUGGY ? extend_IE8 : Prototype.K;
3313 }
3314
3315 function addMethodsToTagName(tagName, methods) {
3316 tagName = tagName.toUpperCase();
3317 if (!ByTag[tagName]) ByTag[tagName] = {};
3318 Object.extend(ByTag[tagName], methods);
3319 }
3320
3321 function mergeMethods(destination, methods, onlyIfAbsent) {
3322 if (Object.isUndefined(onlyIfAbsent)) onlyIfAbsent = false;
3323 for (var property in methods) {
3324 var value = methods[property];
3325 if (!Object.isFunction(value)) continue;
3326 if (!onlyIfAbsent || !(property in destination))
3327 destination[property] = value.methodize();
3328 }
3329 }
3330
3331 function findDOMClass(tagName) {
3332 var klass;
3333 var trans = {
3334 "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
3335 "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
3336 "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
3337 "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
3338 "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
3339 "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
3340 "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
3341 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
3342 "FrameSet", "IFRAME": "IFrame"
3343 };
3344 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
3345 if (window[klass]) return window[klass];
3346 klass = 'HTML' + tagName + 'Element';
3347 if (window[klass]) return window[klass];
3348 klass = 'HTML' + tagName.capitalize() + 'Element';
3349 if (window[klass]) return window[klass];
3350
3351 var element = document.createElement(tagName),
3352 proto = element['__proto__'] || element.constructor.prototype;
3353
3354 element = null;
3355 return proto;
3356 }
3357
3358 function addMethods(methods) {
3359 if (arguments.length === 0) addFormMethods();
3360
3361 if (arguments.length === 2) {
3362 var tagName = methods;
3363 methods = arguments[1];
3364 }
3365
3366 if (!tagName) {
3367 Object.extend(Element.Methods, methods || {});
3368 } else {
3369 if (Object.isArray(tagName)) {
3370 for (var i = 0, tag; tag = tagName[i]; i++)
3371 addMethodsToTagName(tag, methods);
3372 } else {
3373 addMethodsToTagName(tagName, methods);
3374 }
3375 }
3376
3377 var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype :
3378 Element.prototype;
3379
3380 if (F.ElementExtensions) {
3381 mergeMethods(ELEMENT_PROTOTYPE, Element.Methods);
3382 mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true);
3383 }
3384
3385 if (F.SpecificElementExtensions) {
3386 for (var tag in Element.Methods.ByTag) {
3387 var klass = findDOMClass(tag);
3388 if (Object.isUndefined(klass)) continue;
3389 mergeMethods(klass.prototype, ByTag[tag]);
3390 }
3391 }
3392
3393 Object.extend(Element, Element.Methods);
3394 Object.extend(Element, Element.Methods.Simulated);
3395 delete Element.ByTag;
3396 delete Element.Simulated;
3397
3398 Element.extend.refresh();
3399
3400 ELEMENT_CACHE = {};
3401 }
3402
3403 Object.extend(GLOBAL.Element, {
3404 extend: extend,
3405 addMethods: addMethods
3406 });
3407
3408 if (extend === Prototype.K) {
3409 GLOBAL.Element.extend.refresh = Prototype.emptyFunction;
3410 } else {
3411 GLOBAL.Element.extend.refresh = function() {
3412 if (Prototype.BrowserFeatures.ElementExtensions) return;
3413 Object.extend(Methods, Element.Methods);
3414 Object.extend(Methods, Element.Methods.Simulated);
3415
3416 EXTENDED = {};
3417 };
3418 }
3419
3420 function addFormMethods() {
3421 Object.extend(Form, Form.Methods);
3422 Object.extend(Form.Element, Form.Element.Methods);
3423 Object.extend(Element.Methods.ByTag, {
3424 "FORM": Object.clone(Form.Methods),
3425 "INPUT": Object.clone(Form.Element.Methods),
3426 "SELECT": Object.clone(Form.Element.Methods),
3427 "TEXTAREA": Object.clone(Form.Element.Methods),
3428 "BUTTON": Object.clone(Form.Element.Methods)
3429 });
3430 }
3431
3432 Element.addMethods(methods);
3433
3434})(this);
3435(function() {
3436
3437 function toDecimal(pctString) {
3438 var match = pctString.match(/^(\d+)%?$/i);
3439 if (!match) return null;
3440 return (Number(match[1]) / 100);
3441 }
3442
3443 function getRawStyle(element, style) {
3444 element = $(element);
3445
3446 var value = element.style[style];
3447 if (!value || value === 'auto') {
3448 var css = document.defaultView.getComputedStyle(element, null);
3449 value = css ? css[style] : null;
3450 }
3451
3452 if (style === 'opacity') return value ? parseFloat(value) : 1.0;
3453 return value === 'auto' ? null : value;
3454 }
3455
3456 function getRawStyle_IE(element, style) {
3457 var value = element.style[style];
3458 if (!value && element.currentStyle) {
3459 value = element.currentStyle[style];
3460 }
3461 return value;
3462 }
3463
3464 function getContentWidth(element, context) {
3465 var boxWidth = element.offsetWidth;
3466
3467 var bl = getPixelValue(element, 'borderLeftWidth', context) || 0;
3468 var br = getPixelValue(element, 'borderRightWidth', context) || 0;
3469 var pl = getPixelValue(element, 'paddingLeft', context) || 0;
3470 var pr = getPixelValue(element, 'paddingRight', context) || 0;
3471
3472 return boxWidth - bl - br - pl - pr;
3473 }
3474
3475 if ('currentStyle' in document.documentElement) {
3476 getRawStyle = getRawStyle_IE;
3477 }
3478
3479
3480 function getPixelValue(value, property, context) {
3481 var element = null;
3482 if (Object.isElement(value)) {
3483 element = value;
3484 value = getRawStyle(element, property);
3485 }
3486
3487 if (value === null || Object.isUndefined(value)) {
3488 return null;
3489 }
3490
3491 if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3492 return window.parseFloat(value);
3493 }
3494
3495 var isPercentage = value.include('%'), isViewport = (context === document.viewport);
3496
3497 if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3498 var style = element.style.left, rStyle = element.runtimeStyle.left;
3499 element.runtimeStyle.left = element.currentStyle.left;
3500 element.style.left = value || 0;
3501 value = element.style.pixelLeft;
3502 element.style.left = style;
3503 element.runtimeStyle.left = rStyle;
3504
3505 return value;
3506 }
3507
3508 if (element && isPercentage) {
3509 context = context || element.parentNode;
3510 var decimal = toDecimal(value), whole = null;
3511
3512 var isHorizontal = property.include('left') || property.include('right') ||
3513 property.include('width');
3514
3515 var isVertical = property.include('top') || property.include('bottom') ||
3516 property.include('height');
3517
3518 if (context === document.viewport) {
3519 if (isHorizontal) {
3520 whole = document.viewport.getWidth();
3521 } else if (isVertical) {
3522 whole = document.viewport.getHeight();
3523 }
3524 } else {
3525 if (isHorizontal) {
3526 whole = $(context).measure('width');
3527 } else if (isVertical) {
3528 whole = $(context).measure('height');
3529 }
3530 }
3531
3532 return (whole === null) ? 0 : whole * decimal;
3533 }
3534
3535 return 0;
3536 }
3537
3538 function toCSSPixels(number) {
3539 if (Object.isString(number) && number.endsWith('px'))
3540 return number;
3541 return number + 'px';
3542 }
3543
3544 function isDisplayed(element) {
3545 while (element && element.parentNode) {
3546 var display = element.getStyle('display');
3547 if (display === 'none') {
3548 return false;
3549 }
3550 element = $(element.parentNode);
3551 }
3552 return true;
3553 }
3554
3555 var hasLayout = Prototype.K;
3556 if ('currentStyle' in document.documentElement) {
3557 hasLayout = function(element) {
3558 if (!element.currentStyle.hasLayout) {
3559 element.style.zoom = 1;
3560 }
3561 return element;
3562 };
3563 }
3564
3565 function cssNameFor(key) {
3566 if (key.include('border')) key = key + '-width';
3567 return key.camelize();
3568 }
3569
3570 Element.Layout = Class.create(Hash, {
3571 initialize: function($super, element, preCompute) {
3572 $super();
3573 this.element = $(element);
3574
3575 Element.Layout.PROPERTIES.each( function(property) {
3576 this._set(property, null);
3577 }, this);
3578
3579 if (preCompute) {
3580 this._preComputing = true;
3581 this._begin();
3582 Element.Layout.PROPERTIES.each( this._compute, this );
3583 this._end();
3584 this._preComputing = false;
3585 }
3586 },
3587
3588 _set: function(property, value) {
3589 return Hash.prototype.set.call(this, property, value);
3590 },
3591
3592 set: function(property, value) {
3593 throw "Properties of Element.Layout are read-only.";
3594 },
3595
3596 get: function($super, property) {
3597 var value = $super(property);
3598 return value === null ? this._compute(property) : value;
3599 },
3600
3601 _begin: function() {
3602 if (this._isPrepared()) return;
3603
3604 var element = this.element;
3605 if (isDisplayed(element)) {
3606 this._setPrepared(true);
3607 return;
3608 }
3609
3610
3611 var originalStyles = {
3612 position: element.style.position || '',
3613 width: element.style.width || '',
3614 visibility: element.style.visibility || '',
3615 display: element.style.display || ''
3616 };
3617
3618 element.store('prototype_original_styles', originalStyles);
3619
3620 var position = getRawStyle(element, 'position'), width = element.offsetWidth;
3621
3622 if (width === 0 || width === null) {
3623 element.style.display = 'block';
3624 width = element.offsetWidth;
3625 }
3626
3627 var context = (position === 'fixed') ? document.viewport :
3628 element.parentNode;
3629
3630 var tempStyles = {
3631 visibility: 'hidden',
3632 display: 'block'
3633 };
3634
3635 if (position !== 'fixed') tempStyles.position = 'absolute';
3636
3637 element.setStyle(tempStyles);
3638
3639 var positionedWidth = element.offsetWidth, newWidth;
3640 if (width && (positionedWidth === width)) {
3641 newWidth = getContentWidth(element, context);
3642 } else if (position === 'absolute' || position === 'fixed') {
3643 newWidth = getContentWidth(element, context);
3644 } else {
3645 var parent = element.parentNode, pLayout = $(parent).getLayout();
3646
3647 newWidth = pLayout.get('width') -
3648 this.get('margin-left') -
3649 this.get('border-left') -
3650 this.get('padding-left') -
3651 this.get('padding-right') -
3652 this.get('border-right') -
3653 this.get('margin-right');
3654 }
3655
3656 element.setStyle({ width: newWidth + 'px' });
3657
3658 this._setPrepared(true);
3659 },
3660
3661 _end: function() {
3662 var element = this.element;
3663 var originalStyles = element.retrieve('prototype_original_styles');
3664 element.store('prototype_original_styles', null);
3665 element.setStyle(originalStyles);
3666 this._setPrepared(false);
3667 },
3668
3669 _compute: function(property) {
3670 var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3671 if (!(property in COMPUTATIONS)) {
3672 throw "Property not found.";
3673 }
3674
3675 return this._set(property, COMPUTATIONS[property].call(this, this.element));
3676 },
3677
3678 _isPrepared: function() {
3679 return this.element.retrieve('prototype_element_layout_prepared', false);
3680 },
3681
3682 _setPrepared: function(bool) {
3683 return this.element.store('prototype_element_layout_prepared', bool);
3684 },
3685
3686 toObject: function() {
3687 var args = $A(arguments);
3688 var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3689 args.join(' ').split(' ');
3690 var obj = {};
3691 keys.each( function(key) {
3692 if (!Element.Layout.PROPERTIES.include(key)) return;
3693 var value = this.get(key);
3694 if (value != null) obj[key] = value;
3695 }, this);
3696 return obj;
3697 },
3698
3699 toHash: function() {
3700 var obj = this.toObject.apply(this, arguments);
3701 return new Hash(obj);
3702 },
3703
3704 toCSS: function() {
3705 var args = $A(arguments);
3706 var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3707 args.join(' ').split(' ');
3708 var css = {};
3709
3710 keys.each( function(key) {
3711 if (!Element.Layout.PROPERTIES.include(key)) return;
3712 if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3713
3714 var value = this.get(key);
3715 if (value != null) css[cssNameFor(key)] = value + 'px';
3716 }, this);
3717 return css;
3718 },
3719
3720 inspect: function() {
3721 return "#<Element.Layout>";
3722 }
3723 });
3724
3725 Object.extend(Element.Layout, {
3726 PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3727
3728 COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3729
3730 COMPUTATIONS: {
3731 'height': function(element) {
3732 if (!this._preComputing) this._begin();
3733
3734 var bHeight = this.get('border-box-height');
3735 if (bHeight <= 0) {
3736 if (!this._preComputing) this._end();
3737 return 0;
3738 }
3739
3740 var bTop = this.get('border-top'),
3741 bBottom = this.get('border-bottom');
3742
3743 var pTop = this.get('padding-top'),
3744 pBottom = this.get('padding-bottom');
3745
3746 if (!this._preComputing) this._end();
3747
3748 return bHeight - bTop - bBottom - pTop - pBottom;
3749 },
3750
3751 'width': function(element) {
3752 if (!this._preComputing) this._begin();
3753
3754 var bWidth = this.get('border-box-width');
3755 if (bWidth <= 0) {
3756 if (!this._preComputing) this._end();
3757 return 0;
3758 }
3759
3760 var bLeft = this.get('border-left'),
3761 bRight = this.get('border-right');
3762
3763 var pLeft = this.get('padding-left'),
3764 pRight = this.get('padding-right');
3765
3766 if (!this._preComputing) this._end();
3767 return bWidth - bLeft - bRight - pLeft - pRight;
3768 },
3769
3770 'padding-box-height': function(element) {
3771 var height = this.get('height'),
3772 pTop = this.get('padding-top'),
3773 pBottom = this.get('padding-bottom');
3774
3775 return height + pTop + pBottom;
3776 },
3777
3778 'padding-box-width': function(element) {
3779 var width = this.get('width'),
3780 pLeft = this.get('padding-left'),
3781 pRight = this.get('padding-right');
3782
3783 return width + pLeft + pRight;
3784 },
3785
3786 'border-box-height': function(element) {
3787 if (!this._preComputing) this._begin();
3788 var height = element.offsetHeight;
3789 if (!this._preComputing) this._end();
3790 return height;
3791 },
3792
3793 'border-box-width': function(element) {
3794 if (!this._preComputing) this._begin();
3795 var width = element.offsetWidth;
3796 if (!this._preComputing) this._end();
3797 return width;
3798 },
3799
3800 'margin-box-height': function(element) {
3801 var bHeight = this.get('border-box-height'),
3802 mTop = this.get('margin-top'),
3803 mBottom = this.get('margin-bottom');
3804
3805 if (bHeight <= 0) return 0;
3806
3807 return bHeight + mTop + mBottom;
3808 },
3809
3810 'margin-box-width': function(element) {
3811 var bWidth = this.get('border-box-width'),
3812 mLeft = this.get('margin-left'),
3813 mRight = this.get('margin-right');
3814
3815 if (bWidth <= 0) return 0;
3816
3817 return bWidth + mLeft + mRight;
3818 },
3819
3820 'top': function(element) {
3821 var offset = element.positionedOffset();
3822 return offset.top;
3823 },
3824
3825 'bottom': function(element) {
3826 var offset = element.positionedOffset(),
3827 parent = element.getOffsetParent(),
3828 pHeight = parent.measure('height');
3829
3830 var mHeight = this.get('border-box-height');
3831
3832 return pHeight - mHeight - offset.top;
3833 },
3834
3835 'left': function(element) {
3836 var offset = element.positionedOffset();
3837 return offset.left;
3838 },
3839
3840 'right': function(element) {
3841 var offset = element.positionedOffset(),
3842 parent = element.getOffsetParent(),
3843 pWidth = parent.measure('width');
3844
3845 var mWidth = this.get('border-box-width');
3846
3847 return pWidth - mWidth - offset.left;
3848 },
3849
3850 'padding-top': function(element) {
3851 return getPixelValue(element, 'paddingTop');
3852 },
3853
3854 'padding-bottom': function(element) {
3855 return getPixelValue(element, 'paddingBottom');
3856 },
3857
3858 'padding-left': function(element) {
3859 return getPixelValue(element, 'paddingLeft');
3860 },
3861
3862 'padding-right': function(element) {
3863 return getPixelValue(element, 'paddingRight');
3864 },
3865
3866 'border-top': function(element) {
3867 return getPixelValue(element, 'borderTopWidth');
3868 },
3869
3870 'border-bottom': function(element) {
3871 return getPixelValue(element, 'borderBottomWidth');
3872 },
3873
3874 'border-left': function(element) {
3875 return getPixelValue(element, 'borderLeftWidth');
3876 },
3877
3878 'border-right': function(element) {
3879 return getPixelValue(element, 'borderRightWidth');
3880 },
3881
3882 'margin-top': function(element) {
3883 return getPixelValue(element, 'marginTop');
3884 },
3885
3886 'margin-bottom': function(element) {
3887 return getPixelValue(element, 'marginBottom');
3888 },
3889
3890 'margin-left': function(element) {
3891 return getPixelValue(element, 'marginLeft');
3892 },
3893
3894 'margin-right': function(element) {
3895 return getPixelValue(element, 'marginRight');
3896 }
3897 }
3898 });
3899
3900 if ('getBoundingClientRect' in document.documentElement) {
3901 Object.extend(Element.Layout.COMPUTATIONS, {
3902 'right': function(element) {
3903 var parent = hasLayout(element.getOffsetParent());
3904 var rect = element.getBoundingClientRect(),
3905 pRect = parent.getBoundingClientRect();
3906
3907 return (pRect.right - rect.right).round();
3908 },
3909
3910 'bottom': function(element) {
3911 var parent = hasLayout(element.getOffsetParent());
3912 var rect = element.getBoundingClientRect(),
3913 pRect = parent.getBoundingClientRect();
3914
3915 return (pRect.bottom - rect.bottom).round();
3916 }
3917 });
3918 }
3919
3920 Element.Offset = Class.create({
3921 initialize: function(left, top) {
3922 this.left = left.round();
3923 this.top = top.round();
3924
3925 this[0] = this.left;
3926 this[1] = this.top;
3927 },
3928
3929 relativeTo: function(offset) {
3930 return new Element.Offset(
3931 this.left - offset.left,
3932 this.top - offset.top
3933 );
3934 },
3935
3936 inspect: function() {
3937 return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3938 },
3939
3940 toString: function() {
3941 return "[#{left}, #{top}]".interpolate(this);
3942 },
3943
3944 toArray: function() {
3945 return [this.left, this.top];
3946 }
3947 });
3948
3949 function getLayout(element, preCompute) {
3950 return new Element.Layout(element, preCompute);
3951 }
3952
3953 function measure(element, property) {
3954 return $(element).getLayout().get(property);
3955 }
3956
3957 function getHeight(element) {
3958 return Element.getDimensions(element).height;
3959 }
3960
3961 function getWidth(element) {
3962 return Element.getDimensions(element).width;
3963 }
3964
3965 function getDimensions(element) {
3966 element = $(element);
3967 var display = Element.getStyle(element, 'display');
3968
3969 if (display && display !== 'none') {
3970 return { width: element.offsetWidth, height: element.offsetHeight };
3971 }
3972
3973 var style = element.style;
3974 var originalStyles = {
3975 visibility: style.visibility,
3976 position: style.position,
3977 display: style.display
3978 };
3979
3980 var newStyles = {
3981 visibility: 'hidden',
3982 display: 'block'
3983 };
3984
3985 if (originalStyles.position !== 'fixed')
3986 newStyles.position = 'absolute';
3987
3988 Element.setStyle(element, newStyles);
3989
3990 var dimensions = {
3991 width: element.offsetWidth,
3992 height: element.offsetHeight
3993 };
3994
3995 Element.setStyle(element, originalStyles);
3996
3997 return dimensions;
3998 }
3999
4000 function getOffsetParent(element) {
4001 element = $(element);
4002
4003 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
4004 return $(document.body);
4005
4006 var isInline = (Element.getStyle(element, 'display') === 'inline');
4007 if (!isInline && element.offsetParent) return $(element.offsetParent);
4008
4009 while ((element = element.parentNode) && element !== document.body) {
4010 if (Element.getStyle(element, 'position') !== 'static') {
4011 return isHtml(element) ? $(document.body) : $(element);
4012 }
4013 }
4014
4015 return $(document.body);
4016 }
4017
4018
4019 function cumulativeOffset(element) {
4020 element = $(element);
4021 var valueT = 0, valueL = 0;
4022 if (element.parentNode) {
4023 do {
4024 valueT += element.offsetTop || 0;
4025 valueL += element.offsetLeft || 0;
4026 element = element.offsetParent;
4027 } while (element);
4028 }
4029 return new Element.Offset(valueL, valueT);
4030 }
4031
4032 function positionedOffset(element) {
4033 element = $(element);
4034
4035 var layout = element.getLayout();
4036
4037 var valueT = 0, valueL = 0;
4038 do {
4039 valueT += element.offsetTop || 0;
4040 valueL += element.offsetLeft || 0;
4041 element = element.offsetParent;
4042 if (element) {
4043 if (isBody(element)) break;
4044 var p = Element.getStyle(element, 'position');
4045 if (p !== 'static') break;
4046 }
4047 } while (element);
4048
4049 valueL -= layout.get('margin-top');
4050 valueT -= layout.get('margin-left');
4051
4052 return new Element.Offset(valueL, valueT);
4053 }
4054
4055 function cumulativeScrollOffset(element) {
4056 var valueT = 0, valueL = 0;
4057 do {
4058 valueT += element.scrollTop || 0;
4059 valueL += element.scrollLeft || 0;
4060 element = element.parentNode;
4061 } while (element);
4062 return new Element.Offset(valueL, valueT);
4063 }
4064
4065 function viewportOffset(forElement) {
4066 var valueT = 0, valueL = 0, docBody = document.body;
4067
4068 var element = $(forElement);
4069 do {
4070 valueT += element.offsetTop || 0;
4071 valueL += element.offsetLeft || 0;
4072 if (element.offsetParent == docBody &&
4073 Element.getStyle(element, 'position') == 'absolute') break;
4074 } while (element = element.offsetParent);
4075
4076 element = forElement;
4077 do {
4078 if (element != docBody) {
4079 valueT -= element.scrollTop || 0;
4080 valueL -= element.scrollLeft || 0;
4081 }
4082 } while (element = element.parentNode);
4083 return new Element.Offset(valueL, valueT);
4084 }
4085
4086 function absolutize(element) {
4087 element = $(element);
4088
4089 if (Element.getStyle(element, 'position') === 'absolute') {
4090 return element;
4091 }
4092
4093 var offsetParent = getOffsetParent(element);
4094 var eOffset = element.viewportOffset(),
4095 pOffset = offsetParent.viewportOffset();
4096
4097 var offset = eOffset.relativeTo(pOffset);
4098 var layout = element.getLayout();
4099
4100 element.store('prototype_absolutize_original_styles', {
4101 left: element.getStyle('left'),
4102 top: element.getStyle('top'),
4103 width: element.getStyle('width'),
4104 height: element.getStyle('height')
4105 });
4106
4107 element.setStyle({
4108 position: 'absolute',
4109 top: offset.top + 'px',
4110 left: offset.left + 'px',
4111 width: layout.get('width') + 'px',
4112 height: layout.get('height') + 'px'
4113 });
4114
4115 return element;
4116 }
4117
4118 function relativize(element) {
4119 element = $(element);
4120 if (Element.getStyle(element, 'position') === 'relative') {
4121 return element;
4122 }
4123
4124 var originalStyles =
4125 element.retrieve('prototype_absolutize_original_styles');
4126
4127 if (originalStyles) element.setStyle(originalStyles);
4128 return element;
4129 }
4130
4131
4132 function scrollTo(element) {
4133 element = $(element);
4134 var pos = Element.cumulativeOffset(element);
4135 window.scrollTo(pos.left, pos.top);
4136 return element;
4137 }
4138
4139
4140 function makePositioned(element) {
4141 element = $(element);
4142 var position = Element.getStyle(element, 'position'), styles = {};
4143 if (position === 'static' || !position) {
4144 styles.position = 'relative';
4145 if (Prototype.Browser.Opera) {
4146 styles.top = 0;
4147 styles.left = 0;
4148 }
4149 Element.setStyle(element, styles);
4150 Element.store(element, 'prototype_made_positioned', true);
4151 }
4152 return element;
4153 }
4154
4155 function undoPositioned(element) {
4156 element = $(element);
4157 var storage = Element.getStorage(element),
4158 madePositioned = storage.get('prototype_made_positioned');
4159
4160 if (madePositioned) {
4161 storage.unset('prototype_made_positioned');
4162 Element.setStyle(element, {
4163 position: '',
4164 top: '',
4165 bottom: '',
4166 left: '',
4167 right: ''
4168 });
4169 }
4170 return element;
4171 }
4172
4173 function makeClipping(element) {
4174 element = $(element);
4175
4176 var storage = Element.getStorage(element),
4177 madeClipping = storage.get('prototype_made_clipping');
4178
4179 if (Object.isUndefined(madeClipping)) {
4180 var overflow = Element.getStyle(element, 'overflow');
4181 storage.set('prototype_made_clipping', overflow);
4182 if (overflow !== 'hidden')
4183 element.style.overflow = 'hidden';
4184 }
4185
4186 return element;
4187 }
4188
4189 function undoClipping(element) {
4190 element = $(element);
4191 var storage = Element.getStorage(element),
4192 overflow = storage.get('prototype_made_clipping');
4193
4194 if (!Object.isUndefined(overflow)) {
4195 storage.unset('prototype_made_clipping');
4196 element.style.overflow = overflow || '';
4197 }
4198
4199 return element;
4200 }
4201
4202 function clonePosition(element, source, options) {
4203 options = Object.extend({
4204 setLeft: true,
4205 setTop: true,
4206 setWidth: true,
4207 setHeight: true,
4208 offsetTop: 0,
4209 offsetLeft: 0
4210 }, options || {});
4211
4212 source = $(source);
4213 element = $(element);
4214 var p, delta, layout, styles = {};
4215
4216 if (options.setLeft || options.setTop) {
4217 p = Element.viewportOffset(source);
4218 delta = [0, 0];
4219 if (Element.getStyle(element, 'position') === 'absolute') {
4220 var parent = Element.getOffsetParent(element);
4221 if (parent !== document.body) delta = Element.viewportOffset(parent);
4222 }
4223 }
4224
4225 if (options.setWidth || options.setHeight) {
4226 layout = Element.getLayout(source);
4227 }
4228
4229 if (options.setLeft)
4230 styles.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
4231 if (options.setTop)
4232 styles.top = (p[1] - delta[1] + options.offsetTop) + 'px';
4233
4234 if (options.setWidth)
4235 styles.width = layout.get('border-box-width') + 'px';
4236 if (options.setHeight)
4237 styles.height = layout.get('border-box-height') + 'px';
4238
4239 return Element.setStyle(element, styles);
4240 }
4241
4242
4243 if (Prototype.Browser.IE) {
4244 getOffsetParent = getOffsetParent.wrap(
4245 function(proceed, element) {
4246 element = $(element);
4247
4248 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
4249 return $(document.body);
4250
4251 var position = element.getStyle('position');
4252 if (position !== 'static') return proceed(element);
4253
4254 element.setStyle({ position: 'relative' });
4255 var value = proceed(element);
4256 element.setStyle({ position: position });
4257 return value;
4258 }
4259 );
4260
4261 positionedOffset = positionedOffset.wrap(function(proceed, element) {
4262 element = $(element);
4263 if (!element.parentNode) return new Element.Offset(0, 0);
4264 var position = element.getStyle('position');
4265 if (position !== 'static') return proceed(element);
4266
4267 var offsetParent = element.getOffsetParent();
4268 if (offsetParent && offsetParent.getStyle('position') === 'fixed')
4269 hasLayout(offsetParent);
4270
4271 element.setStyle({ position: 'relative' });
4272 var value = proceed(element);
4273 element.setStyle({ position: position });
4274 return value;
4275 });
4276 } else if (Prototype.Browser.Webkit) {
4277 cumulativeOffset = function(element) {
4278 element = $(element);
4279 var valueT = 0, valueL = 0;
4280 do {
4281 valueT += element.offsetTop || 0;
4282 valueL += element.offsetLeft || 0;
4283 if (element.offsetParent == document.body) {
4284 if (Element.getStyle(element, 'position') == 'absolute') break;
4285 }
4286
4287 element = element.offsetParent;
4288 } while (element);
4289
4290 return new Element.Offset(valueL, valueT);
4291 };
4292 }
4293
4294
4295 Element.addMethods({
4296 getLayout: getLayout,
4297 measure: measure,
4298 getWidth: getWidth,
4299 getHeight: getHeight,
4300 getDimensions: getDimensions,
4301 getOffsetParent: getOffsetParent,
4302 cumulativeOffset: cumulativeOffset,
4303 positionedOffset: positionedOffset,
4304 cumulativeScrollOffset: cumulativeScrollOffset,
4305 viewportOffset: viewportOffset,
4306 absolutize: absolutize,
4307 relativize: relativize,
4308 scrollTo: scrollTo,
4309 makePositioned: makePositioned,
4310 undoPositioned: undoPositioned,
4311 makeClipping: makeClipping,
4312 undoClipping: undoClipping,
4313 clonePosition: clonePosition
4314 });
4315
4316 function isBody(element) {
4317 return element.nodeName.toUpperCase() === 'BODY';
4318 }
4319
4320 function isHtml(element) {
4321 return element.nodeName.toUpperCase() === 'HTML';
4322 }
4323
4324 function isDocument(element) {
4325 return element.nodeType === Node.DOCUMENT_NODE;
4326 }
4327
4328 function isDetached(element) {
4329 return element !== document.body &&
4330 !Element.descendantOf(element, document.body);
4331 }
4332
4333 if ('getBoundingClientRect' in document.documentElement) {
4334 Element.addMethods({
4335 viewportOffset: function(element) {
4336 element = $(element);
4337 if (isDetached(element)) return new Element.Offset(0, 0);
4338
4339 var rect = element.getBoundingClientRect(),
4340 docEl = document.documentElement;
4341 return new Element.Offset(rect.left - docEl.clientLeft,
4342 rect.top - docEl.clientTop);
4343 }
4344 });
4345 }
4346
4347
4348})();
4349
4350(function() {
4351
4352 var IS_OLD_OPERA = Prototype.Browser.Opera &&
4353 (window.parseFloat(window.opera.version()) < 9.5);
4354 var ROOT = null;
4355 function getRootElement() {
4356 if (ROOT) return ROOT;
4357 ROOT = IS_OLD_OPERA ? document.body : document.documentElement;
4358 return ROOT;
4359 }
4360
4361 function getDimensions() {
4362 return { width: this.getWidth(), height: this.getHeight() };
4363 }
4364
4365 function getWidth() {
4366 return getRootElement().clientWidth;
4367 }
4368
4369 function getHeight() {
4370 return getRootElement().clientHeight;
4371 }
4372
4373 function getScrollOffsets() {
4374 var x = window.pageXOffset || document.documentElement.scrollLeft ||
4375 document.body.scrollLeft;
4376 var y = window.pageYOffset || document.documentElement.scrollTop ||
4377 document.body.scrollTop;
4378
4379 return new Element.Offset(x, y);
4380 }
4381
4382 document.viewport = {
4383 getDimensions: getDimensions,
4384 getWidth: getWidth,
4385 getHeight: getHeight,
4386 getScrollOffsets: getScrollOffsets
4387 };
4388
4389})();
4390window.$$ = function() {
4391 var expression = $A(arguments).join(', ');
4392 return Prototype.Selector.select(expression, document);
4393};
4394
4395Prototype.Selector = (function() {
4396
4397 function select() {
4398 throw new Error('Method "Prototype.Selector.select" must be defined.');
4399 }
4400
4401 function match() {
4402 throw new Error('Method "Prototype.Selector.match" must be defined.');
4403 }
4404
4405 function find(elements, expression, index) {
4406 index = index || 0;
4407 var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
4408
4409 for (i = 0; i < length; i++) {
4410 if (match(elements[i], expression) && index == matchIndex++) {
4411 return Element.extend(elements[i]);
4412 }
4413 }
4414 }
4415
4416 function extendElements(elements) {
4417 for (var i = 0, length = elements.length; i < length; i++) {
4418 Element.extend(elements[i]);
4419 }
4420 return elements;
4421 }
4422
4423
4424 var K = Prototype.K;
4425
4426 return {
4427 select: select,
4428 match: match,
4429 find: find,
4430 extendElements: (Element.extend === K) ? K : extendElements,
4431 extendElement: Element.extend
4432 };
4433})();
4434/*!
4435 * Sizzle CSS Selector Engine
4436 * Copyright 2011, The Dojo Foundation
4437 * Released under the MIT, BSD, and GPL Licenses.
4438 * More information: http://sizzlejs.com/
4439 */
4440(function(){
4441
4442var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
4443	done = 0,
4444	toString = Object.prototype.toString,
4445	hasDuplicate = false,
4446	baseHasDuplicate = true,
4447	rBackslash = /\\/g,
4448	rNonWord = /\W/;
4449
4450[0, 0].sort(function() {
4451	baseHasDuplicate = false;
4452	return 0;
4453});
4454
4455var Sizzle = function( selector, context, results, seed ) {
4456	results = results || [];
4457	context = context || document;
4458
4459	var origContext = context;
4460
4461	if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
4462		return [];
4463	}
4464
4465	if ( !selector || typeof selector !== "string" ) {
4466		return results;
4467	}
4468
4469	var m, set, checkSet, extra, ret, cur, pop, i,
4470		prune = true,
4471		contextXML = Sizzle.isXML( context ),
4472		parts = [],
4473		soFar = selector;
4474
4475	do {
4476		chunker.exec( "" );
4477		m = chunker.exec( soFar );
4478
4479		if ( m ) {
4480			soFar = m[3];
4481
4482			parts.push( m[1] );
4483
4484			if ( m[2] ) {
4485				extra = m[3];
4486				break;
4487			}
4488		}
4489	} while ( m );
4490
4491	if ( parts.length > 1 && origPOS.exec( selector ) ) {
4492
4493		if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4494			set = posProcess( parts[0] + parts[1], context );
4495
4496		} else {
4497			set = Expr.relative[ parts[0] ] ?
4498				[ context ] :
4499				Sizzle( parts.shift(), context );
4500
4501			while ( parts.length ) {
4502				selector = parts.shift();
4503
4504				if ( Expr.relative[ selector ] ) {
4505					selector += parts.shift();
4506				}
4507
4508				set = posProcess( selector, set );
4509			}
4510		}
4511
4512	} else {
4513		if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4514				Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4515
4516			ret = Sizzle.find( parts.shift(), context, contextXML );
4517			context = ret.expr ?
4518				Sizzle.filter( ret.expr, ret.set )[0] :
4519				ret.set[0];
4520		}
4521
4522		if ( context ) {
4523			ret = seed ?
4524				{ expr: parts.pop(), set: makeArray(seed) } :
4525				Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4526
4527			set = ret.expr ?
4528				Sizzle.filter( ret.expr, ret.set ) :
4529				ret.set;
4530
4531			if ( parts.length > 0 ) {
4532				checkSet = makeArray( set );
4533
4534			} else {
4535				prune = false;
4536			}
4537
4538			while ( parts.length ) {
4539				cur = parts.pop();
4540				pop = cur;
4541
4542				if ( !Expr.relative[ cur ] ) {
4543					cur = "";
4544				} else {
4545					pop = parts.pop();
4546				}
4547
4548				if ( pop == null ) {
4549					pop = context;
4550				}
4551
4552				Expr.relative[ cur ]( checkSet, pop, contextXML );
4553			}
4554
4555		} else {
4556			checkSet = parts = [];
4557		}
4558	}
4559
4560	if ( !checkSet ) {
4561		checkSet = set;
4562	}
4563
4564	if ( !checkSet ) {
4565		Sizzle.error( cur || selector );
4566	}
4567
4568	if ( toString.call(checkSet) === "[object Array]" ) {
4569		if ( !prune ) {
4570			results.push.apply( results, checkSet );
4571
4572		} else if ( context && context.nodeType === 1 ) {
4573			for ( i = 0; checkSet[i] != null; i++ ) {
4574				if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
4575					results.push( set[i] );
4576				}
4577			}
4578
4579		} else {
4580			for ( i = 0; checkSet[i] != null; i++ ) {
4581				if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4582					results.push( set[i] );
4583				}
4584			}
4585		}
4586
4587	} else {
4588		makeArray( checkSet, results );
4589	}
4590
4591	if ( extra ) {
4592		Sizzle( extra, origContext, results, seed );
4593		Sizzle.uniqueSort( results );
4594	}
4595
4596	return results;
4597};
4598
4599Sizzle.uniqueSort = function( results ) {
4600	if ( sortOrder ) {
4601		hasDuplicate = baseHasDuplicate;
4602		results.sort( sortOrder );
4603
4604		if ( hasDuplicate ) {
4605			for ( var i = 1; i < results.length; i++ ) {
4606				if ( results[i] === results[ i - 1 ] ) {
4607					results.splice( i--, 1 );
4608				}
4609			}
4610		}
4611	}
4612
4613	return results;
4614};
4615
4616Sizzle.matches = function( expr, set ) {
4617	return Sizzle( expr, null, null, set );
4618};
4619
4620Sizzle.matchesSelector = function( node, expr ) {
4621	return Sizzle( expr, null, null, [node] ).length > 0;
4622};
4623
4624Sizzle.find = function( expr, context, isXML ) {
4625	var set;
4626
4627	if ( !expr ) {
4628		return [];
4629	}
4630
4631	for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4632		var match,
4633			type = Expr.order[i];
4634
4635		if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4636			var left = match[1];
4637			match.splice( 1, 1 );
4638
4639			if ( left.substr( left.length - 1 ) !== "\\" ) {
4640				match[1] = (match[1] || "").replace( rBackslash, "" );
4641				set = Expr.find[ type ]( match, context, isXML );
4642
4643				if ( set != null ) {
4644					expr = expr.replace( Expr.match[ type ], "" );
4645					break;
4646				}
4647			}
4648		}
4649	}
4650
4651	if ( !set ) {
4652		set = typeof context.getElementsByTagName !== "undefined" ?
4653			context.getElementsByTagName( "*" ) :
4654			[];
4655	}
4656
4657	return { set: set, expr: expr };
4658};
4659
4660Sizzle.filter = function( expr, set, inplace, not ) {
4661	var match, anyFound,
4662		old = expr,
4663		result = [],
4664		curLoop = set,
4665		isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
4666
4667	while ( expr && set.length ) {
4668		for ( var type in Expr.filter ) {
4669			if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
4670				var found, item,
4671					filter = Expr.filter[ type ],
4672					left = match[1];
4673
4674				anyFound = false;
4675
4676				match.splice(1,1);
4677
4678				if ( left.substr( left.length - 1 ) === "\\" ) {
4679					continue;
4680				}
4681
4682				if ( curLoop === result ) {
4683					result = [];
4684				}
4685
4686				if ( Expr.preFilter[ type ] ) {
4687					match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4688
4689					if ( !match ) {
4690						anyFound = found = true;
4691
4692					} else if ( match === true ) {
4693						continue;
4694					}
4695				}
4696
4697				if ( match ) {
4698					for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4699						if ( item ) {
4700							found = filter( item, match, i, curLoop );
4701							var pass = not ^ !!found;
4702
4703							if ( inplace && found != null ) {
4704								if ( pass ) {
4705									anyFound = true;
4706
4707								} else {
4708									curLoop[i] = false;
4709								}
4710
4711							} else if ( pass ) {
4712								result.push( item );
4713								anyFound = true;
4714							}
4715						}
4716					}
4717				}
4718
4719				if ( found !== undefined ) {
4720					if ( !inplace ) {
4721						curLoop = result;
4722					}
4723
4724					expr = expr.replace( Expr.match[ type ], "" );
4725
4726					if ( !anyFound ) {
4727						return [];
4728					}
4729
4730					break;
4731				}
4732			}
4733		}
4734
4735		if ( expr === old ) {
4736			if ( anyFound == null ) {
4737				Sizzle.error( expr );
4738
4739			} else {
4740				break;
4741			}
4742		}
4743
4744		old = expr;
4745	}
4746
4747	return curLoop;
4748};
4749
4750Sizzle.error = function( msg ) {
4751	throw "Syntax error, unrecognized expression: " + msg;
4752};
4753
4754var Expr = Sizzle.selectors = {
4755	order: [ "ID", "NAME", "TAG" ],
4756
4757	match: {
4758		ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4759		CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
4760		NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
4761		ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
4762		TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
4763		CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
4764		POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
4765		PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
4766	},
4767
4768	leftMatch: {},
4769
4770	attrMap: {
4771		"class": "className",
4772		"for": "htmlFor"
4773	},
4774
4775	attrHandle: {
4776		href: function( elem ) {
4777			return elem.getAttribute( "href" );
4778		},
4779		type: function( elem ) {
4780			return elem.getAttribute( "type" );
4781		}
4782	},
4783
4784	relative: {
4785		"+": function(checkSet, part){
4786			var isPartStr = typeof part === "string",
4787				isTag = isPartStr && !rNonWord.test( part ),
4788				isPartStrNotTag = isPartStr && !isTag;
4789
4790			if ( isTag ) {
4791				part = part.toLowerCase();
4792			}
4793
4794			for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4795				if ( (elem = checkSet[i]) ) {
4796					while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4797
4798					checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
4799						elem || false :
4800						elem === part;
4801				}
4802			}
4803
4804			if ( isPartStrNotTag ) {
4805				Sizzle.filter( part, checkSet, true );
4806			}
4807		},
4808
4809		">": function( checkSet, part ) {
4810			var elem,
4811				isPartStr = typeof part === "string",
4812				i = 0,
4813				l = checkSet.length;
4814
4815			if ( isPartStr && !rNonWord.test( part ) ) {
4816				part = part.toLowerCase();
4817
4818				for ( ; i < l; i++ ) {
4819					elem = checkSet[i];
4820
4821					if ( elem ) {
4822						var parent = elem.parentNode;
4823						checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
4824					}
4825				}
4826
4827			} else {
4828				for ( ; i < l; i++ ) {
4829					elem = checkSet[i];
4830
4831					if ( elem ) {
4832						checkSet[i] = isPartStr ?
4833							elem.parentNode :
4834							elem.parentNode === part;
4835					}
4836				}
4837
4838				if ( isPartStr ) {
4839					Sizzle.filter( part, checkSet, true );
4840				}
4841			}
4842		},
4843
4844		"": function(checkSet, part, isXML){
4845			var nodeCheck,
4846				doneName = done++,
4847				checkFn = dirCheck;
4848
4849			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4850				part = part.toLowerCase();
4851				nodeCheck = part;
4852				checkFn = dirNodeCheck;
4853			}
4854
4855			checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
4856		},
4857
4858		"~": function( checkSet, part, isXML ) {
4859			var nodeCheck,
4860				doneName = done++,
4861				checkFn = dirCheck;
4862
4863			if ( typeof part === "string" && !rNonWord.test( part ) ) {
4864				part = part.toLowerCase();
4865				nodeCheck = part;
4866				checkFn = dirNodeCheck;
4867			}
4868
4869			checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
4870		}
4871	},
4872
4873	find: {
4874		ID: function( match, context, isXML ) {
4875			if ( typeof context.getElementById !== "undefined" && !isXML ) {
4876				var m = context.getElementById(match[1]);
4877				return m && m.parentNode ? [m] : [];
4878			}
4879		},
4880
4881		NAME: function( match, context ) {
4882			if ( typeof context.getElementsByName !== "undefined" ) {
4883				var ret = [],
4884					results = context.getElementsByName( match[1] );
4885
4886				for ( var i = 0, l = results.length; i < l; i++ ) {
4887					if ( results[i].getAttribute("name") === match[1] ) {
4888						ret.push( results[i] );
4889					}
4890				}
4891
4892				return ret.length === 0 ? null : ret;
4893			}
4894		},
4895
4896		TAG: function( match, context ) {
4897			if ( typeof context.getElementsByTagName !== "undefined" ) {
4898				return context.getElementsByTagName( match[1] );
4899			}
4900		}
4901	},
4902	preFilter: {
4903		CLASS: function( match, curLoop, inplace, result, not, isXML ) {
4904			match = " " + match[1].replace( rBackslash, "" ) + " ";
4905
4906			if ( isXML ) {
4907				return match;
4908			}
4909
4910			for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4911				if ( elem ) {
4912					if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
4913						if ( !inplace ) {
4914							result.push( elem );
4915						}
4916
4917					} else if ( inplace ) {
4918						curLoop[i] = false;
4919					}
4920				}
4921			}
4922
4923			return false;
4924		},
4925
4926		ID: function( match ) {
4927			return match[1].replace( rBackslash, "" );
4928		},
4929
4930		TAG: function( match, curLoop ) {
4931			return match[1].replace( rBackslash, "" ).toLowerCase();
4932		},
4933
4934		CHILD: function( match ) {
4935			if ( match[1] === "nth" ) {
4936				if ( !match[2] ) {
4937					Sizzle.error( match[0] );
4938				}
4939
4940				match[2] = match[2].replace(/^\+|\s*/g, '');
4941
4942				var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
4943					match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
4944					!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4945
4946				match[2] = (test[1] + (test[2] || 1)) - 0;
4947				match[3] = test[3] - 0;
4948			}
4949			else if ( match[2] ) {
4950				Sizzle.error( match[0] );
4951			}
4952
4953			match[0] = done++;
4954
4955			return match;
4956		},
4957
4958		ATTR: function( match, curLoop, inplace, result, not, isXML ) {
4959			var name = match[1] = match[1].replace( rBackslash, "" );
4960
4961			if ( !isXML && Expr.attrMap[name] ) {
4962				match[1] = Expr.attrMap[name];
4963			}
4964
4965			match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
4966
4967			if ( match[2] === "~=" ) {
4968				match[4] = " " + match[4] + " ";
4969			}
4970
4971			return match;
4972		},
4973
4974		PSEUDO: function( match, curLoop, inplace, result, not ) {
4975			if ( match[1] === "not" ) {
4976				if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4977					match[3] = Sizzle(match[3], null, null, curLoop);
4978
4979				} else {
4980					var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4981
4982					if ( !inplace ) {
4983						result.push.apply( result, ret );
4984					}
4985
4986					return false;
4987				}
4988
4989			} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4990				return true;
4991			}
4992
4993			return match;
4994		},
4995
4996		POS: function( match ) {
4997			match.unshift( true );
4998
4999			return match;
5000		}
5001	},
5002
5003	filters: {
5004		enabled: function( elem ) {
5005			return elem.disabled === false && elem.type !== "hidden";
5006		},
5007
5008		disabled: function( elem ) {
5009			return elem.disabled === true;
5010		},
5011
5012		checked: function( elem ) {
5013			return elem.checked === true;
5014		},
5015
5016		selected: function( elem ) {
5017			if ( elem.parentNode ) {
5018				elem.parentNode.selectedIndex;
5019			}
5020
5021			return elem.selected === true;
5022		},
5023
5024		parent: function( elem ) {
5025			return !!elem.firstChild;
5026		},
5027
5028		empty: function( elem ) {
5029			return !elem.firstChild;
5030		},
5031
5032		has: function( elem, i, match ) {
5033			return !!Sizzle( match[3], elem ).length;
5034		},
5035
5036		header: function( elem ) {
5037			return (/h\d/i).test( elem.nodeName );
5038		},
5039
5040		text: function( elem ) {
5041			var attr = elem.getAttribute( "type" ), type = elem.type;
5042			return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
5043		},
5044
5045		radio: function( elem ) {
5046			return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
5047		},
5048
5049		checkbox: function( elem ) {
5050			return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
5051		},
5052
5053		file: function( elem ) {
5054			return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
5055		},
5056
5057		password: function( elem ) {
5058			return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
5059		},
5060
5061		submit: function( elem ) {
5062			var name = elem.nodeName.toLowerCase();
5063			return (name === "input" || name === "button") && "submit" === elem.type;
5064		},
5065
5066		image: function( elem ) {
5067			return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
5068		},
5069
5070		reset: function( elem ) {
5071			var name = elem.nodeName.toLowerCase();
5072			return (name === "input" || name === "button") && "reset" === elem.type;
5073		},
5074
5075		button: function( elem ) {
5076			var name = elem.nodeName.toLowerCase();
5077			return name === "input" && "button" === elem.type || name === "button";
5078		},
5079
5080		input: function( elem ) {
5081			return (/input|select|textarea|button/i).test( elem.nodeName );
5082		},
5083
5084		focus: function( elem ) {
5085			return elem === elem.ownerDocument.activeElement;
5086		}
5087	},
5088	setFilters: {
5089		first: function( elem, i ) {
5090			return i === 0;
5091		},
5092
5093		last: function( elem, i, match, array ) {
5094			return i === array.length - 1;
5095		},
5096
5097		even: function( elem, i ) {
5098			return i % 2 === 0;
5099		},
5100
5101		odd: function( elem, i ) {
5102			return i % 2 === 1;
5103		},
5104
5105		lt: function( elem, i, match ) {
5106			return i < match[3] - 0;
5107		},
5108
5109		gt: function( elem, i, match ) {
5110			return i > match[3] - 0;
5111		},
5112
5113		nth: function( elem, i, match ) {
5114			return match[3] - 0 === i;
5115		},
5116
5117		eq: function( elem, i, match ) {
5118			return match[3] - 0 === i;
5119		}
5120	},
5121	filter: {
5122		PSEUDO: function( elem, match, i, array ) {
5123			var name = match[1],
5124				filter = Expr.filters[ name ];
5125
5126			if ( filter ) {
5127				return filter( elem, i, match, array );
5128
5129			} else if ( name === "contains" ) {
5130				return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
5131
5132			} else if ( name === "not" ) {
5133				var not = match[3];
5134
5135				for ( var j = 0, l = not.length; j < l; j++ ) {
5136					if ( not[j] === elem ) {
5137						return false;
5138					}
5139				}
5140
5141				return true;
5142
5143			} else {
5144				Sizzle.error( name );
5145			}
5146		},
5147
5148		CHILD: function( elem, match ) {
5149			var type = match[1],
5150				node = elem;
5151
5152			switch ( type ) {
5153				case "only":
5154				case "first":
5155					while ( (node = node.previousSibling) )	 {
5156						if ( node.nodeType === 1 ) {
5157							return false;
5158						}
5159					}
5160
5161					if ( type === "first" ) {
5162						return true;
5163					}
5164
5165					node = elem;
5166
5167				case "last":
5168					while ( (node = node.nextSibling) )	 {
5169						if ( node.nodeType === 1 ) {
5170							return false;
5171						}
5172					}
5173
5174					return true;
5175
5176				case "nth":
5177					var first = match[2],
5178						last = match[3];
5179
5180					if ( first === 1 && last === 0 ) {
5181						return true;
5182					}
5183
5184					var doneName = match[0],
5185						parent = elem.parentNode;
5186
5187					if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
5188						var count = 0;
5189
5190						for ( node = parent.firstChild; node; node = node.nextSibling ) {
5191							if ( node.nodeType === 1 ) {
5192								node.nodeIndex = ++count;
5193							}
5194						}
5195
5196						parent.sizcache = doneName;
5197					}
5198
5199					var diff = elem.nodeIndex - last;
5200
5201					if ( first === 0 ) {
5202						return diff === 0;
5203
5204					} else {
5205						return ( diff % first === 0 && diff / first >= 0 );
5206					}
5207			}
5208		},
5209
5210		ID: function( elem, match ) {
5211			return elem.nodeType === 1 && elem.getAttribute("id") === match;
5212		},
5213
5214		TAG: function( elem, match ) {
5215			return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
5216		},
5217
5218		CLASS: function( elem, match ) {
5219			return (" " + (elem.className || elem.getAttribute("class")) + " ")
5220				.indexOf( match ) > -1;
5221		},
5222
5223		ATTR: function( elem, match ) {
5224			var name = match[1],
5225				result = Expr.attrHandle[ name ] ?
5226					Expr.attrHandle[ name ]( elem ) :
5227					elem[ name ] != null ?
5228						elem[ name ] :
5229						elem.getAttribute( name ),
5230				value = result + "",
5231				type = match[2],
5232				check = match[4];
5233
5234			return result == null ?
5235				type === "!=" :
5236				type === "=" ?
5237				value === check :
5238				type === "*=" ?
5239				value.indexOf(check) >= 0 :
5240				type === "~=" ?
5241				(" " + value + " ").indexOf(check) >= 0 :
5242				!check ?
5243				value && result !== false :
5244				type === "!=" ?
5245				value !== check :
5246				type === "^=" ?
5247				value.indexOf(check) === 0 :
5248				type === "$=" ?
5249				value.substr(value.length - check.length) === check :
5250				type === "|=" ?
5251				value === check || value.substr(0, check.length + 1) === check + "-" :
5252				false;
5253		},
5254
5255		POS: function( elem, match, i, array ) {
5256			var name = match[2],
5257				filter = Expr.setFilters[ name ];
5258
5259			if ( filter ) {
5260				return filter( elem, i, match, array );
5261			}
5262		}
5263	}
5264};
5265
5266var origPOS = Expr.match.POS,
5267	fescape = function(all, num){
5268		return "\\" + (num - 0 + 1);
5269	};
5270
5271for ( var type in Expr.match ) {
5272	Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
5273	Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
5274}
5275
5276var makeArray = function( array, results ) {
5277	array = Array.prototype.slice.call( array, 0 );
5278
5279	if ( results ) {
5280		results.push.apply( results, array );
5281		return results;
5282	}
5283
5284	return array;
5285};
5286
5287try {
5288	Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
5289
5290} catch( e ) {
5291	makeArray = function( array, results ) {
5292		var i = 0,
5293			ret = results || [];
5294
5295		if ( toString.call(array) === "[object Array]" ) {
5296			Array.prototype.push.apply( ret, array );
5297
5298		} else {
5299			if ( typeof array.length === "number" ) {
5300				for ( var l = array.length; i < l; i++ ) {
5301					ret.push( array[i] );
5302				}
5303
5304			} else {
5305				for ( ; array[i]; i++ ) {
5306					ret.push( array[i] );
5307				}
5308			}
5309		}
5310
5311		return ret;
5312	};
5313}
5314
5315var sortOrder, siblingCheck;
5316
5317if ( document.documentElement.compareDocumentPosition ) {
5318	sortOrder = function( a, b ) {
5319		if ( a === b ) {
5320			hasDuplicate = true;
5321			return 0;
5322		}
5323
5324		if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
5325			return a.compareDocumentPosition ? -1 : 1;
5326		}
5327
5328		return a.compareDocumentPosition(b) & 4 ? -1 : 1;
5329	};
5330
5331} else {
5332	sortOrder = function( a, b ) {
5333		if ( a === b ) {
5334			hasDuplicate = true;
5335			return 0;
5336
5337		} else if ( a.sourceIndex && b.sourceIndex ) {
5338			return a.sourceIndex - b.sourceIndex;
5339		}
5340
5341		var al, bl,
5342			ap = [],
5343			bp = [],
5344			aup = a.parentNode,
5345			bup = b.parentNode,
5346			cur = aup;
5347
5348		if ( aup === bup ) {
5349			return siblingCheck( a, b );
5350
5351		} else if ( !aup ) {
5352			return -1;
5353
5354		} else if ( !bup ) {
5355			return 1;
5356		}
5357
5358		while ( cur ) {
5359			ap.unshift( cur );
5360			cur = cur.parentNode;
5361		}
5362
5363		cur = bup;
5364
5365		while ( cur ) {
5366			bp.unshift( cur );
5367			cur = cur.parentNode;
5368		}
5369
5370		al = ap.length;
5371		bl = bp.length;
5372
5373		for ( var i = 0; i < al && i < bl; i++ ) {
5374			if ( ap[i] !== bp[i] ) {
5375				return siblingCheck( ap[i], bp[i] );
5376			}
5377		}
5378
5379		return i === al ?
5380			siblingCheck( a, bp[i], -1 ) :
5381			siblingCheck( ap[i], b, 1 );
5382	};
5383
5384	siblingCheck = function( a, b, ret ) {
5385		if ( a === b ) {
5386			return ret;
5387		}
5388
5389		var cur = a.nextSibling;
5390
5391		while ( cur ) {
5392			if ( cur === b ) {
5393				return -1;
5394			}
5395
5396			cur = cur.nextSibling;
5397		}
5398
5399		return 1;
5400	};
5401}
5402
5403Sizzle.getText = function( elems ) {
5404	var ret = "", elem;
5405
5406	for ( var i = 0; elems[i]; i++ ) {
5407		elem = elems[i];
5408
5409		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
5410			ret += elem.nodeValue;
5411
5412		} else if ( elem.nodeType !== 8 ) {
5413			ret += Sizzle.getText( elem.childNodes );
5414		}
5415	}
5416
5417	return ret;
5418};
5419
5420(function(){
5421	var form = document.createElement("div"),
5422		id = "script" + (new Date()).getTime(),
5423		root = document.documentElement;
5424
5425	form.innerHTML = "<a name='" + id + "'/>";
5426
5427	root.insertBefore( form, root.firstChild );
5428
5429	if ( document.getElementById( id ) ) {
5430		Expr.find.ID = function( match, context, isXML ) {
5431			if ( typeof context.getElementById !== "undefined" && !isXML ) {
5432				var m = context.getElementById(match[1]);
5433
5434				return m ?
5435					m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
5436						[m] :
5437						undefined :
5438					[];
5439			}
5440		};
5441
5442		Expr.filter.ID = function( elem, match ) {
5443			var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
5444
5445			return elem.nodeType === 1 && node && node.nodeValue === match;
5446		};
5447	}
5448
5449	root.removeChild( form );
5450
5451	root = form = null;
5452})();
5453
5454(function(){
5455
5456	var div = document.createElement("div");
5457	div.appendChild( document.createComment("") );
5458
5459	if ( div.getElementsByTagName("*").length > 0 ) {
5460		Expr.find.TAG = function( match, context ) {
5461			var results = context.getElementsByTagName( match[1] );
5462
5463			if ( match[1] === "*" ) {
5464				var tmp = [];
5465
5466				for ( var i = 0; results[i]; i++ ) {
5467					if ( results[i].nodeType === 1 ) {
5468						tmp.push( results[i] );
5469					}
5470				}
5471
5472				results = tmp;
5473			}
5474
5475			return results;
5476		};
5477	}
5478
5479	div.innerHTML = "<a href='#'></a>";
5480
5481	if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
5482			div.firstChild.getAttribute("href") !== "#" ) {
5483
5484		Expr.attrHandle.href = function( elem ) {
5485			return elem.getAttribute( "href", 2 );
5486		};
5487	}
5488
5489	div = null;
5490})();
5491
5492if ( document.querySelectorAll ) {
5493	(function(){
5494		var oldSizzle = Sizzle,
5495			div = document.createElement("div"),
5496			id = "__sizzle__";
5497
5498		div.innerHTML = "<p class='TEST'></p>";
5499
5500		if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
5501			return;
5502		}
5503
5504		Sizzle = function( query, context, extra, seed ) {
5505			context = context || document;
5506
5507			if ( !seed && !Sizzle.isXML(context) ) {
5508				var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
5509
5510				if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
5511					if ( match[1] ) {
5512						return makeArray( context.getElementsByTagName( query ), extra );
5513
5514					} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
5515						return makeArray( context.getElementsByClassName( match[2] ), extra );
5516					}
5517				}
5518
5519				if ( context.nodeType === 9 ) {
5520					if ( query === "body" && context.body ) {
5521						return makeArray( [ context.body ], extra );
5522
5523					} else if ( match && match[3] ) {
5524						var elem = context.getElementById( match[3] );
5525
5526						if ( elem && elem.parentNode ) {
5527							if ( elem.id === match[3] ) {
5528								return makeArray( [ elem ], extra );
5529							}
5530
5531						} else {
5532							return makeArray( [], extra );
5533						}
5534					}
5535
5536					try {
5537						return makeArray( context.querySelectorAll(query), extra );
5538					} catch(qsaError) {}
5539
5540				} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
5541					var oldContext = context,
5542						old = context.getAttribute( "id" ),
5543						nid = old || id,
5544						hasParent = context.parentNode,
5545						relativeHierarchySelector = /^\s*[+~]/.test( query );
5546
5547					if ( !old ) {
5548						context.setAttribute( "id", nid );
5549					} else {
5550						nid = nid.replace( /'/g, "\\$&" );
5551					}
5552					if ( relativeHierarchySelector && hasParent ) {
5553						context = context.parentNode;
5554					}
5555
5556					try {
5557						if ( !relativeHierarchySelector || hasParent ) {
5558							return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
5559						}
5560
5561					} catch(pseudoError) {
5562					} finally {
5563						if ( !old ) {
5564							oldContext.removeAttribute( "id" );
5565						}
5566					}
5567				}
5568			}
5569
5570			return oldSizzle(query, context, extra, seed);
5571		};
5572
5573		for ( var prop in oldSizzle ) {
5574			Sizzle[ prop ] = oldSizzle[ prop ];
5575		}
5576
5577		div = null;
5578	})();
5579}
5580
5581(function(){
5582	var html = document.documentElement,
5583		matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
5584
5585	if ( matches ) {
5586		var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
5587			pseudoWorks = false;
5588
5589		try {
5590			matches.call( document.documentElement, "[test!='']:sizzle" );
5591
5592		} catch( pseudoError ) {
5593			pseudoWorks = true;
5594		}
5595
5596		Sizzle.matchesSelector = function( node, expr ) {
5597			expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
5598
5599			if ( !Sizzle.isXML( node ) ) {
5600				try {
5601					if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
5602						var ret = matches.call( node, expr );
5603
5604						if ( ret || !disconnectedMatch ||
5605								node.document && node.document.nodeType !== 11 ) {
5606							return ret;
5607						}
5608					}
5609				} catch(e) {}
5610			}
5611
5612			return Sizzle(expr, null, null, [node]).length > 0;
5613		};
5614	}
5615})();
5616
5617(function(){
5618	var div = document.createElement("div");
5619
5620	div.innerHTML = "<div class='test e'></div><div class='test'></div>";
5621
5622	if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
5623		return;
5624	}
5625
5626	div.lastChild.className = "e";
5627
5628	if ( div.getElementsByClassName("e").length === 1 ) {
5629		return;
5630	}
5631
5632	Expr.order.splice(1, 0, "CLASS");
5633	Expr.find.CLASS = function( match, context, isXML ) {
5634		if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
5635			return context.getElementsByClassName(match[1]);
5636		}
5637	};
5638
5639	div = null;
5640})();
5641
5642function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5643	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5644		var elem = checkSet[i];
5645
5646		if ( elem ) {
5647			var match = false;
5648
5649			elem = elem[dir];
5650
5651			while ( elem ) {
5652				if ( elem.sizcache === doneName ) {
5653					match = checkSet[elem.sizset];
5654					break;
5655				}
5656
5657				if ( elem.nodeType === 1 && !isXML ){
5658					elem.sizcache = doneName;
5659					elem.sizset = i;
5660				}
5661
5662				if ( elem.nodeName.toLowerCase() === cur ) {
5663					match = elem;
5664					break;
5665				}
5666
5667				elem = elem[dir];
5668			}
5669
5670			checkSet[i] = match;
5671		}
5672	}
5673}
5674
5675function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
5676	for ( var i = 0, l = checkSet.length; i < l; i++ ) {
5677		var elem = checkSet[i];
5678
5679		if ( elem ) {
5680			var match = false;
5681
5682			elem = elem[dir];
5683
5684			while ( elem ) {
5685				if ( elem.sizcache === doneName ) {
5686					match = checkSet[elem.sizset];
5687					break;
5688				}
5689
5690				if ( elem.nodeType === 1 ) {
5691					if ( !isXML ) {
5692						elem.sizcache = doneName;
5693						elem.sizset = i;
5694					}
5695
5696					if ( typeof cur !== "string" ) {
5697						if ( elem === cur ) {
5698							match = true;
5699							break;
5700						}
5701
5702					} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
5703						match = elem;
5704						break;
5705					}
5706				}
5707
5708				elem = elem[dir];
5709			}
5710
5711			checkSet[i] = match;
5712		}
5713	}
5714}
5715
5716if ( document.documentElement.contains ) {
5717	Sizzle.contains = function( a, b ) {
5718		return a !== b && (a.contains ? a.contains(b) : true);
5719	};
5720
5721} else if ( document.documentElement.compareDocumentPosition ) {
5722	Sizzle.contains = function( a, b ) {
5723		return !!(a.compareDocumentPosition(b) & 16);
5724	};
5725
5726} else {
5727	Sizzle.contains = function() {
5728		return false;
5729	};
5730}
5731
5732Sizzle.isXML = function( elem ) {
5733	var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
5734
5735	return documentElement ? documentElement.nodeName !== "HTML" : false;
5736};
5737
5738var posProcess = function( selector, context ) {
5739	var match,
5740		tmpSet = [],
5741		later = "",
5742		root = context.nodeType ? [context] : context;
5743
5744	while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
5745		later += match[0];
5746		selector = selector.replace( Expr.match.PSEUDO, "" );
5747	}
5748
5749	selector = Expr.relative[selector] ? selector + "*" : selector;
5750
5751	for ( var i = 0, l = root.length; i < l; i++ ) {
5752		Sizzle( selector, root[i], tmpSet );
5753	}
5754
5755	return Sizzle.filter( later, tmpSet );
5756};
5757
5758
5759window.Sizzle = Sizzle;
5760
5761})();
5762
5763Prototype._original_property = window.Sizzle;
5764
5765;(function(engine) {
5766 var extendElements = Prototype.Selector.extendElements;
5767
5768 function select(selector, scope) {
5769 return extendElements(engine(selector, scope || document));
5770 }
5771
5772 function match(element, selector) {
5773 return engine.matches(selector, [element]).length == 1;
5774 }
5775
5776 Prototype.Selector.engine = engine;
5777 Prototype.Selector.select = select;
5778 Prototype.Selector.match = match;
5779})(Sizzle);
5780
5781window.Sizzle = Prototype._original_property;
5782delete Prototype._original_property;
5783
5784var Form = {
5785 reset: function(form) {
5786 form = $(form);
5787 form.reset();
5788 return form;
5789 },
5790
5791 serializeElements: function(elements, options) {
5792 if (typeof options != 'object') options = { hash: !!options };
5793 else if (Object.isUndefined(options.hash)) options.hash = true;
5794 var key, value, submitted = false, submit = options.submit, accumulator, initial;
5795
5796 if (options.hash) {
5797 initial = {};
5798 accumulator = function(result, key, value) {
5799 if (key in result) {
5800 if (!Object.isArray(result[key])) result[key] = [result[key]];
5801 result[key].push(value);
5802 } else result[key] = value;
5803 return result;
5804 };
5805 } else {
5806 initial = '';
5807 accumulator = function(result, key, values) {
5808 if (!Object.isArray(values)) {values = [values];}
5809 if (!values.length) {return result;}
5810 var encodedKey = encodeURIComponent(key);
5811 return result + (result ? "&" : "") + values.map(function (value) {
5812 value = value.gsub(/(\r)?\n/, '\r\n');
5813 value = encodeURIComponent(value);
5814 value = value.gsub(/%20/, '+');
5815 return encodedKey + "=" + value;
5816 }).join("&");
5817 };
5818 }
5819
5820 return elements.inject(initial, function(result, element) {
5821 if (!element.disabled && element.name) {
5822 key = element.name; value = $(element).getValue();
5823 if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
5824 submit !== false && (!submit || key == submit) && (submitted = true)))) {
5825 result = accumulator(result, key, value);
5826 }
5827 }
5828 return result;
5829 });
5830 }
5831};
5832
5833Form.Methods = {
5834 serialize: function(form, options) {
5835 return Form.serializeElements(Form.getElements(form), options);
5836 },
5837
5838
5839 getElements: function(form) {
5840 var elements = $(form).getElementsByTagName('*');
5841 var element, results = [], serializers = Form.Element.Serializers;
5842
5843 for (var i = 0; element = elements[i]; i++) {
5844 if (serializers[element.tagName.toLowerCase()])
5845 results.push(Element.extend(element));
5846 }
5847 return results;
5848 },
5849
5850 getInputs: function(form, typeName, name) {
5851 form = $(form);
5852 var inputs = form.getElementsByTagName('input');
5853
5854 if (!typeName && !name) return $A(inputs).map(Element.extend);
5855
5856 for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
5857 var input = inputs[i];
5858 if ((typeName && input.type != typeName) || (name && input.name != name))
5859 continue;
5860 matchingInputs.push(Element.extend(input));
5861 }
5862
5863 return matchingInputs;
5864 },
5865
5866 disable: function(form) {
5867 form = $(form);
5868 Form.getElements(form).invoke('disable');
5869 return form;
5870 },
5871
5872 enable: function(form) {
5873 form = $(form);
5874 Form.getElements(form).invoke('enable');
5875 return form;
5876 },
5877
5878 findFirstElement: function(form) {
5879 var elements = $(form).getElements().findAll(function(element) {
5880 return 'hidden' != element.type && !element.disabled;
5881 });
5882 var firstByIndex = elements.findAll(function(element) {
5883 return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
5884 }).sortBy(function(element) { return element.tabIndex }).first();
5885
5886 return firstByIndex ? firstByIndex : elements.find(function(element) {
5887 return /^(?:input|select|textarea)$/i.test(element.tagName);
5888 });
5889 },
5890
5891 focusFirstElement: function(form) {
5892 form = $(form);
5893 var element = form.findFirstElement();
5894 if (element) element.activate();
5895 return form;
5896 },
5897
5898 request: function(form, options) {
5899 form = $(form), options = Object.clone(options || { });
5900
5901 var params = options.parameters, action = form.readAttribute('action') || '';
5902 if (action.blank()) action = window.location.href;
5903 options.parameters = form.serialize(true);
5904
5905 if (params) {
5906 if (Object.isString(params)) params = params.toQueryParams();
5907 Object.extend(options.parameters, params);
5908 }
5909
5910 if (form.hasAttribute('method') && !options.method)
5911 options.method = form.method;
5912
5913 return new Ajax.Request(action, options);
5914 }
5915};
5916
5917/*--------------------------------------------------------------------------*/
5918
5919
5920Form.Element = {
5921 focus: function(element) {
5922 $(element).focus();
5923 return element;
5924 },
5925
5926 select: function(element) {
5927 $(element).select();
5928 return element;
5929 }
5930};
5931
5932Form.Element.Methods = {
5933
5934 serialize: function(element) {
5935 element = $(element);
5936 if (!element.disabled && element.name) {
5937 var value = element.getValue();
5938 if (value != undefined) {
5939 var pair = { };
5940 pair[element.name] = value;
5941 return Object.toQueryString(pair);
5942 }
5943 }
5944 return '';
5945 },
5946
5947 getValue: function(element) {
5948 element = $(element);
5949 var method = element.tagName.toLowerCase();
5950 return Form.Element.Serializers[method](element);
5951 },
5952
5953 setValue: function(element, value) {
5954 element = $(element);
5955 var method = element.tagName.toLowerCase();
5956 Form.Element.Serializers[method](element, value);
5957 return element;
5958 },
5959
5960 clear: function(element) {
5961 $(element).value = '';
5962 return element;
5963 },
5964
5965 present: function(element) {
5966 return $(element).value != '';
5967 },
5968
5969 activate: function(element) {
5970 element = $(element);
5971 try {
5972 element.focus();
5973 if (element.select && (element.tagName.toLowerCase() != 'input' ||
5974 !(/^(?:button|reset|submit)$/i.test(element.type))))
5975 element.select();
5976 } catch (e) { }
5977 return element;
5978 },
5979
5980 disable: function(element) {
5981 element = $(element);
5982 element.disabled = true;
5983 return element;
5984 },
5985
5986 enable: function(element) {
5987 element = $(element);
5988 element.disabled = false;
5989 return element;
5990 }
5991};
5992
5993/*--------------------------------------------------------------------------*/
5994
5995var Field = Form.Element;
5996
5997var $F = Form.Element.Methods.getValue;
5998
5999/*--------------------------------------------------------------------------*/
6000
6001Form.Element.Serializers = (function() {
6002 function input(element, value) {
6003 switch (element.type.toLowerCase()) {
6004 case 'checkbox':
6005 case 'radio':
6006 return inputSelector(element, value);
6007 default:
6008 return valueSelector(element, value);
6009 }
6010 }
6011
6012 function inputSelector(element, value) {
6013 if (Object.isUndefined(value))
6014 return element.checked ? element.value : null;
6015 else element.checked = !!value;
6016 }
6017
6018 function valueSelector(element, value) {
6019 if (Object.isUndefined(value)) return element.value;
6020 else element.value = value;
6021 }
6022
6023 function select(element, value) {
6024 if (Object.isUndefined(value))
6025 return (element.type === 'select-one' ? selectOne : selectMany)(element);
6026
6027 var opt, currentValue, single = !Object.isArray(value);
6028 for (var i = 0, length = element.length; i < length; i++) {
6029 opt = element.options[i];
6030 currentValue = this.optionValue(opt);
6031 if (single) {
6032 if (currentValue == value) {
6033 opt.selected = true;
6034 return;
6035 }
6036 }
6037 else opt.selected = value.include(currentValue);
6038 }
6039 }
6040
6041 function selectOne(element) {
6042 var index = element.selectedIndex;
6043 return index >= 0 ? optionValue(element.options[index]) : null;
6044 }
6045
6046 function selectMany(element) {
6047 var values, length = element.length;
6048 if (!length) return null;
6049
6050 for (var i = 0, values = []; i < length; i++) {
6051 var opt = element.options[i];
6052 if (opt.selected) values.push(optionValue(opt));
6053 }
6054 return values;
6055 }
6056
6057 function optionValue(opt) {
6058 return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
6059 }
6060
6061 return {
6062 input: input,
6063 inputSelector: inputSelector,
6064 textarea: valueSelector,
6065 select: select,
6066 selectOne: selectOne,
6067 selectMany: selectMany,
6068 optionValue: optionValue,
6069 button: valueSelector
6070 };
6071})();
6072
6073/*--------------------------------------------------------------------------*/
6074
6075
6076Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
6077 initialize: function($super, element, frequency, callback) {
6078 $super(callback, frequency);
6079 this.element = $(element);
6080 this.lastValue = this.getValue();
6081 },
6082
6083 execute: function() {
6084 var value = this.getValue();
6085 if (Object.isString(this.lastValue) && Object.isString(value) ?
6086 this.lastValue != value : String(this.lastValue) != String(value)) {
6087 this.callback(this.element, value);
6088 this.lastValue = value;
6089 }
6090 }
6091});
6092
6093Form.Element.Observer = Class.create(Abstract.TimedObserver, {
6094 getValue: function() {
6095 return Form.Element.getValue(this.element);
6096 }
6097});
6098
6099Form.Observer = Class.create(Abstract.TimedObserver, {
6100 getValue: function() {
6101 return Form.serialize(this.element);
6102 }
6103});
6104
6105/*--------------------------------------------------------------------------*/
6106
6107Abstract.EventObserver = Class.create({
6108 initialize: function(element, callback) {
6109 this.element = $(element);
6110 this.callback = callback;
6111
6112 this.lastValue = this.getValue();
6113 if (this.element.tagName.toLowerCase() == 'form')
6114 this.registerFormCallbacks();
6115 else
6116 this.registerCallback(this.element);
6117 },
6118
6119 onElementEvent: function() {
6120 var value = this.getValue();
6121 if (this.lastValue != value) {
6122 this.callback(this.element, value);
6123 this.lastValue = value;
6124 }
6125 },
6126
6127 registerFormCallbacks: function() {
6128 Form.getElements(this.element).each(this.registerCallback, this);
6129 },
6130
6131 registerCallback: function(element) {
6132 if (element.type) {
6133 switch (element.type.toLowerCase()) {
6134 case 'checkbox':
6135 case 'radio':
6136 Event.observe(element, 'click', this.onElementEvent.bind(this));
6137 break;
6138 default:
6139 Event.observe(element, 'change', this.onElementEvent.bind(this));
6140 break;
6141 }
6142 }
6143 }
6144});
6145
6146Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
6147 getValue: function() {
6148 return Form.Element.getValue(this.element);
6149 }
6150});
6151
6152Form.EventObserver = Class.create(Abstract.EventObserver, {
6153 getValue: function() {
6154 return Form.serialize(this.element);
6155 }
6156});
6157(function(GLOBAL) {
6158 var DIV = document.createElement('div');
6159 var docEl = document.documentElement;
6160 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
6161 && 'onmouseleave' in docEl;
6162
6163 var Event = {
6164 KEY_BACKSPACE: 8,
6165 KEY_TAB: 9,
6166 KEY_RETURN: 13,
6167 KEY_ESC: 27,
6168 KEY_LEFT: 37,
6169 KEY_UP: 38,
6170 KEY_RIGHT: 39,
6171 KEY_DOWN: 40,
6172 KEY_DELETE: 46,
6173 KEY_HOME: 36,
6174 KEY_END: 35,
6175 KEY_PAGEUP: 33,
6176 KEY_PAGEDOWN: 34,
6177 KEY_INSERT: 45
6178 };
6179
6180
6181 var isIELegacyEvent = function(event) { return false; };
6182
6183 if (window.attachEvent) {
6184 if (window.addEventListener) {
6185 isIELegacyEvent = function(event) {
6186 return !(event instanceof window.Event);
6187 };
6188 } else {
6189 isIELegacyEvent = function(event) { return true; };
6190 }
6191 }
6192
6193 var _isButton;
6194
6195 function _isButtonForDOMEvents(event, code) {
6196 return event.which ? (event.which === code + 1) : (event.button === code);
6197 }
6198
6199 var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
6200 function _isButtonForLegacyEvents(event, code) {
6201 return event.button === legacyButtonMap[code];
6202 }
6203
6204 function _isButtonForWebKit(event, code) {
6205 switch (code) {
6206 case 0: return event.which == 1 && !event.metaKey;
6207 case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
6208 case 2: return event.which == 3;
6209 default: return false;
6210 }
6211 }
6212
6213 if (window.attachEvent) {
6214 if (!window.addEventListener) {
6215 _isButton = _isButtonForLegacyEvents;
6216 } else {
6217 _isButton = function(event, code) {
6218 return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
6219 _isButtonForDOMEvents(event, code);
6220 }
6221 }
6222 } else if (Prototype.Browser.WebKit) {
6223 _isButton = _isButtonForWebKit;
6224 } else {
6225 _isButton = _isButtonForDOMEvents;
6226 }
6227
6228 function isLeftClick(event) { return _isButton(event, 0) }
6229
6230 function isMiddleClick(event) { return _isButton(event, 1) }
6231
6232 function isRightClick(event) { return _isButton(event, 2) }
6233
6234 function element(event) {
6235 return Element.extend(_element(event));
6236 }
6237
6238 function _element(event) {
6239 event = Event.extend(event);
6240
6241 var node = event.target, type = event.type,
6242 currentTarget = event.currentTarget;
6243
6244 if (currentTarget && currentTarget.tagName) {
6245 if (type === 'load' || type === 'error' ||
6246 (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
6247 && currentTarget.type === 'radio'))
6248 node = currentTarget;
6249 }
6250
6251 if (node.nodeType == Node.TEXT_NODE)
6252 node = node.parentNode;
6253
6254 return Element.extend(node);
6255 }
6256
6257 function findElement(event, expression) {
6258 var element = _element(event), match = Prototype.Selector.match;
6259 if (!expression) return Element.extend(element);
6260 while (element) {
6261 if (Object.isElement(element) && match(element, expression))
6262 return Element.extend(element);
6263 element = element.parentNode;
6264 }
6265 }
6266
6267 function pointer(event) {
6268 return { x: pointerX(event), y: pointerY(event) };
6269 }
6270
6271 function pointerX(event) {
6272 var docElement = document.documentElement,
6273 body = document.body || { scrollLeft: 0 };
6274
6275 return event.pageX || (event.clientX +
6276 (docElement.scrollLeft || body.scrollLeft) -
6277 (docElement.clientLeft || 0));
6278 }
6279
6280 function pointerY(event) {
6281 var docElement = document.documentElement,
6282 body = document.body || { scrollTop: 0 };
6283
6284 return event.pageY || (event.clientY +
6285 (docElement.scrollTop || body.scrollTop) -
6286 (docElement.clientTop || 0));
6287 }
6288
6289
6290 function stop(event) {
6291 Event.extend(event);
6292 event.preventDefault();
6293 event.stopPropagation();
6294
6295 event.stopped = true;
6296 }
6297
6298
6299 Event.Methods = {
6300 isLeftClick: isLeftClick,
6301 isMiddleClick: isMiddleClick,
6302 isRightClick: isRightClick,
6303
6304 element: element,
6305 findElement: findElement,
6306
6307 pointer: pointer,
6308 pointerX: pointerX,
6309 pointerY: pointerY,
6310
6311 stop: stop
6312 };
6313
6314 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
6315 m[name] = Event.Methods[name].methodize();
6316 return m;
6317 });
6318
6319 if (window.attachEvent) {
6320 function _relatedTarget(event) {
6321 var element;
6322 switch (event.type) {
6323 case 'mouseover':
6324 case 'mouseenter':
6325 element = event.fromElement;
6326 break;
6327 case 'mouseout':
6328 case 'mouseleave':
6329 element = event.toElement;
6330 break;
6331 default:
6332 return null;
6333 }
6334 return Element.extend(element);
6335 }
6336
6337 var additionalMethods = {
6338 stopPropagation: function() { this.cancelBubble = true },
6339 preventDefault: function() { this.returnValue = false },
6340 inspect: function() { return '[object Event]' }
6341 };
6342
6343 Event.extend = function(event, element) {
6344 if (!event) return false;
6345
6346 if (!isIELegacyEvent(event)) return event;
6347
6348 if (event._extendedByPrototype) return event;
6349 event._extendedByPrototype = Prototype.emptyFunction;
6350
6351 var pointer = Event.pointer(event);
6352
6353 Object.extend(event, {
6354 target: event.srcElement || element,
6355 relatedTarget: _relatedTarget(event),
6356 pageX: pointer.x,
6357 pageY: pointer.y
6358 });
6359
6360 Object.extend(event, methods);
6361 Object.extend(event, additionalMethods);
6362
6363 return event;
6364 };
6365 } else {
6366 Event.extend = Prototype.K;
6367 }
6368
6369 if (window.addEventListener) {
6370 Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
6371 Object.extend(Event.prototype, methods);
6372 }
6373
6374 var EVENT_TRANSLATIONS = {
6375 mouseenter: 'mouseover',
6376 mouseleave: 'mouseout'
6377 };
6378
6379 function getDOMEventName(eventName) {
6380 return EVENT_TRANSLATIONS[eventName] || eventName;
6381 }
6382
6383 if (MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED)
6384 getDOMEventName = Prototype.K;
6385
6386 function getUniqueElementID(element) {
6387 if (element === window) return 0;
6388
6389 if (typeof element._prototypeUID === 'undefined')
6390 element._prototypeUID = Element.Storage.UID++;
6391 return element._prototypeUID;
6392 }
6393
6394 function getUniqueElementID_IE(element) {
6395 if (element === window) return 0;
6396 if (element == document) return 1;
6397 return element.uniqueID;
6398 }
6399
6400 if ('uniqueID' in DIV)
6401 getUniqueElementID = getUniqueElementID_IE;
6402
6403 function isCustomEvent(eventName) {
6404 return eventName.include(':');
6405 }
6406
6407 Event._isCustomEvent = isCustomEvent;
6408
6409 function getRegistryForElement(element, uid) {
6410 var CACHE = GLOBAL.Event.cache;
6411 if (Object.isUndefined(uid))
6412 uid = getUniqueElementID(element);
6413 if (!CACHE[uid]) CACHE[uid] = { element: element };
6414 return CACHE[uid];
6415 }
6416
6417 function destroyRegistryForElement(element, uid) {
6418 if (Object.isUndefined(uid))
6419 uid = getUniqueElementID(element);
6420 delete GLOBAL.Event.cache[uid];
6421 }
6422
6423
6424 function register(element, eventName, handler) {
6425 var registry = getRegistryForElement(element);
6426 if (!registry[eventName]) registry[eventName] = [];
6427 var entries = registry[eventName];
6428
6429 var i = entries.length;
6430 while (i--)
6431 if (entries[i].handler === handler) return null;
6432
6433 var uid = getUniqueElementID(element);
6434 var responder = GLOBAL.Event._createResponder(uid, eventName, handler);
6435 var entry = {
6436 responder: responder,
6437 handler: handler
6438 };
6439
6440 entries.push(entry);
6441 return entry;
6442 }
6443
6444 function unregister(element, eventName, handler) {
6445 var registry = getRegistryForElement(element);
6446 var entries = registry[eventName];
6447 if (!entries) return;
6448
6449 var i = entries.length, entry;
6450 while (i--) {
6451 if (entries[i].handler === handler) {
6452 entry = entries[i];
6453 break;
6454 }
6455 }
6456
6457 if (!entry) return;
6458
6459 var index = entries.indexOf(entry);
6460 entries.splice(index, 1);
6461
6462 return entry;
6463 }
6464
6465
6466 function observe(element, eventName, handler) {
6467 element = $(element);
6468 var entry = register(element, eventName, handler);
6469
6470 if (entry === null) return element;
6471
6472 var responder = entry.responder;
6473 if (isCustomEvent(eventName))
6474 observeCustomEvent(element, eventName, responder);
6475 else
6476 observeStandardEvent(element, eventName, responder);
6477
6478 return element;
6479 }
6480
6481 function observeStandardEvent(element, eventName, responder) {
6482 var actualEventName = getDOMEventName(eventName);
6483 if (element.addEventListener) {
6484 element.addEventListener(actualEventName, responder, false);
6485 } else {
6486 element.attachEvent('on' + actualEventName, responder);
6487 }
6488 }
6489
6490 function observeCustomEvent(element, eventName, responder) {
6491 if (element.addEventListener) {
6492 element.addEventListener('dataavailable', responder, false);
6493 } else {
6494 element.attachEvent('ondataavailable', responder);
6495 element.attachEvent('onlosecapture', responder);
6496 }
6497 }
6498
6499 function stopObserving(element, eventName, handler) {
6500 element = $(element);
6501 var handlerGiven = !Object.isUndefined(handler),
6502 eventNameGiven = !Object.isUndefined(eventName);
6503
6504 if (!eventNameGiven && !handlerGiven) {
6505 stopObservingElement(element);
6506 return element;
6507 }
6508
6509 if (!handlerGiven) {
6510 stopObservingEventName(element, eventName);
6511 return element;
6512 }
6513
6514 var entry = unregister(element, eventName, handler);
6515
6516 if (!entry) return element;
6517 removeEvent(element, eventName, entry.responder);
6518 return element;
6519 }
6520
6521 function stopObservingStandardEvent(element, eventName, responder) {
6522 var actualEventName = getDOMEventName(eventName);
6523 if (element.removeEventListener) {
6524 element.removeEventListener(actualEventName, responder, false);
6525 } else {
6526 element.detachEvent('on' + actualEventName, responder);
6527 }
6528 }
6529
6530 function stopObservingCustomEvent(element, eventName, responder) {
6531 if (element.removeEventListener) {
6532 element.removeEventListener('dataavailable', responder, false);
6533 } else {
6534 element.detachEvent('ondataavailable', responder);
6535 element.detachEvent('onlosecapture', responder);
6536 }
6537 }
6538
6539
6540
6541 function stopObservingElement(element) {
6542 var uid = getUniqueElementID(element),
6543 registry = getRegistryForElement(element, uid);
6544
6545 destroyRegistryForElement(element, uid);
6546
6547 var entries, i;
6548 for (var eventName in registry) {
6549 if (eventName === 'element') continue;
6550
6551 entries = registry[eventName];
6552 i = entries.length;
6553 while (i--)
6554 removeEvent(element, eventName, entries[i].responder);
6555 }
6556 }
6557
6558 function stopObservingEventName(element, eventName) {
6559 var registry = getRegistryForElement(element);
6560 var entries = registry[eventName];
6561 if (!entries) return;
6562 delete registry[eventName];
6563
6564 var i = entries.length;
6565 while (i--)
6566 removeEvent(element, eventName, entries[i].responder);
6567 }
6568
6569
6570 function removeEvent(element, eventName, handler) {
6571 if (isCustomEvent(eventName))
6572 stopObservingCustomEvent(element, eventName, handler);
6573 else
6574 stopObservingStandardEvent(element, eventName, handler);
6575 }
6576
6577
6578
6579 function getFireTarget(element) {
6580 if (element !== document) return element;
6581 if (document.createEvent && !element.dispatchEvent)
6582 return document.documentElement;
6583 return element;
6584 }
6585
6586 function fire(element, eventName, memo, bubble) {
6587 element = getFireTarget($(element));
6588 if (Object.isUndefined(bubble)) bubble = true;
6589 memo = memo || {};
6590
6591 var event = fireEvent(element, eventName, memo, bubble);
6592 return Event.extend(event);
6593 }
6594
6595 function fireEvent_DOM(element, eventName, memo, bubble) {
6596 var event = document.createEvent('HTMLEvents');
6597 event.initEvent('dataavailable', bubble, true);
6598
6599 event.eventName = eventName;
6600 event.memo = memo;
6601
6602 element.dispatchEvent(event);
6603 return event;
6604 }
6605
6606 function fireEvent_IE(element, eventName, memo, bubble) {
6607 var event = document.createEventObject();
6608 event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
6609
6610 event.eventName = eventName;
6611 event.memo = memo;
6612
6613 element.fireEvent(event.eventType, event);
6614 return event;
6615 }
6616
6617 var fireEvent = document.createEvent ? fireEvent_DOM : fireEvent_IE;
6618
6619
6620
6621 Event.Handler = Class.create({
6622 initialize: function(element, eventName, selector, callback) {
6623 this.element = $(element);
6624 this.eventName = eventName;
6625 this.selector = selector;
6626 this.callback = callback;
6627 this.handler = this.handleEvent.bind(this);
6628 },
6629
6630
6631 start: function() {
6632 Event.observe(this.element, this.eventName, this.handler);
6633 return this;
6634 },
6635
6636 stop: function() {
6637 Event.stopObserving(this.element, this.eventName, this.handler);
6638 return this;
6639 },
6640
6641 handleEvent: function(event) {
6642 var element = Event.findElement(event, this.selector);
6643 if (element) this.callback.call(this.element, event, element);
6644 }
6645 });
6646
6647 function on(element, eventName, selector, callback) {
6648 element = $(element);
6649 if (Object.isFunction(selector) && Object.isUndefined(callback)) {
6650 callback = selector, selector = null;
6651 }
6652
6653 return new Event.Handler(element, eventName, selector, callback).start();
6654 }
6655
6656 Object.extend(Event, Event.Methods);
6657
6658 Object.extend(Event, {
6659 fire: fire,
6660 observe: observe,
6661 stopObserving: stopObserving,
6662 on: on
6663 });
6664
6665 Element.addMethods({
6666 fire: fire,
6667
6668 observe: observe,
6669
6670 stopObserving: stopObserving,
6671
6672 on: on
6673 });
6674
6675 Object.extend(document, {
6676 fire: fire.methodize(),
6677
6678 observe: observe.methodize(),
6679
6680 stopObserving: stopObserving.methodize(),
6681
6682 on: on.methodize(),
6683
6684 loaded: false
6685 });
6686
6687 if (GLOBAL.Event) Object.extend(window.Event, Event);
6688 else GLOBAL.Event = Event;
6689
6690 GLOBAL.Event.cache = {};
6691
6692 function destroyCache_IE() {
6693 GLOBAL.Event.cache = null;
6694 }
6695
6696 if (window.attachEvent)
6697 window.attachEvent('onunload', destroyCache_IE);
6698
6699 DIV = null;
6700 docEl = null;
6701})(this);
6702
6703(function(GLOBAL) {
6704 /* Code for creating leak-free event responders is based on work by
6705 John-David Dalton. */
6706
6707 var docEl = document.documentElement;
6708 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
6709 && 'onmouseleave' in docEl;
6710
6711 function isSimulatedMouseEnterLeaveEvent(eventName) {
6712 return !MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
6713 (eventName === 'mouseenter' || eventName === 'mouseleave');
6714 }
6715
6716 function createResponder(uid, eventName, handler) {
6717 if (Event._isCustomEvent(eventName))
6718 return createResponderForCustomEvent(uid, eventName, handler);
6719 if (isSimulatedMouseEnterLeaveEvent(eventName))
6720 return createMouseEnterLeaveResponder(uid, eventName, handler);
6721
6722 return function(event) {
6723 var cacheEntry = Event.cache[uid];
6724 var element = cacheEntry.element;
6725
6726 Event.extend(event, element);
6727 handler.call(element, event);
6728 };
6729 }
6730
6731 function createResponderForCustomEvent(uid, eventName, handler) {
6732 return function(event) {
6733 var cacheEntry = Event.cache[uid], element = cacheEntry.element;
6734
6735 if (Object.isUndefined(event.eventName))
6736 return false;
6737
6738 if (event.eventName !== eventName)
6739 return false;
6740
6741 Event.extend(event, element);
6742 handler.call(element, event);
6743 };
6744 }
6745
6746 function createMouseEnterLeaveResponder(uid, eventName, handler) {
6747 return function(event) {
6748 var cacheEntry = Event.cache[uid], element = cacheEntry.element;
6749
6750 Event.extend(event, element);
6751 var parent = event.relatedTarget;
6752
6753 while (parent && parent !== element) {
6754 try { parent = parent.parentNode; }
6755 catch(e) { parent = element; }
6756 }
6757
6758 if (parent === element) return;
6759 handler.call(element, event);
6760 }
6761 }
6762
6763 GLOBAL.Event._createResponder = createResponder;
6764 docEl = null;
6765})(this);
6766
6767(function(GLOBAL) {
6768 /* Support for the DOMContentLoaded event is based on work by Dan Webb,
6769 Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
6770
6771 var TIMER;
6772
6773 function fireContentLoadedEvent() {
6774 if (document.loaded) return;
6775 if (TIMER) window.clearTimeout(TIMER);
6776 document.loaded = true;
6777 document.fire('dom:loaded');
6778 }
6779
6780 function checkReadyState() {
6781 if (document.readyState === 'complete') {
6782 document.detachEvent('onreadystatechange', checkReadyState);
6783 fireContentLoadedEvent();
6784 }
6785 }
6786
6787 function pollDoScroll() {
6788 try {
6789 document.documentElement.doScroll('left');
6790 } catch (e) {
6791 TIMER = pollDoScroll.defer();
6792 return;
6793 }
6794
6795 fireContentLoadedEvent();
6796 }
6797
6798 if (document.addEventListener) {
6799 document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
6800 } else {
6801 document.attachEvent('onreadystatechange', checkReadyState);
6802 if (window == top) TIMER = pollDoScroll.defer();
6803 }
6804
6805 Event.observe(window, 'load', fireContentLoadedEvent);
6806})(this);
6807
6808
6809Element.addMethods();
6810/*------------------------------- DEPRECATED -------------------------------*/
6811
6812Hash.toQueryString = Object.toQueryString;
6813
6814var Toggle = { display: Element.toggle };
6815
6816Element.Methods.childOf = Element.Methods.descendantOf;
6817
6818var Insertion = {
6819 Before: function(element, content) {
6820 return Element.insert(element, {before:content});
6821 },
6822
6823 Top: function(element, content) {
6824 return Element.insert(element, {top:content});
6825 },
6826
6827 Bottom: function(element, content) {
6828 return Element.insert(element, {bottom:content});
6829 },
6830
6831 After: function(element, content) {
6832 return Element.insert(element, {after:content});
6833 }
6834};
6835
6836var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
6837
6838var Position = {
6839 includeScrollOffsets: false,
6840
6841 prepare: function() {
6842 this.deltaX = window.pageXOffset
6843 || document.documentElement.scrollLeft
6844 || document.body.scrollLeft
6845 || 0;
6846 this.deltaY = window.pageYOffset
6847 || document.documentElement.scrollTop
6848 || document.body.scrollTop
6849 || 0;
6850 },
6851
6852 within: function(element, x, y) {
6853 if (this.includeScrollOffsets)
6854 return this.withinIncludingScrolloffsets(element, x, y);
6855 this.xcomp = x;
6856 this.ycomp = y;
6857 this.offset = Element.cumulativeOffset(element);
6858
6859 return (y >= this.offset[1] &&
6860 y < this.offset[1] + element.offsetHeight &&
6861 x >= this.offset[0] &&
6862 x < this.offset[0] + element.offsetWidth);
6863 },
6864
6865 withinIncludingScrolloffsets: function(element, x, y) {
6866 var offsetcache = Element.cumulativeScrollOffset(element);
6867
6868 this.xcomp = x + offsetcache[0] - this.deltaX;
6869 this.ycomp = y + offsetcache[1] - this.deltaY;
6870 this.offset = Element.cumulativeOffset(element);
6871
6872 return (this.ycomp >= this.offset[1] &&
6873 this.ycomp < this.offset[1] + element.offsetHeight &&
6874 this.xcomp >= this.offset[0] &&
6875 this.xcomp < this.offset[0] + element.offsetWidth);
6876 },
6877
6878 overlap: function(mode, element) {
6879 if (!mode) return 0;
6880 if (mode == 'vertical')
6881 return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
6882 element.offsetHeight;
6883 if (mode == 'horizontal')
6884 return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
6885 element.offsetWidth;
6886 },
6887
6888
6889 cumulativeOffset: Element.Methods.cumulativeOffset,
6890
6891 positionedOffset: Element.Methods.positionedOffset,
6892
6893 absolutize: function(element) {
6894 Position.prepare();
6895 return Element.absolutize(element);
6896 },
6897
6898 relativize: function(element) {
6899 Position.prepare();
6900 return Element.relativize(element);
6901 },
6902
6903 realOffset: Element.Methods.cumulativeScrollOffset,
6904
6905 offsetParent: Element.Methods.getOffsetParent,
6906
6907 page: Element.Methods.viewportOffset,
6908
6909 clone: function(source, target, options) {
6910 options = options || { };
6911 return Element.clonePosition(target, source, options);
6912 }
6913};
6914
6915/*--------------------------------------------------------------------------*/
6916
6917if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
6918 function iter(name) {
6919 return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
6920 }
6921
6922 instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
6923 function(element, className) {
6924 className = className.toString().strip();
6925 var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
6926 return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
6927 } : function(element, className) {
6928 className = className.toString().strip();
6929 var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
6930 if (!classNames && !className) return elements;
6931
6932 var nodes = $(element).getElementsByTagName('*');
6933 className = ' ' + className + ' ';
6934
6935 for (var i = 0, child, cn; child = nodes[i]; i++) {
6936 if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
6937 (classNames && classNames.all(function(name) {
6938 return !name.toString().blank() && cn.include(' ' + name + ' ');
6939 }))))
6940 elements.push(Element.extend(child));
6941 }
6942 return elements;
6943 };
6944
6945 return function(className, parentElement) {
6946 return $(parentElement || document.body).getElementsByClassName(className);
6947 };
6948}(Element.Methods);
6949
6950/*--------------------------------------------------------------------------*/
6951
6952Element.ClassNames = Class.create();
6953Element.ClassNames.prototype = {
6954 initialize: function(element) {
6955 this.element = $(element);
6956 },
6957
6958 _each: function(iterator, context) {
6959 this.element.className.split(/\s+/).select(function(name) {
6960 return name.length > 0;
6961 })._each(iterator, context);
6962 },
6963
6964 set: function(className) {
6965 this.element.className = className;
6966 },
6967
6968 add: function(classNameToAdd) {
6969 if (this.include(classNameToAdd)) return;
6970 this.set($A(this).concat(classNameToAdd).join(' '));
6971 },
6972
6973 remove: function(classNameToRemove) {
6974 if (!this.include(classNameToRemove)) return;
6975 this.set($A(this).without(classNameToRemove).join(' '));
6976 },
6977
6978 toString: function() {
6979 return $A(this).join(' ');
6980 }
6981};
6982
6983Object.extend(Element.ClassNames.prototype, Enumerable);
6984
6985/*--------------------------------------------------------------------------*/
6986
6987(function() {
6988 window.Selector = Class.create({
6989 initialize: function(expression) {
6990 this.expression = expression.strip();
6991 },
6992
6993 findElements: function(rootElement) {
6994 return Prototype.Selector.select(this.expression, rootElement);
6995 },
6996
6997 match: function(element) {
6998 return Prototype.Selector.match(element, this.expression);
6999 },
7000
7001 toString: function() {
7002 return this.expression;
7003 },
7004
7005 inspect: function() {
7006 return "#<Selector: " + this.expression + ">";
7007 }
7008 });
7009
7010 Object.extend(Selector, {
7011 matchElements: function(elements, expression) {
7012 var match = Prototype.Selector.match,
7013 results = [];
7014
7015 for (var i = 0, length = elements.length; i < length; i++) {
7016 var element = elements[i];
7017 if (match(element, expression)) {
7018 results.push(Element.extend(element));
7019 }
7020 }
7021 return results;
7022 },
7023
7024 findElement: function(elements, expression, index) {
7025 index = index || 0;
7026 var matchIndex = 0, element;
7027 for (var i = 0, length = elements.length; i < length; i++) {
7028 element = elements[i];
7029 if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
7030 return Element.extend(element);
7031 }
7032 }
7033 },
7034
7035 findChildElements: function(element, expressions) {
7036 var selector = expressions.toArray().join(', ');
7037 return Prototype.Selector.select(selector, element || document);
7038 }
7039 });
7040})();
7041;// script.aculo.us scriptaculous.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
7042
7043// Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7044//
7045// Permission is hereby granted, free of charge, to any person obtaining
7046// a copy of this software and associated documentation files (the
7047// "Software"), to deal in the Software without restriction, including
7048// without limitation the rights to use, copy, modify, merge, publish,
7049// distribute, sublicense, and/or sell copies of the Software, and to
7050// permit persons to whom the Software is furnished to do so, subject to
7051// the following conditions:
7052//
7053// The above copyright notice and this permission notice shall be
7054// included in all copies or substantial portions of the Software.
7055//
7056// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
7057// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7058// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
7059// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
7060// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
7061// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
7062// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7063//
7064// For details, see the script.aculo.us web site: http://script.aculo.us/
7065
7066var Scriptaculous = {
7067 Version: '1.9.0',
7068 require: function(libraryName) {
7069 try{
7070 // inserting via DOM fails in Safari 2.0, so brute force approach
7071 document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
7072 } catch(e) {
7073 // for xhtml+xml served content, fall back to DOM methods
7074 var script = document.createElement('script');
7075 script.type = 'text/javascript';
7076 script.src = libraryName;
7077 document.getElementsByTagName('head')[0].appendChild(script);
7078 }
7079 },
7080 REQUIRED_PROTOTYPE: '1.6.0.3',
7081 load: function() {
7082 function convertVersionString(versionString) {
7083 var v = versionString.replace(/_.*|\./g, '');
7084 v = parseInt(v + '0'.times(4-v.length));
7085 return versionString.indexOf('_') > -1 ? v-1 : v;
7086 }
7087
7088 if((typeof Prototype=='undefined') ||
7089 (typeof Element == 'undefined') ||
7090 (typeof Element.Methods=='undefined') ||
7091 (convertVersionString(Prototype.Version) <
7092 convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
7093 throw("script.aculo.us requires the Prototype JavaScript framework >= " +
7094 Scriptaculous.REQUIRED_PROTOTYPE);
7095
7096 var js = /scriptaculous\.js(\?.*)?$/;
7097 $$('script[src]').findAll(function(s) {
7098 return s.src.match(js);
7099 }).each(function(s) {
7100 var path = s.src.replace(js, ''),
7101 includes = s.src.match(/\?.*load=([a-z,]*)/);
7102 (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
7103 function(include) { Scriptaculous.require(path+include+'.js') });
7104 });
7105 }
7106};
7107
7108Scriptaculous.load();;// script.aculo.us effects.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
7109
7110// Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
7111// Contributors:
7112// Justin Palmer (http://encytemedia.com/)
7113// Mark Pilgrim (http://diveintomark.org/)
7114// Martin Bialasinki
7115//
7116// script.aculo.us is freely distributable under the terms of an MIT-style license.
7117// For details, see the script.aculo.us web site: http://script.aculo.us/
7118
7119// converts rgb() and #xxx to #xxxxxx format,
7120// returns self (or first argument) if not convertable
7121String.prototype.parseColor = function() {
7122 var color = '#';
7123 if (this.slice(0,4) == 'rgb(') {
7124 var cols = this.slice(4,this.length-1).split(',');
7125 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
7126 } else {
7127 if (this.slice(0,1) == '#') {
7128 if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
7129 if (this.length==7) color = this.toLowerCase();
7130 }
7131 }
7132 return (color.length==7 ? color : (arguments[0] || this));
7133};
7134
7135/*--------------------------------------------------------------------------*/
7136
7137Element.collectTextNodes = function(element) {
7138 return $A($(element).childNodes).collect( function(node) {
7139 return (node.nodeType==3 ? node.nodeValue :
7140 (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
7141 }).flatten().join('');
7142};
7143
7144Element.collectTextNodesIgnoreClass = function(element, className) {
7145 return $A($(element).childNodes).collect( function(node) {
7146 return (node.nodeType==3 ? node.nodeValue :
7147 ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
7148 Element.collectTextNodesIgnoreClass(node, className) : ''));
7149 }).flatten().join('');
7150};
7151
7152Element.setContentZoom = function(element, percent) {
7153 element = $(element);
7154 element.setStyle({fontSize: (percent/100) + 'em'});
7155 if (Prototype.Browser.WebKit) window.scrollBy(0,0);
7156 return element;
7157};
7158
7159Element.getInlineOpacity = function(element){
7160 return $(element).style.opacity || '';
7161};
7162
7163Element.forceRerendering = function(element) {
7164 try {
7165 element = $(element);
7166 var n = document.createTextNode(' ');
7167 element.appendChild(n);
7168 element.removeChild(n);
7169 } catch(e) { }
7170};
7171
7172/*--------------------------------------------------------------------------*/
7173
7174var Effect = {
7175 _elementDoesNotExistError: {
7176 name: 'ElementDoesNotExistError',
7177 message: 'The specified DOM element does not exist, but is required for this effect to operate'
7178 },
7179 Transitions: {
7180 linear: Prototype.K,
7181 sinoidal: function(pos) {
7182 return (-Math.cos(pos*Math.PI)/2) + .5;
7183 },
7184 reverse: function(pos) {
7185 return 1-pos;
7186 },
7187 flicker: function(pos) {
7188 var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
7189 return pos > 1 ? 1 : pos;
7190 },
7191 wobble: function(pos) {
7192 return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
7193 },
7194 pulse: function(pos, pulses) {
7195 return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
7196 },
7197 spring: function(pos) {
7198 return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
7199 },
7200 none: function(pos) {
7201 return 0;
7202 },
7203 full: function(pos) {
7204 return 1;
7205 }
7206 },
7207 DefaultOptions: {
7208 duration: 1.0, // seconds
7209 fps: 100, // 100= assume 66fps max.
7210 sync: false, // true for combining
7211 from: 0.0,
7212 to: 1.0,
7213 delay: 0.0,
7214 queue: 'parallel'
7215 },
7216 tagifyText: function(element) {
7217 var tagifyStyle = 'position:relative';
7218 if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
7219
7220 element = $(element);
7221 $A(element.childNodes).each( function(child) {
7222 if (child.nodeType==3) {
7223 child.nodeValue.toArray().each( function(character) {
7224 element.insertBefore(
7225 new Element('span', {style: tagifyStyle}).update(
7226 character == ' ' ? String.fromCharCode(160) : character),
7227 child);
7228 });
7229 Element.remove(child);
7230 }
7231 });
7232 },
7233 multiple: function(element, effect) {
7234 var elements;
7235 if (((typeof element == 'object') ||
7236 Object.isFunction(element)) &&
7237 (element.length))
7238 elements = element;
7239 else
7240 elements = $(element).childNodes;
7241
7242 var options = Object.extend({
7243 speed: 0.1,
7244 delay: 0.0
7245 }, arguments[2] || { });
7246 var masterDelay = options.delay;
7247
7248 $A(elements).each( function(element, index) {
7249 new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
7250 });
7251 },
7252 PAIRS: {
7253 'slide': ['SlideDown','SlideUp'],
7254 'blind': ['BlindDown','BlindUp'],
7255 'appear': ['Appear','Fade']
7256 },
7257 toggle: function(element, effect, options) {
7258 element = $(element);
7259 effect = (effect || 'appear').toLowerCase();
7260 
7261 return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
7262 queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
7263 }, options || {}));
7264 }
7265};
7266
7267Effect.DefaultOptions.transition = Effect.Transitions.sinoidal;
7268
7269/* ------------- core effects ------------- */
7270
7271Effect.ScopedQueue = Class.create(Enumerable, {
7272 initialize: function() {
7273 this.effects = [];
7274 this.interval = null;
7275 },
7276 _each: function(iterator) {
7277 this.effects._each(iterator);
7278 },
7279 add: function(effect) {
7280 var timestamp = new Date().getTime();
7281
7282 var position = Object.isString(effect.options.queue) ?
7283 effect.options.queue : effect.options.queue.position;
7284
7285 switch(position) {
7286 case 'front':
7287 // move unstarted effects after this effect
7288 this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
7289 e.startOn += effect.finishOn;
7290 e.finishOn += effect.finishOn;
7291 });
7292 break;
7293 case 'with-last':
7294 timestamp = this.effects.pluck('startOn').max() || timestamp;
7295 break;
7296 case 'end':
7297 // start effect after last queued effect has finished
7298 timestamp = this.effects.pluck('finishOn').max() || timestamp;
7299 break;
7300 }
7301
7302 effect.startOn += timestamp;
7303 effect.finishOn += timestamp;
7304
7305 if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
7306 this.effects.push(effect);
7307
7308 if (!this.interval)
7309 this.interval = setInterval(this.loop.bind(this), 15);
7310 },
7311 remove: function(effect) {
7312 this.effects = this.effects.reject(function(e) { return e==effect });
7313 if (this.effects.length == 0) {
7314 clearInterval(this.interval);
7315 this.interval = null;
7316 }
7317 },
7318 loop: function() {
7319 var timePos = new Date().getTime();
7320 for(var i=0, len=this.effects.length;i<len;i++)
7321 this.effects[i] && this.effects[i].loop(timePos);
7322 }
7323});
7324
7325Effect.Queues = {
7326 instances: $H(),
7327 get: function(queueName) {
7328 if (!Object.isString(queueName)) return queueName;
7329
7330 return this.instances.get(queueName) ||
7331 this.instances.set(queueName, new Effect.ScopedQueue());
7332 }
7333};
7334Effect.Queue = Effect.Queues.get('global');
7335
7336Effect.Base = Class.create({
7337 position: null,
7338 start: function(options) {
7339 if (options && options.transition === false) options.transition = Effect.Transitions.linear;
7340 this.options = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
7341 this.currentFrame = 0;
7342 this.state = 'idle';
7343 this.startOn = this.options.delay*1000;
7344 this.finishOn = this.startOn+(this.options.duration*1000);
7345 this.fromToDelta = this.options.to-this.options.from;
7346 this.totalTime = this.finishOn-this.startOn;
7347 this.totalFrames = this.options.fps*this.options.duration;
7348
7349 this.render = (function() {
7350 function dispatch(effect, eventName) {
7351 if (effect.options[eventName + 'Internal'])
7352 effect.options[eventName + 'Internal'](effect);
7353 if (effect.options[eventName])
7354 effect.options[eventName](effect);
7355 }
7356
7357 return function(pos) {
7358 if (this.state === "idle") {
7359 this.state = "running";
7360 dispatch(this, 'beforeSetup');
7361 if (this.setup) this.setup();
7362 dispatch(this, 'afterSetup');
7363 }
7364 if (this.state === "running") {
7365 pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
7366 this.position = pos;
7367 dispatch(this, 'beforeUpdate');
7368 if (this.update) this.update(pos);
7369 dispatch(this, 'afterUpdate');
7370 }
7371 };
7372 })();
7373
7374 this.event('beforeStart');
7375 if (!this.options.sync)
7376 Effect.Queues.get(Object.isString(this.options.queue) ?
7377 'global' : this.options.queue.scope).add(this);
7378 },
7379 loop: function(timePos) {
7380 if (timePos >= this.startOn) {
7381 if (timePos >= this.finishOn) {
7382 this.render(1.0);
7383 this.cancel();
7384 this.event('beforeFinish');
7385 if (this.finish) this.finish();
7386 this.event('afterFinish');
7387 return;
7388 }
7389 var pos = (timePos - this.startOn) / this.totalTime,
7390 frame = (pos * this.totalFrames).round();
7391 if (frame > this.currentFrame) {
7392 this.render(pos);
7393 this.currentFrame = frame;
7394 }
7395 }
7396 },
7397 cancel: function() {
7398 if (!this.options.sync)
7399 Effect.Queues.get(Object.isString(this.options.queue) ?
7400 'global' : this.options.queue.scope).remove(this);
7401 this.state = 'finished';
7402 },
7403 event: function(eventName) {
7404 if (this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
7405 if (this.options[eventName]) this.options[eventName](this);
7406 },
7407 inspect: function() {
7408 var data = $H();
7409 for(property in this)
7410 if (!Object.isFunction(this[property])) data.set(property, this[property]);
7411 return '#<Effect:' + data.inspect() + ',options:' + $H(this.options).inspect() + '>';
7412 }
7413});
7414
7415Effect.Parallel = Class.create(Effect.Base, {
7416 initialize: function(effects) {
7417 this.effects = effects || [];
7418 this.start(arguments[1]);
7419 },
7420 update: function(position) {
7421 this.effects.invoke('render', position);
7422 },
7423 finish: function(position) {
7424 this.effects.each( function(effect) {
7425 effect.render(1.0);
7426 effect.cancel();
7427 effect.event('beforeFinish');
7428 if (effect.finish) effect.finish(position);
7429 effect.event('afterFinish');
7430 });
7431 }
7432});
7433
7434Effect.Tween = Class.create(Effect.Base, {
7435 initialize: function(object, from, to) {
7436 object = Object.isString(object) ? $(object) : object;
7437 var args = $A(arguments), method = args.last(),
7438 options = args.length == 5 ? args[3] : null;
7439 this.method = Object.isFunction(method) ? method.bind(object) :
7440 Object.isFunction(object[method]) ? object[method].bind(object) :
7441 function(value) { object[method] = value };
7442 this.start(Object.extend({ from: from, to: to }, options || { }));
7443 },
7444 update: function(position) {
7445 this.method(position);
7446 }
7447});
7448
7449Effect.Event = Class.create(Effect.Base, {
7450 initialize: function() {
7451 this.start(Object.extend({ duration: 0 }, arguments[0] || { }));
7452 },
7453 update: Prototype.emptyFunction
7454});
7455
7456Effect.Opacity = Class.create(Effect.Base, {
7457 initialize: function(element) {
7458 this.element = $(element);
7459 if (!this.element) throw(Effect._elementDoesNotExistError);
7460 // make this work on IE on elements without 'layout'
7461 if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
7462 this.element.setStyle({zoom: 1});
7463 var options = Object.extend({
7464 from: this.element.getOpacity() || 0.0,
7465 to: 1.0
7466 }, arguments[1] || { });
7467 this.start(options);
7468 },
7469 update: function(position) {
7470 this.element.setOpacity(position);
7471 }
7472});
7473
7474Effect.Move = Class.create(Effect.Base, {
7475 initialize: function(element) {
7476 this.element = $(element);
7477 if (!this.element) throw(Effect._elementDoesNotExistError);
7478 var options = Object.extend({
7479 x: 0,
7480 y: 0,
7481 mode: 'relative'
7482 }, arguments[1] || { });
7483 this.start(options);
7484 },
7485 setup: function() {
7486 this.element.makePositioned();
7487 this.originalLeft = parseFloat(this.element.getStyle('left') || '0');
7488 this.originalTop = parseFloat(this.element.getStyle('top') || '0');
7489 if (this.options.mode == 'absolute') {
7490 this.options.x = this.options.x - this.originalLeft;
7491 this.options.y = this.options.y - this.originalTop;
7492 }
7493 },
7494 update: function(position) {
7495 this.element.setStyle({
7496 left: (this.options.x * position + this.originalLeft).round() + 'px',
7497 top: (this.options.y * position + this.originalTop).round() + 'px'
7498 });
7499 }
7500});
7501
7502// for backwards compatibility
7503Effect.MoveBy = function(element, toTop, toLeft) {
7504 return new Effect.Move(element,
7505 Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
7506};
7507
7508Effect.Scale = Class.create(Effect.Base, {
7509 initialize: function(element, percent) {
7510 this.element = $(element);
7511 if (!this.element) throw(Effect._elementDoesNotExistError);
7512 var options = Object.extend({
7513 scaleX: true,
7514 scaleY: true,
7515 scaleContent: true,
7516 scaleFromCenter: false,
7517 scaleMode: 'box', // 'box' or 'contents' or { } with provided values
7518 scaleFrom: 100.0,
7519 scaleTo: percent
7520 }, arguments[2] || { });
7521 this.start(options);
7522 },
7523 setup: function() {
7524 this.restoreAfterFinish = this.options.restoreAfterFinish || false;
7525 this.elementPositioning = this.element.getStyle('position');
7526
7527 this.originalStyle = { };
7528 ['top','left','width','height','fontSize'].each( function(k) {
7529 this.originalStyle[k] = this.element.style[k];
7530 }.bind(this));
7531
7532 this.originalTop = this.element.offsetTop;
7533 this.originalLeft = this.element.offsetLeft;
7534
7535 var fontSize = this.element.getStyle('font-size') || '100%';
7536 ['em','px','%','pt'].each( function(fontSizeType) {
7537 if (fontSize.indexOf(fontSizeType)>0) {
7538 this.fontSize = parseFloat(fontSize);
7539 this.fontSizeType = fontSizeType;
7540 }
7541 }.bind(this));
7542
7543 this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
7544
7545 this.dims = null;
7546 if (this.options.scaleMode=='box')
7547 this.dims = [this.element.offsetHeight, this.element.offsetWidth];
7548 if (/^content/.test(this.options.scaleMode))
7549 this.dims = [this.element.scrollHeight, this.element.scrollWidth];
7550 if (!this.dims)
7551 this.dims = [this.options.scaleMode.originalHeight,
7552 this.options.scaleMode.originalWidth];
7553 },
7554 update: function(position) {
7555 var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
7556 if (this.options.scaleContent && this.fontSize)
7557 this.element.setStyle({fontSize: this.fontSize * currentScale + this.fontSizeType });
7558 this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
7559 },
7560 finish: function(position) {
7561 if (this.restoreAfterFinish) this.element.setStyle(this.originalStyle);
7562 },
7563 setDimensions: function(height, width) {
7564 var d = { };
7565 if (this.options.scaleX) d.width = width.round() + 'px';
7566 if (this.options.scaleY) d.height = height.round() + 'px';
7567 if (this.options.scaleFromCenter) {
7568 var topd = (height - this.dims[0])/2;
7569 var leftd = (width - this.dims[1])/2;
7570 if (this.elementPositioning == 'absolute') {
7571 if (this.options.scaleY) d.top = this.originalTop-topd + 'px';
7572 if (this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
7573 } else {
7574 if (this.options.scaleY) d.top = -topd + 'px';
7575 if (this.options.scaleX) d.left = -leftd + 'px';
7576 }
7577 }
7578 this.element.setStyle(d);
7579 }
7580});
7581
7582Effect.Highlight = Class.create(Effect.Base, {
7583 initialize: function(element) {
7584 this.element = $(element);
7585 if (!this.element) throw(Effect._elementDoesNotExistError);
7586 var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || { });
7587 this.start(options);
7588 },
7589 setup: function() {
7590 // Prevent executing on elements not in the layout flow
7591 if (this.element.getStyle('display')=='none') { this.cancel(); return; }
7592 // Disable background image during the effect
7593 this.oldStyle = { };
7594 if (!this.options.keepBackgroundImage) {
7595 this.oldStyle.backgroundImage = this.element.getStyle('background-image');
7596 this.element.setStyle({backgroundImage: 'none'});
7597 }
7598 if (!this.options.endcolor)
7599 this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
7600 if (!this.options.restorecolor)
7601 this.options.restorecolor = this.element.getStyle('background-color');
7602 // init color calculations
7603 this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
7604 this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
7605 },
7606 update: function(position) {
7607 this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
7608 return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
7609 },
7610 finish: function() {
7611 this.element.setStyle(Object.extend(this.oldStyle, {
7612 backgroundColor: this.options.restorecolor
7613 }));
7614 }
7615});
7616
7617Effect.ScrollTo = function(element) {
7618 var options = arguments[1] || { },
7619 scrollOffsets = document.viewport.getScrollOffsets(),
7620 elementOffsets = $(element).cumulativeOffset();
7621
7622 if (options.offset) elementOffsets[1] += options.offset;
7623
7624 return new Effect.Tween(null,
7625 scrollOffsets.top,
7626 elementOffsets[1],
7627 options,
7628 function(p){ scrollTo(scrollOffsets.left, p.round()); }
7629 );
7630};
7631
7632/* ------------- combination effects ------------- */
7633
7634Effect.Fade = function(element) {
7635 element = $(element);
7636 var oldOpacity = element.getInlineOpacity();
7637 var options = Object.extend({
7638 from: element.getOpacity() || 1.0,
7639 to: 0.0,
7640 afterFinishInternal: function(effect) {
7641 if (effect.options.to!=0) return;
7642 effect.element.hide().setStyle({opacity: oldOpacity});
7643 }
7644 }, arguments[1] || { });
7645 return new Effect.Opacity(element,options);
7646};
7647
7648Effect.Appear = function(element) {
7649 element = $(element);
7650 var options = Object.extend({
7651 from: (element.getStyle('display') == 'none' ? 0.0 : element.getOpacity() || 0.0),
7652 to: 1.0,
7653 // force Safari to render floated elements properly
7654 afterFinishInternal: function(effect) {
7655 effect.element.forceRerendering();
7656 },
7657 beforeSetup: function(effect) {
7658 effect.element.setOpacity(effect.options.from).show();
7659 }}, arguments[1] || { });
7660 return new Effect.Opacity(element,options);
7661};
7662
7663Effect.Puff = function(element) {
7664 element = $(element);
7665 var oldStyle = {
7666 opacity: element.getInlineOpacity(),
7667 position: element.getStyle('position'),
7668 top: element.style.top,
7669 left: element.style.left,
7670 width: element.style.width,
7671 height: element.style.height
7672 };
7673 return new Effect.Parallel(
7674 [ new Effect.Scale(element, 200,
7675 { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
7676 new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
7677 Object.extend({ duration: 1.0,
7678 beforeSetupInternal: function(effect) {
7679 Position.absolutize(effect.effects[0].element);
7680 },
7681 afterFinishInternal: function(effect) {
7682 effect.effects[0].element.hide().setStyle(oldStyle); }
7683 }, arguments[1] || { })
7684 );
7685};
7686
7687Effect.BlindUp = function(element) {
7688 element = $(element);
7689 element.makeClipping();
7690 return new Effect.Scale(element, 0,
7691 Object.extend({ scaleContent: false,
7692 scaleX: false,
7693 restoreAfterFinish: true,
7694 afterFinishInternal: function(effect) {
7695 effect.element.hide().undoClipping();
7696 }
7697 }, arguments[1] || { })
7698 );
7699};
7700
7701Effect.BlindDown = function(element) {
7702 element = $(element);
7703 var elementDimensions = element.getDimensions();
7704 return new Effect.Scale(element, 100, Object.extend({
7705 scaleContent: false,
7706 scaleX: false,
7707 scaleFrom: 0,
7708 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
7709 restoreAfterFinish: true,
7710 afterSetup: function(effect) {
7711 effect.element.makeClipping().setStyle({height: '0px'}).show();
7712 },
7713 afterFinishInternal: function(effect) {
7714 effect.element.undoClipping();
7715 }
7716 }, arguments[1] || { }));
7717};
7718
7719Effect.SwitchOff = function(element) {
7720 element = $(element);
7721 var oldOpacity = element.getInlineOpacity();
7722 return new Effect.Appear(element, Object.extend({
7723 duration: 0.4,
7724 from: 0,
7725 transition: Effect.Transitions.flicker,
7726 afterFinishInternal: function(effect) {
7727 new Effect.Scale(effect.element, 1, {
7728 duration: 0.3, scaleFromCenter: true,
7729 scaleX: false, scaleContent: false, restoreAfterFinish: true,
7730 beforeSetup: function(effect) {
7731 effect.element.makePositioned().makeClipping();
7732 },
7733 afterFinishInternal: function(effect) {
7734 effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
7735 }
7736 });
7737 }
7738 }, arguments[1] || { }));
7739};
7740
7741Effect.DropOut = function(element) {
7742 element = $(element);
7743 var oldStyle = {
7744 top: element.getStyle('top'),
7745 left: element.getStyle('left'),
7746 opacity: element.getInlineOpacity() };
7747 return new Effect.Parallel(
7748 [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
7749 new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
7750 Object.extend(
7751 { duration: 0.5,
7752 beforeSetup: function(effect) {
7753 effect.effects[0].element.makePositioned();
7754 },
7755 afterFinishInternal: function(effect) {
7756 effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
7757 }
7758 }, arguments[1] || { }));
7759};
7760
7761Effect.Shake = function(element) {
7762 element = $(element);
7763 var options = Object.extend({
7764 distance: 20,
7765 duration: 0.5
7766 }, arguments[1] || {});
7767 var distance = parseFloat(options.distance);
7768 var split = parseFloat(options.duration) / 10.0;
7769 var oldStyle = {
7770 top: element.getStyle('top'),
7771 left: element.getStyle('left') };
7772 return new Effect.Move(element,
7773 { x: distance, y: 0, duration: split, afterFinishInternal: function(effect) {
7774 new Effect.Move(effect.element,
7775 { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
7776 new Effect.Move(effect.element,
7777 { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
7778 new Effect.Move(effect.element,
7779 { x: -distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
7780 new Effect.Move(effect.element,
7781 { x: distance*2, y: 0, duration: split*2, afterFinishInternal: function(effect) {
7782 new Effect.Move(effect.element,
7783 { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
7784 effect.element.undoPositioned().setStyle(oldStyle);
7785 }}); }}); }}); }}); }}); }});
7786};
7787
7788Effect.SlideDown = function(element) {
7789 element = $(element).cleanWhitespace();
7790 // SlideDown need to have the content of the element wrapped in a container element with fixed height!
7791 var oldInnerBottom = element.down().getStyle('bottom');
7792 var elementDimensions = element.getDimensions();
7793 return new Effect.Scale(element, 100, Object.extend({
7794 scaleContent: false,
7795 scaleX: false,
7796 scaleFrom: window.opera ? 0 : 1,
7797 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
7798 restoreAfterFinish: true,
7799 afterSetup: function(effect) {
7800 effect.element.makePositioned();
7801 effect.element.down().makePositioned();
7802 if (window.opera) effect.element.setStyle({top: ''});
7803 effect.element.makeClipping().setStyle({height: '0px'}).show();
7804 },
7805 afterUpdateInternal: function(effect) {
7806 effect.element.down().setStyle({bottom:
7807 (effect.dims[0] - effect.element.clientHeight) + 'px' });
7808 },
7809 afterFinishInternal: function(effect) {
7810 effect.element.undoClipping().undoPositioned();
7811 effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom}); }
7812 }, arguments[1] || { })
7813 );
7814};
7815
7816Effect.SlideUp = function(element) {
7817 element = $(element).cleanWhitespace();
7818 var oldInnerBottom = element.down().getStyle('bottom');
7819 var elementDimensions = element.getDimensions();
7820 return new Effect.Scale(element, window.opera ? 0 : 1,
7821 Object.extend({ scaleContent: false,
7822 scaleX: false,
7823 scaleMode: 'box',
7824 scaleFrom: 100,
7825 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
7826 restoreAfterFinish: true,
7827 afterSetup: function(effect) {
7828 effect.element.makePositioned();
7829 effect.element.down().makePositioned();
7830 if (window.opera) effect.element.setStyle({top: ''});
7831 effect.element.makeClipping().show();
7832 },
7833 afterUpdateInternal: function(effect) {
7834 effect.element.down().setStyle({bottom:
7835 (effect.dims[0] - effect.element.clientHeight) + 'px' });
7836 },
7837 afterFinishInternal: function(effect) {
7838 effect.element.hide().undoClipping().undoPositioned();
7839 effect.element.down().undoPositioned().setStyle({bottom: oldInnerBottom});
7840 }
7841 }, arguments[1] || { })
7842 );
7843};
7844
7845// Bug in opera makes the TD containing this element expand for a instance after finish
7846Effect.Squish = function(element) {
7847 return new Effect.Scale(element, window.opera ? 1 : 0, {
7848 restoreAfterFinish: true,
7849 beforeSetup: function(effect) {
7850 effect.element.makeClipping();
7851 },
7852 afterFinishInternal: function(effect) {
7853 effect.element.hide().undoClipping();
7854 }
7855 });
7856};
7857
7858Effect.Grow = function(element) {
7859 element = $(element);
7860 var options = Object.extend({
7861 direction: 'center',
7862 moveTransition: Effect.Transitions.sinoidal,
7863 scaleTransition: Effect.Transitions.sinoidal,
7864 opacityTransition: Effect.Transitions.full
7865 }, arguments[1] || { });
7866 var oldStyle = {
7867 top: element.style.top,
7868 left: element.style.left,
7869 height: element.style.height,
7870 width: element.style.width,
7871 opacity: element.getInlineOpacity() };
7872
7873 var dims = element.getDimensions();
7874 var initialMoveX, initialMoveY;
7875 var moveX, moveY;
7876
7877 switch (options.direction) {
7878 case 'top-left':
7879 initialMoveX = initialMoveY = moveX = moveY = 0;
7880 break;
7881 case 'top-right':
7882 initialMoveX = dims.width;
7883 initialMoveY = moveY = 0;
7884 moveX = -dims.width;
7885 break;
7886 case 'bottom-left':
7887 initialMoveX = moveX = 0;
7888 initialMoveY = dims.height;
7889 moveY = -dims.height;
7890 break;
7891 case 'bottom-right':
7892 initialMoveX = dims.width;
7893 initialMoveY = dims.height;
7894 moveX = -dims.width;
7895 moveY = -dims.height;
7896 break;
7897 case 'center':
7898 initialMoveX = dims.width / 2;
7899 initialMoveY = dims.height / 2;
7900 moveX = -dims.width / 2;
7901 moveY = -dims.height / 2;
7902 break;
7903 }
7904
7905 return new Effect.Move(element, {
7906 x: initialMoveX,
7907 y: initialMoveY,
7908 duration: 0.01,
7909 beforeSetup: function(effect) {
7910 effect.element.hide().makeClipping().makePositioned();
7911 },
7912 afterFinishInternal: function(effect) {
7913 new Effect.Parallel(
7914 [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
7915 new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
7916 new Effect.Scale(effect.element, 100, {
7917 scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
7918 sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
7919 ], Object.extend({
7920 beforeSetup: function(effect) {
7921 effect.effects[0].element.setStyle({height: '0px'}).show();
7922 },
7923 afterFinishInternal: function(effect) {
7924 effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
7925 }
7926 }, options)
7927 );
7928 }
7929 });
7930};
7931
7932Effect.Shrink = function(element) {
7933 element = $(element);
7934 var options = Object.extend({
7935 direction: 'center',
7936 moveTransition: Effect.Transitions.sinoidal,
7937 scaleTransition: Effect.Transitions.sinoidal,
7938 opacityTransition: Effect.Transitions.none
7939 }, arguments[1] || { });
7940 var oldStyle = {
7941 top: element.style.top,
7942 left: element.style.left,
7943 height: element.style.height,
7944 width: element.style.width,
7945 opacity: element.getInlineOpacity() };
7946
7947 var dims = element.getDimensions();
7948 var moveX, moveY;
7949
7950 switch (options.direction) {
7951 case 'top-left':
7952 moveX = moveY = 0;
7953 break;
7954 case 'top-right':
7955 moveX = dims.width;
7956 moveY = 0;
7957 break;
7958 case 'bottom-left':
7959 moveX = 0;
7960 moveY = dims.height;
7961 break;
7962 case 'bottom-right':
7963 moveX = dims.width;
7964 moveY = dims.height;
7965 break;
7966 case 'center':
7967 moveX = dims.width / 2;
7968 moveY = dims.height / 2;
7969 break;
7970 }
7971
7972 return new Effect.Parallel(
7973 [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
7974 new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
7975 new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
7976 ], Object.extend({
7977 beforeStartInternal: function(effect) {
7978 effect.effects[0].element.makePositioned().makeClipping();
7979 },
7980 afterFinishInternal: function(effect) {
7981 effect.effects[0].element.hide().undoClipping().undoPositioned().setStyle(oldStyle); }
7982 }, options)
7983 );
7984};
7985
7986Effect.Pulsate = function(element) {
7987 element = $(element);
7988 var options = arguments[1] || { },
7989 oldOpacity = element.getInlineOpacity(),
7990 transition = options.transition || Effect.Transitions.linear,
7991 reverser = function(pos){
7992 return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
7993 };
7994
7995 return new Effect.Opacity(element,
7996 Object.extend(Object.extend({ duration: 2.0, from: 0,
7997 afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
7998 }, options), {transition: reverser}));
7999};
8000
8001Effect.Fold = function(element) {
8002 element = $(element);
8003 var oldStyle = {
8004 top: element.style.top,
8005 left: element.style.left,
8006 width: element.style.width,
8007 height: element.style.height };
8008 element.makeClipping();
8009 return new Effect.Scale(element, 5, Object.extend({
8010 scaleContent: false,
8011 scaleX: false,
8012 afterFinishInternal: function(effect) {
8013 new Effect.Scale(element, 1, {
8014 scaleContent: false,
8015 scaleY: false,
8016 afterFinishInternal: function(effect) {
8017 effect.element.hide().undoClipping().setStyle(oldStyle);
8018 } });
8019 }}, arguments[1] || { }));
8020};
8021
8022Effect.Morph = Class.create(Effect.Base, {
8023 initialize: function(element) {
8024 this.element = $(element);
8025 if (!this.element) throw(Effect._elementDoesNotExistError);
8026 var options = Object.extend({
8027 style: { }
8028 }, arguments[1] || { });
8029
8030 if (!Object.isString(options.style)) this.style = $H(options.style);
8031 else {
8032 if (options.style.include(':'))
8033 this.style = options.style.parseStyle();
8034 else {
8035 this.element.addClassName(options.style);
8036 this.style = $H(this.element.getStyles());
8037 this.element.removeClassName(options.style);
8038 var css = this.element.getStyles();
8039 this.style = this.style.reject(function(style) {
8040 return style.value == css[style.key];
8041 });
8042 options.afterFinishInternal = function(effect) {
8043 effect.element.addClassName(effect.options.style);
8044 effect.transforms.each(function(transform) {
8045 effect.element.style[transform.style] = '';
8046 });
8047 };
8048 }
8049 }
8050 this.start(options);
8051 },
8052
8053 setup: function(){
8054 function parseColor(color){
8055 if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
8056 color = color.parseColor();
8057 return $R(0,2).map(function(i){
8058 return parseInt( color.slice(i*2+1,i*2+3), 16 );
8059 });
8060 }
8061 this.transforms = this.style.map(function(pair){
8062 var property = pair[0], value = pair[1], unit = null;
8063
8064 if (value.parseColor('#zzzzzz') != '#zzzzzz') {
8065 value = value.parseColor();
8066 unit = 'color';
8067 } else if (property == 'opacity') {
8068 value = parseFloat(value);
8069 if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
8070 this.element.setStyle({zoom: 1});
8071 } else if (Element.CSS_LENGTH.test(value)) {
8072 var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
8073 value = parseFloat(components[1]);
8074 unit = (components.length == 3) ? components[2] : null;
8075 }
8076
8077 var originalValue = this.element.getStyle(property);
8078 return {
8079 style: property.camelize(),
8080 originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
8081 targetValue: unit=='color' ? parseColor(value) : value,
8082 unit: unit
8083 };
8084 }.bind(this)).reject(function(transform){
8085 return (
8086 (transform.originalValue == transform.targetValue) ||
8087 (
8088 transform.unit != 'color' &&
8089 (isNaN(transform.originalValue) || isNaN(transform.targetValue))
8090 )
8091 );
8092 });
8093 },
8094 update: function(position) {
8095 var style = { }, transform, i = this.transforms.length;
8096 while(i--)
8097 style[(transform = this.transforms[i]).style] =
8098 transform.unit=='color' ? '#'+
8099 (Math.round(transform.originalValue[0]+
8100 (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
8101 (Math.round(transform.originalValue[1]+
8102 (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
8103 (Math.round(transform.originalValue[2]+
8104 (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
8105 (transform.originalValue +
8106 (transform.targetValue - transform.originalValue) * position).toFixed(3) +
8107 (transform.unit === null ? '' : transform.unit);
8108 this.element.setStyle(style, true);
8109 }
8110});
8111
8112Effect.Transform = Class.create({
8113 initialize: function(tracks){
8114 this.tracks = [];
8115 this.options = arguments[1] || { };
8116 this.addTracks(tracks);
8117 },
8118 addTracks: function(tracks){
8119 tracks.each(function(track){
8120 track = $H(track);
8121 var data = track.values().first();
8122 this.tracks.push($H({
8123 ids: track.keys().first(),
8124 effect: Effect.Morph,
8125 options: { style: data }
8126 }));
8127 }.bind(this));
8128 return this;
8129 },
8130 play: function(){
8131 return new Effect.Parallel(
8132 this.tracks.map(function(track){
8133 var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
8134 var elements = [$(ids) || $$(ids)].flatten();
8135 return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
8136 }).flatten(),
8137 this.options
8138 );
8139 }
8140});
8141
8142Element.CSS_PROPERTIES = $w(
8143 'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
8144 'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
8145 'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
8146 'borderTopColor borderTopStyle borderTopWidth bottom clip color ' +
8147 'fontSize fontWeight height left letterSpacing lineHeight ' +
8148 'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
8149 'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
8150 'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
8151 'right textIndent top width wordSpacing zIndex');
8152
8153Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
8154
8155String.__parseStyleElement = document.createElement('div');
8156String.prototype.parseStyle = function(){
8157 var style, styleRules = $H();
8158 if (Prototype.Browser.WebKit)
8159 style = new Element('div',{style:this}).style;
8160 else {
8161 String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
8162 style = String.__parseStyleElement.childNodes[0].style;
8163 }
8164
8165 Element.CSS_PROPERTIES.each(function(property){
8166 if (style[property]) styleRules.set(property, style[property]);
8167 });
8168
8169 if (Prototype.Browser.IE && this.include('opacity'))
8170 styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
8171
8172 return styleRules;
8173};
8174
8175if (document.defaultView && document.defaultView.getComputedStyle) {
8176 Element.getStyles = function(element) {
8177 var css = document.defaultView.getComputedStyle($(element), null);
8178 return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
8179 styles[property] = css[property];
8180 return styles;
8181 });
8182 };
8183} else {
8184 Element.getStyles = function(element) {
8185 element = $(element);
8186 var css = element.currentStyle, styles;
8187 styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
8188 results[property] = css[property];
8189 return results;
8190 });
8191 if (!styles.opacity) styles.opacity = element.getOpacity();
8192 return styles;
8193 };
8194}
8195
8196Effect.Methods = {
8197 morph: function(element, style) {
8198 element = $(element);
8199 new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
8200 return element;
8201 },
8202 visualEffect: function(element, effect, options) {
8203 element = $(element);
8204 var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
8205 new Effect[klass](element, options);
8206 return element;
8207 },
8208 highlight: function(element, options) {
8209 element = $(element);
8210 new Effect.Highlight(element, options);
8211 return element;
8212 }
8213};
8214
8215$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
8216 'pulsate shake puff squish switchOff dropOut').each(
8217 function(effect) {
8218 Effect.Methods[effect] = function(element, options){
8219 element = $(element);
8220 Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
8221 return element;
8222 };
8223 }
8224);
8225
8226$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
8227 function(f) { Effect.Methods[f] = Element[f]; }
8228);
8229
8230Element.addMethods(Effect.Methods);;// script.aculo.us builder.js v1.9.0, Thu Dec 23 16:54:48 -0500 2010
8231
8232// Copyright (c) 2005-2010 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
8233//
8234// script.aculo.us is freely distributable under the terms of an MIT-style license.
8235// For details, see the script.aculo.us web site: http://script.aculo.us/
8236
8237var Builder = {
8238 NODEMAP: {
8239 AREA: 'map',
8240 CAPTION: 'table',
8241 COL: 'table',
8242 COLGROUP: 'table',
8243 LEGEND: 'fieldset',
8244 OPTGROUP: 'select',
8245 OPTION: 'select',
8246 PARAM: 'object',
8247 TBODY: 'table',
8248 TD: 'table',
8249 TFOOT: 'table',
8250 TH: 'table',
8251 THEAD: 'table',
8252 TR: 'table'
8253 },
8254 // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken,
8255 // due to a Firefox bug
8256 node: function(elementName) {
8257 elementName = elementName.toUpperCase();
8258
8259 // try innerHTML approach
8260 var parentTag = this.NODEMAP[elementName] || 'div';
8261 var parentElement = document.createElement(parentTag);
8262 try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
8263 parentElement.innerHTML = "<" + elementName + "></" + elementName + ">";
8264 } catch(e) {}
8265 var element = parentElement.firstChild || null;
8266
8267 // see if browser added wrapping tags
8268 if(element && (element.tagName.toUpperCase() != elementName))
8269 element = element.getElementsByTagName(elementName)[0];
8270
8271 // fallback to createElement approach
8272 if(!element) element = document.createElement(elementName);
8273
8274 // abort if nothing could be created
8275 if(!element) return;
8276
8277 // attributes (or text)
8278 if(arguments[1])
8279 if(this._isStringOrNumber(arguments[1]) ||
8280 (arguments[1] instanceof Array) ||
8281 arguments[1].tagName) {
8282 this._children(element, arguments[1]);
8283 } else {
8284 var attrs = this._attributes(arguments[1]);
8285 if(attrs.length) {
8286 try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707
8287 parentElement.innerHTML = "<" +elementName + " " +
8288 attrs + "></" + elementName + ">";
8289 } catch(e) {}
8290 element = parentElement.firstChild || null;
8291 // workaround firefox 1.0.X bug
8292 if(!element) {
8293 element = document.createElement(elementName);
8294 for(attr in arguments[1])
8295 element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
8296 }
8297 if(element.tagName.toUpperCase() != elementName)
8298 element = parentElement.getElementsByTagName(elementName)[0];
8299 }
8300 }
8301
8302 // text, or array of children
8303 if(arguments[2])
8304 this._children(element, arguments[2]);
8305
8306 return $(element);
8307 },
8308 _text: function(text) {
8309 return document.createTextNode(text);
8310 },
8311
8312 ATTR_MAP: {
8313 'className': 'class',
8314 'htmlFor': 'for'
8315 },
8316
8317 _attributes: function(attributes) {
8318 var attrs = [];
8319 for(attribute in attributes)
8320 attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) +
8321 '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'&quot;') + '"');
8322 return attrs.join(" ");
8323 },
8324 _children: function(element, children) {
8325 if(children.tagName) {
8326 element.appendChild(children);
8327 return;
8328 }
8329 if(typeof children=='object') { // array can hold nodes and text
8330 children.flatten().each( function(e) {
8331 if(typeof e=='object')
8332 element.appendChild(e);
8333 else
8334 if(Builder._isStringOrNumber(e))
8335 element.appendChild(Builder._text(e));
8336 });
8337 } else
8338 if(Builder._isStringOrNumber(children))
8339 element.appendChild(Builder._text(children));
8340 },
8341 _isStringOrNumber: function(param) {
8342 return(typeof param=='string' || typeof param=='number');
8343 },
8344 build: function(html) {
8345 var element = this.node('div');
8346 $(element).update(html.strip());
8347 return element.down();
8348 },
8349 dump: function(scope) {
8350 if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
8351
8352 var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
8353 "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
8354 "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+
8355 "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+
8356 "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
8357 "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
8358
8359 tags.each( function(tag){
8360 scope[tag] = function() {
8361 return Builder.node.apply(Builder, [tag].concat($A(arguments)));
8362 };
8363 });
8364 }
8365};;// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
8366// 
8367// Permission is hereby granted, free of charge, to any person obtaining
8368// a copy of this software and associated documentation files (the
8369// "Software"), to deal in the Software without restriction, including
8370// without limitation the rights to use, copy, modify, merge, publish,
8371// distribute, sublicense, and/or sell copies of the Software, and to
8372// permit persons to whom the Software is furnished to do so, subject to
8373// the following conditions:
8374// 
8375// The above copyright notice and this permission notice shall be
8376// included in all copies or substantial portions of the Software.
8377//
8378// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
8379// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8380// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
8381// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
8382// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
8383// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
8384// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8385//
8386// VERSION 1.3
8387
8388var Window = Class.create();
8389
8390Window.keepMultiModalWindow = false;
8391Window.hasEffectLib = (typeof Effect != 'undefined');
8392Window.resizeEffectDuration = 0;
8393
8394Window.prototype = {
8395 // Constructor
8396 // Available parameters : className, blurClassName, title, minWidth, minHeight, maxWidth, maxHeight, width, height, top, left, bottom, right, resizable, zIndex, opacity, recenterAuto, wiredDrag
8397 // hideEffect, showEffect, showEffectOptions, hideEffectOptions, effectOptions, url, draggable, closable, minimizable, maximizable, parent, onload
8398 // add all callbacks (if you do not use an observer)
8399 // onDestroy onStartResize onStartMove onResize onMove onEndResize onEndMove onFocus onBlur onBeforeShow onShow onHide onMinimize onMaximize onClose
8400 
8401 initialize: function() {
8402 var id;
8403 var optionIndex = 0;
8404 // For backward compatibility like win= new Window("id", {...}) instead of win = new Window({id: "id", ...})
8405 if (arguments.length > 0) {
8406 if (typeof arguments[0] == "string" ) {
8407 id = arguments[0];
8408 optionIndex = 1;
8409 }
8410 else
8411 id = arguments[0] ? arguments[0].id : null;
8412 }
8413 
8414 // Generate unique ID if not specified
8415 if (!id)
8416 id = "window_" + new Date().getTime();
8417 
8418 if ($(id))
8419 alert("Window " + id + " is already registered in the DOM! Make sure you use setDestroyOnClose() or destroyOnClose: true in the constructor");
8420
8421 this.options = Object.extend({
8422 className: "dialog",
8423 blurClassName: null,
8424 minWidth: 100, 
8425 minHeight: 20,
8426 resizable: true,
8427 closable: true,
8428 minimizable: true,
8429 maximizable: true,
8430 draggable: true,
8431 userData: null,
8432 showEffect: (Window.hasEffectLib ? Effect.Appear : Element.show),
8433 hideEffect: (Window.hasEffectLib ? Effect.Fade : Element.hide),
8434 showEffectOptions: {},
8435 hideEffectOptions: {},
8436 effectOptions: null,
8437 parent: document.body,
8438 title: "&nbsp;",
8439 url: null,
8440 onload: Prototype.emptyFunction,
8441 width: 200,
8442 height: 300,
8443 opacity: 1,
8444 recenterAuto: true,
8445 wiredDrag: false,
8446 closeCallback: null,
8447 destroyOnClose: false,
8448 gridX: 1, 
8449 gridY: 1 
8450 }, arguments[optionIndex] || {});
8451 if (this.options.blurClassName)
8452 this.options.focusClassName = this.options.className;
8453 
8454 if (typeof this.options.top == "undefined" && typeof this.options.bottom == "undefined") 
8455 this.options.top = this._round(Math.random()*500, this.options.gridY);
8456 if (typeof this.options.left == "undefined" && typeof this.options.right == "undefined") 
8457 this.options.left = this._round(Math.random()*500, this.options.gridX);
8458
8459 if (this.options.effectOptions) {
8460 Object.extend(this.options.hideEffectOptions, this.options.effectOptions);
8461 Object.extend(this.options.showEffectOptions, this.options.effectOptions);
8462 if (this.options.showEffect == Element.Appear)
8463 this.options.showEffectOptions.to = this.options.opacity;
8464 }
8465 if (Window.hasEffectLib) {
8466 if (this.options.showEffect == Effect.Appear)
8467 this.options.showEffectOptions.to = this.options.opacity;
8468 
8469 if (this.options.hideEffect == Effect.Fade)
8470 this.options.hideEffectOptions.from = this.options.opacity;
8471 }
8472 if (this.options.hideEffect == Element.hide)
8473 this.options.hideEffect = function(){ Element.hide(this.element); if (this.options.destroyOnClose) this.destroy(); }.bind(this)
8474 
8475 if (this.options.parent != document.body) 
8476 this.options.parent = $(this.options.parent);
8477 
8478 this.element = this._createWindow(id); 
8479 this.element.win = this;
8480 
8481 // Bind event listener
8482 this.eventMouseDown = this._initDrag.bindAsEventListener(this);
8483 this.eventMouseUp = this._endDrag.bindAsEventListener(this);
8484 this.eventMouseMove = this._updateDrag.bindAsEventListener(this);
8485 this.eventOnLoad = this._getWindowBorderSize.bindAsEventListener(this);
8486 this.eventMouseDownContent = this.toFront.bindAsEventListener(this);
8487 this.eventResize = this._recenter.bindAsEventListener(this);
8488 
8489 this.topbar = $(this.element.id + "_top");
8490 this.bottombar = $(this.element.id + "_bottom");
8491 this.content = $(this.element.id + "_content");
8492 
8493 Event.observe(this.topbar, "mousedown", this.eventMouseDown);
8494 Event.observe(this.bottombar, "mousedown", this.eventMouseDown);
8495 Event.observe(this.content, "mousedown", this.eventMouseDownContent);
8496 Event.observe(window, "load", this.eventOnLoad);
8497 Event.observe(window, "resize", this.eventResize);
8498 Event.observe(window, "scroll", this.eventResize);
8499 Event.observe(this.options.parent, "scroll", this.eventResize);
8500 
8501 if (this.options.draggable) {
8502 var that = this;
8503 [this.topbar, this.topbar.up().previous(), this.topbar.up().next()].each(function(element) {
8504 element.observe("mousedown", that.eventMouseDown);
8505 element.addClassName("top_draggable");
8506 });
8507 [this.bottombar.up(), this.bottombar.up().previous(), this.bottombar.up().next()].each(function(element) {
8508 element.observe("mousedown", that.eventMouseDown);
8509 element.addClassName("bottom_draggable");
8510 });
8511 
8512 } 
8513 
8514 if (this.options.resizable) {
8515 this.sizer = $(this.element.id + "_sizer");
8516 Event.observe(this.sizer, "mousedown", this.eventMouseDown);
8517 } 
8518 
8519 this.useLeft = null;
8520 this.useTop = null;
8521 if (typeof this.options.left != "undefined") {
8522 this.element.setStyle({left: parseFloat(this.options.left) + 'px'});
8523 this.useLeft = true;
8524 }
8525 else {
8526 this.element.setStyle({right: parseFloat(this.options.right) + 'px'});
8527 this.useLeft = false;
8528 }
8529 
8530 if (typeof this.options.top != "undefined") {
8531 this.element.setStyle({top: parseFloat(this.options.top) + 'px'});
8532 this.useTop = true;
8533 }
8534 else {
8535 this.element.setStyle({bottom: parseFloat(this.options.bottom) + 'px'}); 
8536 this.useTop = false;
8537 }
8538 
8539 this.storedLocation = null;
8540 
8541 this.setOpacity(this.options.opacity);
8542 if (this.options.zIndex)
8543 this.setZIndex(this.options.zIndex)
8544
8545 if (this.options.destroyOnClose)
8546 this.setDestroyOnClose(true);
8547
8548 this._getWindowBorderSize();
8549 this.width = this.options.width;
8550 this.height = this.options.height;
8551 this.visible = false;
8552 
8553 this.constraint = false;
8554 this.constraintPad = {top: 0, left:0, bottom:0, right:0};
8555 
8556 if (this.width && this.height)
8557 this.setSize(this.options.width, this.options.height);
8558 this.setTitle(this.options.title)
8559 Windows.register(this); 
8560 },
8561 
8562 // Destructor
8563 destroy: function() {
8564 this._notify("onDestroy");
8565 Event.stopObserving(this.topbar, "mousedown", this.eventMouseDown);
8566 Event.stopObserving(this.bottombar, "mousedown", this.eventMouseDown);
8567 Event.stopObserving(this.content, "mousedown", this.eventMouseDownContent);
8568 
8569 Event.stopObserving(window, "load", this.eventOnLoad);
8570 Event.stopObserving(window, "resize", this.eventResize);
8571 Event.stopObserving(window, "scroll", this.eventResize);
8572 
8573 Event.stopObserving(this.content, "load", this.options.onload);
8574
8575 if (this._oldParent) {
8576 var content = this.getContent();
8577 var originalContent = null;
8578 for(var i = 0; i < content.childNodes.length; i++) {
8579 originalContent = content.childNodes[i];
8580 if (originalContent.nodeType == 1) 
8581 break;
8582 originalContent = null;
8583 }
8584 if (originalContent)
8585 this._oldParent.appendChild(originalContent);
8586 this._oldParent = null;
8587 }
8588
8589 if (this.sizer)
8590 Event.stopObserving(this.sizer, "mousedown", this.eventMouseDown);
8591
8592 // if (this.options.url) 
8593 // this.content.src = null
8594
8595 if(this.iefix) 
8596 Element.remove(this.iefix);
8597
8598 Element.remove(this.element);
8599 Windows.unregister(this); 
8600 },
8601 
8602 // Sets close callback, if it sets, it should return true to be able to close the window.
8603 setCloseCallback: function(callback) {
8604 this.options.closeCallback = callback;
8605 },
8606 
8607 // Gets window content
8608 getContent: function () {
8609 return this.content;
8610 },
8611 
8612 // Sets the content with an element id
8613 setContent: function(id, autoresize, autoposition) {
8614 var element = $(id);
8615 if (null == element) throw "Unable to find element '" + id + "' in DOM";
8616 this._oldParent = element.parentNode;
8617
8618 var d = null;
8619 var p = null;
8620
8621 if (autoresize) 
8622 d = Element.getDimensions(element);
8623 if (autoposition) 
8624 p = Position.cumulativeOffset(element);
8625
8626 var content = this.getContent();
8627 // Clear HTML (and even iframe)
8628 this.setHTMLContent("");
8629 content = this.getContent();
8630 
8631 content.appendChild(element);
8632 element.show();
8633 if (autoresize) 
8634 this.setSize(d.width, d.height);
8635 if (autoposition) 
8636 this.setLocation(p[1] - this.heightN, p[0] - this.widthW); 
8637 },
8638 
8639 setHTMLContent: function(html) {
8640 // It was an url (iframe), recreate a div content instead of iframe content
8641 if (this.options.url) {
8642 this.content.src = null;
8643 this.options.url = null;
8644 
8645 	 var content ="<div id=\"" + this.getId() + "_content\" class=\"" + this.options.className + "_content\"> </div>";
8646 $(this.getId() +"_table_content").innerHTML = content;
8647 
8648 this.content = $(this.element.id + "_content");
8649 }
8650 
8651 this.getContent().innerHTML = html;
8652 },
8653 
8654 setAjaxContent: function(url, options, showCentered, showModal) {
8655 this.showFunction = showCentered ? "showCenter" : "show";
8656 this.showModal = showModal || false;
8657 
8658 options = options || {};
8659
8660 // Clear HTML (and even iframe)
8661 this.setHTMLContent("");
8662 
8663 this.onComplete = options.onComplete;
8664 if (! this._onCompleteHandler)
8665 this._onCompleteHandler = this._setAjaxContent.bind(this);
8666 options.onComplete = this._onCompleteHandler;
8667
8668 new Ajax.Request(url, options); 
8669 options.onComplete = this.onComplete;
8670 },
8671 
8672 _setAjaxContent: function(originalRequest) {
8673 Element.update(this.getContent(), originalRequest.responseText);
8674 if (this.onComplete)
8675 this.onComplete(originalRequest);
8676 this.onComplete = null;
8677 this[this.showFunction](this.showModal)
8678 },
8679 
8680 setURL: function(url) {
8681 // Not an url content, change div to iframe
8682 if (this.options.url) 
8683 this.content.src = null;
8684 this.options.url = url;
8685 var content= "<iframe frameborder='0' name='" + this.getId() + "_content' id='" + this.getId() + "_content' src='" + url + "' width='" + this.width + "' height='" + this.height + "'> </iframe>";
8686 $(this.getId() +"_table_content").innerHTML = content;
8687 
8688 this.content = $(this.element.id + "_content");
8689 },
8690
8691 getURL: function() {
8692 	return this.options.url ? this.options.url : null;
8693 },
8694
8695 refresh: function() {
8696 if (this.options.url)
8697	 $(this.element.getAttribute('id') + '_content').src = this.options.url;
8698 },
8699 
8700 // Stores position/size in a cookie, by default named with window id
8701 setCookie: function(name, expires, path, domain, secure) {
8702 name = name || this.element.id;
8703 this.cookie = [name, expires, path, domain, secure];
8704 
8705 // Get cookie
8706 var value = WindowUtilities.getCookie(name)
8707 // If exists
8708 if (value) {
8709 var values = value.split(',');
8710 var x = values[0].split(':');
8711 var y = values[1].split(':');
8712
8713 var w = parseFloat(values[2]), h = parseFloat(values[3]);
8714 var mini = values[4];
8715 var maxi = values[5];
8716
8717 this.setSize(w, h);
8718 if (mini == "true")
8719 this.doMinimize = true; // Minimize will be done at onload window event
8720 else if (maxi == "true")
8721 this.doMaximize = true; // Maximize will be done at onload window event
8722
8723 this.useLeft = x[0] == "l";
8724 this.useTop = y[0] == "t";
8725
8726 this.element.setStyle(this.useLeft ? {left: x[1]} : {right: x[1]});
8727 this.element.setStyle(this.useTop ? {top: y[1]} : {bottom: y[1]});
8728 }
8729 },
8730 
8731 // Gets window ID
8732 getId: function() {
8733 return this.element.id;
8734 },
8735 
8736 // Detroys itself when closing 
8737 setDestroyOnClose: function() {
8738 this.options.destroyOnClose = true;
8739 },
8740 
8741 setConstraint: function(bool, padding) {
8742 this.constraint = bool;
8743 this.constraintPad = Object.extend(this.constraintPad, padding || {});
8744 // Reset location to apply constraint
8745 if (this.useTop && this.useLeft)
8746 this.setLocation(parseFloat(this.element.style.top), parseFloat(this.element.style.left));
8747 },
8748 
8749 // initDrag event
8750
8751 _initDrag: function(event) {
8752 // No resize on minimized window
8753 if (Event.element(event) == this.sizer && this.isMinimized())
8754 return;
8755
8756 // No move on maximzed window
8757 if (Event.element(event) != this.sizer && this.isMaximized())
8758 return;
8759 
8760 if (Prototype.Browser.IE && this.heightN == 0)
8761 this._getWindowBorderSize();
8762 
8763 // Get pointer X,Y
8764 this.pointer = [this._round(Event.pointerX(event), this.options.gridX), this._round(Event.pointerY(event), this.options.gridY)];
8765 if (this.options.wiredDrag) 
8766 this.currentDrag = this._createWiredElement();
8767 else
8768 this.currentDrag = this.element;
8769 
8770 // Resize
8771 if (Event.element(event) == this.sizer) {
8772 this.doResize = true;
8773 this.widthOrg = this.width;
8774 this.heightOrg = this.height;
8775 this.bottomOrg = parseFloat(this.element.getStyle('bottom'));
8776 this.rightOrg = parseFloat(this.element.getStyle('right'));
8777 this._notify("onStartResize");
8778 }
8779 else {
8780 this.doResize = false;
8781
8782 // Check if click on close button, 
8783 var closeButton = $(this.getId() + '_close');
8784 if (closeButton && Position.within(closeButton, this.pointer[0], this.pointer[1])) {
8785 this.currentDrag = null;
8786 return;
8787 }
8788
8789 this.toFront();
8790
8791 if (! this.options.draggable) 
8792 return;
8793 this._notify("onStartMove");
8794 } 
8795 // Register global event to capture mouseUp and mouseMove
8796 Event.observe(document, "mouseup", this.eventMouseUp, false);
8797 Event.observe(document, "mousemove", this.eventMouseMove, false);
8798 
8799 // Add an invisible div to keep catching mouse event over iframes
8800 WindowUtilities.disableScreen('__invisible__', '__invisible__', this.overlayOpacity);
8801
8802 // Stop selection while dragging
8803 document.body.ondrag = function () { return false; };
8804 document.body.onselectstart = function () { return false; };
8805 
8806 this.currentDrag.show();
8807 Event.stop(event);
8808 },
8809 
8810 _round: function(val, round) {
8811 return round == 1 ? val : val = Math.floor(val / round) * round;
8812 },
8813
8814 // updateDrag event
8815 _updateDrag: function(event) {
8816 var pointer = [this._round(Event.pointerX(event), this.options.gridX), this._round(Event.pointerY(event), this.options.gridY)]; 
8817 var dx = pointer[0] - this.pointer[0];
8818 var dy = pointer[1] - this.pointer[1];
8819 
8820 // Resize case, update width/height
8821 if (this.doResize) {
8822 var w = this.widthOrg + dx;
8823 var h = this.heightOrg + dy;
8824 
8825 dx = this.width - this.widthOrg
8826 dy = this.height - this.heightOrg
8827 
8828 // Check if it's a right position, update it to keep upper-left corner at the same position
8829 if (this.useLeft) 
8830 w = this._updateWidthConstraint(w)
8831 else 
8832 this.currentDrag.setStyle({right: (this.rightOrg -dx) + 'px'});
8833 // Check if it's a bottom position, update it to keep upper-left corner at the same position
8834 if (this.useTop) 
8835 h = this._updateHeightConstraint(h)
8836 else
8837 this.currentDrag.setStyle({bottom: (this.bottomOrg -dy) + 'px'});
8838 
8839 this.setSize(w , h);
8840 this._notify("onResize");
8841 }
8842 // Move case, update top/left
8843 else {
8844 this.pointer = pointer;
8845 
8846 if (this.useLeft) {
8847 var left = parseFloat(this.currentDrag.getStyle('left')) + dx;
8848 var newLeft = this._updateLeftConstraint(left);
8849 // Keep mouse pointer correct
8850 this.pointer[0] += newLeft-left;
8851 this.currentDrag.setStyle({left: newLeft + 'px'});
8852 }
8853 else 
8854 this.currentDrag.setStyle({right: parseFloat(this.currentDrag.getStyle('right')) - dx + 'px'});
8855 
8856 if (this.useTop) {
8857 var top = parseFloat(this.currentDrag.getStyle('top')) + dy;
8858 var newTop = this._updateTopConstraint(top);
8859 // Keep mouse pointer correct
8860 this.pointer[1] += newTop - top;
8861 this.currentDrag.setStyle({top: newTop + 'px'});
8862 }
8863 else 
8864 this.currentDrag.setStyle({bottom: parseFloat(this.currentDrag.getStyle('bottom')) - dy + 'px'});
8865
8866 this._notify("onMove");
8867 }
8868 if (this.iefix) 
8869 this._fixIEOverlapping(); 
8870 
8871 this._removeStoreLocation();
8872 Event.stop(event);
8873 },
8874
8875 // endDrag callback
8876 _endDrag: function(event) {
8877 // Remove temporary div over iframes
8878 WindowUtilities.enableScreen('__invisible__');
8879 
8880 if (this.doResize)
8881 this._notify("onEndResize");
8882 else
8883 this._notify("onEndMove");
8884 
8885 // Release event observing
8886 Event.stopObserving(document, "mouseup", this.eventMouseUp,false);
8887 Event.stopObserving(document, "mousemove", this.eventMouseMove, false);
8888
8889 Event.stop(event);
8890 
8891 this._hideWiredElement();
8892
8893 // Store new location/size if need be
8894 this._saveCookie()
8895 
8896 // Restore selection
8897 document.body.ondrag = null;
8898 document.body.onselectstart = null;
8899 },
8900
8901 _updateLeftConstraint: function(left) {
8902 if (this.constraint && this.useLeft && this.useTop) {
8903 var width = this.options.parent == document.body ? WindowUtilities.getPageSize().windowWidth : this.options.parent.getDimensions().width;
8904
8905 if (left < this.constraintPad.left)
8906 left = this.constraintPad.left;
8907 if (left + this.width + this.widthE + this.widthW > width - this.constraintPad.right) 
8908 left = width - this.constraintPad.right - this.width - this.widthE - this.widthW;
8909 }
8910 return left;
8911 },
8912 
8913 _updateTopConstraint: function(top) {
8914 if (this.constraint && this.useLeft && this.useTop) { 
8915 var height = this.options.parent == document.body ? WindowUtilities.getPageSize().windowHeight : this.options.parent.getDimensions().height;
8916 
8917 var h = this.height + this.heightN + this.heightS;
8918
8919 if (top < this.constraintPad.top)
8920 top = this.constraintPad.top;
8921 if (top + h > height - this.constraintPad.bottom) 
8922 top = height - this.constraintPad.bottom - h;
8923 }
8924 return top;
8925 },
8926 
8927 _updateWidthConstraint: function(w) {
8928 if (this.constraint && this.useLeft && this.useTop) {
8929 var width = this.options.parent == document.body ? WindowUtilities.getPageSize().windowWidth : this.options.parent.getDimensions().width;
8930 var left = parseFloat(this.element.getStyle("left"));
8931
8932 if (left + w + this.widthE + this.widthW > width - this.constraintPad.right) 
8933 w = width - this.constraintPad.right - left - this.widthE - this.widthW;
8934 }
8935 return w;
8936 },
8937 
8938 _updateHeightConstraint: function(h) {
8939 if (this.constraint && this.useLeft && this.useTop) {
8940 var height = this.options.parent == document.body ? WindowUtilities.getPageSize().windowHeight : this.options.parent.getDimensions().height;
8941 var top = parseFloat(this.element.getStyle("top"));
8942
8943 if (top + h + this.heightN + this.heightS > height - this.constraintPad.bottom) 
8944 h = height - this.constraintPad.bottom - top - this.heightN - this.heightS;
8945 }
8946 return h;
8947 },
8948 
8949 
8950 // Creates HTML window code
8951 _createWindow: function(id) {
8952 var className = this.options.className;
8953 var win = document.createElement("div");
8954 win.setAttribute('id', id);
8955 win.className = "dialog";
8956
8957 var content;
8958 //ESI WARNING ?????????? 2020-02-20 takeuchi
8959 if (this.options.url)
8960 content= "<iframe frameborder=\"0\" name=\"" + _h(id) + "_content\" id=\"" + _h(id) + "_content\" src=\"" + _h(this.options.url) + "\"> </iframe>";
8961 else
8962 content ="<div id=\"" + _h(id) + "_content\" class=\"" +_h(className) + "_content\"> </div>";
8963
8964 var closeDiv = this.options.closable ? "<div class='"+ className +"_close' id='"+ id +"_close' onclick='Windows.close(\""+ id +"\", event)'> </div>" : "";
8965 var minDiv = this.options.minimizable ? "<div class='"+ className + "_minimize' id='"+ id +"_minimize' onclick='Windows.minimize(\""+ id +"\", event)'> </div>" : "";
8966 var maxDiv = this.options.maximizable ? "<div class='"+ className + "_maximize' id='"+ id +"_maximize' onclick='Windows.maximize(\""+ id +"\", event)'> </div>" : "";
8967 var seAttributes = this.options.resizable ? "class='" + className + "_sizer' id='" + id + "_sizer'" : "class='" + className + "_se'";
8968 var blank = "../themes/default/blank.gif";
8969 
8970 win.innerHTML = closeDiv + minDiv + maxDiv + "\
8971 <table id='"+ id +"_row1' class=\"top table_window\">\
8972 <tr>\
8973 <td class='"+ className +"_nw'></td>\
8974 <td class='"+ className +"_n'><div id='"+ id +"_top' class='"+ className +"_title title_window'>"+ this.options.title +"</div></td>\
8975 <td class='"+ className +"_ne'></td>\
8976 </tr>\
8977 </table>\
8978 <table id='"+ id +"_row2' class=\"mid table_window\">\
8979 <tr>\
8980 <td class='"+ className +"_w'></td>\
8981 <td id='"+ id +"_table_content' class='"+ className +"_content' valign='top'>" + content + "</td>\
8982 <td class='"+ className +"_e'></td>\
8983 </tr>\
8984 </table>\
8985 <table id='"+ id +"_row3' class=\"bot table_window\">\
8986 <tr>\
8987 <td class='"+ className +"_sw'></td>\
8988 <td class='"+ className +"_s'><div id='"+ id +"_bottom' class='status_bar'><span style='float:left; width:1px; height:1px'></span></div></td>\
8989 <td " + seAttributes + "></td>\
8990 </tr>\
8991 </table>\
8992 ";
8993 Element.hide(win);
8994 this.options.parent.insertBefore(win, this.options.parent.firstChild);
8995 Event.observe($(id + "_content"), "load", this.options.onload);
8996 return win;
8997 },
8998 
8999 
9000 changeClassName: function(newClassName) { 
9001 var className = this.options.className;
9002 var id = this.getId();
9003 $A(["_close", "_minimize", "_maximize", "_sizer", "_content"]).each(function(value) { this._toggleClassName($(id + value), className + value, newClassName + value) }.bind(this));
9004 this._toggleClassName($(id + "_top"), className + "_title", newClassName + "_title");
9005 $$("#" + id + " td").each(function(td) {td.className = td.className.sub(className,newClassName); });
9006 this.options.className = newClassName;
9007 },
9008 
9009 _toggleClassName: function(element, oldClassName, newClassName) { 
9010 if (element) {
9011 element.removeClassName(oldClassName);
9012 element.addClassName(newClassName);
9013 }
9014 },
9015 
9016 // Sets window location
9017 setLocation: function(top, left) {
9018 top = this._updateTopConstraint(top);
9019 left = this._updateLeftConstraint(left);
9020
9021 var e = this.currentDrag || this.element;
9022 e.setStyle({top: top + 'px'});
9023 e.setStyle({left: left + 'px'});
9024
9025 this.useLeft = true;
9026 this.useTop = true;
9027 },
9028 
9029 getLocation: function() {
9030 var location = {};
9031 if (this.useTop)
9032 location = Object.extend(location, {top: this.element.getStyle("top")});
9033 else
9034 location = Object.extend(location, {bottom: this.element.getStyle("bottom")});
9035 if (this.useLeft)
9036 location = Object.extend(location, {left: this.element.getStyle("left")});
9037 else
9038 location = Object.extend(location, {right: this.element.getStyle("right")});
9039 
9040 return location;
9041 },
9042 
9043 // Gets window size
9044 getSize: function() {
9045 return {width: this.width, height: this.height};
9046 },
9047 
9048 // Sets window size
9049 setSize: function(width, height, useEffect) { 
9050 width = parseFloat(width);
9051 height = parseFloat(height);
9052 
9053 // Check min and max size
9054 if (!this.minimized && width < this.options.minWidth)
9055 width = this.options.minWidth;
9056
9057 if (!this.minimized && height < this.options.minHeight)
9058 height = this.options.minHeight;
9059 
9060 if (this.options. maxHeight && height > this.options. maxHeight)
9061 height = this.options. maxHeight;
9062
9063 if (this.options. maxWidth && width > this.options. maxWidth)
9064 width = this.options. maxWidth;
9065
9066 
9067 if (this.useTop && this.useLeft && Window.hasEffectLib && Effect.ResizeWindow && useEffect) {
9068 new Effect.ResizeWindow(this, null, null, width, height, {duration: Window.resizeEffectDuration});
9069 } else {
9070 this.width = width;
9071 this.height = height;
9072 var e = this.currentDrag ? this.currentDrag : this.element;
9073
9074 e.setStyle({width: width + this.widthW + this.widthE + "px"})
9075 e.setStyle({height: height + this.heightN + this.heightS + "px"})
9076
9077 // Update content size
9078 if (!this.currentDrag || this.currentDrag == this.element) {
9079 var content = $(this.element.id + '_content');
9080 content.setStyle({height: height + 'px'});
9081 content.setStyle({width: width + 'px'});
9082 }
9083 }
9084 },
9085 
9086 updateHeight: function() {
9087 this.setSize(this.width, this.content.scrollHeight, true);
9088 },
9089 
9090 updateWidth: function() {
9091 this.setSize(this.content.scrollWidth, this.height, true);
9092 },
9093 
9094 // Brings window to front
9095 toFront: function() {
9096 if (this.element.style.zIndex < Windows.maxZIndex) 
9097 this.setZIndex(Windows.maxZIndex + 2);
9098 if (this.iefix) 
9099 this._fixIEOverlapping(); 
9100 },
9101 
9102 getBounds: function(insideOnly) {
9103 if (! this.width || !this.height || !this.visible) 
9104 this.computeBounds();
9105 var w = this.width;
9106 var h = this.height;
9107
9108 if (!insideOnly) {
9109 w += this.widthW + this.widthE;
9110 h += this.heightN + this.heightS;
9111 }
9112 var bounds = Object.extend(this.getLocation(), {width: w + "px", height: h + "px"});
9113 return bounds;
9114 },
9115 
9116 computeBounds: function() {
9117 if (! this.width || !this.height) {
9118 var size = WindowUtilities._computeSize(this.content.innerHTML, this.content.id, this.width, this.height, 0, this.options.className)
9119 if (this.height)
9120 this.width = size + 5
9121 else
9122 this.height = size + 5
9123 }
9124
9125 this.setSize(this.width, this.height);
9126 if (this.centered)
9127 this._center(this.centerTop, this.centerLeft); 
9128 },
9129 
9130 // Displays window modal state or not
9131 show: function(modal) {
9132 this.visible = true;
9133 if (modal) {
9134 // Hack for Safari !!
9135 if (typeof this.overlayOpacity == "undefined") {
9136 var that = this;
9137 setTimeout(function() {that.show(modal)}, 10);
9138 return;
9139 }
9140 Windows.addModalWindow(this);
9141 
9142 this.modal = true; 
9143 this.setZIndex(Windows.maxZIndex + 2);
9144 Windows.unsetOverflow(this);
9145 }
9146 else 
9147 if (!this.element.style.zIndex) 
9148 this.setZIndex(Windows.maxZIndex + 2); 
9149 
9150 // To restore overflow if need be
9151 if (this.oldStyle)
9152 this.getContent().setStyle({overflow: this.oldStyle});
9153 
9154 this.computeBounds();
9155 
9156 this._notify("onBeforeShow"); 
9157 if (this.options.showEffect != Element.show && this.options.showEffectOptions)
9158 this.options.showEffect(this.element, this.options.showEffectOptions); 
9159 else
9160 this.options.showEffect(this.element); 
9161 
9162 this._checkIEOverlapping();
9163 WindowUtilities.focusedWindow = this
9164 this._notify("onShow"); 
9165 },
9166 
9167 // Displays window modal state or not at the center of the page
9168 showCenter: function(modal, top, left) {
9169 this.centered = true;
9170 this.centerTop = top;
9171 this.centerLeft = left;
9172
9173 this.show(modal);
9174 },
9175 
9176 isVisible: function() {
9177 return this.visible;
9178 },
9179 
9180 _center: function(top, left) { 
9181 var windowScroll = WindowUtilities.getWindowScroll(this.options.parent); 
9182 var pageSize = WindowUtilities.getPageSize(this.options.parent); 
9183 if (typeof top == "undefined")
9184 top = (pageSize.windowHeight - (this.height + this.heightN + this.heightS))/2;
9185 top += windowScroll.top
9186 
9187 if (typeof left == "undefined")
9188 left = (pageSize.windowWidth - (this.width + this.widthW + this.widthE))/2;
9189 left += windowScroll.left 
9190 this.setLocation(top, left);
9191 this.toFront();
9192 },
9193 
9194 _recenter: function(event) { 
9195 if (this.centered) {
9196 var pageSize = WindowUtilities.getPageSize(this.options.parent);
9197 var windowScroll = WindowUtilities.getWindowScroll(this.options.parent); 
9198
9199 // Check for this stupid IE that sends dumb events
9200 if (this.pageSize && this.pageSize.windowWidth == pageSize.windowWidth && this.pageSize.windowHeight == pageSize.windowHeight && 
9201 this.windowScroll.left == windowScroll.left && this.windowScroll.top == windowScroll.top) 
9202 return;
9203 this.pageSize = pageSize;
9204 this.windowScroll = windowScroll;
9205 // set height of Overlay to take up whole page and show
9206 if ($('overlay_modal')) 
9207 $('overlay_modal').setStyle({height: (pageSize.pageHeight + 'px')});
9208 
9209 if (this.options.recenterAuto)
9210 this._center(this.centerTop, this.centerLeft); 
9211 }
9212 },
9213 
9214 // Hides window
9215 hide: function() {
9216 this.visible = false;
9217 if (this.modal) {
9218 Windows.removeModalWindow(this);
9219 Windows.resetOverflow();
9220 }
9221 // To avoid bug on scrolling bar
9222 this.oldStyle = this.getContent().getStyle('overflow') || "auto"
9223 this.getContent().setStyle({overflow: "hidden"});
9224
9225 this.options.hideEffect(this.element, this.options.hideEffectOptions); 
9226
9227 if(this.iefix) 
9228 this.iefix.hide();
9229
9230 if (!this.doNotNotifyHide)
9231 this._notify("onHide");
9232 },
9233
9234 close: function() {
9235 // Asks closeCallback if exists
9236 if (this.visible) {
9237 if (this.options.closeCallback && ! this.options.closeCallback(this)) 
9238 return;
9239
9240 if (this.options.destroyOnClose) {
9241 var destroyFunc = this.destroy.bind(this);
9242 if (this.options.hideEffectOptions.afterFinish) {
9243 var func = this.options.hideEffectOptions.afterFinish;
9244 this.options.hideEffectOptions.afterFinish = function() {func();destroyFunc() }
9245 }
9246 else 
9247 this.options.hideEffectOptions.afterFinish = function() {destroyFunc() }
9248 }
9249 Windows.updateFocusedWindow();
9250 
9251 this.doNotNotifyHide = true;
9252 this.hide();
9253 this.doNotNotifyHide = false;
9254 this._notify("onClose");
9255 }
9256 },
9257 
9258 minimize: function() {
9259 if (this.resizing)
9260 return;
9261 
9262 var r2 = $(this.getId() + "_row2");
9263 
9264 if (!this.minimized) {
9265 this.minimized = true;
9266
9267 var dh = r2.getDimensions().height;
9268 this.r2Height = dh;
9269 var h = this.element.getHeight() - dh;
9270
9271 if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow) {
9272 new Effect.ResizeWindow(this, null, null, null, this.height -dh, {duration: Window.resizeEffectDuration});
9273 } else {
9274 this.height -= dh;
9275 this.element.setStyle({height: h + "px"});
9276 r2.hide();
9277 }
9278
9279 if (! this.useTop) {
9280 var bottom = parseFloat(this.element.getStyle('bottom'));
9281 this.element.setStyle({bottom: (bottom + dh) + 'px'});
9282 }
9283 } 
9284 else { 
9285 this.minimized = false;
9286 
9287 var dh = this.r2Height;
9288 this.r2Height = null;
9289 if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow) {
9290 new Effect.ResizeWindow(this, null, null, null, this.height + dh, {duration: Window.resizeEffectDuration});
9291 }
9292 else {
9293 var h = this.element.getHeight() + dh;
9294 this.height += dh;
9295 this.element.setStyle({height: h + "px"})
9296 r2.show();
9297 }
9298 if (! this.useTop) {
9299 var bottom = parseFloat(this.element.getStyle('bottom'));
9300 this.element.setStyle({bottom: (bottom - dh) + 'px'});
9301 }
9302 this.toFront();
9303 }
9304 this._notify("onMinimize");
9305 
9306 // Store new location/size if need be
9307 this._saveCookie()
9308 },
9309 
9310 maximize: function() {
9311 if (this.isMinimized() || this.resizing)
9312 return;
9313 
9314 if (Prototype.Browser.IE && this.heightN == 0)
9315 this._getWindowBorderSize();
9316 
9317 if (this.storedLocation != null) {
9318 this._restoreLocation();
9319 if(this.iefix) 
9320 this.iefix.hide();
9321 }
9322 else {
9323 this._storeLocation();
9324 Windows.unsetOverflow(this);
9325 
9326 var windowScroll = WindowUtilities.getWindowScroll(this.options.parent);
9327 var pageSize = WindowUtilities.getPageSize(this.options.parent); 
9328 var left = windowScroll.left;
9329 var top = windowScroll.top;
9330 
9331 if (this.options.parent != document.body) {
9332 windowScroll = {top:0, left:0, bottom:0, right:0};
9333 var dim = this.options.parent.getDimensions();
9334 pageSize.windowWidth = dim.width;
9335 pageSize.windowHeight = dim.height;
9336 top = 0; 
9337 left = 0;
9338 }
9339 
9340 if (this.constraint) {
9341 pageSize.windowWidth -= Math.max(0, this.constraintPad.left) + Math.max(0, this.constraintPad.right);
9342 pageSize.windowHeight -= Math.max(0, this.constraintPad.top) + Math.max(0, this.constraintPad.bottom);
9343 left += Math.max(0, this.constraintPad.left);
9344 top += Math.max(0, this.constraintPad.top);
9345 }
9346 
9347 var width = pageSize.windowWidth - this.widthW - this.widthE;
9348 var height= pageSize.windowHeight - this.heightN - this.heightS;
9349
9350 if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow) {
9351 new Effect.ResizeWindow(this, top, left, width, height, {duration: Window.resizeEffectDuration});
9352 }
9353 else {
9354 this.setSize(width, height);
9355 this.element.setStyle(this.useLeft ? {left: left} : {right: left});
9356 this.element.setStyle(this.useTop ? {top: top} : {bottom: top});
9357 }
9358 
9359 this.toFront();
9360 if (this.iefix) 
9361 this._fixIEOverlapping(); 
9362 }
9363 this._notify("onMaximize");
9364
9365 // Store new location/size if need be
9366 this._saveCookie()
9367 },
9368 
9369 isMinimized: function() {
9370 return this.minimized;
9371 },
9372 
9373 isMaximized: function() {
9374 return (this.storedLocation != null);
9375 },
9376 
9377 setOpacity: function(opacity) {
9378 if (Element.setOpacity)
9379 Element.setOpacity(this.element, opacity);
9380 },
9381 
9382 setZIndex: function(zindex) {
9383 this.element.setStyle({zIndex: zindex});
9384 Windows.updateZindex(zindex, this);
9385 },
9386
9387 setTitle: function(newTitle) {
9388 if (!newTitle || newTitle == "") 
9389 newTitle = "&nbsp;";
9390 
9391 Element.update(this.element.id + '_top', newTitle);
9392 },
9393 
9394 getTitle: function() {
9395 return $(this.element.id + '_top').innerHTML;
9396 },
9397 
9398 setStatusBar: function(element) {
9399 var statusBar = $(this.getId() + "_bottom");
9400
9401 if (typeof(element) == "object") {
9402 if (this.bottombar.firstChild)
9403 this.bottombar.replaceChild(element, this.bottombar.firstChild);
9404 else
9405 this.bottombar.appendChild(element);
9406 }
9407 else
9408 this.bottombar.innerHTML = element;
9409 },
9410
9411 _checkIEOverlapping: function() {
9412 if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && (navigator.userAgent.indexOf('Opera')<0) && (this.element.getStyle('position')=='absolute')) {
9413 new Insertion.After(this.element.id, '<iframe id="' + this.element.id + '_iefix" '+ 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
9414 this.iefix = $(this.element.id+'_iefix');
9415 }
9416 if(this.iefix) 
9417 setTimeout(this._fixIEOverlapping.bind(this), 50);
9418 },
9419
9420 _fixIEOverlapping: function() {
9421 Position.clone(this.element, this.iefix);
9422 this.iefix.style.zIndex = this.element.style.zIndex - 1;
9423 this.iefix.show();
9424 },
9425 
9426 _getWindowBorderSize: function(event) {
9427 // Hack to get real window border size!!
9428 var div = this._createHiddenDiv(this.options.className + "_n")
9429 this.heightN = Element.getDimensions(div).height; 
9430 div.parentNode.removeChild(div)
9431
9432 var div = this._createHiddenDiv(this.options.className + "_s")
9433 this.heightS = Element.getDimensions(div).height; 
9434 div.parentNode.removeChild(div)
9435
9436 var div = this._createHiddenDiv(this.options.className + "_e")
9437 this.widthE = Element.getDimensions(div).width; 
9438 div.parentNode.removeChild(div)
9439
9440 var div = this._createHiddenDiv(this.options.className + "_w")
9441 this.widthW = Element.getDimensions(div).width;
9442 div.parentNode.removeChild(div);
9443 
9444 var div = document.createElement("div");
9445 div.className = "overlay_" + this.options.className ;
9446 document.body.appendChild(div);
9447 //alert("no timeout:\nopacity: " + div.getStyle("opacity") + "\nwidth: " + document.defaultView.getComputedStyle(div, null).width);
9448 var that = this;
9449 
9450 // Workaround for Safari!!
9451 setTimeout(function() {that.overlayOpacity = ($(div).getStyle("opacity")); div.parentNode.removeChild(div);}, 10);
9452 
9453 // Workaround for IE!!
9454 if (Prototype.Browser.IE) {
9455 this.heightS = $(this.getId() +"_row3").getDimensions().height;
9456 this.heightN = $(this.getId() +"_row1").getDimensions().height;
9457 }
9458
9459 // Safari size fix
9460 if (Prototype.Browser.WebKit && Prototype.Browser.WebKitVersion < 420)
9461 this.setSize(this.width, this.height);
9462 if (this.doMaximize)
9463 this.maximize();
9464 if (this.doMinimize)
9465 this.minimize();
9466 },
9467 
9468 _createHiddenDiv: function(className) {
9469 var objBody = document.body;
9470 var win = document.createElement("div");
9471 win.setAttribute('id', this.element.id+ "_tmp");
9472 win.className = className;
9473 win.style.display = 'none';
9474 win.innerHTML = '';
9475 objBody.insertBefore(win, objBody.firstChild);
9476 return win;
9477 },
9478 
9479 _storeLocation: function() {
9480 if (this.storedLocation == null) {
9481 this.storedLocation = {useTop: this.useTop, useLeft: this.useLeft, 
9482 top: this.element.getStyle('top'), bottom: this.element.getStyle('bottom'),
9483 left: this.element.getStyle('left'), right: this.element.getStyle('right'),
9484 width: this.width, height: this.height };
9485 }
9486 },
9487 
9488 _restoreLocation: function() {
9489 if (this.storedLocation != null) {
9490 this.useLeft = this.storedLocation.useLeft;
9491 this.useTop = this.storedLocation.useTop;
9492 
9493 if (this.useLeft && this.useTop && Window.hasEffectLib && Effect.ResizeWindow)
9494 new Effect.ResizeWindow(this, this.storedLocation.top, this.storedLocation.left, this.storedLocation.width, this.storedLocation.height, {duration: Window.resizeEffectDuration});
9495 else {
9496 this.element.setStyle(this.useLeft ? {left: this.storedLocation.left} : {right: this.storedLocation.right});
9497 this.element.setStyle(this.useTop ? {top: this.storedLocation.top} : {bottom: this.storedLocation.bottom});
9498 this.setSize(this.storedLocation.width, this.storedLocation.height);
9499 }
9500 
9501 Windows.resetOverflow();
9502 this._removeStoreLocation();
9503 }
9504 },
9505 
9506 _removeStoreLocation: function() {
9507 this.storedLocation = null;
9508 },
9509 
9510 _saveCookie: function() {
9511 if (this.cookie) {
9512 var value = "";
9513 if (this.useLeft)
9514 value += "l:" + (this.storedLocation ? this.storedLocation.left : this.element.getStyle('left'))
9515 else
9516 value += "r:" + (this.storedLocation ? this.storedLocation.right : this.element.getStyle('right'))
9517 if (this.useTop)
9518 value += ",t:" + (this.storedLocation ? this.storedLocation.top : this.element.getStyle('top'))
9519 else
9520 value += ",b:" + (this.storedLocation ? this.storedLocation.bottom :this.element.getStyle('bottom'))
9521 
9522 value += "," + (this.storedLocation ? this.storedLocation.width : this.width);
9523 value += "," + (this.storedLocation ? this.storedLocation.height : this.height);
9524 value += "," + this.isMinimized();
9525 value += "," + this.isMaximized();
9526 WindowUtilities.setCookie(value, this.cookie)
9527 }
9528 },
9529 
9530 _createWiredElement: function() {
9531 if (! this.wiredElement) {
9532 if (Prototype.Browser.IE)
9533 this._getWindowBorderSize();
9534 var div = document.createElement("div");
9535 div.className = "wired_frame " + this.options.className + "_wired_frame";
9536 
9537 div.style.position = 'absolute';
9538 this.options.parent.insertBefore(div, this.options.parent.firstChild);
9539 this.wiredElement = $(div);
9540 }
9541 if (this.useLeft) 
9542 this.wiredElement.setStyle({left: this.element.getStyle('left')});
9543 else 
9544 this.wiredElement.setStyle({right: this.element.getStyle('right')});
9545 
9546 if (this.useTop) 
9547 this.wiredElement.setStyle({top: this.element.getStyle('top')});
9548 else 
9549 this.wiredElement.setStyle({bottom: this.element.getStyle('bottom')});
9550
9551 var dim = this.element.getDimensions();
9552 this.wiredElement.setStyle({width: dim.width + "px", height: dim.height +"px"});
9553
9554 this.wiredElement.setStyle({zIndex: Windows.maxZIndex+30});
9555 return this.wiredElement;
9556 },
9557 
9558 _hideWiredElement: function() {
9559 if (! this.wiredElement || ! this.currentDrag)
9560 return;
9561 if (this.currentDrag == this.element) 
9562 this.currentDrag = null;
9563 else {
9564 if (this.useLeft) 
9565 this.element.setStyle({left: this.currentDrag.getStyle('left')});
9566 else 
9567 this.element.setStyle({right: this.currentDrag.getStyle('right')});
9568
9569 if (this.useTop) 
9570 this.element.setStyle({top: this.currentDrag.getStyle('top')});
9571 else 
9572 this.element.setStyle({bottom: this.currentDrag.getStyle('bottom')});
9573
9574 this.currentDrag.hide();
9575 this.currentDrag = null;
9576 if (this.doResize)
9577 this.setSize(this.width, this.height);
9578 } 
9579 },
9580 
9581 _notify: function(eventName) {
9582 if (this.options[eventName])
9583 this.options[eventName](this);
9584 else
9585 Windows.notify(eventName, this);
9586 }
9587};
9588
9589// Windows containers, register all page windows
9590var Windows = {
9591 windows: [],
9592 modalWindows: [],
9593 observers: [],
9594 focusedWindow: null,
9595 maxZIndex: 0,
9596 overlayShowEffectOptions: {duration: 0.1},
9597 overlayHideEffectOptions: {duration: 0.1},
9598
9599 addObserver: function(observer) {
9600 this.removeObserver(observer);
9601 this.observers.push(observer);
9602 },
9603 
9604 removeObserver: function(observer) { 
9605 this.observers = this.observers.reject( function(o) { return o==observer });
9606 },
9607 
9608 // onDestroy onStartResize onStartMove onResize onMove onEndResize onEndMove onFocus onBlur onBeforeShow onShow onHide onMinimize onMaximize onClose
9609 notify: function(eventName, win) { 
9610 this.observers.each( function(o) {if(o[eventName]) o[eventName](eventName, win);});
9611 },
9612
9613 // Gets window from its id
9614 getWindow: function(id) {
9615 return this.windows.detect(function(d) { return d.getId() ==id });
9616 },
9617
9618 // Gets the last focused window
9619 getFocusedWindow: function() {
9620 return this.focusedWindow;
9621 },
9622
9623 updateFocusedWindow: function() {
9624 this.focusedWindow = this.windows.length >=2 ? this.windows[this.windows.length-2] : null; 
9625 },
9626 
9627 // Registers a new window (called by Windows constructor)
9628 register: function(win) {
9629 this.windows.push(win);
9630 },
9631 
9632 // Add a modal window in the stack
9633 addModalWindow: function(win) {
9634 // Disable screen if first modal window
9635 if (this.modalWindows.length == 0) {
9636 WindowUtilities.disableScreen(win.options.className, 'overlay_modal', win.overlayOpacity, win.getId(), win.options.parent);
9637 }
9638 else {
9639 // Move overlay over all windows
9640 if (Window.keepMultiModalWindow) {
9641 $('overlay_modal').style.zIndex = Windows.maxZIndex + 2;
9642 Windows.maxZIndex += 1;
9643 WindowUtilities._hideSelect(this.modalWindows.last().getId());
9644 }
9645 // Hide current modal window
9646 else
9647 this.modalWindows.last().element.hide();
9648 // Fucking IE select issue
9649 WindowUtilities._showSelect(win.getId());
9650 } 
9651 this.modalWindows.push(win); 
9652 },
9653 
9654 removeModalWindow: function(win) {
9655 this.modalWindows.pop();
9656 
9657 // No more modal windows
9658 if (this.modalWindows.length == 0)
9659 WindowUtilities.enableScreen(); 
9660 else {
9661 if (Window.keepMultiModalWindow) {
9662 this.modalWindows.last().toFront();
9663 WindowUtilities._showSelect(this.modalWindows.last().getId()); 
9664 }
9665 else
9666 this.modalWindows.last().element.show();
9667 }
9668 },
9669 
9670 // Registers a new window (called by Windows constructor)
9671 register: function(win) {
9672 this.windows.push(win);
9673 },
9674 
9675 // Unregisters a window (called by Windows destructor)
9676 unregister: function(win) {
9677 this.windows = this.windows.reject(function(d) { return d==win });
9678 }, 
9679 
9680 // Closes all windows
9681 closeAll: function() { 
9682 this.windows.each( function(w) {Windows.close(w.getId())} );
9683 },
9684 
9685 closeAllModalWindows: function() {
9686 WindowUtilities.enableScreen(); 
9687 this.modalWindows.each( function(win) {if (win) win.close()}); 
9688 },
9689
9690 // Minimizes a window with its id
9691 minimize: function(id, event) {
9692 var win = this.getWindow(id)
9693 if (win && win.visible)
9694 win.minimize();
9695 Event.stop(event);
9696 },
9697 
9698 // Maximizes a window with its id
9699 maximize: function(id, event) {
9700 var win = this.getWindow(id)
9701 if (win && win.visible)
9702 win.maximize();
9703 Event.stop(event);
9704 },
9705
9706 // Closes a window with its id
9707 close: function(id, event) {
9708 var win = this.getWindow(id);
9709 if (win) 
9710 win.close();
9711 if (event)
9712 Event.stop(event);
9713 },
9714 
9715 blur: function(id) {
9716 var win = this.getWindow(id); 
9717 if (!win)
9718 return;
9719 if (win.options.blurClassName)
9720 win.changeClassName(win.options.blurClassName);
9721 if (this.focusedWindow == win) 
9722 this.focusedWindow = null;
9723 win._notify("onBlur"); 
9724 },
9725 
9726 focus: function(id) {
9727 var win = this.getWindow(id); 
9728 if (!win)
9729 return; 
9730 if (this.focusedWindow)
9731 this.blur(this.focusedWindow.getId())
9732
9733 if (win.options.focusClassName)
9734 win.changeClassName(win.options.focusClassName); 
9735 this.focusedWindow = win;
9736 win._notify("onFocus");
9737 },
9738 
9739 unsetOverflow: function(except) { 
9740 this.windows.each(function(d) { d.oldOverflow = d.getContent().getStyle("overflow") || "auto" ; d.getContent().setStyle({overflow: "hidden"}) });
9741 if (except && except.oldOverflow)
9742 except.getContent().setStyle({overflow: except.oldOverflow});
9743 },
9744
9745 resetOverflow: function() {
9746 this.windows.each(function(d) { if (d.oldOverflow) d.getContent().setStyle({overflow: d.oldOverflow}) });
9747 },
9748
9749 updateZindex: function(zindex, win) { 
9750 if (zindex > this.maxZIndex) { 
9751 this.maxZIndex = zindex; 
9752 if (this.focusedWindow) 
9753 this.blur(this.focusedWindow.getId())
9754 }
9755 this.focusedWindow = win;
9756 if (this.focusedWindow) 
9757 this.focus(this.focusedWindow.getId())
9758 }
9759};
9760
9761var Dialog = {
9762 dialogId: null,
9763 onCompleteFunc: null,
9764 callFunc: null, 
9765 parameters: null, 
9766 
9767 confirm: function(content, parameters) {
9768 // Get Ajax return before
9769 if (content && typeof content != "string") {
9770 Dialog._runAjaxRequest(content, parameters, Dialog.confirm);
9771 return 
9772 }
9773 content = content || "";
9774 
9775 parameters = parameters || {};
9776 var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
9777 var cancelLabel = parameters.cancelLabel ? parameters.cancelLabel : "Cancel";
9778
9779 // Backward compatibility
9780 parameters = Object.extend(parameters, parameters.windowParameters || {});
9781 parameters.windowParameters = parameters.windowParameters || {};
9782
9783 parameters.className = parameters.className || "alert";
9784
9785 var okButtonClass = "class ='" + (parameters.buttonClass ? _h(parameters.buttonClass) + " " : "") + " ok_button'" 
9786 var cancelButtonClass = "class ='" + (parameters.buttonClass ? _h(parameters.buttonClass) + " " : "") + " cancel_button'" 
9787 //ESI WARNING ?????????? 2020-02-20 takeuchi
9788 // contentは?ML
9789 var content = "\
9790 <div class='" + _h(parameters.className) + "_message'>" + content + "</div>\
9791 <div class='" + _h(parameters.className) + "_buttons'>\
9792 <input type='button' value='" + _h(okLabel) + "' onclick='Dialog.okCallback()' " + okButtonClass + "/>\
9793 <input type='button' value='" + _h(cancelLabel) + "' onclick='Dialog.cancelCallback()' " + cancelButtonClass + "/>\
9794 </div>\
9795 ";
9796 return this._openDialog(content, parameters)
9797 },
9798 
9799 alert: function(content, parameters) {
9800 // Get Ajax return before
9801 if (content && typeof content != "string") {
9802 Dialog._runAjaxRequest(content, parameters, Dialog.alert);
9803 return 
9804 }
9805 content = content || "";
9806 
9807 parameters = parameters || {};
9808 var okLabel = parameters.okLabel ? parameters.okLabel : "Ok";
9809
9810 // Backward compatibility 
9811 parameters = Object.extend(parameters, parameters.windowParameters || {});
9812 parameters.windowParameters = parameters.windowParameters || {};
9813 
9814 parameters.className = parameters.className || "alert";
9815 
9816 //ESI WARNING ?????????? 2020-02-20 takeuchi
9817 // content HMTL
9818 var okButtonClass = "class ='" + (parameters.buttonClass ? _h(parameters.buttonClass) + " " : "") + " ok_button'" 
9819 var content = "\
9820 <div class='" + _h(parameters.className) + "_message'>" + content + "</div>\
9821 <div class='" + _h(parameters.className) + "_buttons'>\
9822 <input type='button' value='" + _h(okLabel) + "' onclick='Dialog.okCallback()' " + okButtonClass + "/>\
9823 </div>"; 
9824 return this._openDialog(content, parameters)
9825 },
9826 
9827 info: function(content, parameters) { 
9828 // Get Ajax return before
9829 if (content && typeof content != "string") {
9830 Dialog._runAjaxRequest(content, parameters, Dialog.info);
9831 return 
9832 }
9833 content = content || "";
9834 
9835 // Backward compatibility
9836 parameters = parameters || {};
9837 parameters = Object.extend(parameters, parameters.windowParameters || {});
9838 parameters.windowParameters = parameters.windowParameters || {};
9839 
9840 parameters.className = parameters.className || "alert";
9841 
9842 //ESI WARNING ?????????? 2020-02-20 takeuchi
9843 // content HTML
9844 var content = "<div id='modal_dialog_message' class='" + _h(parameters.className) + "_message'>" + content + "</div>";
9845 if (parameters.showProgress)
9846 content += "<div id='modal_dialog_progress' class='" + _h(parameters.className) + "_progress'> </div>";
9847 parameters.ok = null;
9848 parameters.cancel = null;
9849 
9850 return this._openDialog(content, parameters)
9851 },
9852 
9853 setInfoMessage: function(message) {
9854 $('modal_dialog_message').update(message);
9855 },
9856 
9857 closeInfo: function() {
9858 Windows.close(this.dialogId);
9859 },
9860 
9861 _openDialog: function(content, parameters) {
9862 var className = parameters.className;
9863 
9864 if (! parameters.height && ! parameters.width) {
9865 parameters.width = WindowUtilities.getPageSize(parameters.options.parent || document.body).pageWidth / 2;
9866 }
9867 if (parameters.id)
9868 this.dialogId = parameters.id;
9869 else { 
9870 var t = new Date();
9871 this.dialogId = 'modal_dialog_' + t.getTime();
9872 parameters.id = this.dialogId;
9873 }
9874
9875 // compute height or width if need be
9876 if (! parameters.height || ! parameters.width) {
9877 var size = WindowUtilities._computeSize(content, this.dialogId, parameters.width, parameters.height, 5, className)
9878 if (parameters.height)
9879 parameters.width = size + 5
9880 else
9881 parameters.height = size + 5
9882 }
9883 parameters.effectOptions = parameters.effectOptions ;
9884 parameters.resizable = parameters.resizable || false;
9885 parameters.minimizable = parameters.minimizable || false;
9886 parameters.maximizable = parameters.maximizable || false;
9887 parameters.draggable = parameters.draggable || false;
9888 parameters.closable = parameters.closable || false;
9889 
9890 var win = new Window(parameters);
9891 win.getContent().innerHTML = content;
9892 win.getContent().innerHTML.evalScripts();
9893 
9894 win.showCenter(true, parameters.top, parameters.left); 
9895 win.setDestroyOnClose();
9896 
9897 win.cancelCallback = parameters.onCancel || parameters.cancel; 
9898 win.okCallback = parameters.onOk || parameters.ok;
9899 
9900 return win; 
9901 },
9902 
9903 _getAjaxContent: function(originalRequest) {
9904 Dialog.callFunc(originalRequest.responseText, Dialog.parameters)
9905 },
9906 
9907 _runAjaxRequest: function(message, parameters, callFunc) {
9908 if (message.options == null)
9909 message.options = {} 
9910 Dialog.onCompleteFunc = message.options.onComplete;
9911 Dialog.parameters = parameters;
9912 Dialog.callFunc = callFunc;
9913 
9914 message.options.onComplete = Dialog._getAjaxContent;
9915 new Ajax.Request(message.url, message.options);
9916 },
9917 
9918 okCallback: function() {
9919 var win = Windows.focusedWindow;
9920 if (!win.okCallback || win.okCallback(win)) {
9921 // Remove onclick on button
9922 $$("#" + win.getId()+" input").each(function(element) {element.onclick=null;})
9923 win.close();
9924 }
9925 },
9926
9927 cancelCallback: function() {
9928 var win = Windows.focusedWindow;
9929 // Remove onclick on button
9930 $$("#" + win.getId()+" input").each(function(element) {element.onclick=null})
9931 win.close();
9932 if (win.cancelCallback)
9933 win.cancelCallback(win);
9934 }
9935}
9936/*
9937 Based on Lightbox JS: Fullsize Image Overlays 
9938 by Lokesh Dhakar - http://www.huddletogether.com
9939
9940 For more information on this script, visit:
9941 http://huddletogether.com/projects/lightbox/
9942
9943 Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
9944 (basically, do anything you want, just leave my name and link)
9945*/
9946
9947if (Prototype.Browser.WebKit) {
9948 var array = navigator.userAgent.match(new RegExp(/AppleWebKit\/([\d\.\+]*)/));
9949 Prototype.Browser.WebKitVersion = parseFloat(array[1]);
9950}
9951
9952var WindowUtilities = { 
9953 // From dragdrop.js
9954 getWindowScroll: function(parent) {
9955 var T, L, W, H;
9956 parent = parent || document.body; 
9957 if (parent != document.body) {
9958 T = parent.scrollTop;
9959 L = parent.scrollLeft;
9960 W = parent.scrollWidth;
9961 H = parent.scrollHeight;
9962 } 
9963 else {
9964 var w = window;
9965 with (w.document) {
9966 if (w.document.documentElement && documentElement.scrollTop) {
9967 T = documentElement.scrollTop;
9968 L = documentElement.scrollLeft;
9969 } else if (w.document.body) {
9970 T = body.scrollTop;
9971 L = body.scrollLeft;
9972 }
9973 if (w.innerWidth) {
9974 W = w.innerWidth;
9975 H = w.innerHeight;
9976 } else if (w.document.documentElement && documentElement.clientWidth) {
9977 W = documentElement.clientWidth;
9978 H = documentElement.clientHeight;
9979 } else {
9980 W = body.offsetWidth;
9981 H = body.offsetHeight
9982 }
9983 }
9984 }
9985 return { top: T, left: L, width: W, height: H };
9986 }, 
9987 //
9988 // getPageSize()
9989 // Returns array with page width, height and window width, height
9990 // Core code from - quirksmode.org
9991 // Edit for Firefox by pHaez
9992 //
9993 getPageSize: function(parent){
9994 parent = parent || document.body; 
9995 var windowWidth, windowHeight;
9996 var pageHeight, pageWidth;
9997 if (parent != document.body) {
9998 windowWidth = parent.getWidth();
9999 windowHeight = parent.getHeight(); 
10000 pageWidth = parent.scrollWidth;
10001 pageHeight = parent.scrollHeight; 
10002 } 
10003 else {
10004 var xScroll, yScroll;
10005
10006 if (window.innerHeight && window.scrollMaxY) { 
10007 xScroll = document.body.scrollWidth;
10008 yScroll = window.innerHeight + window.scrollMaxY;
10009 } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
10010 xScroll = document.body.scrollWidth;
10011 yScroll = document.body.scrollHeight;
10012 } else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
10013 xScroll = document.body.offsetWidth;
10014 yScroll = document.body.offsetHeight;
10015 }
10016
10017
10018 if (self.innerHeight) { // all except Explorer
10019 windowWidth = self.innerWidth;
10020 windowHeight = self.innerHeight;
10021 } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
10022 windowWidth = document.documentElement.clientWidth;
10023 windowHeight = document.documentElement.clientHeight;
10024 } else if (document.body) { // other Explorers
10025 windowWidth = document.body.clientWidth;
10026 windowHeight = document.body.clientHeight;
10027 } 
10028
10029 // for small pages with total height less then height of the viewport
10030 if(yScroll < windowHeight){
10031 pageHeight = windowHeight;
10032 } else { 
10033 pageHeight = yScroll;
10034 }
10035
10036 // for small pages with total width less then width of the viewport
10037 if(xScroll < windowWidth){ 
10038 pageWidth = windowWidth;
10039 } else {
10040 pageWidth = xScroll;
10041 }
10042 } 
10043 return {pageWidth: pageWidth ,pageHeight: pageHeight , windowWidth: windowWidth, windowHeight: windowHeight};
10044 },
10045
10046 disableScreen: function(className, overlayId, overlayOpacity, contentId, parent) {
10047 WindowUtilities.initLightbox(overlayId, className, function() {this._disableScreen(className, overlayId, overlayOpacity, contentId)}.bind(this), parent || document.body);
10048 },
10049
10050 _disableScreen: function(className, overlayId, overlayOpacity, contentId) {
10051 // prep objects
10052 var objOverlay = $(overlayId);
10053
10054 var pageSize = WindowUtilities.getPageSize(objOverlay.parentNode);
10055
10056 // Hide select boxes as they will 'peek' through the image in IE, store old value
10057 if (contentId && Prototype.Browser.IE) {
10058 WindowUtilities._hideSelect();
10059 WindowUtilities._showSelect(contentId);
10060 } 
10061 
10062 // set height of Overlay to take up whole page and show
10063 objOverlay.style.height = (pageSize.pageHeight + 'px');
10064 objOverlay.style.display = 'none'; 
10065 if (overlayId == "overlay_modal" && Window.hasEffectLib && Windows.overlayShowEffectOptions) {
10066 objOverlay.overlayOpacity = overlayOpacity;
10067 new Effect.Appear(objOverlay, Object.extend({from: 0, to: overlayOpacity}, Windows.overlayShowEffectOptions));
10068 }
10069 else
10070 objOverlay.style.display = "block";
10071 },
10072 
10073 enableScreen: function(id) {
10074 id = id || 'overlay_modal';
10075 var objOverlay = $(id);
10076 if (objOverlay) {
10077 // hide lightbox and overlay
10078 if (id == "overlay_modal" && Window.hasEffectLib && Windows.overlayHideEffectOptions)
10079 new Effect.Fade(objOverlay, Object.extend({from: objOverlay.overlayOpacity, to:0}, Windows.overlayHideEffectOptions));
10080 else {
10081 objOverlay.style.display = 'none';
10082 objOverlay.parentNode.removeChild(objOverlay);
10083 }
10084 
10085 // make select boxes visible using old value
10086 if (id != "__invisible__") 
10087 WindowUtilities._showSelect();
10088 }
10089 },
10090
10091 _hideSelect: function(id) {
10092 if (Prototype.Browser.IE) {
10093 id = id == null ? "" : "#" + id + " ";
10094 $$(id + 'select').each(function(element) {
10095 if (! WindowUtilities.isDefined(element.oldVisibility)) {
10096 element.oldVisibility = element.style.visibility ? element.style.visibility : "visible";
10097 element.style.visibility = "hidden";
10098 }
10099 });
10100 }
10101 },
10102 
10103 _showSelect: function(id) {
10104 if (Prototype.Browser.IE) {
10105 id = id == null ? "" : "#" + id + " ";
10106 $$(id + 'select').each(function(element) {
10107 if (WindowUtilities.isDefined(element.oldVisibility)) {
10108 // Why?? Ask IE
10109 try {
10110 element.style.visibility = element.oldVisibility;
10111 } catch(e) {
10112 element.style.visibility = "visible";
10113 }
10114 element.oldVisibility = null;
10115 }
10116 else {
10117 if (element.style.visibility)
10118 element.style.visibility = "visible";
10119 }
10120 });
10121 }
10122 },
10123
10124 isDefined: function(object) {
10125 return typeof(object) != "undefined" && object != null;
10126 },
10127 
10128 // initLightbox()
10129 // Function runs on window load, going through link tags looking for rel="lightbox".
10130 // These links receive onclick events that enable the lightbox display for their targets.
10131 // The function also inserts html markup at the top of the page which will be used as a
10132 // container for the overlay pattern and the inline image.
10133 initLightbox: function(id, className, doneHandler, parent) {
10134 // Already done, just update zIndex
10135 if ($(id)) {
10136 Element.setStyle(id, {zIndex: Windows.maxZIndex + 2});
10137 Windows.maxZIndex++;
10138 doneHandler();
10139 }
10140 // create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
10141 else {
10142 var objOverlay = document.createElement("div");
10143 objOverlay.setAttribute('id', id);
10144 objOverlay.className = "overlay_" + className
10145 objOverlay.style.display = 'none';
10146 objOverlay.style.position = 'absolute';
10147 objOverlay.style.top = '0';
10148 objOverlay.style.left = '0';
10149 objOverlay.style.zIndex = Windows.maxZIndex + 2;
10150 Windows.maxZIndex++;
10151 objOverlay.style.width = '100%';
10152 parent.insertBefore(objOverlay, parent.firstChild);
10153 if (Prototype.Browser.WebKit && id == "overlay_modal") {
10154 setTimeout(function() {doneHandler()}, 10);
10155 }
10156 else
10157 doneHandler();
10158 } 
10159 },
10160 
10161 setCookie: function(value, parameters) {
10162 //ESI ERROR ??????? parameters 2020-02-20 takeuchi
10163 document.cookie= parameters[0] + "=" + encodeURIComponent(value) +
10164 ((parameters[1]) ? "; expires=" + parameters[1].toGMTString() : "") +
10165 ((parameters[2]) ? "; path=" + parameters[2] : "") +
10166 ((parameters[3]) ? "; domain=" + parameters[3] : "") +
10167 ((parameters[4]) ? "; secure" : "");
10168 },
10169
10170 getCookie: function(name) {
10171 var dc = document.cookie;
10172 var prefix = name + "=";
10173 var begin = dc.indexOf("; " + prefix);
10174 if (begin == -1) {
10175 begin = dc.indexOf(prefix);
10176 if (begin != 0) return null;
10177 } else {
10178 begin += 2;
10179 }
10180 var end = document.cookie.indexOf(";", begin);
10181 if (end == -1) {
10182 end = dc.length;
10183 }
10184 return unescape(dc.substring(begin + prefix.length, end));
10185 },
10186 
10187 _computeSize: function(content, id, width, height, margin, className) {
10188 var objBody = document.body;
10189 var tmpObj = document.createElement("div");
10190 tmpObj.setAttribute('id', id);
10191 tmpObj.className = className + "_content";
10192
10193 if (height)
10194 tmpObj.style.height = height + "px"
10195 else
10196 tmpObj.style.width = width + "px"
10197 
10198 tmpObj.style.position = 'absolute';
10199 tmpObj.style.top = '0';
10200 tmpObj.style.left = '0';
10201 tmpObj.style.display = 'none';
10202
10203 tmpObj.innerHTML = content;
10204 objBody.insertBefore(tmpObj, objBody.firstChild);
10205
10206 var size;
10207 if (height)
10208 size = $(tmpObj).getDimensions().width + margin;
10209 else
10210 size = $(tmpObj).getDimensions().height + margin;
10211 objBody.removeChild(tmpObj);
10212 return size;
10213 } 
10214}
10215
10216;

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.