/dev/adei-asec

To get this branch, use:
bzr branch http://darksoft.org/webbzr/dev/adei-asec

« back to all changes in this revision

Viewing changes to includes/prototype.js

  • Committer: Suren A. Chilingaryan
  • Date: 2011-03-15 02:47:05 UTC
  • mfrom: (210.1.3 adei)
  • Revision ID: csa@dside.dyndns.org-20110315024705-qljn30gwin8yrkne
Integration of work of students with fixes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  Prototype JavaScript framework, version 1.6.0.1
2
 
 *  (c) 2005-2007 Sam Stephenson
 
1
/*  Prototype JavaScript framework, version 1.7
 
2
 *  (c) 2005-2010 Sam Stephenson
3
3
 *
4
4
 *  Prototype is freely distributable under the terms of an MIT-style license.
5
5
 *  For details, see the Prototype web site: http://www.prototypejs.org/
7
7
 *--------------------------------------------------------------------------*/
8
8
 
9
9
var Prototype = {
10
 
  Version: '1.6.0.1',
11
 
 
12
 
  Browser: {
13
 
    IE:     !!(window.attachEvent && !window.opera),
14
 
    Opera:  !!window.opera,
15
 
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
16
 
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
17
 
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
18
 
  },
 
10
 
 
11
  Version: '1.7',
 
12
 
 
13
  Browser: (function(){
 
14
    var ua = navigator.userAgent;
 
15
    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
 
16
    return {
 
17
      IE:             !!window.attachEvent && !isOpera,
 
18
      Opera:          isOpera,
 
19
      WebKit:         ua.indexOf('AppleWebKit/') > -1,
 
20
      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
 
21
      MobileSafari:   /Apple.*Mobile/.test(ua)
 
22
    }
 
23
  })(),
19
24
 
20
25
  BrowserFeatures: {
21
26
    XPath: !!document.evaluate,
22
 
    ElementExtensions: !!window.HTMLElement,
23
 
    SpecificElementExtensions:
24
 
      document.createElement('div').__proto__ &&
25
 
      document.createElement('div').__proto__ !==
26
 
        document.createElement('form').__proto__
 
27
 
 
28
    SelectorsAPI: !!document.querySelector,
 
29
 
 
30
    ElementExtensions: (function() {
 
31
      var constructor = window.Element || window.HTMLElement;
 
32
      return !!(constructor && constructor.prototype);
 
33
    })(),
 
34
    SpecificElementExtensions: (function() {
 
35
      if (typeof window.HTMLDivElement !== 'undefined')
 
36
        return true;
 
37
 
 
38
      var div = document.createElement('div'),
 
39
          form = document.createElement('form'),
 
40
          isSupported = false;
 
41
 
 
42
      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
 
43
        isSupported = true;
 
44
      }
 
45
 
 
46
      div = form = null;
 
47
 
 
48
      return isSupported;
 
49
    })()
27
50
  },
28
51
 
29
52
  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
30
53
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
31
54
 
32
55
  emptyFunction: function() { },
 
56
 
33
57
  K: function(x) { return x }
34
58
};
35
59
 
37
61
  Prototype.BrowserFeatures.SpecificElementExtensions = false;
38
62
 
39
63
 
 
64
var Abstract = { };
 
65
 
 
66
 
 
67
var Try = {
 
68
  these: function() {
 
69
    var returnValue;
 
70
 
 
71
    for (var i = 0, length = arguments.length; i < length; i++) {
 
72
      var lambda = arguments[i];
 
73
      try {
 
74
        returnValue = lambda();
 
75
        break;
 
76
      } catch (e) { }
 
77
    }
 
78
 
 
79
    return returnValue;
 
80
  }
 
81
};
 
82
 
40
83
/* Based on Alex Arnell's inheritance implementation. */
41
 
var Class = {
42
 
  create: function() {
 
84
 
 
85
var Class = (function() {
 
86
 
 
87
  var IS_DONTENUM_BUGGY = (function(){
 
88
    for (var p in { toString: 1 }) {
 
89
      if (p === 'toString') return false;
 
90
    }
 
91
    return true;
 
92
  })();
 
93
 
 
94
  function subclass() {};
 
95
  function create() {
43
96
    var parent = null, properties = $A(arguments);
44
97
    if (Object.isFunction(properties[0]))
45
98
      parent = properties.shift();
53
106
    klass.subclasses = [];
54
107
 
55
108
    if (parent) {
56
 
      var subclass = function() { };
57
109
      subclass.prototype = parent.prototype;
58
110
      klass.prototype = new subclass;
59
111
      parent.subclasses.push(klass);
60
112
    }
61
113
 
62
 
    for (var i = 0; i < properties.length; i++)
 
114
    for (var i = 0, length = properties.length; i < length; i++)
63
115
      klass.addMethods(properties[i]);
64
116
 
65
117
    if (!klass.prototype.initialize)
66
118
      klass.prototype.initialize = Prototype.emptyFunction;
67
119
 
68
120
    klass.prototype.constructor = klass;
69
 
 
70
121
    return klass;
71
122
  }
72
 
};
73
 
 
74
 
Class.Methods = {
75
 
  addMethods: function(source) {
76
 
    var ancestor   = this.superclass && this.superclass.prototype;
77
 
    var properties = Object.keys(source);
78
 
 
79
 
    if (!Object.keys({ toString: true }).length)
80
 
      properties.push("toString", "valueOf");
 
123
 
 
124
  function addMethods(source) {
 
125
    var ancestor   = this.superclass && this.superclass.prototype,
 
126
        properties = Object.keys(source);
 
127
 
 
128
    if (IS_DONTENUM_BUGGY) {
 
129
      if (source.toString != Object.prototype.toString)
 
130
        properties.push("toString");
 
131
      if (source.valueOf != Object.prototype.valueOf)
 
132
        properties.push("valueOf");
 
133
    }
81
134
 
82
135
    for (var i = 0, length = properties.length; i < length; i++) {
83
136
      var property = properties[i], value = source[property];
84
137
      if (ancestor && Object.isFunction(value) &&
85
 
          value.argumentNames().first() == "$super") {
86
 
        var method = value, value = Object.extend((function(m) {
87
 
          return function() { return ancestor[m].apply(this, arguments) };
88
 
        })(property).wrap(method), {
89
 
          valueOf:  function() { return method },
90
 
          toString: function() { return method.toString() }
91
 
        });
 
138
          value.argumentNames()[0] == "$super") {
 
139
        var method = value;
 
140
        value = (function(m) {
 
141
          return function() { return ancestor[m].apply(this, arguments); };
 
142
        })(property).wrap(method);
 
143
 
 
144
        value.valueOf = method.valueOf.bind(method);
 
145
        value.toString = method.toString.bind(method);
92
146
      }
93
147
      this.prototype[property] = value;
94
148
    }
95
149
 
96
150
    return this;
97
151
  }
98
 
};
99
 
 
100
 
var Abstract = { };
101
 
 
102
 
Object.extend = function(destination, source) {
103
 
  for (var property in source)
104
 
    destination[property] = source[property];
105
 
  return destination;
106
 
};
107
 
 
108
 
Object.extend(Object, {
109
 
  inspect: function(object) {
 
152
 
 
153
  return {
 
154
    create: create,
 
155
    Methods: {
 
156
      addMethods: addMethods
 
157
    }
 
158
  };
 
159
})();
 
160
(function() {
 
161
 
 
162
  var _toString = Object.prototype.toString,
 
163
      NULL_TYPE = 'Null',
 
164
      UNDEFINED_TYPE = 'Undefined',
 
165
      BOOLEAN_TYPE = 'Boolean',
 
166
      NUMBER_TYPE = 'Number',
 
167
      STRING_TYPE = 'String',
 
168
      OBJECT_TYPE = 'Object',
 
169
      FUNCTION_CLASS = '[object Function]',
 
170
      BOOLEAN_CLASS = '[object Boolean]',
 
171
      NUMBER_CLASS = '[object Number]',
 
172
      STRING_CLASS = '[object String]',
 
173
      ARRAY_CLASS = '[object Array]',
 
174
      DATE_CLASS = '[object Date]',
 
175
      NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
 
176
        typeof JSON.stringify === 'function' &&
 
177
        JSON.stringify(0) === '0' &&
 
178
        typeof JSON.stringify(Prototype.K) === 'undefined';
 
179
 
 
180
  function Type(o) {
 
181
    switch(o) {
 
182
      case null: return NULL_TYPE;
 
183
      case (void 0): return UNDEFINED_TYPE;
 
184
    }
 
185
    var type = typeof o;
 
186
    switch(type) {
 
187
      case 'boolean': return BOOLEAN_TYPE;
 
188
      case 'number':  return NUMBER_TYPE;
 
189
      case 'string':  return STRING_TYPE;
 
190
    }
 
191
    return OBJECT_TYPE;
 
192
  }
 
193
 
 
194
  function extend(destination, source) {
 
195
    for (var property in source)
 
196
      destination[property] = source[property];
 
197
    return destination;
 
198
  }
 
199
 
 
200
  function inspect(object) {
110
201
    try {
111
 
      if (Object.isUndefined(object)) return 'undefined';
 
202
      if (isUndefined(object)) return 'undefined';
112
203
      if (object === null) return 'null';
113
 
      return object.inspect ? object.inspect() : object.toString();
 
204
      return object.inspect ? object.inspect() : String(object);
114
205
    } catch (e) {
115
206
      if (e instanceof RangeError) return '...';
116
207
      throw e;
117
208
    }
118
 
  },
119
 
 
120
 
  toJSON: function(object) {
121
 
    var type = typeof object;
 
209
  }
 
210
 
 
211
  function toJSON(value) {
 
212
    return Str('', { '': value }, []);
 
213
  }
 
214
 
 
215
  function Str(key, holder, stack) {
 
216
    var value = holder[key],
 
217
        type = typeof value;
 
218
 
 
219
    if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
 
220
      value = value.toJSON(key);
 
221
    }
 
222
 
 
223
    var _class = _toString.call(value);
 
224
 
 
225
    switch (_class) {
 
226
      case NUMBER_CLASS:
 
227
      case BOOLEAN_CLASS:
 
228
      case STRING_CLASS:
 
229
        value = value.valueOf();
 
230
    }
 
231
 
 
232
    switch (value) {
 
233
      case null: return 'null';
 
234
      case true: return 'true';
 
235
      case false: return 'false';
 
236
    }
 
237
 
 
238
    type = typeof value;
122
239
    switch (type) {
123
 
      case 'undefined':
124
 
      case 'function':
125
 
      case 'unknown': return;
126
 
      case 'boolean': return object.toString();
127
 
    }
128
 
 
129
 
    if (object === null) return 'null';
130
 
    if (object.toJSON) return object.toJSON();
131
 
    if (Object.isElement(object)) return;
132
 
 
133
 
    var results = [];
134
 
    for (var property in object) {
135
 
      var value = Object.toJSON(object[property]);
136
 
      if (!Object.isUndefined(value))
137
 
        results.push(property.toJSON() + ': ' + value);
138
 
    }
139
 
 
140
 
    return '{' + results.join(', ') + '}';
141
 
  },
142
 
 
143
 
  toQueryString: function(object) {
 
240
      case 'string':
 
241
        return value.inspect(true);
 
242
      case 'number':
 
243
        return isFinite(value) ? String(value) : 'null';
 
244
      case 'object':
 
245
 
 
246
        for (var i = 0, length = stack.length; i < length; i++) {
 
247
          if (stack[i] === value) { throw new TypeError(); }
 
248
        }
 
249
        stack.push(value);
 
250
 
 
251
        var partial = [];
 
252
        if (_class === ARRAY_CLASS) {
 
253
          for (var i = 0, length = value.length; i < length; i++) {
 
254
            var str = Str(i, value, stack);
 
255
            partial.push(typeof str === 'undefined' ? 'null' : str);
 
256
          }
 
257
          partial = '[' + partial.join(',') + ']';
 
258
        } else {
 
259
          var keys = Object.keys(value);
 
260
          for (var i = 0, length = keys.length; i < length; i++) {
 
261
            var key = keys[i], str = Str(key, value, stack);
 
262
            if (typeof str !== "undefined") {
 
263
               partial.push(key.inspect(true)+ ':' + str);
 
264
             }
 
265
          }
 
266
          partial = '{' + partial.join(',') + '}';
 
267
        }
 
268
        stack.pop();
 
269
        return partial;
 
270
    }
 
271
  }
 
272
 
 
273
  function stringify(object) {
 
274
    return JSON.stringify(object);
 
275
  }
 
276
 
 
277
  function toQueryString(object) {
144
278
    return $H(object).toQueryString();
145
 
  },
 
279
  }
146
280
 
147
 
  toHTML: function(object) {
 
281
  function toHTML(object) {
148
282
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
149
 
  },
150
 
 
151
 
  keys: function(object) {
152
 
    var keys = [];
153
 
    for (var property in object)
154
 
      keys.push(property);
155
 
    return keys;
156
 
  },
157
 
 
158
 
  values: function(object) {
159
 
    var values = [];
160
 
    for (var property in object)
161
 
      values.push(object[property]);
162
 
    return values;
163
 
  },
164
 
 
165
 
  clone: function(object) {
166
 
    return Object.extend({ }, object);
167
 
  },
168
 
 
169
 
  isElement: function(object) {
170
 
    return object && object.nodeType == 1;
171
 
  },
172
 
 
173
 
  isArray: function(object) {
174
 
    return object && object.constructor === Array;
175
 
  },
176
 
 
177
 
  isHash: function(object) {
 
283
  }
 
284
 
 
285
  function keys(object) {
 
286
    if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
 
287
    var results = [];
 
288
    for (var property in object) {
 
289
      if (object.hasOwnProperty(property)) {
 
290
        results.push(property);
 
291
      }
 
292
    }
 
293
    return results;
 
294
  }
 
295
 
 
296
  function values(object) {
 
297
    var results = [];
 
298
    for (var property in object)
 
299
      results.push(object[property]);
 
300
    return results;
 
301
  }
 
302
 
 
303
  function clone(object) {
 
304
    return extend({ }, object);
 
305
  }
 
306
 
 
307
  function isElement(object) {
 
308
    return !!(object && object.nodeType == 1);
 
309
  }
 
310
 
 
311
  function isArray(object) {
 
312
    return _toString.call(object) === ARRAY_CLASS;
 
313
  }
 
314
 
 
315
  var hasNativeIsArray = (typeof Array.isArray == 'function')
 
316
    && Array.isArray([]) && !Array.isArray({});
 
317
 
 
318
  if (hasNativeIsArray) {
 
319
    isArray = Array.isArray;
 
320
  }
 
321
 
 
322
  function isHash(object) {
178
323
    return object instanceof Hash;
179
 
  },
180
 
 
181
 
  isFunction: function(object) {
182
 
    return typeof object == "function";
183
 
  },
184
 
 
185
 
  isString: function(object) {
186
 
    return typeof object == "string";
187
 
  },
188
 
 
189
 
  isNumber: function(object) {
190
 
    return typeof object == "number";
191
 
  },
192
 
 
193
 
  isUndefined: function(object) {
194
 
    return typeof object == "undefined";
195
 
  }
196
 
});
197
 
 
198
 
Object.extend(Function.prototype, {
199
 
  argumentNames: function() {
200
 
    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
 
324
  }
 
325
 
 
326
  function isFunction(object) {
 
327
    return _toString.call(object) === FUNCTION_CLASS;
 
328
  }
 
329
 
 
330
  function isString(object) {
 
331
    return _toString.call(object) === STRING_CLASS;
 
332
  }
 
333
 
 
334
  function isNumber(object) {
 
335
    return _toString.call(object) === NUMBER_CLASS;
 
336
  }
 
337
 
 
338
  function isDate(object) {
 
339
    return _toString.call(object) === DATE_CLASS;
 
340
  }
 
341
 
 
342
  function isUndefined(object) {
 
343
    return typeof object === "undefined";
 
344
  }
 
345
 
 
346
  extend(Object, {
 
347
    extend:        extend,
 
348
    inspect:       inspect,
 
349
    toJSON:        NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
 
350
    toQueryString: toQueryString,
 
351
    toHTML:        toHTML,
 
352
    keys:          Object.keys || keys,
 
353
    values:        values,
 
354
    clone:         clone,
 
355
    isElement:     isElement,
 
356
    isArray:       isArray,
 
357
    isHash:        isHash,
 
358
    isFunction:    isFunction,
 
359
    isString:      isString,
 
360
    isNumber:      isNumber,
 
361
    isDate:        isDate,
 
362
    isUndefined:   isUndefined
 
363
  });
 
364
})();
 
365
Object.extend(Function.prototype, (function() {
 
366
  var slice = Array.prototype.slice;
 
367
 
 
368
  function update(array, args) {
 
369
    var arrayLength = array.length, length = args.length;
 
370
    while (length--) array[arrayLength + length] = args[length];
 
371
    return array;
 
372
  }
 
373
 
 
374
  function merge(array, args) {
 
375
    array = slice.call(array, 0);
 
376
    return update(array, args);
 
377
  }
 
378
 
 
379
  function argumentNames() {
 
380
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
 
381
      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
 
382
      .replace(/\s+/g, '').split(',');
201
383
    return names.length == 1 && !names[0] ? [] : names;
202
 
  },
 
384
  }
203
385
 
204
 
  bind: function() {
 
386
  function bind(context) {
205
387
    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
206
 
    var __method = this, args = $A(arguments), object = args.shift();
 
388
    var __method = this, args = slice.call(arguments, 1);
207
389
    return function() {
208
 
      return __method.apply(object, args.concat($A(arguments)));
 
390
      var a = merge(args, arguments);
 
391
      return __method.apply(context, a);
209
392
    }
210
 
  },
 
393
  }
211
394
 
212
 
  bindAsEventListener: function() {
213
 
    var __method = this, args = $A(arguments), object = args.shift();
 
395
  function bindAsEventListener(context) {
 
396
    var __method = this, args = slice.call(arguments, 1);
214
397
    return function(event) {
215
 
      return __method.apply(object, [event || window.event].concat(args));
 
398
      var a = update([event || window.event], args);
 
399
      return __method.apply(context, a);
216
400
    }
217
 
  },
 
401
  }
218
402
 
219
 
  curry: function() {
 
403
  function curry() {
220
404
    if (!arguments.length) return this;
221
 
    var __method = this, args = $A(arguments);
 
405
    var __method = this, args = slice.call(arguments, 0);
222
406
    return function() {
223
 
      return __method.apply(this, args.concat($A(arguments)));
 
407
      var a = merge(args, arguments);
 
408
      return __method.apply(this, a);
224
409
    }
225
 
  },
 
410
  }
226
411
 
227
 
  delay: function() {
228
 
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
 
412
  function delay(timeout) {
 
413
    var __method = this, args = slice.call(arguments, 1);
 
414
    timeout = timeout * 1000;
229
415
    return window.setTimeout(function() {
230
416
      return __method.apply(__method, args);
231
417
    }, timeout);
232
 
  },
233
 
 
234
 
  wrap: function(wrapper) {
 
418
  }
 
419
 
 
420
  function defer() {
 
421
    var args = update([0.01], arguments);
 
422
    return this.delay.apply(this, args);
 
423
  }
 
424
 
 
425
  function wrap(wrapper) {
235
426
    var __method = this;
236
427
    return function() {
237
 
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
 
428
      var a = update([__method.bind(this)], arguments);
 
429
      return wrapper.apply(this, a);
238
430
    }
239
 
  },
 
431
  }
240
432
 
241
 
  methodize: function() {
 
433
  function methodize() {
242
434
    if (this._methodized) return this._methodized;
243
435
    var __method = this;
244
436
    return this._methodized = function() {
245
 
      return __method.apply(null, [this].concat($A(arguments)));
 
437
      var a = update([this], arguments);
 
438
      return __method.apply(null, a);
246
439
    };
247
440
  }
248
 
});
249
 
 
250
 
Function.prototype.defer = Function.prototype.delay.curry(0.01);
251
 
 
252
 
Date.prototype.toJSON = function() {
253
 
  return '"' + this.getUTCFullYear() + '-' +
254
 
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
255
 
    this.getUTCDate().toPaddedString(2) + 'T' +
256
 
    this.getUTCHours().toPaddedString(2) + ':' +
257
 
    this.getUTCMinutes().toPaddedString(2) + ':' +
258
 
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
259
 
};
260
 
 
261
 
var Try = {
262
 
  these: function() {
263
 
    var returnValue;
264
 
 
265
 
    for (var i = 0, length = arguments.length; i < length; i++) {
266
 
      var lambda = arguments[i];
267
 
      try {
268
 
        returnValue = lambda();
269
 
        break;
270
 
      } catch (e) { }
271
 
    }
272
 
 
273
 
    return returnValue;
274
 
  }
275
 
};
 
441
 
 
442
  return {
 
443
    argumentNames:       argumentNames,
 
444
    bind:                bind,
 
445
    bindAsEventListener: bindAsEventListener,
 
446
    curry:               curry,
 
447
    delay:               delay,
 
448
    defer:               defer,
 
449
    wrap:                wrap,
 
450
    methodize:           methodize
 
451
  }
 
452
})());
 
453
 
 
454
 
 
455
 
 
456
(function(proto) {
 
457
 
 
458
 
 
459
  function toISOString() {
 
460
    return this.getUTCFullYear() + '-' +
 
461
      (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
 
462
      this.getUTCDate().toPaddedString(2) + 'T' +
 
463
      this.getUTCHours().toPaddedString(2) + ':' +
 
464
      this.getUTCMinutes().toPaddedString(2) + ':' +
 
465
      this.getUTCSeconds().toPaddedString(2) + 'Z';
 
466
  }
 
467
 
 
468
 
 
469
  function toJSON() {
 
470
    return this.toISOString();
 
471
  }
 
472
 
 
473
  if (!proto.toISOString) proto.toISOString = toISOString;
 
474
  if (!proto.toJSON) proto.toJSON = toJSON;
 
475
 
 
476
})(Date.prototype);
 
477
 
276
478
 
277
479
RegExp.prototype.match = RegExp.prototype.test;
278
480
 
279
481
RegExp.escape = function(str) {
280
482
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
281
483
};
282
 
 
283
 
/*--------------------------------------------------------------------------*/
284
 
 
285
484
var PeriodicalExecuter = Class.create({
286
485
  initialize: function(callback, frequency) {
287
486
    this.callback = callback;
310
509
      try {
311
510
        this.currentlyExecuting = true;
312
511
        this.execute();
313
 
      } finally {
314
 
        this.currentlyExecuting = false;
 
512
        this.currentlyExecuting = false;
 
513
      } catch(e) {
 
514
        this.currentlyExecuting = false;
 
515
        throw e;
315
516
      }
316
517
    }
317
518
  }
330
531
  }
331
532
});
332
533
 
333
 
Object.extend(String.prototype, {
334
 
  gsub: function(pattern, replacement) {
 
534
Object.extend(String.prototype, (function() {
 
535
  var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
 
536
    typeof JSON.parse === 'function' &&
 
537
    JSON.parse('{"test": true}').test;
 
538
 
 
539
  function prepareReplacement(replacement) {
 
540
    if (Object.isFunction(replacement)) return replacement;
 
541
    var template = new Template(replacement);
 
542
    return function(match) { return template.evaluate(match) };
 
543
  }
 
544
 
 
545
  function gsub(pattern, replacement) {
335
546
    var result = '', source = this, match;
336
 
    replacement = arguments.callee.prepareReplacement(replacement);
 
547
    replacement = prepareReplacement(replacement);
 
548
 
 
549
    if (Object.isString(pattern))
 
550
      pattern = RegExp.escape(pattern);
 
551
 
 
552
    if (!(pattern.length || pattern.source)) {
 
553
      replacement = replacement('');
 
554
      return replacement + source.split('').join(replacement) + replacement;
 
555
    }
337
556
 
338
557
    while (source.length > 0) {
339
558
      if (match = source.match(pattern)) {
345
564
      }
346
565
    }
347
566
    return result;
348
 
  },
 
567
  }
349
568
 
350
 
  sub: function(pattern, replacement, count) {
351
 
    replacement = this.gsub.prepareReplacement(replacement);
 
569
  function sub(pattern, replacement, count) {
 
570
    replacement = prepareReplacement(replacement);
352
571
    count = Object.isUndefined(count) ? 1 : count;
353
572
 
354
573
    return this.gsub(pattern, function(match) {
355
574
      if (--count < 0) return match[0];
356
575
      return replacement(match);
357
576
    });
358
 
  },
 
577
  }
359
578
 
360
 
  scan: function(pattern, iterator) {
 
579
  function scan(pattern, iterator) {
361
580
    this.gsub(pattern, iterator);
362
581
    return String(this);
363
 
  },
 
582
  }
364
583
 
365
 
  truncate: function(length, truncation) {
 
584
  function truncate(length, truncation) {
366
585
    length = length || 30;
367
586
    truncation = Object.isUndefined(truncation) ? '...' : truncation;
368
587
    return this.length > length ?
369
588
      this.slice(0, length - truncation.length) + truncation : String(this);
370
 
  },
 
589
  }
371
590
 
372
 
  strip: function() {
 
591
  function strip() {
373
592
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
374
 
  },
375
 
 
376
 
  stripTags: function() {
377
 
    return this.replace(/<\/?[^>]+>/gi, '');
378
 
  },
379
 
 
380
 
  stripScripts: function() {
 
593
  }
 
594
 
 
595
  function stripTags() {
 
596
    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
 
597
  }
 
598
 
 
599
  function stripScripts() {
381
600
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
382
 
  },
 
601
  }
383
602
 
384
 
  extractScripts: function() {
385
 
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
386
 
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
 
603
  function extractScripts() {
 
604
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
 
605
        matchOne = new RegExp(Prototype.ScriptFragment, 'im');
387
606
    return (this.match(matchAll) || []).map(function(scriptTag) {
388
607
      return (scriptTag.match(matchOne) || ['', ''])[1];
389
608
    });
390
 
  },
 
609
  }
391
610
 
392
 
  evalScripts: function() {
 
611
  function evalScripts() {
393
612
    return this.extractScripts().map(function(script) { return eval(script) });
394
 
  },
395
 
 
396
 
  escapeHTML: function() {
397
 
    var self = arguments.callee;
398
 
    self.text.data = this;
399
 
    return self.div.innerHTML;
400
 
  },
401
 
 
402
 
  unescapeHTML: function() {
403
 
    var div = new Element('div');
404
 
    div.innerHTML = this.stripTags();
405
 
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
406
 
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
407
 
      div.childNodes[0].nodeValue) : '';
408
 
  },
409
 
 
410
 
  toQueryParams: function(separator) {
 
613
  }
 
614
 
 
615
  function escapeHTML() {
 
616
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
 
617
  }
 
618
 
 
619
  function unescapeHTML() {
 
620
    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
 
621
  }
 
622
 
 
623
 
 
624
  function toQueryParams(separator) {
411
625
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
412
626
    if (!match) return { };
413
627
 
414
628
    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
415
629
      if ((pair = pair.split('='))[0]) {
416
 
        var key = decodeURIComponent(pair.shift());
417
 
        var value = pair.length > 1 ? pair.join('=') : pair[0];
 
630
        var key = decodeURIComponent(pair.shift()),
 
631
            value = pair.length > 1 ? pair.join('=') : pair[0];
 
632
 
418
633
        if (value != undefined) value = decodeURIComponent(value);
419
634
 
420
635
        if (key in hash) {
425
640
      }
426
641
      return hash;
427
642
    });
428
 
  },
 
643
  }
429
644
 
430
 
  toArray: function() {
 
645
  function toArray() {
431
646
    return this.split('');
432
 
  },
 
647
  }
433
648
 
434
 
  succ: function() {
 
649
  function succ() {
435
650
    return this.slice(0, this.length - 1) +
436
651
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
437
 
  },
 
652
  }
438
653
 
439
 
  times: function(count) {
 
654
  function times(count) {
440
655
    return count < 1 ? '' : new Array(count + 1).join(this);
441
 
  },
442
 
 
443
 
  camelize: function() {
444
 
    var parts = this.split('-'), len = parts.length;
445
 
    if (len == 1) return parts[0];
446
 
 
447
 
    var camelized = this.charAt(0) == '-'
448
 
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
449
 
      : parts[0];
450
 
 
451
 
    for (var i = 1; i < len; i++)
452
 
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
453
 
 
454
 
    return camelized;
455
 
  },
456
 
 
457
 
  capitalize: function() {
 
656
  }
 
657
 
 
658
  function camelize() {
 
659
    return this.replace(/-+(.)?/g, function(match, chr) {
 
660
      return chr ? chr.toUpperCase() : '';
 
661
    });
 
662
  }
 
663
 
 
664
  function capitalize() {
458
665
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
459
 
  },
460
 
 
461
 
  underscore: function() {
462
 
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
463
 
  },
464
 
 
465
 
  dasherize: function() {
466
 
    return this.gsub(/_/,'-');
467
 
  },
468
 
 
469
 
  inspect: function(useDoubleQuotes) {
470
 
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
471
 
      var character = String.specialChar[match[0]];
472
 
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
 
666
  }
 
667
 
 
668
  function underscore() {
 
669
    return this.replace(/::/g, '/')
 
670
               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
 
671
               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
 
672
               .replace(/-/g, '_')
 
673
               .toLowerCase();
 
674
  }
 
675
 
 
676
  function dasherize() {
 
677
    return this.replace(/_/g, '-');
 
678
  }
 
679
 
 
680
  function inspect(useDoubleQuotes) {
 
681
    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
 
682
      if (character in String.specialChar) {
 
683
        return String.specialChar[character];
 
684
      }
 
685
      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
473
686
    });
474
687
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
475
688
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
476
 
  },
477
 
 
478
 
  toJSON: function() {
479
 
    return this.inspect(true);
480
 
  },
481
 
 
482
 
  unfilterJSON: function(filter) {
483
 
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
484
 
  },
485
 
 
486
 
  isJSON: function() {
 
689
  }
 
690
 
 
691
  function unfilterJSON(filter) {
 
692
    return this.replace(filter || Prototype.JSONFilter, '$1');
 
693
  }
 
694
 
 
695
  function isJSON() {
487
696
    var str = this;
488
697
    if (str.blank()) return false;
489
 
    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
490
 
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
491
 
  },
 
698
    str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
 
699
    str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
 
700
    str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
 
701
    return (/^[\],:{}\s]*$/).test(str);
 
702
  }
492
703
 
493
 
  evalJSON: function(sanitize) {
494
 
    var json = this.unfilterJSON();
 
704
  function evalJSON(sanitize) {
 
705
    var json = this.unfilterJSON(),
 
706
        cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
 
707
    if (cx.test(json)) {
 
708
      json = json.replace(cx, function (a) {
 
709
        return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
 
710
      });
 
711
    }
495
712
    try {
496
713
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
497
714
    } catch (e) { }
498
715
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
499
 
  },
500
 
 
501
 
  include: function(pattern) {
 
716
  }
 
717
 
 
718
  function parseJSON() {
 
719
    var json = this.unfilterJSON();
 
720
    return JSON.parse(json);
 
721
  }
 
722
 
 
723
  function include(pattern) {
502
724
    return this.indexOf(pattern) > -1;
503
 
  },
504
 
 
505
 
  startsWith: function(pattern) {
506
 
    return this.indexOf(pattern) === 0;
507
 
  },
508
 
 
509
 
  endsWith: function(pattern) {
 
725
  }
 
726
 
 
727
  function startsWith(pattern) {
 
728
    return this.lastIndexOf(pattern, 0) === 0;
 
729
  }
 
730
 
 
731
  function endsWith(pattern) {
510
732
    var d = this.length - pattern.length;
511
 
    return d >= 0 && this.lastIndexOf(pattern) === d;
512
 
  },
 
733
    return d >= 0 && this.indexOf(pattern, d) === d;
 
734
  }
513
735
 
514
 
  empty: function() {
 
736
  function empty() {
515
737
    return this == '';
516
 
  },
 
738
  }
517
739
 
518
 
  blank: function() {
 
740
  function blank() {
519
741
    return /^\s*$/.test(this);
520
 
  },
 
742
  }
521
743
 
522
 
  interpolate: function(object, pattern) {
 
744
  function interpolate(object, pattern) {
523
745
    return new Template(this, pattern).evaluate(object);
524
746
  }
525
 
});
526
 
 
527
 
if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
528
 
  escapeHTML: function() {
529
 
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
530
 
  },
531
 
  unescapeHTML: function() {
532
 
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
533
 
  }
534
 
});
535
 
 
536
 
String.prototype.gsub.prepareReplacement = function(replacement) {
537
 
  if (Object.isFunction(replacement)) return replacement;
538
 
  var template = new Template(replacement);
539
 
  return function(match) { return template.evaluate(match) };
540
 
};
541
 
 
542
 
String.prototype.parseQuery = String.prototype.toQueryParams;
543
 
 
544
 
Object.extend(String.prototype.escapeHTML, {
545
 
  div:  document.createElement('div'),
546
 
  text: document.createTextNode('')
547
 
});
548
 
 
549
 
with (String.prototype.escapeHTML) div.appendChild(text);
 
747
 
 
748
  return {
 
749
    gsub:           gsub,
 
750
    sub:            sub,
 
751
    scan:           scan,
 
752
    truncate:       truncate,
 
753
    strip:          String.prototype.trim || strip,
 
754
    stripTags:      stripTags,
 
755
    stripScripts:   stripScripts,
 
756
    extractScripts: extractScripts,
 
757
    evalScripts:    evalScripts,
 
758
    escapeHTML:     escapeHTML,
 
759
    unescapeHTML:   unescapeHTML,
 
760
    toQueryParams:  toQueryParams,
 
761
    parseQuery:     toQueryParams,
 
762
    toArray:        toArray,
 
763
    succ:           succ,
 
764
    times:          times,
 
765
    camelize:       camelize,
 
766
    capitalize:     capitalize,
 
767
    underscore:     underscore,
 
768
    dasherize:      dasherize,
 
769
    inspect:        inspect,
 
770
    unfilterJSON:   unfilterJSON,
 
771
    isJSON:         isJSON,
 
772
    evalJSON:       NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
 
773
    include:        include,
 
774
    startsWith:     startsWith,
 
775
    endsWith:       endsWith,
 
776
    empty:          empty,
 
777
    blank:          blank,
 
778
    interpolate:    interpolate
 
779
  };
 
780
})());
550
781
 
551
782
var Template = Class.create({
552
783
  initialize: function(template, pattern) {
555
786
  },
556
787
 
557
788
  evaluate: function(object) {
558
 
    if (Object.isFunction(object.toTemplateReplacements))
 
789
    if (object && Object.isFunction(object.toTemplateReplacements))
559
790
      object = object.toTemplateReplacements();
560
791
 
561
792
    return this.template.gsub(this.pattern, function(match) {
562
 
      if (object == null) return '';
 
793
      if (object == null) return (match[1] + '');
563
794
 
564
795
      var before = match[1] || '';
565
796
      if (before == '\\') return match[2];
566
797
 
567
 
      var ctx = object, expr = match[3];
568
 
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
 
798
      var ctx = object, expr = match[3],
 
799
          pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
 
800
 
569
801
      match = pattern.exec(expr);
570
802
      if (match == null) return before;
571
803
 
572
804
      while (match != null) {
573
 
        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
 
805
        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
574
806
        ctx = ctx[comp];
575
807
        if (null == ctx || '' == match[3]) break;
576
808
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
578
810
      }
579
811
 
580
812
      return before + String.interpret(ctx);
581
 
    }.bind(this));
 
813
    });
582
814
  }
583
815
});
584
816
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
585
817
 
586
818
var $break = { };
587
819
 
588
 
var Enumerable = {
589
 
  each: function(iterator, context) {
 
820
var Enumerable = (function() {
 
821
  function each(iterator, context) {
590
822
    var index = 0;
591
 
    iterator = iterator.bind(context);
592
823
    try {
593
824
      this._each(function(value) {
594
 
        iterator(value, index++);
 
825
        iterator.call(context, value, index++);
595
826
      });
596
827
    } catch (e) {
597
828
      if (e != $break) throw e;
598
829
    }
599
830
    return this;
600
 
  },
 
831
  }
601
832
 
602
 
  eachSlice: function(number, iterator, context) {
603
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
833
  function eachSlice(number, iterator, context) {
604
834
    var index = -number, slices = [], array = this.toArray();
 
835
    if (number < 1) return array;
605
836
    while ((index += number) < array.length)
606
837
      slices.push(array.slice(index, index+number));
607
838
    return slices.collect(iterator, context);
608
 
  },
 
839
  }
609
840
 
610
 
  all: function(iterator, context) {
611
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
841
  function all(iterator, context) {
 
842
    iterator = iterator || Prototype.K;
612
843
    var result = true;
613
844
    this.each(function(value, index) {
614
 
      result = result && !!iterator(value, index);
 
845
      result = result && !!iterator.call(context, value, index);
615
846
      if (!result) throw $break;
616
847
    });
617
848
    return result;
618
 
  },
 
849
  }
619
850
 
620
 
  any: function(iterator, context) {
621
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
851
  function any(iterator, context) {
 
852
    iterator = iterator || Prototype.K;
622
853
    var result = false;
623
854
    this.each(function(value, index) {
624
 
      if (result = !!iterator(value, index))
 
855
      if (result = !!iterator.call(context, value, index))
625
856
        throw $break;
626
857
    });
627
858
    return result;
628
 
  },
 
859
  }
629
860
 
630
 
  collect: function(iterator, context) {
631
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
861
  function collect(iterator, context) {
 
862
    iterator = iterator || Prototype.K;
632
863
    var results = [];
633
864
    this.each(function(value, index) {
634
 
      results.push(iterator(value, index));
 
865
      results.push(iterator.call(context, value, index));
635
866
    });
636
867
    return results;
637
 
  },
 
868
  }
638
869
 
639
 
  detect: function(iterator, context) {
640
 
    iterator = iterator.bind(context);
 
870
  function detect(iterator, context) {
641
871
    var result;
642
872
    this.each(function(value, index) {
643
 
      if (iterator(value, index)) {
 
873
      if (iterator.call(context, value, index)) {
644
874
        result = value;
645
875
        throw $break;
646
876
      }
647
877
    });
648
878
    return result;
649
 
  },
 
879
  }
650
880
 
651
 
  findAll: function(iterator, context) {
652
 
    iterator = iterator.bind(context);
 
881
  function findAll(iterator, context) {
653
882
    var results = [];
654
883
    this.each(function(value, index) {
655
 
      if (iterator(value, index))
 
884
      if (iterator.call(context, value, index))
656
885
        results.push(value);
657
886
    });
658
887
    return results;
659
 
  },
 
888
  }
660
889
 
661
 
  grep: function(filter, iterator, context) {
662
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
890
  function grep(filter, iterator, context) {
 
891
    iterator = iterator || Prototype.K;
663
892
    var results = [];
664
893
 
665
894
    if (Object.isString(filter))
666
 
      filter = new RegExp(filter);
 
895
      filter = new RegExp(RegExp.escape(filter));
667
896
 
668
897
    this.each(function(value, index) {
669
898
      if (filter.match(value))
670
 
        results.push(iterator(value, index));
 
899
        results.push(iterator.call(context, value, index));
671
900
    });
672
901
    return results;
673
 
  },
 
902
  }
674
903
 
675
 
  include: function(object) {
 
904
  function include(object) {
676
905
    if (Object.isFunction(this.indexOf))
677
906
      if (this.indexOf(object) != -1) return true;
678
907
 
684
913
      }
685
914
    });
686
915
    return found;
687
 
  },
 
916
  }
688
917
 
689
 
  inGroupsOf: function(number, fillWith) {
 
918
  function inGroupsOf(number, fillWith) {
690
919
    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
691
920
    return this.eachSlice(number, function(slice) {
692
921
      while(slice.length < number) slice.push(fillWith);
693
922
      return slice;
694
923
    });
695
 
  },
 
924
  }
696
925
 
697
 
  inject: function(memo, iterator, context) {
698
 
    iterator = iterator.bind(context);
 
926
  function inject(memo, iterator, context) {
699
927
    this.each(function(value, index) {
700
 
      memo = iterator(memo, value, index);
 
928
      memo = iterator.call(context, memo, value, index);
701
929
    });
702
930
    return memo;
703
 
  },
 
931
  }
704
932
 
705
 
  invoke: function(method) {
 
933
  function invoke(method) {
706
934
    var args = $A(arguments).slice(1);
707
935
    return this.map(function(value) {
708
936
      return value[method].apply(value, args);
709
937
    });
710
 
  },
 
938
  }
711
939
 
712
 
  max: function(iterator, context) {
713
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
940
  function max(iterator, context) {
 
941
    iterator = iterator || Prototype.K;
714
942
    var result;
715
943
    this.each(function(value, index) {
716
 
      value = iterator(value, index);
 
944
      value = iterator.call(context, value, index);
717
945
      if (result == null || value >= result)
718
946
        result = value;
719
947
    });
720
948
    return result;
721
 
  },
 
949
  }
722
950
 
723
 
  min: function(iterator, context) {
724
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
951
  function min(iterator, context) {
 
952
    iterator = iterator || Prototype.K;
725
953
    var result;
726
954
    this.each(function(value, index) {
727
 
      value = iterator(value, index);
 
955
      value = iterator.call(context, value, index);
728
956
      if (result == null || value < result)
729
957
        result = value;
730
958
    });
731
959
    return result;
732
 
  },
 
960
  }
733
961
 
734
 
  partition: function(iterator, context) {
735
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
962
  function partition(iterator, context) {
 
963
    iterator = iterator || Prototype.K;
736
964
    var trues = [], falses = [];
737
965
    this.each(function(value, index) {
738
 
      (iterator(value, index) ?
 
966
      (iterator.call(context, value, index) ?
739
967
        trues : falses).push(value);
740
968
    });
741
969
    return [trues, falses];
742
 
  },
 
970
  }
743
971
 
744
 
  pluck: function(property) {
 
972
  function pluck(property) {
745
973
    var results = [];
746
974
    this.each(function(value) {
747
975
      results.push(value[property]);
748
976
    });
749
977
    return results;
750
 
  },
 
978
  }
751
979
 
752
 
  reject: function(iterator, context) {
753
 
    iterator = iterator.bind(context);
 
980
  function reject(iterator, context) {
754
981
    var results = [];
755
982
    this.each(function(value, index) {
756
 
      if (!iterator(value, index))
 
983
      if (!iterator.call(context, value, index))
757
984
        results.push(value);
758
985
    });
759
986
    return results;
760
 
  },
 
987
  }
761
988
 
762
 
  sortBy: function(iterator, context) {
763
 
    iterator = iterator.bind(context);
 
989
  function sortBy(iterator, context) {
764
990
    return this.map(function(value, index) {
765
 
      return {value: value, criteria: iterator(value, index)};
 
991
      return {
 
992
        value: value,
 
993
        criteria: iterator.call(context, value, index)
 
994
      };
766
995
    }).sort(function(left, right) {
767
996
      var a = left.criteria, b = right.criteria;
768
997
      return a < b ? -1 : a > b ? 1 : 0;
769
998
    }).pluck('value');
770
 
  },
 
999
  }
771
1000
 
772
 
  toArray: function() {
 
1001
  function toArray() {
773
1002
    return this.map();
774
 
  },
 
1003
  }
775
1004
 
776
 
  zip: function() {
 
1005
  function zip() {
777
1006
    var iterator = Prototype.K, args = $A(arguments);
778
1007
    if (Object.isFunction(args.last()))
779
1008
      iterator = args.pop();
782
1011
    return this.map(function(value, index) {
783
1012
      return iterator(collections.pluck(index));
784
1013
    });
785
 
  },
 
1014
  }
786
1015
 
787
 
  size: function() {
 
1016
  function size() {
788
1017
    return this.toArray().length;
789
 
  },
 
1018
  }
790
1019
 
791
 
  inspect: function() {
 
1020
  function inspect() {
792
1021
    return '#<Enumerable:' + this.toArray().inspect() + '>';
793
1022
  }
794
 
};
795
 
 
796
 
Object.extend(Enumerable, {
797
 
  map:     Enumerable.collect,
798
 
  find:    Enumerable.detect,
799
 
  select:  Enumerable.findAll,
800
 
  filter:  Enumerable.findAll,
801
 
  member:  Enumerable.include,
802
 
  entries: Enumerable.toArray,
803
 
  every:   Enumerable.all,
804
 
  some:    Enumerable.any
805
 
});
 
1023
 
 
1024
 
 
1025
 
 
1026
 
 
1027
 
 
1028
 
 
1029
 
 
1030
 
 
1031
 
 
1032
  return {
 
1033
    each:       each,
 
1034
    eachSlice:  eachSlice,
 
1035
    all:        all,
 
1036
    every:      all,
 
1037
    any:        any,
 
1038
    some:       any,
 
1039
    collect:    collect,
 
1040
    map:        collect,
 
1041
    detect:     detect,
 
1042
    findAll:    findAll,
 
1043
    select:     findAll,
 
1044
    filter:     findAll,
 
1045
    grep:       grep,
 
1046
    include:    include,
 
1047
    member:     include,
 
1048
    inGroupsOf: inGroupsOf,
 
1049
    inject:     inject,
 
1050
    invoke:     invoke,
 
1051
    max:        max,
 
1052
    min:        min,
 
1053
    partition:  partition,
 
1054
    pluck:      pluck,
 
1055
    reject:     reject,
 
1056
    sortBy:     sortBy,
 
1057
    toArray:    toArray,
 
1058
    entries:    toArray,
 
1059
    zip:        zip,
 
1060
    size:       size,
 
1061
    inspect:    inspect,
 
1062
    find:       detect
 
1063
  };
 
1064
})();
 
1065
 
806
1066
function $A(iterable) {
807
1067
  if (!iterable) return [];
808
 
  if (iterable.toArray) return iterable.toArray();
 
1068
  if ('toArray' in Object(iterable)) return iterable.toArray();
809
1069
  var length = iterable.length || 0, results = new Array(length);
810
1070
  while (length--) results[length] = iterable[length];
811
1071
  return results;
812
1072
}
813
1073
 
814
 
if (Prototype.Browser.WebKit) {
815
 
  function $A(iterable) {
816
 
    if (!iterable) return [];
817
 
    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
818
 
        iterable.toArray) return iterable.toArray();
819
 
    var length = iterable.length || 0, results = new Array(length);
820
 
    while (length--) results[length] = iterable[length];
821
 
    return results;
822
 
  }
 
1074
 
 
1075
function $w(string) {
 
1076
  if (!Object.isString(string)) return [];
 
1077
  string = string.strip();
 
1078
  return string ? string.split(/\s+/) : [];
823
1079
}
824
1080
 
825
1081
Array.from = $A;
826
1082
 
827
 
Object.extend(Array.prototype, Enumerable);
828
 
 
829
 
if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
830
 
 
831
 
Object.extend(Array.prototype, {
832
 
  _each: function(iterator) {
833
 
    for (var i = 0, length = this.length; i < length; i++)
834
 
      iterator(this[i]);
835
 
  },
836
 
 
837
 
  clear: function() {
 
1083
 
 
1084
(function() {
 
1085
  var arrayProto = Array.prototype,
 
1086
      slice = arrayProto.slice,
 
1087
      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
 
1088
 
 
1089
  function each(iterator, context) {
 
1090
    for (var i = 0, length = this.length >>> 0; i < length; i++) {
 
1091
      if (i in this) iterator.call(context, this[i], i, this);
 
1092
    }
 
1093
  }
 
1094
  if (!_each) _each = each;
 
1095
 
 
1096
  function clear() {
838
1097
    this.length = 0;
839
1098
    return this;
840
 
  },
 
1099
  }
841
1100
 
842
 
  first: function() {
 
1101
  function first() {
843
1102
    return this[0];
844
 
  },
 
1103
  }
845
1104
 
846
 
  last: function() {
 
1105
  function last() {
847
1106
    return this[this.length - 1];
848
 
  },
 
1107
  }
849
1108
 
850
 
  compact: function() {
 
1109
  function compact() {
851
1110
    return this.select(function(value) {
852
1111
      return value != null;
853
1112
    });
854
 
  },
 
1113
  }
855
1114
 
856
 
  flatten: function() {
 
1115
  function flatten() {
857
1116
    return this.inject([], function(array, value) {
858
 
      return array.concat(Object.isArray(value) ?
859
 
        value.flatten() : [value]);
 
1117
      if (Object.isArray(value))
 
1118
        return array.concat(value.flatten());
 
1119
      array.push(value);
 
1120
      return array;
860
1121
    });
861
 
  },
 
1122
  }
862
1123
 
863
 
  without: function() {
864
 
    var values = $A(arguments);
 
1124
  function without() {
 
1125
    var values = slice.call(arguments, 0);
865
1126
    return this.select(function(value) {
866
1127
      return !values.include(value);
867
1128
    });
868
 
  },
869
 
 
870
 
  reverse: function(inline) {
871
 
    return (inline !== false ? this : this.toArray())._reverse();
872
 
  },
873
 
 
874
 
  reduce: function() {
875
 
    return this.length > 1 ? this : this[0];
876
 
  },
877
 
 
878
 
  uniq: function(sorted) {
 
1129
  }
 
1130
 
 
1131
  function reverse(inline) {
 
1132
    return (inline === false ? this.toArray() : this)._reverse();
 
1133
  }
 
1134
 
 
1135
  function uniq(sorted) {
879
1136
    return this.inject([], function(array, value, index) {
880
1137
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
881
1138
        array.push(value);
882
1139
      return array;
883
1140
    });
884
 
  },
 
1141
  }
885
1142
 
886
 
  intersect: function(array) {
 
1143
  function intersect(array) {
887
1144
    return this.uniq().findAll(function(item) {
888
1145
      return array.detect(function(value) { return item === value });
889
1146
    });
890
 
  },
891
 
 
892
 
  clone: function() {
893
 
    return [].concat(this);
894
 
  },
895
 
 
896
 
  size: function() {
 
1147
  }
 
1148
 
 
1149
 
 
1150
  function clone() {
 
1151
    return slice.call(this, 0);
 
1152
  }
 
1153
 
 
1154
  function size() {
897
1155
    return this.length;
898
 
  },
 
1156
  }
899
1157
 
900
 
  inspect: function() {
 
1158
  function inspect() {
901
1159
    return '[' + this.map(Object.inspect).join(', ') + ']';
902
 
  },
903
 
 
904
 
  toJSON: function() {
905
 
    var results = [];
906
 
    this.each(function(object) {
907
 
      var value = Object.toJSON(object);
908
 
      if (!Object.isUndefined(value)) results.push(value);
909
 
    });
910
 
    return '[' + results.join(', ') + ']';
911
 
  }
912
 
});
913
 
 
914
 
// use native browser JS 1.6 implementation if available
915
 
if (Object.isFunction(Array.prototype.forEach))
916
 
  Array.prototype._each = Array.prototype.forEach;
917
 
 
918
 
if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
919
 
  i || (i = 0);
920
 
  var length = this.length;
921
 
  if (i < 0) i = length + i;
922
 
  for (; i < length; i++)
923
 
    if (this[i] === item) return i;
924
 
  return -1;
925
 
};
926
 
 
927
 
if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
928
 
  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
929
 
  var n = this.slice(0, i).reverse().indexOf(item);
930
 
  return (n < 0) ? n : i - n - 1;
931
 
};
932
 
 
933
 
Array.prototype.toArray = Array.prototype.clone;
934
 
 
935
 
function $w(string) {
936
 
  if (!Object.isString(string)) return [];
937
 
  string = string.strip();
938
 
  return string ? string.split(/\s+/) : [];
939
 
}
940
 
 
941
 
if (Prototype.Browser.Opera){
942
 
  Array.prototype.concat = function() {
943
 
    var array = [];
944
 
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
 
1160
  }
 
1161
 
 
1162
  function indexOf(item, i) {
 
1163
    i || (i = 0);
 
1164
    var length = this.length;
 
1165
    if (i < 0) i = length + i;
 
1166
    for (; i < length; i++)
 
1167
      if (this[i] === item) return i;
 
1168
    return -1;
 
1169
  }
 
1170
 
 
1171
  function lastIndexOf(item, i) {
 
1172
    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
 
1173
    var n = this.slice(0, i).reverse().indexOf(item);
 
1174
    return (n < 0) ? n : i - n - 1;
 
1175
  }
 
1176
 
 
1177
  function concat() {
 
1178
    var array = slice.call(this, 0), item;
945
1179
    for (var i = 0, length = arguments.length; i < length; i++) {
946
 
      if (Object.isArray(arguments[i])) {
947
 
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
948
 
          array.push(arguments[i][j]);
 
1180
      item = arguments[i];
 
1181
      if (Object.isArray(item) && !('callee' in item)) {
 
1182
        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
 
1183
          array.push(item[j]);
949
1184
      } else {
950
 
        array.push(arguments[i]);
 
1185
        array.push(item);
951
1186
      }
952
1187
    }
953
1188
    return array;
954
 
  };
955
 
}
956
 
Object.extend(Number.prototype, {
957
 
  toColorPart: function() {
958
 
    return this.toPaddedString(2, 16);
959
 
  },
960
 
 
961
 
  succ: function() {
962
 
    return this + 1;
963
 
  },
964
 
 
965
 
  times: function(iterator) {
966
 
    $R(0, this, true).each(iterator);
967
 
    return this;
968
 
  },
969
 
 
970
 
  toPaddedString: function(length, radix) {
971
 
    var string = this.toString(radix || 10);
972
 
    return '0'.times(length - string.length) + string;
973
 
  },
974
 
 
975
 
  toJSON: function() {
976
 
    return isFinite(this) ? this.toString() : 'null';
977
1189
  }
978
 
});
979
 
 
980
 
$w('abs round ceil floor').each(function(method){
981
 
  Number.prototype[method] = Math[method].methodize();
982
 
});
 
1190
 
 
1191
  Object.extend(arrayProto, Enumerable);
 
1192
 
 
1193
  if (!arrayProto._reverse)
 
1194
    arrayProto._reverse = arrayProto.reverse;
 
1195
 
 
1196
  Object.extend(arrayProto, {
 
1197
    _each:     _each,
 
1198
    clear:     clear,
 
1199
    first:     first,
 
1200
    last:      last,
 
1201
    compact:   compact,
 
1202
    flatten:   flatten,
 
1203
    without:   without,
 
1204
    reverse:   reverse,
 
1205
    uniq:      uniq,
 
1206
    intersect: intersect,
 
1207
    clone:     clone,
 
1208
    toArray:   clone,
 
1209
    size:      size,
 
1210
    inspect:   inspect
 
1211
  });
 
1212
 
 
1213
  var CONCAT_ARGUMENTS_BUGGY = (function() {
 
1214
    return [].concat(arguments)[0][0] !== 1;
 
1215
  })(1,2)
 
1216
 
 
1217
  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
 
1218
 
 
1219
  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
 
1220
  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
 
1221
})();
983
1222
function $H(object) {
984
1223
  return new Hash(object);
985
1224
};
986
1225
 
987
1226
var Hash = Class.create(Enumerable, (function() {
 
1227
  function initialize(object) {
 
1228
    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
 
1229
  }
 
1230
 
 
1231
 
 
1232
  function _each(iterator) {
 
1233
    for (var key in this._object) {
 
1234
      var value = this._object[key], pair = [key, value];
 
1235
      pair.key = key;
 
1236
      pair.value = value;
 
1237
      iterator(pair);
 
1238
    }
 
1239
  }
 
1240
 
 
1241
  function set(key, value) {
 
1242
    return this._object[key] = value;
 
1243
  }
 
1244
 
 
1245
  function get(key) {
 
1246
    if (this._object[key] !== Object.prototype[key])
 
1247
      return this._object[key];
 
1248
  }
 
1249
 
 
1250
  function unset(key) {
 
1251
    var value = this._object[key];
 
1252
    delete this._object[key];
 
1253
    return value;
 
1254
  }
 
1255
 
 
1256
  function toObject() {
 
1257
    return Object.clone(this._object);
 
1258
  }
 
1259
 
 
1260
 
 
1261
 
 
1262
  function keys() {
 
1263
    return this.pluck('key');
 
1264
  }
 
1265
 
 
1266
  function values() {
 
1267
    return this.pluck('value');
 
1268
  }
 
1269
 
 
1270
  function index(value) {
 
1271
    var match = this.detect(function(pair) {
 
1272
      return pair.value === value;
 
1273
    });
 
1274
    return match && match.key;
 
1275
  }
 
1276
 
 
1277
  function merge(object) {
 
1278
    return this.clone().update(object);
 
1279
  }
 
1280
 
 
1281
  function update(object) {
 
1282
    return new Hash(object).inject(this, function(result, pair) {
 
1283
      result.set(pair.key, pair.value);
 
1284
      return result;
 
1285
    });
 
1286
  }
988
1287
 
989
1288
  function toQueryPair(key, value) {
990
1289
    if (Object.isUndefined(value)) return key;
991
1290
    return key + '=' + encodeURIComponent(String.interpret(value));
992
1291
  }
993
1292
 
 
1293
  function toQueryString() {
 
1294
    return this.inject([], function(results, pair) {
 
1295
      var key = encodeURIComponent(pair.key), values = pair.value;
 
1296
 
 
1297
      if (values && typeof values == 'object') {
 
1298
        if (Object.isArray(values)) {
 
1299
          var queryValues = [];
 
1300
          for (var i = 0, len = values.length, value; i < len; i++) {
 
1301
            value = values[i];
 
1302
            queryValues.push(toQueryPair(key, value));
 
1303
          }
 
1304
          return results.concat(queryValues);
 
1305
        }
 
1306
      } else results.push(toQueryPair(key, values));
 
1307
      return results;
 
1308
    }).join('&');
 
1309
  }
 
1310
 
 
1311
  function inspect() {
 
1312
    return '#<Hash:{' + this.map(function(pair) {
 
1313
      return pair.map(Object.inspect).join(': ');
 
1314
    }).join(', ') + '}>';
 
1315
  }
 
1316
 
 
1317
  function clone() {
 
1318
    return new Hash(this);
 
1319
  }
 
1320
 
994
1321
  return {
995
 
    initialize: function(object) {
996
 
      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
997
 
    },
998
 
 
999
 
    _each: function(iterator) {
1000
 
      for (var key in this._object) {
1001
 
        var value = this._object[key], pair = [key, value];
1002
 
        pair.key = key;
1003
 
        pair.value = value;
1004
 
        iterator(pair);
1005
 
      }
1006
 
    },
1007
 
 
1008
 
    set: function(key, value) {
1009
 
      return this._object[key] = value;
1010
 
    },
1011
 
 
1012
 
    get: function(key) {
1013
 
      return this._object[key];
1014
 
    },
1015
 
 
1016
 
    unset: function(key) {
1017
 
      var value = this._object[key];
1018
 
      delete this._object[key];
1019
 
      return value;
1020
 
    },
1021
 
 
1022
 
    toObject: function() {
1023
 
      return Object.clone(this._object);
1024
 
    },
1025
 
 
1026
 
    keys: function() {
1027
 
      return this.pluck('key');
1028
 
    },
1029
 
 
1030
 
    values: function() {
1031
 
      return this.pluck('value');
1032
 
    },
1033
 
 
1034
 
    index: function(value) {
1035
 
      var match = this.detect(function(pair) {
1036
 
        return pair.value === value;
1037
 
      });
1038
 
      return match && match.key;
1039
 
    },
1040
 
 
1041
 
    merge: function(object) {
1042
 
      return this.clone().update(object);
1043
 
    },
1044
 
 
1045
 
    update: function(object) {
1046
 
      return new Hash(object).inject(this, function(result, pair) {
1047
 
        result.set(pair.key, pair.value);
1048
 
        return result;
1049
 
      });
1050
 
    },
1051
 
 
1052
 
    toQueryString: function() {
1053
 
      return this.map(function(pair) {
1054
 
        var key = encodeURIComponent(pair.key), values = pair.value;
1055
 
 
1056
 
        if (values && typeof values == 'object') {
1057
 
          if (Object.isArray(values))
1058
 
            return values.map(toQueryPair.curry(key)).join('&');
1059
 
        }
1060
 
        return toQueryPair(key, values);
1061
 
      }).join('&');
1062
 
    },
1063
 
 
1064
 
    inspect: function() {
1065
 
      return '#<Hash:{' + this.map(function(pair) {
1066
 
        return pair.map(Object.inspect).join(': ');
1067
 
      }).join(', ') + '}>';
1068
 
    },
1069
 
 
1070
 
    toJSON: function() {
1071
 
      return Object.toJSON(this.toObject());
1072
 
    },
1073
 
 
1074
 
    clone: function() {
1075
 
      return new Hash(this);
1076
 
    }
1077
 
  }
 
1322
    initialize:             initialize,
 
1323
    _each:                  _each,
 
1324
    set:                    set,
 
1325
    get:                    get,
 
1326
    unset:                  unset,
 
1327
    toObject:               toObject,
 
1328
    toTemplateReplacements: toObject,
 
1329
    keys:                   keys,
 
1330
    values:                 values,
 
1331
    index:                  index,
 
1332
    merge:                  merge,
 
1333
    update:                 update,
 
1334
    toQueryString:          toQueryString,
 
1335
    inspect:                inspect,
 
1336
    toJSON:                 toObject,
 
1337
    clone:                  clone
 
1338
  };
1078
1339
})());
1079
1340
 
1080
 
Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
1081
1341
Hash.from = $H;
1082
 
var ObjectRange = Class.create(Enumerable, {
1083
 
  initialize: function(start, end, exclusive) {
 
1342
Object.extend(Number.prototype, (function() {
 
1343
  function toColorPart() {
 
1344
    return this.toPaddedString(2, 16);
 
1345
  }
 
1346
 
 
1347
  function succ() {
 
1348
    return this + 1;
 
1349
  }
 
1350
 
 
1351
  function times(iterator, context) {
 
1352
    $R(0, this, true).each(iterator, context);
 
1353
    return this;
 
1354
  }
 
1355
 
 
1356
  function toPaddedString(length, radix) {
 
1357
    var string = this.toString(radix || 10);
 
1358
    return '0'.times(length - string.length) + string;
 
1359
  }
 
1360
 
 
1361
  function abs() {
 
1362
    return Math.abs(this);
 
1363
  }
 
1364
 
 
1365
  function round() {
 
1366
    return Math.round(this);
 
1367
  }
 
1368
 
 
1369
  function ceil() {
 
1370
    return Math.ceil(this);
 
1371
  }
 
1372
 
 
1373
  function floor() {
 
1374
    return Math.floor(this);
 
1375
  }
 
1376
 
 
1377
  return {
 
1378
    toColorPart:    toColorPart,
 
1379
    succ:           succ,
 
1380
    times:          times,
 
1381
    toPaddedString: toPaddedString,
 
1382
    abs:            abs,
 
1383
    round:          round,
 
1384
    ceil:           ceil,
 
1385
    floor:          floor
 
1386
  };
 
1387
})());
 
1388
 
 
1389
function $R(start, end, exclusive) {
 
1390
  return new ObjectRange(start, end, exclusive);
 
1391
}
 
1392
 
 
1393
var ObjectRange = Class.create(Enumerable, (function() {
 
1394
  function initialize(start, end, exclusive) {
1084
1395
    this.start = start;
1085
1396
    this.end = end;
1086
1397
    this.exclusive = exclusive;
1087
 
  },
 
1398
  }
1088
1399
 
1089
 
  _each: function(iterator) {
 
1400
  function _each(iterator) {
1090
1401
    var value = this.start;
1091
1402
    while (this.include(value)) {
1092
1403
      iterator(value);
1093
1404
      value = value.succ();
1094
1405
    }
1095
 
  },
 
1406
  }
1096
1407
 
1097
 
  include: function(value) {
 
1408
  function include(value) {
1098
1409
    if (value < this.start)
1099
1410
      return false;
1100
1411
    if (this.exclusive)
1101
1412
      return value < this.end;
1102
1413
    return value <= this.end;
1103
1414
  }
1104
 
});
1105
 
 
1106
 
var $R = function(start, end, exclusive) {
1107
 
  return new ObjectRange(start, end, exclusive);
1108
 
};
 
1415
 
 
1416
  return {
 
1417
    initialize: initialize,
 
1418
    _each:      _each,
 
1419
    include:    include
 
1420
  };
 
1421
})());
 
1422
 
 
1423
 
1109
1424
 
1110
1425
var Ajax = {
1111
1426
  getTransport: function() {
1152
1467
  onCreate:   function() { Ajax.activeRequestCount++ },
1153
1468
  onComplete: function() { Ajax.activeRequestCount-- }
1154
1469
});
1155
 
 
1156
1470
Ajax.Base = Class.create({
1157
1471
  initialize: function(options) {
1158
1472
    this.options = {
1168
1482
 
1169
1483
    this.options.method = this.options.method.toLowerCase();
1170
1484
 
1171
 
    if (Object.isString(this.options.parameters))
1172
 
      this.options.parameters = this.options.parameters.toQueryParams();
1173
 
    else if (Object.isHash(this.options.parameters))
 
1485
    if (Object.isHash(this.options.parameters))
1174
1486
      this.options.parameters = this.options.parameters.toObject();
1175
1487
  }
1176
1488
});
1177
 
 
1178
1489
Ajax.Request = Class.create(Ajax.Base, {
1179
1490
  _complete: false,
1180
1491
 
1187
1498
  request: function(url) {
1188
1499
    this.url = url;
1189
1500
    this.method = this.options.method;
1190
 
    var params = Object.clone(this.options.parameters);
 
1501
    var params = Object.isString(this.options.parameters) ?
 
1502
          this.options.parameters :
 
1503
          Object.toQueryString(this.options.parameters);
1191
1504
 
1192
1505
    if (!['get', 'post'].include(this.method)) {
1193
 
      // simulate other verbs over post
1194
 
      params['_method'] = this.method;
 
1506
      params += (params ? '&' : '') + "_method=" + this.method;
1195
1507
      this.method = 'post';
1196
1508
    }
1197
1509
 
1198
 
    this.parameters = params;
1199
 
 
1200
 
    if (params = Object.toQueryString(params)) {
1201
 
      // when GET, append parameters to URL
1202
 
      if (this.method == 'get')
1203
 
        this.url += (this.url.include('?') ? '&' : '?') + params;
1204
 
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
1205
 
        params += '&_=';
 
1510
    if (params && this.method === 'get') {
 
1511
      this.url += (this.url.include('?') ? '&' : '?') + params;
1206
1512
    }
1207
1513
 
 
1514
    this.parameters = params.toQueryParams();
 
1515
 
1208
1516
    try {
1209
1517
      var response = new Ajax.Response(this);
1210
1518
      if (this.options.onCreate) this.options.onCreate(response);
1257
1565
            headers['Connection'] = 'close';
1258
1566
    }
1259
1567
 
1260
 
    // user-defined headers
1261
1568
    if (typeof this.options.requestHeaders == 'object') {
1262
1569
      var extras = this.options.requestHeaders;
1263
1570
 
1274
1581
 
1275
1582
  success: function() {
1276
1583
    var status = this.getStatus();
1277
 
    return !status || (status >= 200 && status < 300);
 
1584
    return !status || (status >= 200 && status < 300) || status == 304;
1278
1585
  },
1279
1586
 
1280
1587
  getStatus: function() {
1281
1588
    try {
 
1589
      if (this.transport.status === 1223) return 204;
1282
1590
      return this.transport.status || 0;
1283
1591
    } catch (e) { return 0 }
1284
1592
  },
1298
1606
 
1299
1607
      var contentType = response.getHeader('Content-type');
1300
1608
      if (this.options.evalJS == 'force'
1301
 
          || (this.options.evalJS && contentType
 
1609
          || (this.options.evalJS && this.isSameOrigin() && contentType
1302
1610
          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
1303
1611
        this.evalResponse();
1304
1612
    }
1311
1619
    }
1312
1620
 
1313
1621
    if (state == 'Complete') {
1314
 
      // avoid memory leak in MSIE: clean up
1315
1622
      this.transport.onreadystatechange = Prototype.emptyFunction;
1316
1623
    }
1317
1624
  },
1318
1625
 
 
1626
  isSameOrigin: function() {
 
1627
    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
 
1628
    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
 
1629
      protocol: location.protocol,
 
1630
      domain: document.domain,
 
1631
      port: location.port ? ':' + location.port : ''
 
1632
    }));
 
1633
  },
 
1634
 
1319
1635
  getHeader: function(name) {
1320
1636
    try {
1321
1637
      return this.transport.getResponseHeader(name) || null;
1322
 
    } catch (e) { return null }
 
1638
    } catch (e) { return null; }
1323
1639
  },
1324
1640
 
1325
1641
  evalResponse: function() {
1339
1655
Ajax.Request.Events =
1340
1656
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
1341
1657
 
 
1658
 
 
1659
 
 
1660
 
 
1661
 
 
1662
 
 
1663
 
 
1664
 
1342
1665
Ajax.Response = Class.create({
1343
1666
  initialize: function(request){
1344
1667
    this.request = request;
1345
1668
    var transport  = this.transport  = request.transport,
1346
1669
        readyState = this.readyState = transport.readyState;
1347
1670
 
1348
 
    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
 
1671
    if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1349
1672
      this.status       = this.getStatus();
1350
1673
      this.statusText   = this.getStatusText();
1351
1674
      this.responseText = String.interpret(transport.responseText);
1352
1675
      this.headerJSON   = this._getHeaderJSON();
1353
1676
    }
1354
1677
 
1355
 
    if(readyState == 4) {
 
1678
    if (readyState == 4) {
1356
1679
      var xml = transport.responseXML;
1357
1680
      this.responseXML  = Object.isUndefined(xml) ? null : xml;
1358
1681
      this.responseJSON = this._getResponseJSON();
1360
1683
  },
1361
1684
 
1362
1685
  status:      0,
 
1686
 
1363
1687
  statusText: '',
1364
1688
 
1365
1689
  getStatus: Ajax.Request.prototype.getStatus,
1391
1715
    if (!json) return null;
1392
1716
    json = decodeURIComponent(escape(json));
1393
1717
    try {
1394
 
      return json.evalJSON(this.request.options.sanitizeJSON);
 
1718
      return json.evalJSON(this.request.options.sanitizeJSON ||
 
1719
        !this.request.isSameOrigin());
1395
1720
    } catch (e) {
1396
1721
      this.request.dispatchException(e);
1397
1722
    }
1404
1729
        this.responseText.blank())
1405
1730
          return null;
1406
1731
    try {
1407
 
      return this.responseText.evalJSON(options.sanitizeJSON);
 
1732
      return this.responseText.evalJSON(options.sanitizeJSON ||
 
1733
        !this.request.isSameOrigin());
1408
1734
    } catch (e) {
1409
1735
      this.request.dispatchException(e);
1410
1736
    }
1487
1813
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
1488
1814
  }
1489
1815
});
 
1816
 
 
1817
 
1490
1818
function $(element) {
1491
1819
  if (arguments.length > 1) {
1492
1820
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1511
1839
 
1512
1840
/*--------------------------------------------------------------------------*/
1513
1841
 
1514
 
if (!window.Node) var Node = { };
 
1842
if (!Node) var Node = { };
1515
1843
 
1516
1844
if (!Node.ELEMENT_NODE) {
1517
 
  // DOM level 2 ECMAScript Language Binding
1518
1845
  Object.extend(Node, {
1519
1846
    ELEMENT_NODE: 1,
1520
1847
    ATTRIBUTE_NODE: 2,
1531
1858
  });
1532
1859
}
1533
1860
 
1534
 
(function() {
1535
 
  var element = this.Element;
1536
 
  this.Element = function(tagName, attributes) {
 
1861
 
 
1862
 
 
1863
(function(global) {
 
1864
  function shouldUseCache(tagName, attributes) {
 
1865
    if (tagName === 'select') return false;
 
1866
    if ('type' in attributes) return false;
 
1867
    return true;
 
1868
  }
 
1869
 
 
1870
  var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
 
1871
    try {
 
1872
      var el = document.createElement('<input name="x">');
 
1873
      return el.tagName.toLowerCase() === 'input' && el.name === 'x';
 
1874
    }
 
1875
    catch(err) {
 
1876
      return false;
 
1877
    }
 
1878
  })();
 
1879
 
 
1880
  var element = global.Element;
 
1881
 
 
1882
  global.Element = function(tagName, attributes) {
1537
1883
    attributes = attributes || { };
1538
1884
    tagName = tagName.toLowerCase();
1539
1885
    var cache = Element.cache;
1540
 
    if (Prototype.Browser.IE && attributes.name) {
 
1886
 
 
1887
    if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
1541
1888
      tagName = '<' + tagName + ' name="' + attributes.name + '">';
1542
1889
      delete attributes.name;
1543
1890
      return Element.writeAttribute(document.createElement(tagName), attributes);
1544
1891
    }
 
1892
 
1545
1893
    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
1546
 
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
 
1894
 
 
1895
    var node = shouldUseCache(tagName, attributes) ?
 
1896
     cache[tagName].cloneNode(false) : document.createElement(tagName);
 
1897
 
 
1898
    return Element.writeAttribute(node, attributes);
1547
1899
  };
1548
 
  Object.extend(this.Element, element || { });
1549
 
}).call(window);
1550
 
 
 
1900
 
 
1901
  Object.extend(global.Element, element || { });
 
1902
  if (element) global.Element.prototype = element.prototype;
 
1903
 
 
1904
})(this);
 
1905
 
 
1906
Element.idCounter = 1;
1551
1907
Element.cache = { };
1552
1908
 
 
1909
Element._purgeElement = function(element) {
 
1910
  var uid = element._prototypeUID;
 
1911
  if (uid) {
 
1912
    Element.stopObserving(element);
 
1913
    element._prototypeUID = void 0;
 
1914
    delete Element.Storage[uid];
 
1915
  }
 
1916
}
 
1917
 
1553
1918
Element.Methods = {
1554
1919
  visible: function(element) {
1555
1920
    return $(element).style.display != 'none';
1562
1927
  },
1563
1928
 
1564
1929
  hide: function(element) {
1565
 
    $(element).style.display = 'none';
 
1930
    element = $(element);
 
1931
    element.style.display = 'none';
1566
1932
    return element;
1567
1933
  },
1568
1934
 
1569
1935
  show: function(element) {
1570
 
    $(element).style.display = '';
 
1936
    element = $(element);
 
1937
    element.style.display = '';
1571
1938
    return element;
1572
1939
  },
1573
1940
 
1577
1944
    return element;
1578
1945
  },
1579
1946
 
1580
 
  update: function(element, content) {
1581
 
    element = $(element);
1582
 
    if (content && content.toElement) content = content.toElement();
1583
 
    if (Object.isElement(content)) return element.update().insert(content);
1584
 
    content = Object.toHTML(content);
1585
 
    element.innerHTML = content.stripScripts();
1586
 
    content.evalScripts.bind(content).defer();
1587
 
    return element;
1588
 
  },
 
1947
  update: (function(){
 
1948
 
 
1949
    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
 
1950
      var el = document.createElement("select"),
 
1951
          isBuggy = true;
 
1952
      el.innerHTML = "<option value=\"test\">test</option>";
 
1953
      if (el.options && el.options[0]) {
 
1954
        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
 
1955
      }
 
1956
      el = null;
 
1957
      return isBuggy;
 
1958
    })();
 
1959
 
 
1960
    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
 
1961
      try {
 
1962
        var el = document.createElement("table");
 
1963
        if (el && el.tBodies) {
 
1964
          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
 
1965
          var isBuggy = typeof el.tBodies[0] == "undefined";
 
1966
          el = null;
 
1967
          return isBuggy;
 
1968
        }
 
1969
      } catch (e) {
 
1970
        return true;
 
1971
      }
 
1972
    })();
 
1973
 
 
1974
    var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
 
1975
      try {
 
1976
        var el = document.createElement('div');
 
1977
        el.innerHTML = "<link>";
 
1978
        var isBuggy = (el.childNodes.length === 0);
 
1979
        el = null;
 
1980
        return isBuggy;
 
1981
      } catch(e) {
 
1982
        return true;
 
1983
      }
 
1984
    })();
 
1985
 
 
1986
    var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
 
1987
     TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
 
1988
 
 
1989
    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
 
1990
      var s = document.createElement("script"),
 
1991
          isBuggy = false;
 
1992
      try {
 
1993
        s.appendChild(document.createTextNode(""));
 
1994
        isBuggy = !s.firstChild ||
 
1995
          s.firstChild && s.firstChild.nodeType !== 3;
 
1996
      } catch (e) {
 
1997
        isBuggy = true;
 
1998
      }
 
1999
      s = null;
 
2000
      return isBuggy;
 
2001
    })();
 
2002
 
 
2003
 
 
2004
    function update(element, content) {
 
2005
      element = $(element);
 
2006
      var purgeElement = Element._purgeElement;
 
2007
 
 
2008
      var descendants = element.getElementsByTagName('*'),
 
2009
       i = descendants.length;
 
2010
      while (i--) purgeElement(descendants[i]);
 
2011
 
 
2012
      if (content && content.toElement)
 
2013
        content = content.toElement();
 
2014
 
 
2015
      if (Object.isElement(content))
 
2016
        return element.update().insert(content);
 
2017
 
 
2018
      content = Object.toHTML(content);
 
2019
 
 
2020
      var tagName = element.tagName.toUpperCase();
 
2021
 
 
2022
      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
 
2023
        element.text = content;
 
2024
        return element;
 
2025
      }
 
2026
 
 
2027
      if (ANY_INNERHTML_BUGGY) {
 
2028
        if (tagName in Element._insertionTranslations.tags) {
 
2029
          while (element.firstChild) {
 
2030
            element.removeChild(element.firstChild);
 
2031
          }
 
2032
          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
 
2033
            .each(function(node) {
 
2034
              element.appendChild(node)
 
2035
            });
 
2036
        } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
 
2037
          while (element.firstChild) {
 
2038
            element.removeChild(element.firstChild);
 
2039
          }
 
2040
          var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
 
2041
          nodes.each(function(node) { element.appendChild(node) });
 
2042
        }
 
2043
        else {
 
2044
          element.innerHTML = content.stripScripts();
 
2045
        }
 
2046
      }
 
2047
      else {
 
2048
        element.innerHTML = content.stripScripts();
 
2049
      }
 
2050
 
 
2051
      content.evalScripts.bind(content).defer();
 
2052
      return element;
 
2053
    }
 
2054
 
 
2055
    return update;
 
2056
  })(),
1589
2057
 
1590
2058
  replace: function(element, content) {
1591
2059
    element = $(element);
1610
2078
 
1611
2079
    var content, insert, tagName, childNodes;
1612
2080
 
1613
 
    for (position in insertions) {
 
2081
    for (var position in insertions) {
1614
2082
      content  = insertions[position];
1615
2083
      position = position.toLowerCase();
1616
2084
      insert = Element._insertionTranslations[position];
1653
2121
    element = $(element);
1654
2122
    var result = '<' + element.tagName.toLowerCase();
1655
2123
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
1656
 
      var property = pair.first(), attribute = pair.last();
1657
 
      var value = (element[property] || '').toString();
 
2124
      var property = pair.first(),
 
2125
          attribute = pair.last(),
 
2126
          value = (element[property] || '').toString();
1658
2127
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
1659
2128
    });
1660
2129
    return result + '>';
1661
2130
  },
1662
2131
 
1663
 
  recursivelyCollect: function(element, property) {
 
2132
  recursivelyCollect: function(element, property, maximumLength) {
1664
2133
    element = $(element);
 
2134
    maximumLength = maximumLength || -1;
1665
2135
    var elements = [];
1666
 
    while (element = element[property])
 
2136
 
 
2137
    while (element = element[property]) {
1667
2138
      if (element.nodeType == 1)
1668
2139
        elements.push(Element.extend(element));
 
2140
      if (elements.length == maximumLength)
 
2141
        break;
 
2142
    }
 
2143
 
1669
2144
    return elements;
1670
2145
  },
1671
2146
 
1672
2147
  ancestors: function(element) {
1673
 
    return $(element).recursivelyCollect('parentNode');
 
2148
    return Element.recursivelyCollect(element, 'parentNode');
1674
2149
  },
1675
2150
 
1676
2151
  descendants: function(element) {
1677
 
    return $(element).getElementsBySelector("*");
 
2152
    return Element.select(element, "*");
1678
2153
  },
1679
2154
 
1680
2155
  firstDescendant: function(element) {
1684
2159
  },
1685
2160
 
1686
2161
  immediateDescendants: function(element) {
1687
 
    if (!(element = $(element).firstChild)) return [];
1688
 
    while (element && element.nodeType != 1) element = element.nextSibling;
1689
 
    if (element) return [element].concat($(element).nextSiblings());
1690
 
    return [];
 
2162
    var results = [], child = $(element).firstChild;
 
2163
    while (child) {
 
2164
      if (child.nodeType === 1) {
 
2165
        results.push(Element.extend(child));
 
2166
      }
 
2167
      child = child.nextSibling;
 
2168
    }
 
2169
    return results;
1691
2170
  },
1692
2171
 
1693
 
  previousSiblings: function(element) {
1694
 
    return $(element).recursivelyCollect('previousSibling');
 
2172
  previousSiblings: function(element, maximumLength) {
 
2173
    return Element.recursivelyCollect(element, 'previousSibling');
1695
2174
  },
1696
2175
 
1697
2176
  nextSiblings: function(element) {
1698
 
    return $(element).recursivelyCollect('nextSibling');
 
2177
    return Element.recursivelyCollect(element, 'nextSibling');
1699
2178
  },
1700
2179
 
1701
2180
  siblings: function(element) {
1702
2181
    element = $(element);
1703
 
    return element.previousSiblings().reverse().concat(element.nextSiblings());
 
2182
    return Element.previousSiblings(element).reverse()
 
2183
      .concat(Element.nextSiblings(element));
1704
2184
  },
1705
2185
 
1706
2186
  match: function(element, selector) {
 
2187
    element = $(element);
1707
2188
    if (Object.isString(selector))
1708
 
      selector = new Selector(selector);
1709
 
    return selector.match($(element));
 
2189
      return Prototype.Selector.match(element, selector);
 
2190
    return selector.match(element);
1710
2191
  },
1711
2192
 
1712
2193
  up: function(element, expression, index) {
1713
2194
    element = $(element);
1714
2195
    if (arguments.length == 1) return $(element.parentNode);
1715
 
    var ancestors = element.ancestors();
 
2196
    var ancestors = Element.ancestors(element);
1716
2197
    return Object.isNumber(expression) ? ancestors[expression] :
1717
 
      Selector.findElement(ancestors, expression, index);
 
2198
      Prototype.Selector.find(ancestors, expression, index);
1718
2199
  },
1719
2200
 
1720
2201
  down: function(element, expression, index) {
1721
2202
    element = $(element);
1722
 
    if (arguments.length == 1) return element.firstDescendant();
1723
 
    return Object.isNumber(expression) ? element.descendants()[expression] :
1724
 
      element.select(expression)[index || 0];
 
2203
    if (arguments.length == 1) return Element.firstDescendant(element);
 
2204
    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
 
2205
      Element.select(element, expression)[index || 0];
1725
2206
  },
1726
2207
 
1727
2208
  previous: function(element, expression, index) {
1728
2209
    element = $(element);
1729
 
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
1730
 
    var previousSiblings = element.previousSiblings();
1731
 
    return Object.isNumber(expression) ? previousSiblings[expression] :
1732
 
      Selector.findElement(previousSiblings, expression, index);
 
2210
    if (Object.isNumber(expression)) index = expression, expression = false;
 
2211
    if (!Object.isNumber(index)) index = 0;
 
2212
 
 
2213
    if (expression) {
 
2214
      return Prototype.Selector.find(element.previousSiblings(), expression, index);
 
2215
    } else {
 
2216
      return element.recursivelyCollect("previousSibling", index + 1)[index];
 
2217
    }
1733
2218
  },
1734
2219
 
1735
2220
  next: function(element, expression, index) {
1736
2221
    element = $(element);
1737
 
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
1738
 
    var nextSiblings = element.nextSiblings();
1739
 
    return Object.isNumber(expression) ? nextSiblings[expression] :
1740
 
      Selector.findElement(nextSiblings, expression, index);
1741
 
  },
1742
 
 
1743
 
  select: function() {
1744
 
    var args = $A(arguments), element = $(args.shift());
1745
 
    return Selector.findChildElements(element, args);
1746
 
  },
1747
 
 
1748
 
  adjacent: function() {
1749
 
    var args = $A(arguments), element = $(args.shift());
1750
 
    return Selector.findChildElements(element.parentNode, args).without(element);
 
2222
    if (Object.isNumber(expression)) index = expression, expression = false;
 
2223
    if (!Object.isNumber(index)) index = 0;
 
2224
 
 
2225
    if (expression) {
 
2226
      return Prototype.Selector.find(element.nextSiblings(), expression, index);
 
2227
    } else {
 
2228
      var maximumLength = Object.isNumber(index) ? index + 1 : 1;
 
2229
      return element.recursivelyCollect("nextSibling", index + 1)[index];
 
2230
    }
 
2231
  },
 
2232
 
 
2233
 
 
2234
  select: function(element) {
 
2235
    element = $(element);
 
2236
    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
 
2237
    return Prototype.Selector.select(expressions, element);
 
2238
  },
 
2239
 
 
2240
  adjacent: function(element) {
 
2241
    element = $(element);
 
2242
    var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
 
2243
    return Prototype.Selector.select(expressions, element.parentNode).without(element);
1751
2244
  },
1752
2245
 
1753
2246
  identify: function(element) {
1754
2247
    element = $(element);
1755
 
    var id = element.readAttribute('id'), self = arguments.callee;
 
2248
    var id = Element.readAttribute(element, 'id');
1756
2249
    if (id) return id;
1757
 
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
1758
 
    element.writeAttribute('id', id);
 
2250
    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
 
2251
    Element.writeAttribute(element, 'id', id);
1759
2252
    return id;
1760
2253
  },
1761
2254
 
1794
2287
  },
1795
2288
 
1796
2289
  getHeight: function(element) {
1797
 
    return $(element).getDimensions().height;
 
2290
    return Element.getDimensions(element).height;
1798
2291
  },
1799
2292
 
1800
2293
  getWidth: function(element) {
1801
 
    return $(element).getDimensions().width;
 
2294
    return Element.getDimensions(element).width;
1802
2295
  },
1803
2296
 
1804
2297
  classNames: function(element) {
1814
2307
 
1815
2308
  addClassName: function(element, className) {
1816
2309
    if (!(element = $(element))) return;
1817
 
    if (!element.hasClassName(className))
 
2310
    if (!Element.hasClassName(element, className))
1818
2311
      element.className += (element.className ? ' ' : '') + className;
1819
2312
    return element;
1820
2313
  },
1828
2321
 
1829
2322
  toggleClassName: function(element, className) {
1830
2323
    if (!(element = $(element))) return;
1831
 
    return element[element.hasClassName(className) ?
1832
 
      'removeClassName' : 'addClassName'](className);
 
2324
    return Element[Element.hasClassName(element, className) ?
 
2325
      'removeClassName' : 'addClassName'](element, className);
1833
2326
  },
1834
2327
 
1835
 
  // removes whitespace-only text node children
1836
2328
  cleanWhitespace: function(element) {
1837
2329
    element = $(element);
1838
2330
    var node = element.firstChild;
1851
2343
 
1852
2344
  descendantOf: function(element, ancestor) {
1853
2345
    element = $(element), ancestor = $(ancestor);
1854
 
    var originalAncestor = ancestor;
1855
2346
 
1856
2347
    if (element.compareDocumentPosition)
1857
2348
      return (element.compareDocumentPosition(ancestor) & 8) === 8;
1858
2349
 
1859
 
    if (element.sourceIndex && !Prototype.Browser.Opera) {
1860
 
      var e = element.sourceIndex, a = ancestor.sourceIndex,
1861
 
       nextAncestor = ancestor.nextSibling;
1862
 
      if (!nextAncestor) {
1863
 
        do { ancestor = ancestor.parentNode; }
1864
 
        while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
1865
 
      }
1866
 
      if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
1867
 
    }
 
2350
    if (ancestor.contains)
 
2351
      return ancestor.contains(element) && ancestor !== element;
1868
2352
 
1869
2353
    while (element = element.parentNode)
1870
 
      if (element == originalAncestor) return true;
 
2354
      if (element == ancestor) return true;
 
2355
 
1871
2356
    return false;
1872
2357
  },
1873
2358
 
1874
2359
  scrollTo: function(element) {
1875
2360
    element = $(element);
1876
 
    var pos = element.cumulativeOffset();
 
2361
    var pos = Element.cumulativeOffset(element);
1877
2362
    window.scrollTo(pos[0], pos[1]);
1878
2363
    return element;
1879
2364
  },
1882
2367
    element = $(element);
1883
2368
    style = style == 'float' ? 'cssFloat' : style.camelize();
1884
2369
    var value = element.style[style];
1885
 
    if (!value) {
 
2370
    if (!value || value == 'auto') {
1886
2371
      var css = document.defaultView.getComputedStyle(element, null);
1887
2372
      value = css ? css[style] : null;
1888
2373
    }
1919
2404
    return element;
1920
2405
  },
1921
2406
 
1922
 
  getDimensions: function(element) {
1923
 
    element = $(element);
1924
 
    var display = $(element).getStyle('display');
1925
 
    if (display != 'none' && display != null) // Safari bug
1926
 
      return {width: element.offsetWidth, height: element.offsetHeight};
1927
 
 
1928
 
    // All *Width and *Height properties give 0 on elements with display none,
1929
 
    // so enable the element temporarily
1930
 
    var els = element.style;
1931
 
    var originalVisibility = els.visibility;
1932
 
    var originalPosition = els.position;
1933
 
    var originalDisplay = els.display;
1934
 
    els.visibility = 'hidden';
1935
 
    els.position = 'absolute';
1936
 
    els.display = 'block';
1937
 
    var originalWidth = element.clientWidth;
1938
 
    var originalHeight = element.clientHeight;
1939
 
    els.display = originalDisplay;
1940
 
    els.position = originalPosition;
1941
 
    els.visibility = originalVisibility;
1942
 
    return {width: originalWidth, height: originalHeight};
1943
 
  },
1944
 
 
1945
2407
  makePositioned: function(element) {
1946
2408
    element = $(element);
1947
2409
    var pos = Element.getStyle(element, 'position');
1948
2410
    if (pos == 'static' || !pos) {
1949
2411
      element._madePositioned = true;
1950
2412
      element.style.position = 'relative';
1951
 
      // Opera returns the offset relative to the positioning context, when an
1952
 
      // element is position relative but top and left have not been defined
1953
 
      if (window.opera) {
 
2413
      if (Prototype.Browser.Opera) {
1954
2414
        element.style.top = 0;
1955
2415
        element.style.left = 0;
1956
2416
      }
1988
2448
    return element;
1989
2449
  },
1990
2450
 
1991
 
  cumulativeOffset: function(element) {
1992
 
    var valueT = 0, valueL = 0;
1993
 
    do {
1994
 
      valueT += element.offsetTop  || 0;
1995
 
      valueL += element.offsetLeft || 0;
1996
 
      element = element.offsetParent;
1997
 
    } while (element);
1998
 
    return Element._returnOffset(valueL, valueT);
1999
 
  },
2000
 
 
2001
 
  positionedOffset: function(element) {
2002
 
    var valueT = 0, valueL = 0;
2003
 
    do {
2004
 
      valueT += element.offsetTop  || 0;
2005
 
      valueL += element.offsetLeft || 0;
2006
 
      element = element.offsetParent;
2007
 
      if (element) {
2008
 
        if (element.tagName == 'BODY') break;
2009
 
        var p = Element.getStyle(element, 'position');
2010
 
        if (p == 'relative' || p == 'absolute') break;
2011
 
      }
2012
 
    } while (element);
2013
 
    return Element._returnOffset(valueL, valueT);
2014
 
  },
2015
 
 
2016
 
  absolutize: function(element) {
2017
 
    element = $(element);
2018
 
    if (element.getStyle('position') == 'absolute') return;
2019
 
    // Position.prepare(); // To be done manually by Scripty when it needs it.
2020
 
 
2021
 
    var offsets = element.positionedOffset();
2022
 
    var top     = offsets[1];
2023
 
    var left    = offsets[0];
2024
 
    var width   = element.clientWidth;
2025
 
    var height  = element.clientHeight;
2026
 
 
2027
 
    element._originalLeft   = left - parseFloat(element.style.left  || 0);
2028
 
    element._originalTop    = top  - parseFloat(element.style.top || 0);
2029
 
    element._originalWidth  = element.style.width;
2030
 
    element._originalHeight = element.style.height;
2031
 
 
2032
 
    element.style.position = 'absolute';
2033
 
    element.style.top    = top + 'px';
2034
 
    element.style.left   = left + 'px';
2035
 
    element.style.width  = width + 'px';
2036
 
    element.style.height = height + 'px';
2037
 
    return element;
2038
 
  },
2039
 
 
2040
 
  relativize: function(element) {
2041
 
    element = $(element);
2042
 
    if (element.getStyle('position') == 'relative') return;
2043
 
    // Position.prepare(); // To be done manually by Scripty when it needs it.
2044
 
 
2045
 
    element.style.position = 'relative';
2046
 
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
2047
 
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
2048
 
 
2049
 
    element.style.top    = top + 'px';
2050
 
    element.style.left   = left + 'px';
2051
 
    element.style.height = element._originalHeight;
2052
 
    element.style.width  = element._originalWidth;
2053
 
    return element;
2054
 
  },
2055
 
 
2056
 
  cumulativeScrollOffset: function(element) {
2057
 
    var valueT = 0, valueL = 0;
2058
 
    do {
2059
 
      valueT += element.scrollTop  || 0;
2060
 
      valueL += element.scrollLeft || 0;
2061
 
      element = element.parentNode;
2062
 
    } while (element);
2063
 
    return Element._returnOffset(valueL, valueT);
2064
 
  },
2065
 
 
2066
 
  getOffsetParent: function(element) {
2067
 
    if (element.offsetParent) return $(element.offsetParent);
2068
 
    if (element == document.body) return $(element);
2069
 
 
2070
 
    while ((element = element.parentNode) && element != document.body)
2071
 
      if (Element.getStyle(element, 'position') != 'static')
2072
 
        return $(element);
2073
 
 
2074
 
    return $(document.body);
2075
 
  },
2076
 
 
2077
 
  viewportOffset: function(forElement) {
2078
 
    var valueT = 0, valueL = 0;
2079
 
 
2080
 
    var element = forElement;
2081
 
    do {
2082
 
      valueT += element.offsetTop  || 0;
2083
 
      valueL += element.offsetLeft || 0;
2084
 
 
2085
 
      // Safari fix
2086
 
      if (element.offsetParent == document.body &&
2087
 
        Element.getStyle(element, 'position') == 'absolute') break;
2088
 
 
2089
 
    } while (element = element.offsetParent);
2090
 
 
2091
 
    element = forElement;
2092
 
    do {
2093
 
      if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
2094
 
        valueT -= element.scrollTop  || 0;
2095
 
        valueL -= element.scrollLeft || 0;
2096
 
      }
2097
 
    } while (element = element.parentNode);
2098
 
 
2099
 
    return Element._returnOffset(valueL, valueT);
2100
 
  },
2101
 
 
2102
2451
  clonePosition: function(element, source) {
2103
2452
    var options = Object.extend({
2104
2453
      setLeft:    true,
2109
2458
      offsetLeft: 0
2110
2459
    }, arguments[2] || { });
2111
2460
 
2112
 
    // find page position of source
2113
2461
    source = $(source);
2114
 
    var p = source.viewportOffset();
 
2462
    var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
2115
2463
 
2116
 
    // find coordinate system to use
2117
2464
    element = $(element);
2118
 
    var delta = [0, 0];
2119
 
    var parent = null;
2120
 
    // delta [0,0] will do fine with position: fixed elements,
2121
 
    // position:absolute needs offsetParent deltas
 
2465
 
2122
2466
    if (Element.getStyle(element, 'position') == 'absolute') {
2123
 
      parent = element.getOffsetParent();
2124
 
      delta = parent.viewportOffset();
 
2467
      parent = Element.getOffsetParent(element);
 
2468
      delta = Element.viewportOffset(parent);
2125
2469
    }
2126
2470
 
2127
 
    // correct by body offsets (fixes Safari)
2128
2471
    if (parent == document.body) {
2129
2472
      delta[0] -= document.body.offsetLeft;
2130
2473
      delta[1] -= document.body.offsetTop;
2131
2474
    }
2132
2475
 
2133
 
    // set position
2134
2476
    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
2135
2477
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
2136
2478
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
2139
2481
  }
2140
2482
};
2141
2483
 
2142
 
Element.Methods.identify.counter = 1;
2143
 
 
2144
2484
Object.extend(Element.Methods, {
2145
2485
  getElementsBySelector: Element.Methods.select,
 
2486
 
2146
2487
  childElements: Element.Methods.immediateDescendants
2147
2488
});
2148
2489
 
2160
2501
  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
2161
2502
    function(proceed, element, style) {
2162
2503
      switch (style) {
2163
 
        case 'left': case 'top': case 'right': case 'bottom':
2164
 
          if (proceed(element, 'position') === 'static') return null;
2165
2504
        case 'height': case 'width':
2166
 
          // returns '0px' for hidden elements; we want it to return null
2167
2505
          if (!Element.visible(element)) return null;
2168
2506
 
2169
 
          // returns the border-box dimensions rather than the content-box
2170
 
          // dimensions, so we subtract padding and borders from the value
2171
2507
          var dim = parseInt(proceed(element, style), 10);
2172
2508
 
2173
2509
          if (dim !== element['offset' + style.capitalize()])
2200
2536
}
2201
2537
 
2202
2538
else if (Prototype.Browser.IE) {
2203
 
  $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
2204
 
    Element.Methods[method] = Element.Methods[method].wrap(
2205
 
      function(proceed, element) {
2206
 
        element = $(element);
2207
 
        var position = element.getStyle('position');
2208
 
        if (position != 'static') return proceed(element);
2209
 
        element.setStyle({ position: 'relative' });
2210
 
        var value = proceed(element);
2211
 
        element.setStyle({ position: position });
2212
 
        return value;
2213
 
      }
2214
 
    );
2215
 
  });
2216
 
 
2217
2539
  Element.Methods.getStyle = function(element, style) {
2218
2540
    element = $(element);
2219
2541
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
2255
2577
    return element;
2256
2578
  };
2257
2579
 
2258
 
  Element._attributeTranslations = {
2259
 
    read: {
2260
 
      names: {
2261
 
        'class': 'className',
2262
 
        'for':   'htmlFor'
2263
 
      },
2264
 
      values: {
2265
 
        _getAttr: function(element, attribute) {
2266
 
          return element.getAttribute(attribute, 2);
2267
 
        },
2268
 
        _getAttrNode: function(element, attribute) {
2269
 
          var node = element.getAttributeNode(attribute);
2270
 
          return node ? node.value : "";
2271
 
        },
2272
 
        _getEv: function(element, attribute) {
2273
 
          attribute = element.getAttribute(attribute);
2274
 
          return attribute ? attribute.toString().slice(23, -2) : null;
2275
 
        },
2276
 
        _flag: function(element, attribute) {
2277
 
          return $(element).hasAttribute(attribute) ? attribute : null;
2278
 
        },
2279
 
        style: function(element) {
2280
 
          return element.style.cssText.toLowerCase();
2281
 
        },
2282
 
        title: function(element) {
2283
 
          return element.title;
 
2580
  Element._attributeTranslations = (function(){
 
2581
 
 
2582
    var classProp = 'className',
 
2583
        forProp = 'for',
 
2584
        el = document.createElement('div');
 
2585
 
 
2586
    el.setAttribute(classProp, 'x');
 
2587
 
 
2588
    if (el.className !== 'x') {
 
2589
      el.setAttribute('class', 'x');
 
2590
      if (el.className === 'x') {
 
2591
        classProp = 'class';
 
2592
      }
 
2593
    }
 
2594
    el = null;
 
2595
 
 
2596
    el = document.createElement('label');
 
2597
    el.setAttribute(forProp, 'x');
 
2598
    if (el.htmlFor !== 'x') {
 
2599
      el.setAttribute('htmlFor', 'x');
 
2600
      if (el.htmlFor === 'x') {
 
2601
        forProp = 'htmlFor';
 
2602
      }
 
2603
    }
 
2604
    el = null;
 
2605
 
 
2606
    return {
 
2607
      read: {
 
2608
        names: {
 
2609
          'class':      classProp,
 
2610
          'className':  classProp,
 
2611
          'for':        forProp,
 
2612
          'htmlFor':    forProp
 
2613
        },
 
2614
        values: {
 
2615
          _getAttr: function(element, attribute) {
 
2616
            return element.getAttribute(attribute);
 
2617
          },
 
2618
          _getAttr2: function(element, attribute) {
 
2619
            return element.getAttribute(attribute, 2);
 
2620
          },
 
2621
          _getAttrNode: function(element, attribute) {
 
2622
            var node = element.getAttributeNode(attribute);
 
2623
            return node ? node.value : "";
 
2624
          },
 
2625
          _getEv: (function(){
 
2626
 
 
2627
            var el = document.createElement('div'), f;
 
2628
            el.onclick = Prototype.emptyFunction;
 
2629
            var value = el.getAttribute('onclick');
 
2630
 
 
2631
            if (String(value).indexOf('{') > -1) {
 
2632
              f = function(element, attribute) {
 
2633
                attribute = element.getAttribute(attribute);
 
2634
                if (!attribute) return null;
 
2635
                attribute = attribute.toString();
 
2636
                attribute = attribute.split('{')[1];
 
2637
                attribute = attribute.split('}')[0];
 
2638
                return attribute.strip();
 
2639
              };
 
2640
            }
 
2641
            else if (value === '') {
 
2642
              f = function(element, attribute) {
 
2643
                attribute = element.getAttribute(attribute);
 
2644
                if (!attribute) return null;
 
2645
                return attribute.strip();
 
2646
              };
 
2647
            }
 
2648
            el = null;
 
2649
            return f;
 
2650
          })(),
 
2651
          _flag: function(element, attribute) {
 
2652
            return $(element).hasAttribute(attribute) ? attribute : null;
 
2653
          },
 
2654
          style: function(element) {
 
2655
            return element.style.cssText.toLowerCase();
 
2656
          },
 
2657
          title: function(element) {
 
2658
            return element.title;
 
2659
          }
2284
2660
        }
2285
2661
      }
2286
2662
    }
2287
 
  };
 
2663
  })();
2288
2664
 
2289
2665
  Element._attributeTranslations.write = {
2290
 
    names: Object.clone(Element._attributeTranslations.read.names),
 
2666
    names: Object.extend({
 
2667
      cellpadding: 'cellPadding',
 
2668
      cellspacing: 'cellSpacing'
 
2669
    }, Element._attributeTranslations.read.names),
2291
2670
    values: {
2292
2671
      checked: function(element, value) {
2293
2672
        element.checked = !!value;
2302
2681
  Element._attributeTranslations.has = {};
2303
2682
 
2304
2683
  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
2305
 
      'encType maxLength readOnly longDesc').each(function(attr) {
 
2684
      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
2306
2685
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
2307
2686
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
2308
2687
  });
2309
2688
 
2310
2689
  (function(v) {
2311
2690
    Object.extend(v, {
2312
 
      href:        v._getAttr,
2313
 
      src:         v._getAttr,
 
2691
      href:        v._getAttr2,
 
2692
      src:         v._getAttr2,
2314
2693
      type:        v._getAttr,
2315
2694
      action:      v._getAttrNode,
2316
2695
      disabled:    v._flag,
2337
2716
      onchange:    v._getEv
2338
2717
    });
2339
2718
  })(Element._attributeTranslations.read.values);
 
2719
 
 
2720
  if (Prototype.BrowserFeatures.ElementExtensions) {
 
2721
    (function() {
 
2722
      function _descendants(element) {
 
2723
        var nodes = element.getElementsByTagName('*'), results = [];
 
2724
        for (var i = 0, node; node = nodes[i]; i++)
 
2725
          if (node.tagName !== "!") // Filter out comment nodes.
 
2726
            results.push(node);
 
2727
        return results;
 
2728
      }
 
2729
 
 
2730
      Element.Methods.down = function(element, expression, index) {
 
2731
        element = $(element);
 
2732
        if (arguments.length == 1) return element.firstDescendant();
 
2733
        return Object.isNumber(expression) ? _descendants(element)[expression] :
 
2734
          Element.select(element, expression)[index || 0];
 
2735
      }
 
2736
    })();
 
2737
  }
 
2738
 
2340
2739
}
2341
2740
 
2342
2741
else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
2355
2754
      (value < 0.00001) ? 0 : value;
2356
2755
 
2357
2756
    if (value == 1)
2358
 
      if(element.tagName == 'IMG' && element.width) {
 
2757
      if (element.tagName.toUpperCase() == 'IMG' && element.width) {
2359
2758
        element.width++; element.width--;
2360
2759
      } else try {
2361
2760
        var n = document.createTextNode(' ');
2365
2764
 
2366
2765
    return element;
2367
2766
  };
2368
 
 
2369
 
  // Safari returns margins on body which is incorrect if the child is absolutely
2370
 
  // positioned.  For performance reasons, redefine Element#cumulativeOffset for
2371
 
  // KHTML/WebKit only.
2372
 
  Element.Methods.cumulativeOffset = function(element) {
2373
 
    var valueT = 0, valueL = 0;
2374
 
    do {
2375
 
      valueT += element.offsetTop  || 0;
2376
 
      valueL += element.offsetLeft || 0;
2377
 
      if (element.offsetParent == document.body)
2378
 
        if (Element.getStyle(element, 'position') == 'absolute') break;
2379
 
 
2380
 
      element = element.offsetParent;
2381
 
    } while (element);
2382
 
 
2383
 
    return Element._returnOffset(valueL, valueT);
2384
 
  };
2385
 
}
2386
 
 
2387
 
if (Prototype.Browser.IE || Prototype.Browser.Opera) {
2388
 
  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
2389
 
  Element.Methods.update = function(element, content) {
2390
 
    element = $(element);
2391
 
 
2392
 
    if (content && content.toElement) content = content.toElement();
2393
 
    if (Object.isElement(content)) return element.update().insert(content);
2394
 
 
2395
 
    content = Object.toHTML(content);
2396
 
    var tagName = element.tagName.toUpperCase();
2397
 
 
2398
 
    if (tagName in Element._insertionTranslations.tags) {
2399
 
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
2400
 
      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
2401
 
        .each(function(node) { element.appendChild(node) });
2402
 
    }
2403
 
    else element.innerHTML = content.stripScripts();
2404
 
 
2405
 
    content.evalScripts.bind(content).defer();
2406
 
    return element;
2407
 
  };
2408
 
}
2409
 
 
2410
 
if (document.createElement('div').outerHTML) {
 
2767
}
 
2768
 
 
2769
if ('outerHTML' in document.documentElement) {
2411
2770
  Element.Methods.replace = function(element, content) {
2412
2771
    element = $(element);
2413
2772
 
2421
2780
    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2422
2781
 
2423
2782
    if (Element._insertionTranslations.tags[tagName]) {
2424
 
      var nextSibling = element.next();
2425
 
      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
 
2783
      var nextSibling = element.next(),
 
2784
          fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2426
2785
      parent.removeChild(element);
2427
2786
      if (nextSibling)
2428
2787
        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
2443
2802
  return result;
2444
2803
};
2445
2804
 
2446
 
Element._getContentFromAnonymousElement = function(tagName, html) {
2447
 
  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
2448
 
  if (t) {
2449
 
    div.innerHTML = t[0] + html + t[1];
2450
 
    t[2].times(function() { div = div.firstChild });
2451
 
  } else div.innerHTML = html;
 
2805
Element._getContentFromAnonymousElement = function(tagName, html, force) {
 
2806
  var div = new Element('div'),
 
2807
      t = Element._insertionTranslations.tags[tagName];
 
2808
 
 
2809
  var workaround = false;
 
2810
  if (t) workaround = true;
 
2811
  else if (force) {
 
2812
    workaround = true;
 
2813
    t = ['', '', 0];
 
2814
  }
 
2815
 
 
2816
  if (workaround) {
 
2817
    div.innerHTML = '&nbsp;' + t[0] + html + t[1];
 
2818
    div.removeChild(div.firstChild);
 
2819
    for (var i = t[2]; i--; ) {
 
2820
      div = div.firstChild;
 
2821
    }
 
2822
  }
 
2823
  else {
 
2824
    div.innerHTML = html;
 
2825
  }
2452
2826
  return $A(div.childNodes);
2453
2827
};
2454
2828
 
2475
2849
};
2476
2850
 
2477
2851
(function() {
2478
 
  Object.extend(this.tags, {
2479
 
    THEAD: this.tags.TBODY,
2480
 
    TFOOT: this.tags.TBODY,
2481
 
    TH:    this.tags.TD
 
2852
  var tags = Element._insertionTranslations.tags;
 
2853
  Object.extend(tags, {
 
2854
    THEAD: tags.TBODY,
 
2855
    TFOOT: tags.TBODY,
 
2856
    TH:    tags.TD
2482
2857
  });
2483
 
}).call(Element._insertionTranslations);
 
2858
})();
2484
2859
 
2485
2860
Element.Methods.Simulated = {
2486
2861
  hasAttribute: function(element, attribute) {
2487
2862
    attribute = Element._attributeTranslations.has[attribute] || attribute;
2488
2863
    var node = $(element).getAttributeNode(attribute);
2489
 
    return node && node.specified;
 
2864
    return !!(node && node.specified);
2490
2865
  }
2491
2866
};
2492
2867
 
2494
2869
 
2495
2870
Object.extend(Element, Element.Methods);
2496
2871
 
2497
 
if (!Prototype.BrowserFeatures.ElementExtensions &&
2498
 
    document.createElement('div').__proto__) {
2499
 
  window.HTMLElement = { };
2500
 
  window.HTMLElement.prototype = document.createElement('div').__proto__;
2501
 
  Prototype.BrowserFeatures.ElementExtensions = true;
2502
 
}
 
2872
(function(div) {
 
2873
 
 
2874
  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
 
2875
    window.HTMLElement = { };
 
2876
    window.HTMLElement.prototype = div['__proto__'];
 
2877
    Prototype.BrowserFeatures.ElementExtensions = true;
 
2878
  }
 
2879
 
 
2880
  div = null;
 
2881
 
 
2882
})(document.createElement('div'));
2503
2883
 
2504
2884
Element.extend = (function() {
2505
 
  if (Prototype.BrowserFeatures.SpecificElementExtensions)
 
2885
 
 
2886
  function checkDeficiency(tagName) {
 
2887
    if (typeof window.Element != 'undefined') {
 
2888
      var proto = window.Element.prototype;
 
2889
      if (proto) {
 
2890
        var id = '_' + (Math.random()+'').slice(2),
 
2891
            el = document.createElement(tagName);
 
2892
        proto[id] = 'x';
 
2893
        var isBuggy = (el[id] !== 'x');
 
2894
        delete proto[id];
 
2895
        el = null;
 
2896
        return isBuggy;
 
2897
      }
 
2898
    }
 
2899
    return false;
 
2900
  }
 
2901
 
 
2902
  function extendElementWith(element, methods) {
 
2903
    for (var property in methods) {
 
2904
      var value = methods[property];
 
2905
      if (Object.isFunction(value) && !(property in element))
 
2906
        element[property] = value.methodize();
 
2907
    }
 
2908
  }
 
2909
 
 
2910
  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
 
2911
 
 
2912
  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
 
2913
    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
 
2914
      return function(element) {
 
2915
        if (element && typeof element._extendedByPrototype == 'undefined') {
 
2916
          var t = element.tagName;
 
2917
          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
 
2918
            extendElementWith(element, Element.Methods);
 
2919
            extendElementWith(element, Element.Methods.Simulated);
 
2920
            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
 
2921
          }
 
2922
        }
 
2923
        return element;
 
2924
      }
 
2925
    }
2506
2926
    return Prototype.K;
 
2927
  }
2507
2928
 
2508
2929
  var Methods = { }, ByTag = Element.Methods.ByTag;
2509
2930
 
2510
2931
  var extend = Object.extend(function(element) {
2511
 
    if (!element || element._extendedByPrototype ||
 
2932
    if (!element || typeof element._extendedByPrototype != 'undefined' ||
2512
2933
        element.nodeType != 1 || element == window) return element;
2513
2934
 
2514
2935
    var methods = Object.clone(Methods),
2515
 
      tagName = element.tagName, property, value;
 
2936
        tagName = element.tagName.toUpperCase();
2516
2937
 
2517
 
    // extend methods for specific tags
2518
2938
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
2519
2939
 
2520
 
    for (property in methods) {
2521
 
      value = methods[property];
2522
 
      if (Object.isFunction(value) && !(property in element))
2523
 
        element[property] = value.methodize();
2524
 
    }
 
2940
    extendElementWith(element, methods);
2525
2941
 
2526
2942
    element._extendedByPrototype = Prototype.emptyFunction;
2527
2943
    return element;
2528
2944
 
2529
2945
  }, {
2530
2946
    refresh: function() {
2531
 
      // extend methods for all tags (Safari doesn't need this)
2532
2947
      if (!Prototype.BrowserFeatures.ElementExtensions) {
2533
2948
        Object.extend(Methods, Element.Methods);
2534
2949
        Object.extend(Methods, Element.Methods.Simulated);
2540
2955
  return extend;
2541
2956
})();
2542
2957
 
2543
 
Element.hasAttribute = function(element, attribute) {
2544
 
  if (element.hasAttribute) return element.hasAttribute(attribute);
2545
 
  return Element.Methods.Simulated.hasAttribute(element, attribute);
2546
 
};
 
2958
if (document.documentElement.hasAttribute) {
 
2959
  Element.hasAttribute = function(element, attribute) {
 
2960
    return element.hasAttribute(attribute);
 
2961
  };
 
2962
}
 
2963
else {
 
2964
  Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
 
2965
}
2547
2966
 
2548
2967
Element.addMethods = function(methods) {
2549
2968
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
2555
2974
      "FORM":     Object.clone(Form.Methods),
2556
2975
      "INPUT":    Object.clone(Form.Element.Methods),
2557
2976
      "SELECT":   Object.clone(Form.Element.Methods),
2558
 
      "TEXTAREA": Object.clone(Form.Element.Methods)
 
2977
      "TEXTAREA": Object.clone(Form.Element.Methods),
 
2978
      "BUTTON":   Object.clone(Form.Element.Methods)
2559
2979
    });
2560
2980
  }
2561
2981
 
2607
3027
    klass = 'HTML' + tagName.capitalize() + 'Element';
2608
3028
    if (window[klass]) return window[klass];
2609
3029
 
2610
 
    window[klass] = { };
2611
 
    window[klass].prototype = document.createElement(tagName).__proto__;
2612
 
    return window[klass];
 
3030
    var element = document.createElement(tagName),
 
3031
        proto = element['__proto__'] || element.constructor.prototype;
 
3032
 
 
3033
    element = null;
 
3034
    return proto;
2613
3035
  }
2614
3036
 
 
3037
  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
 
3038
   Element.prototype;
 
3039
 
2615
3040
  if (F.ElementExtensions) {
2616
 
    copy(Element.Methods, HTMLElement.prototype);
2617
 
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
 
3041
    copy(Element.Methods, elementPrototype);
 
3042
    copy(Element.Methods.Simulated, elementPrototype, true);
2618
3043
  }
2619
3044
 
2620
3045
  if (F.SpecificElementExtensions) {
2632
3057
  Element.cache = { };
2633
3058
};
2634
3059
 
 
3060
 
2635
3061
document.viewport = {
 
3062
 
2636
3063
  getDimensions: function() {
2637
 
    var dimensions = { };
2638
 
    var B = Prototype.Browser;
2639
 
    $w('width height').each(function(d) {
2640
 
      var D = d.capitalize();
2641
 
      dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
2642
 
        (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
2643
 
    });
2644
 
    return dimensions;
2645
 
  },
2646
 
 
2647
 
  getWidth: function() {
2648
 
    return this.getDimensions().width;
2649
 
  },
2650
 
 
2651
 
  getHeight: function() {
2652
 
    return this.getDimensions().height;
 
3064
    return { width: this.getWidth(), height: this.getHeight() };
2653
3065
  },
2654
3066
 
2655
3067
  getScrollOffsets: function() {
2656
3068
    return Element._returnOffset(
2657
3069
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
2658
 
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
2659
 
  }
2660
 
};
2661
 
/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
2662
 
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
2663
 
 * license.  Please see http://www.yui-ext.com/ for more information. */
2664
 
 
2665
 
var Selector = Class.create({
2666
 
  initialize: function(expression) {
2667
 
    this.expression = expression.strip();
2668
 
    this.compileMatcher();
2669
 
  },
2670
 
 
2671
 
  shouldUseXPath: function() {
2672
 
    if (!Prototype.BrowserFeatures.XPath) return false;
2673
 
 
2674
 
    var e = this.expression;
2675
 
 
2676
 
    // Safari 3 chokes on :*-of-type and :empty
2677
 
    if (Prototype.Browser.WebKit &&
2678
 
     (e.include("-of-type") || e.include(":empty")))
2679
 
      return false;
2680
 
 
2681
 
    // XPath can't do namespaced attributes, nor can it read
2682
 
    // the "checked" property from DOM nodes
2683
 
    if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
2684
 
      return false;
2685
 
 
 
3070
      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
 
3071
  }
 
3072
};
 
3073
 
 
3074
(function(viewport) {
 
3075
  var B = Prototype.Browser, doc = document, element, property = {};
 
3076
 
 
3077
  function getRootElement() {
 
3078
    if (B.WebKit && !doc.evaluate)
 
3079
      return document;
 
3080
 
 
3081
    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
 
3082
      return document.body;
 
3083
 
 
3084
    return document.documentElement;
 
3085
  }
 
3086
 
 
3087
  function define(D) {
 
3088
    if (!element) element = getRootElement();
 
3089
 
 
3090
    property[D] = 'client' + D;
 
3091
 
 
3092
    viewport['get' + D] = function() { return element[property[D]] };
 
3093
    return viewport['get' + D]();
 
3094
  }
 
3095
 
 
3096
  viewport.getWidth  = define.curry('Width');
 
3097
 
 
3098
  viewport.getHeight = define.curry('Height');
 
3099
})(document.viewport);
 
3100
 
 
3101
 
 
3102
Element.Storage = {
 
3103
  UID: 1
 
3104
};
 
3105
 
 
3106
Element.addMethods({
 
3107
  getStorage: function(element) {
 
3108
    if (!(element = $(element))) return;
 
3109
 
 
3110
    var uid;
 
3111
    if (element === window) {
 
3112
      uid = 0;
 
3113
    } else {
 
3114
      if (typeof element._prototypeUID === "undefined")
 
3115
        element._prototypeUID = Element.Storage.UID++;
 
3116
      uid = element._prototypeUID;
 
3117
    }
 
3118
 
 
3119
    if (!Element.Storage[uid])
 
3120
      Element.Storage[uid] = $H();
 
3121
 
 
3122
    return Element.Storage[uid];
 
3123
  },
 
3124
 
 
3125
  store: function(element, key, value) {
 
3126
    if (!(element = $(element))) return;
 
3127
 
 
3128
    if (arguments.length === 2) {
 
3129
      Element.getStorage(element).update(key);
 
3130
    } else {
 
3131
      Element.getStorage(element).set(key, value);
 
3132
    }
 
3133
 
 
3134
    return element;
 
3135
  },
 
3136
 
 
3137
  retrieve: function(element, key, defaultValue) {
 
3138
    if (!(element = $(element))) return;
 
3139
    var hash = Element.getStorage(element), value = hash.get(key);
 
3140
 
 
3141
    if (Object.isUndefined(value)) {
 
3142
      hash.set(key, defaultValue);
 
3143
      value = defaultValue;
 
3144
    }
 
3145
 
 
3146
    return value;
 
3147
  },
 
3148
 
 
3149
  clone: function(element, deep) {
 
3150
    if (!(element = $(element))) return;
 
3151
    var clone = element.cloneNode(deep);
 
3152
    clone._prototypeUID = void 0;
 
3153
    if (deep) {
 
3154
      var descendants = Element.select(clone, '*'),
 
3155
          i = descendants.length;
 
3156
      while (i--) {
 
3157
        descendants[i]._prototypeUID = void 0;
 
3158
      }
 
3159
    }
 
3160
    return Element.extend(clone);
 
3161
  },
 
3162
 
 
3163
  purge: function(element) {
 
3164
    if (!(element = $(element))) return;
 
3165
    var purgeElement = Element._purgeElement;
 
3166
 
 
3167
    purgeElement(element);
 
3168
 
 
3169
    var descendants = element.getElementsByTagName('*'),
 
3170
     i = descendants.length;
 
3171
 
 
3172
    while (i--) purgeElement(descendants[i]);
 
3173
 
 
3174
    return null;
 
3175
  }
 
3176
});
 
3177
 
 
3178
(function() {
 
3179
 
 
3180
  function toDecimal(pctString) {
 
3181
    var match = pctString.match(/^(\d+)%?$/i);
 
3182
    if (!match) return null;
 
3183
    return (Number(match[1]) / 100);
 
3184
  }
 
3185
 
 
3186
  function getPixelValue(value, property, context) {
 
3187
    var element = null;
 
3188
    if (Object.isElement(value)) {
 
3189
      element = value;
 
3190
      value = element.getStyle(property);
 
3191
    }
 
3192
 
 
3193
    if (value === null) {
 
3194
      return null;
 
3195
    }
 
3196
 
 
3197
    if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
 
3198
      return window.parseFloat(value);
 
3199
    }
 
3200
 
 
3201
    var isPercentage = value.include('%'), isViewport = (context === document.viewport);
 
3202
 
 
3203
    if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
 
3204
      var style = element.style.left, rStyle = element.runtimeStyle.left;
 
3205
      element.runtimeStyle.left = element.currentStyle.left;
 
3206
      element.style.left = value || 0;
 
3207
      value = element.style.pixelLeft;
 
3208
      element.style.left = style;
 
3209
      element.runtimeStyle.left = rStyle;
 
3210
 
 
3211
      return value;
 
3212
    }
 
3213
 
 
3214
    if (element && isPercentage) {
 
3215
      context = context || element.parentNode;
 
3216
      var decimal = toDecimal(value);
 
3217
      var whole = null;
 
3218
      var position = element.getStyle('position');
 
3219
 
 
3220
      var isHorizontal = property.include('left') || property.include('right') ||
 
3221
       property.include('width');
 
3222
 
 
3223
      var isVertical =  property.include('top') || property.include('bottom') ||
 
3224
        property.include('height');
 
3225
 
 
3226
      if (context === document.viewport) {
 
3227
        if (isHorizontal) {
 
3228
          whole = document.viewport.getWidth();
 
3229
        } else if (isVertical) {
 
3230
          whole = document.viewport.getHeight();
 
3231
        }
 
3232
      } else {
 
3233
        if (isHorizontal) {
 
3234
          whole = $(context).measure('width');
 
3235
        } else if (isVertical) {
 
3236
          whole = $(context).measure('height');
 
3237
        }
 
3238
      }
 
3239
 
 
3240
      return (whole === null) ? 0 : whole * decimal;
 
3241
    }
 
3242
 
 
3243
    return 0;
 
3244
  }
 
3245
 
 
3246
  function toCSSPixels(number) {
 
3247
    if (Object.isString(number) && number.endsWith('px')) {
 
3248
      return number;
 
3249
    }
 
3250
    return number + 'px';
 
3251
  }
 
3252
 
 
3253
  function isDisplayed(element) {
 
3254
    var originalElement = element;
 
3255
    while (element && element.parentNode) {
 
3256
      var display = element.getStyle('display');
 
3257
      if (display === 'none') {
 
3258
        return false;
 
3259
      }
 
3260
      element = $(element.parentNode);
 
3261
    }
2686
3262
    return true;
2687
 
  },
2688
 
 
2689
 
  compileMatcher: function() {
2690
 
    if (this.shouldUseXPath())
2691
 
      return this.compileXPathMatcher();
2692
 
 
2693
 
    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
2694
 
        c = Selector.criteria, le, p, m;
2695
 
 
2696
 
    if (Selector._cache[e]) {
2697
 
      this.matcher = Selector._cache[e];
2698
 
      return;
2699
 
    }
2700
 
 
2701
 
    this.matcher = ["this.matcher = function(root) {",
2702
 
                    "var r = root, h = Selector.handlers, c = false, n;"];
2703
 
 
2704
 
    while (e && le != e && (/\S/).test(e)) {
2705
 
      le = e;
2706
 
      for (var i in ps) {
2707
 
        p = ps[i];
2708
 
        if (m = e.match(p)) {
2709
 
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
2710
 
              new Template(c[i]).evaluate(m));
2711
 
          e = e.replace(m[0], '');
2712
 
          break;
2713
 
        }
2714
 
      }
2715
 
    }
2716
 
 
2717
 
    this.matcher.push("return h.unique(n);\n}");
2718
 
    eval(this.matcher.join('\n'));
2719
 
    Selector._cache[this.expression] = this.matcher;
2720
 
  },
2721
 
 
2722
 
  compileXPathMatcher: function() {
2723
 
    var e = this.expression, ps = Selector.patterns,
2724
 
        x = Selector.xpath, le, m;
2725
 
 
2726
 
    if (Selector._cache[e]) {
2727
 
      this.xpath = Selector._cache[e]; return;
2728
 
    }
2729
 
 
2730
 
    this.matcher = ['.//*'];
2731
 
    while (e && le != e && (/\S/).test(e)) {
2732
 
      le = e;
2733
 
      for (var i in ps) {
2734
 
        if (m = e.match(ps[i])) {
2735
 
          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
2736
 
            new Template(x[i]).evaluate(m));
2737
 
          e = e.replace(m[0], '');
2738
 
          break;
2739
 
        }
2740
 
      }
2741
 
    }
2742
 
 
2743
 
    this.xpath = this.matcher.join('');
2744
 
    Selector._cache[this.expression] = this.xpath;
2745
 
  },
2746
 
 
2747
 
  findElements: function(root) {
2748
 
    root = root || document;
2749
 
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
2750
 
    return this.matcher(root);
2751
 
  },
2752
 
 
2753
 
  match: function(element) {
2754
 
    this.tokens = [];
2755
 
 
2756
 
    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
2757
 
    var le, p, m;
2758
 
 
2759
 
    while (e && le !== e && (/\S/).test(e)) {
2760
 
      le = e;
2761
 
      for (var i in ps) {
2762
 
        p = ps[i];
2763
 
        if (m = e.match(p)) {
2764
 
          // use the Selector.assertions methods unless the selector
2765
 
          // is too complex.
2766
 
          if (as[i]) {
2767
 
            this.tokens.push([i, Object.clone(m)]);
2768
 
            e = e.replace(m[0], '');
2769
 
          } else {
2770
 
            // reluctantly do a document-wide search
2771
 
            // and look for a match in the array
2772
 
            return this.findElements(document).include(element);
2773
 
          }
2774
 
        }
2775
 
      }
2776
 
    }
2777
 
 
2778
 
    var match = true, name, matches;
2779
 
    for (var i = 0, token; token = this.tokens[i]; i++) {
2780
 
      name = token[0], matches = token[1];
2781
 
      if (!Selector.assertions[name](element, matches)) {
2782
 
        match = false; break;
2783
 
      }
2784
 
    }
2785
 
 
2786
 
    return match;
2787
 
  },
2788
 
 
2789
 
  toString: function() {
2790
 
    return this.expression;
2791
 
  },
2792
 
 
2793
 
  inspect: function() {
2794
 
    return "#<Selector:" + this.expression.inspect() + ">";
2795
 
  }
2796
 
});
2797
 
 
2798
 
Object.extend(Selector, {
2799
 
  _cache: { },
2800
 
 
2801
 
  xpath: {
2802
 
    descendant:   "//*",
2803
 
    child:        "/*",
2804
 
    adjacent:     "/following-sibling::*[1]",
2805
 
    laterSibling: '/following-sibling::*',
2806
 
    tagName:      function(m) {
2807
 
      if (m[1] == '*') return '';
2808
 
      return "[local-name()='" + m[1].toLowerCase() +
2809
 
             "' or local-name()='" + m[1].toUpperCase() + "']";
2810
 
    },
2811
 
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
2812
 
    id:           "[@id='#{1}']",
2813
 
    attrPresence: function(m) {
2814
 
      m[1] = m[1].toLowerCase();
2815
 
      return new Template("[@#{1}]").evaluate(m);
2816
 
    },
2817
 
    attr: function(m) {
2818
 
      m[1] = m[1].toLowerCase();
2819
 
      m[3] = m[5] || m[6];
2820
 
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
2821
 
    },
2822
 
    pseudo: function(m) {
2823
 
      var h = Selector.xpath.pseudos[m[1]];
2824
 
      if (!h) return '';
2825
 
      if (Object.isFunction(h)) return h(m);
2826
 
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
2827
 
    },
2828
 
    operators: {
2829
 
      '=':  "[@#{1}='#{3}']",
2830
 
      '!=': "[@#{1}!='#{3}']",
2831
 
      '^=': "[starts-with(@#{1}, '#{3}')]",
2832
 
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
2833
 
      '*=': "[contains(@#{1}, '#{3}')]",
2834
 
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
2835
 
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
2836
 
    },
2837
 
    pseudos: {
2838
 
      'first-child': '[not(preceding-sibling::*)]',
2839
 
      'last-child':  '[not(following-sibling::*)]',
2840
 
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
2841
 
      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
2842
 
      'checked':     "[@checked]",
2843
 
      'disabled':    "[@disabled]",
2844
 
      'enabled':     "[not(@disabled)]",
2845
 
      'not': function(m) {
2846
 
        var e = m[6], p = Selector.patterns,
2847
 
            x = Selector.xpath, le, v;
2848
 
 
2849
 
        var exclusion = [];
2850
 
        while (e && le != e && (/\S/).test(e)) {
2851
 
          le = e;
2852
 
          for (var i in p) {
2853
 
            if (m = e.match(p[i])) {
2854
 
              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
2855
 
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
2856
 
              e = e.replace(m[0], '');
2857
 
              break;
2858
 
            }
2859
 
          }
2860
 
        }
2861
 
        return "[not(" + exclusion.join(" and ") + ")]";
2862
 
      },
2863
 
      'nth-child':      function(m) {
2864
 
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
2865
 
      },
2866
 
      'nth-last-child': function(m) {
2867
 
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
2868
 
      },
2869
 
      'nth-of-type':    function(m) {
2870
 
        return Selector.xpath.pseudos.nth("position() ", m);
2871
 
      },
2872
 
      'nth-last-of-type': function(m) {
2873
 
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
2874
 
      },
2875
 
      'first-of-type':  function(m) {
2876
 
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
2877
 
      },
2878
 
      'last-of-type':   function(m) {
2879
 
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
2880
 
      },
2881
 
      'only-of-type':   function(m) {
2882
 
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
2883
 
      },
2884
 
      nth: function(fragment, m) {
2885
 
        var mm, formula = m[6], predicate;
2886
 
        if (formula == 'even') formula = '2n+0';
2887
 
        if (formula == 'odd')  formula = '2n+1';
2888
 
        if (mm = formula.match(/^(\d+)$/)) // digit only
2889
 
          return '[' + fragment + "= " + mm[1] + ']';
2890
 
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
2891
 
          if (mm[1] == "-") mm[1] = -1;
2892
 
          var a = mm[1] ? Number(mm[1]) : 1;
2893
 
          var b = mm[2] ? Number(mm[2]) : 0;
2894
 
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
2895
 
          "((#{fragment} - #{b}) div #{a} >= 0)]";
2896
 
          return new Template(predicate).evaluate({
2897
 
            fragment: fragment, a: a, b: b });
2898
 
        }
2899
 
      }
2900
 
    }
2901
 
  },
2902
 
 
2903
 
  criteria: {
2904
 
    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
2905
 
    className:    'n = h.className(n, r, "#{1}", c); c = false;',
2906
 
    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
2907
 
    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
2908
 
    attr: function(m) {
2909
 
      m[3] = (m[5] || m[6]);
2910
 
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
2911
 
    },
2912
 
    pseudo: function(m) {
2913
 
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
2914
 
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
2915
 
    },
2916
 
    descendant:   'c = "descendant";',
2917
 
    child:        'c = "child";',
2918
 
    adjacent:     'c = "adjacent";',
2919
 
    laterSibling: 'c = "laterSibling";'
2920
 
  },
2921
 
 
2922
 
  patterns: {
2923
 
    // combinators must be listed first
2924
 
    // (and descendant needs to be last combinator)
2925
 
    laterSibling: /^\s*~\s*/,
2926
 
    child:        /^\s*>\s*/,
2927
 
    adjacent:     /^\s*\+\s*/,
2928
 
    descendant:   /^\s/,
2929
 
 
2930
 
    // selectors follow
2931
 
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
2932
 
    id:           /^#([\w\-\*]+)(\b|$)/,
2933
 
    className:    /^\.([\w\-\*]+)(\b|$)/,
2934
 
    pseudo:
2935
 
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
2936
 
    attrPresence: /^\[([\w]+)\]/,
2937
 
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
2938
 
  },
2939
 
 
2940
 
  // for Selector.match and Element#match
2941
 
  assertions: {
2942
 
    tagName: function(element, matches) {
2943
 
      return matches[1].toUpperCase() == element.tagName.toUpperCase();
2944
 
    },
2945
 
 
2946
 
    className: function(element, matches) {
2947
 
      return Element.hasClassName(element, matches[1]);
2948
 
    },
2949
 
 
2950
 
    id: function(element, matches) {
2951
 
      return element.id === matches[1];
2952
 
    },
2953
 
 
2954
 
    attrPresence: function(element, matches) {
2955
 
      return Element.hasAttribute(element, matches[1]);
2956
 
    },
2957
 
 
2958
 
    attr: function(element, matches) {
2959
 
      var nodeValue = Element.readAttribute(element, matches[1]);
2960
 
      return Selector.operators[matches[2]](nodeValue, matches[3]);
2961
 
    }
2962
 
  },
2963
 
 
2964
 
  handlers: {
2965
 
    // UTILITY FUNCTIONS
2966
 
    // joins two collections
2967
 
    concat: function(a, b) {
2968
 
      for (var i = 0, node; node = b[i]; i++)
2969
 
        a.push(node);
2970
 
      return a;
2971
 
    },
2972
 
 
2973
 
    // marks an array of nodes for counting
2974
 
    mark: function(nodes) {
2975
 
      for (var i = 0, node; node = nodes[i]; i++)
2976
 
        node._counted = true;
2977
 
      return nodes;
2978
 
    },
2979
 
 
2980
 
    unmark: function(nodes) {
2981
 
      for (var i = 0, node; node = nodes[i]; i++)
2982
 
        node._counted = undefined;
2983
 
      return nodes;
2984
 
    },
2985
 
 
2986
 
    // mark each child node with its position (for nth calls)
2987
 
    // "ofType" flag indicates whether we're indexing for nth-of-type
2988
 
    // rather than nth-child
2989
 
    index: function(parentNode, reverse, ofType) {
2990
 
      parentNode._counted = true;
2991
 
      if (reverse) {
2992
 
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
2993
 
          var node = nodes[i];
2994
 
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
2995
 
        }
2996
 
      } else {
2997
 
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
2998
 
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
2999
 
      }
3000
 
    },
3001
 
 
3002
 
    // filters out duplicates and extends all nodes
3003
 
    unique: function(nodes) {
3004
 
      if (nodes.length == 0) return nodes;
3005
 
      var results = [], n;
3006
 
      for (var i = 0, l = nodes.length; i < l; i++)
3007
 
        if (!(n = nodes[i])._counted) {
3008
 
          n._counted = true;
3009
 
          results.push(Element.extend(n));
3010
 
        }
3011
 
      return Selector.handlers.unmark(results);
3012
 
    },
3013
 
 
3014
 
    // COMBINATOR FUNCTIONS
3015
 
    descendant: function(nodes) {
3016
 
      var h = Selector.handlers;
3017
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3018
 
        h.concat(results, node.getElementsByTagName('*'));
3019
 
      return results;
3020
 
    },
3021
 
 
3022
 
    child: function(nodes) {
3023
 
      var h = Selector.handlers;
3024
 
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
3025
 
        for (var j = 0, child; child = node.childNodes[j]; j++)
3026
 
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
3027
 
      }
3028
 
      return results;
3029
 
    },
3030
 
 
3031
 
    adjacent: function(nodes) {
3032
 
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
3033
 
        var next = this.nextElementSibling(node);
3034
 
        if (next) results.push(next);
3035
 
      }
3036
 
      return results;
3037
 
    },
3038
 
 
3039
 
    laterSibling: function(nodes) {
3040
 
      var h = Selector.handlers;
3041
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3042
 
        h.concat(results, Element.nextSiblings(node));
3043
 
      return results;
3044
 
    },
3045
 
 
3046
 
    nextElementSibling: function(node) {
3047
 
      while (node = node.nextSibling)
3048
 
              if (node.nodeType == 1) return node;
3049
 
      return null;
3050
 
    },
3051
 
 
3052
 
    previousElementSibling: function(node) {
3053
 
      while (node = node.previousSibling)
3054
 
        if (node.nodeType == 1) return node;
3055
 
      return null;
3056
 
    },
3057
 
 
3058
 
    // TOKEN FUNCTIONS
3059
 
    tagName: function(nodes, root, tagName, combinator) {
3060
 
      var uTagName = tagName.toUpperCase();
3061
 
      var results = [], h = Selector.handlers;
3062
 
      if (nodes) {
3063
 
        if (combinator) {
3064
 
          // fastlane for ordinary descendant combinators
3065
 
          if (combinator == "descendant") {
3066
 
            for (var i = 0, node; node = nodes[i]; i++)
3067
 
              h.concat(results, node.getElementsByTagName(tagName));
3068
 
            return results;
3069
 
          } else nodes = this[combinator](nodes);
3070
 
          if (tagName == "*") return nodes;
3071
 
        }
3072
 
        for (var i = 0, node; node = nodes[i]; i++)
3073
 
          if (node.tagName.toUpperCase() === uTagName) results.push(node);
3074
 
        return results;
3075
 
      } else return root.getElementsByTagName(tagName);
3076
 
    },
3077
 
 
3078
 
    id: function(nodes, root, id, combinator) {
3079
 
      var targetNode = $(id), h = Selector.handlers;
3080
 
      if (!targetNode) return [];
3081
 
      if (!nodes && root == document) return [targetNode];
3082
 
      if (nodes) {
3083
 
        if (combinator) {
3084
 
          if (combinator == 'child') {
3085
 
            for (var i = 0, node; node = nodes[i]; i++)
3086
 
              if (targetNode.parentNode == node) return [targetNode];
3087
 
          } else if (combinator == 'descendant') {
3088
 
            for (var i = 0, node; node = nodes[i]; i++)
3089
 
              if (Element.descendantOf(targetNode, node)) return [targetNode];
3090
 
          } else if (combinator == 'adjacent') {
3091
 
            for (var i = 0, node; node = nodes[i]; i++)
3092
 
              if (Selector.handlers.previousElementSibling(targetNode) == node)
3093
 
                return [targetNode];
3094
 
          } else nodes = h[combinator](nodes);
3095
 
        }
3096
 
        for (var i = 0, node; node = nodes[i]; i++)
3097
 
          if (node == targetNode) return [targetNode];
3098
 
        return [];
3099
 
      }
3100
 
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
3101
 
    },
3102
 
 
3103
 
    className: function(nodes, root, className, combinator) {
3104
 
      if (nodes && combinator) nodes = this[combinator](nodes);
3105
 
      return Selector.handlers.byClassName(nodes, root, className);
3106
 
    },
3107
 
 
3108
 
    byClassName: function(nodes, root, className) {
3109
 
      if (!nodes) nodes = Selector.handlers.descendant([root]);
3110
 
      var needle = ' ' + className + ' ';
3111
 
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
3112
 
        nodeClassName = node.className;
3113
 
        if (nodeClassName.length == 0) continue;
3114
 
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
3115
 
          results.push(node);
3116
 
      }
3117
 
      return results;
3118
 
    },
3119
 
 
3120
 
    attrPresence: function(nodes, root, attr) {
3121
 
      if (!nodes) nodes = root.getElementsByTagName("*");
3122
 
      var results = [];
3123
 
      for (var i = 0, node; node = nodes[i]; i++)
3124
 
        if (Element.hasAttribute(node, attr)) results.push(node);
3125
 
      return results;
3126
 
    },
3127
 
 
3128
 
    attr: function(nodes, root, attr, value, operator) {
3129
 
      if (!nodes) nodes = root.getElementsByTagName("*");
3130
 
      var handler = Selector.operators[operator], results = [];
3131
 
      for (var i = 0, node; node = nodes[i]; i++) {
3132
 
        var nodeValue = Element.readAttribute(node, attr);
3133
 
        if (nodeValue === null) continue;
3134
 
        if (handler(nodeValue, value)) results.push(node);
3135
 
      }
3136
 
      return results;
3137
 
    },
3138
 
 
3139
 
    pseudo: function(nodes, name, value, root, combinator) {
3140
 
      if (nodes && combinator) nodes = this[combinator](nodes);
3141
 
      if (!nodes) nodes = root.getElementsByTagName("*");
3142
 
      return Selector.pseudos[name](nodes, value, root);
3143
 
    }
3144
 
  },
3145
 
 
3146
 
  pseudos: {
3147
 
    'first-child': function(nodes, value, root) {
3148
 
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
3149
 
        if (Selector.handlers.previousElementSibling(node)) continue;
3150
 
          results.push(node);
3151
 
      }
3152
 
      return results;
3153
 
    },
3154
 
    'last-child': function(nodes, value, root) {
3155
 
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
3156
 
        if (Selector.handlers.nextElementSibling(node)) continue;
3157
 
          results.push(node);
3158
 
      }
3159
 
      return results;
3160
 
    },
3161
 
    'only-child': function(nodes, value, root) {
3162
 
      var h = Selector.handlers;
3163
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3164
 
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
3165
 
          results.push(node);
3166
 
      return results;
3167
 
    },
3168
 
    'nth-child':        function(nodes, formula, root) {
3169
 
      return Selector.pseudos.nth(nodes, formula, root);
3170
 
    },
3171
 
    'nth-last-child':   function(nodes, formula, root) {
3172
 
      return Selector.pseudos.nth(nodes, formula, root, true);
3173
 
    },
3174
 
    'nth-of-type':      function(nodes, formula, root) {
3175
 
      return Selector.pseudos.nth(nodes, formula, root, false, true);
3176
 
    },
3177
 
    'nth-last-of-type': function(nodes, formula, root) {
3178
 
      return Selector.pseudos.nth(nodes, formula, root, true, true);
3179
 
    },
3180
 
    'first-of-type':    function(nodes, formula, root) {
3181
 
      return Selector.pseudos.nth(nodes, "1", root, false, true);
3182
 
    },
3183
 
    'last-of-type':     function(nodes, formula, root) {
3184
 
      return Selector.pseudos.nth(nodes, "1", root, true, true);
3185
 
    },
3186
 
    'only-of-type':     function(nodes, formula, root) {
3187
 
      var p = Selector.pseudos;
3188
 
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
3189
 
    },
3190
 
 
3191
 
    // handles the an+b logic
3192
 
    getIndices: function(a, b, total) {
3193
 
      if (a == 0) return b > 0 ? [b] : [];
3194
 
      return $R(1, total).inject([], function(memo, i) {
3195
 
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
3196
 
        return memo;
 
3263
  }
 
3264
 
 
3265
  var hasLayout = Prototype.K;
 
3266
  if ('currentStyle' in document.documentElement) {
 
3267
    hasLayout = function(element) {
 
3268
      if (!element.currentStyle.hasLayout) {
 
3269
        element.style.zoom = 1;
 
3270
      }
 
3271
      return element;
 
3272
    };
 
3273
  }
 
3274
 
 
3275
  function cssNameFor(key) {
 
3276
    if (key.include('border')) key = key + '-width';
 
3277
    return key.camelize();
 
3278
  }
 
3279
 
 
3280
  Element.Layout = Class.create(Hash, {
 
3281
    initialize: function($super, element, preCompute) {
 
3282
      $super();
 
3283
      this.element = $(element);
 
3284
 
 
3285
      Element.Layout.PROPERTIES.each( function(property) {
 
3286
        this._set(property, null);
 
3287
      }, this);
 
3288
 
 
3289
      if (preCompute) {
 
3290
        this._preComputing = true;
 
3291
        this._begin();
 
3292
        Element.Layout.PROPERTIES.each( this._compute, this );
 
3293
        this._end();
 
3294
        this._preComputing = false;
 
3295
      }
 
3296
    },
 
3297
 
 
3298
    _set: function(property, value) {
 
3299
      return Hash.prototype.set.call(this, property, value);
 
3300
    },
 
3301
 
 
3302
    set: function(property, value) {
 
3303
      throw "Properties of Element.Layout are read-only.";
 
3304
    },
 
3305
 
 
3306
    get: function($super, property) {
 
3307
      var value = $super(property);
 
3308
      return value === null ? this._compute(property) : value;
 
3309
    },
 
3310
 
 
3311
    _begin: function() {
 
3312
      if (this._prepared) return;
 
3313
 
 
3314
      var element = this.element;
 
3315
      if (isDisplayed(element)) {
 
3316
        this._prepared = true;
 
3317
        return;
 
3318
      }
 
3319
 
 
3320
      var originalStyles = {
 
3321
        position:   element.style.position   || '',
 
3322
        width:      element.style.width      || '',
 
3323
        visibility: element.style.visibility || '',
 
3324
        display:    element.style.display    || ''
 
3325
      };
 
3326
 
 
3327
      element.store('prototype_original_styles', originalStyles);
 
3328
 
 
3329
      var position = element.getStyle('position'),
 
3330
       width = element.getStyle('width');
 
3331
 
 
3332
      if (width === "0px" || width === null) {
 
3333
        element.style.display = 'block';
 
3334
        width = element.getStyle('width');
 
3335
      }
 
3336
 
 
3337
      var context = (position === 'fixed') ? document.viewport :
 
3338
       element.parentNode;
 
3339
 
 
3340
      element.setStyle({
 
3341
        position:   'absolute',
 
3342
        visibility: 'hidden',
 
3343
        display:    'block'
3197
3344
      });
3198
 
    },
3199
 
 
3200
 
    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
3201
 
    nth: function(nodes, formula, root, reverse, ofType) {
3202
 
      if (nodes.length == 0) return [];
3203
 
      if (formula == 'even') formula = '2n+0';
3204
 
      if (formula == 'odd')  formula = '2n+1';
3205
 
      var h = Selector.handlers, results = [], indexed = [], m;
3206
 
      h.mark(nodes);
3207
 
      for (var i = 0, node; node = nodes[i]; i++) {
3208
 
        if (!node.parentNode._counted) {
3209
 
          h.index(node.parentNode, reverse, ofType);
3210
 
          indexed.push(node.parentNode);
3211
 
        }
3212
 
      }
3213
 
      if (formula.match(/^\d+$/)) { // just a number
3214
 
        formula = Number(formula);
3215
 
        for (var i = 0, node; node = nodes[i]; i++)
3216
 
          if (node.nodeIndex == formula) results.push(node);
3217
 
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
3218
 
        if (m[1] == "-") m[1] = -1;
3219
 
        var a = m[1] ? Number(m[1]) : 1;
3220
 
        var b = m[2] ? Number(m[2]) : 0;
3221
 
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
3222
 
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
3223
 
          for (var j = 0; j < l; j++)
3224
 
            if (node.nodeIndex == indices[j]) results.push(node);
3225
 
        }
3226
 
      }
3227
 
      h.unmark(nodes);
3228
 
      h.unmark(indexed);
3229
 
      return results;
3230
 
    },
3231
 
 
3232
 
    'empty': function(nodes, value, root) {
3233
 
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
3234
 
        // IE treats comments as element nodes
3235
 
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
3236
 
        results.push(node);
3237
 
      }
3238
 
      return results;
3239
 
    },
3240
 
 
3241
 
    'not': function(nodes, selector, root) {
3242
 
      var h = Selector.handlers, selectorType, m;
3243
 
      var exclusions = new Selector(selector).findElements(root);
3244
 
      h.mark(exclusions);
3245
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3246
 
        if (!node._counted) results.push(node);
3247
 
      h.unmark(exclusions);
3248
 
      return results;
3249
 
    },
3250
 
 
3251
 
    'enabled': function(nodes, value, root) {
3252
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3253
 
        if (!node.disabled) results.push(node);
3254
 
      return results;
3255
 
    },
3256
 
 
3257
 
    'disabled': function(nodes, value, root) {
3258
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3259
 
        if (node.disabled) results.push(node);
3260
 
      return results;
3261
 
    },
3262
 
 
3263
 
    'checked': function(nodes, value, root) {
3264
 
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3265
 
        if (node.checked) results.push(node);
3266
 
      return results;
3267
 
    }
3268
 
  },
3269
 
 
3270
 
  operators: {
3271
 
    '=':  function(nv, v) { return nv == v; },
3272
 
    '!=': function(nv, v) { return nv != v; },
3273
 
    '^=': function(nv, v) { return nv.startsWith(v); },
3274
 
    '$=': function(nv, v) { return nv.endsWith(v); },
3275
 
    '*=': function(nv, v) { return nv.include(v); },
3276
 
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
3277
 
    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
3278
 
  },
3279
 
 
3280
 
  matchElements: function(elements, expression) {
3281
 
    var matches = new Selector(expression).findElements(), h = Selector.handlers;
3282
 
    h.mark(matches);
3283
 
    for (var i = 0, results = [], element; element = elements[i]; i++)
3284
 
      if (element._counted) results.push(element);
3285
 
    h.unmark(matches);
3286
 
    return results;
3287
 
  },
3288
 
 
3289
 
  findElement: function(elements, expression, index) {
3290
 
    if (Object.isNumber(expression)) {
3291
 
      index = expression; expression = false;
3292
 
    }
3293
 
    return Selector.matchElements(elements, expression || '*')[index || 0];
3294
 
  },
3295
 
 
3296
 
  findChildElements: function(element, expressions) {
3297
 
    var exprs = expressions.join(',');
3298
 
    expressions = [];
3299
 
    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
3300
 
      expressions.push(m[1].strip());
3301
 
    });
3302
 
    var results = [], h = Selector.handlers;
3303
 
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
3304
 
      selector = new Selector(expressions[i].strip());
3305
 
      h.concat(results, selector.findElements(element));
3306
 
    }
3307
 
    return (l > 1) ? h.unique(results) : results;
3308
 
  }
3309
 
});
3310
 
 
3311
 
if (Prototype.Browser.IE) {
3312
 
  // IE returns comment nodes on getElementsByTagName("*").
3313
 
  // Filter them out.
3314
 
  Selector.handlers.concat = function(a, b) {
3315
 
    for (var i = 0, node; node = b[i]; i++)
3316
 
      if (node.tagName !== "!") a.push(node);
3317
 
    return a;
 
3345
 
 
3346
      var positionedWidth = element.getStyle('width');
 
3347
 
 
3348
      var newWidth;
 
3349
      if (width && (positionedWidth === width)) {
 
3350
        newWidth = getPixelValue(element, 'width', context);
 
3351
      } else if (position === 'absolute' || position === 'fixed') {
 
3352
        newWidth = getPixelValue(element, 'width', context);
 
3353
      } else {
 
3354
        var parent = element.parentNode, pLayout = $(parent).getLayout();
 
3355
 
 
3356
        newWidth = pLayout.get('width') -
 
3357
         this.get('margin-left') -
 
3358
         this.get('border-left') -
 
3359
         this.get('padding-left') -
 
3360
         this.get('padding-right') -
 
3361
         this.get('border-right') -
 
3362
         this.get('margin-right');
 
3363
      }
 
3364
 
 
3365
      element.setStyle({ width: newWidth + 'px' });
 
3366
 
 
3367
      this._prepared = true;
 
3368
    },
 
3369
 
 
3370
    _end: function() {
 
3371
      var element = this.element;
 
3372
      var originalStyles = element.retrieve('prototype_original_styles');
 
3373
      element.store('prototype_original_styles', null);
 
3374
      element.setStyle(originalStyles);
 
3375
      this._prepared = false;
 
3376
    },
 
3377
 
 
3378
    _compute: function(property) {
 
3379
      var COMPUTATIONS = Element.Layout.COMPUTATIONS;
 
3380
      if (!(property in COMPUTATIONS)) {
 
3381
        throw "Property not found.";
 
3382
      }
 
3383
 
 
3384
      return this._set(property, COMPUTATIONS[property].call(this, this.element));
 
3385
    },
 
3386
 
 
3387
    toObject: function() {
 
3388
      var args = $A(arguments);
 
3389
      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
 
3390
       args.join(' ').split(' ');
 
3391
      var obj = {};
 
3392
      keys.each( function(key) {
 
3393
        if (!Element.Layout.PROPERTIES.include(key)) return;
 
3394
        var value = this.get(key);
 
3395
        if (value != null) obj[key] = value;
 
3396
      }, this);
 
3397
      return obj;
 
3398
    },
 
3399
 
 
3400
    toHash: function() {
 
3401
      var obj = this.toObject.apply(this, arguments);
 
3402
      return new Hash(obj);
 
3403
    },
 
3404
 
 
3405
    toCSS: function() {
 
3406
      var args = $A(arguments);
 
3407
      var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
 
3408
       args.join(' ').split(' ');
 
3409
      var css = {};
 
3410
 
 
3411
      keys.each( function(key) {
 
3412
        if (!Element.Layout.PROPERTIES.include(key)) return;
 
3413
        if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
 
3414
 
 
3415
        var value = this.get(key);
 
3416
        if (value != null) css[cssNameFor(key)] = value + 'px';
 
3417
      }, this);
 
3418
      return css;
 
3419
    },
 
3420
 
 
3421
    inspect: function() {
 
3422
      return "#<Element.Layout>";
 
3423
    }
 
3424
  });
 
3425
 
 
3426
  Object.extend(Element.Layout, {
 
3427
    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'),
 
3428
 
 
3429
    COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
 
3430
 
 
3431
    COMPUTATIONS: {
 
3432
      'height': function(element) {
 
3433
        if (!this._preComputing) this._begin();
 
3434
 
 
3435
        var bHeight = this.get('border-box-height');
 
3436
        if (bHeight <= 0) {
 
3437
          if (!this._preComputing) this._end();
 
3438
          return 0;
 
3439
        }
 
3440
 
 
3441
        var bTop = this.get('border-top'),
 
3442
         bBottom = this.get('border-bottom');
 
3443
 
 
3444
        var pTop = this.get('padding-top'),
 
3445
         pBottom = this.get('padding-bottom');
 
3446
 
 
3447
        if (!this._preComputing) this._end();
 
3448
 
 
3449
        return bHeight - bTop - bBottom - pTop - pBottom;
 
3450
      },
 
3451
 
 
3452
      'width': function(element) {
 
3453
        if (!this._preComputing) this._begin();
 
3454
 
 
3455
        var bWidth = this.get('border-box-width');
 
3456
        if (bWidth <= 0) {
 
3457
          if (!this._preComputing) this._end();
 
3458
          return 0;
 
3459
        }
 
3460
 
 
3461
        var bLeft = this.get('border-left'),
 
3462
         bRight = this.get('border-right');
 
3463
 
 
3464
        var pLeft = this.get('padding-left'),
 
3465
         pRight = this.get('padding-right');
 
3466
 
 
3467
        if (!this._preComputing) this._end();
 
3468
 
 
3469
        return bWidth - bLeft - bRight - pLeft - pRight;
 
3470
      },
 
3471
 
 
3472
      'padding-box-height': function(element) {
 
3473
        var height = this.get('height'),
 
3474
         pTop = this.get('padding-top'),
 
3475
         pBottom = this.get('padding-bottom');
 
3476
 
 
3477
        return height + pTop + pBottom;
 
3478
      },
 
3479
 
 
3480
      'padding-box-width': function(element) {
 
3481
        var width = this.get('width'),
 
3482
         pLeft = this.get('padding-left'),
 
3483
         pRight = this.get('padding-right');
 
3484
 
 
3485
        return width + pLeft + pRight;
 
3486
      },
 
3487
 
 
3488
      'border-box-height': function(element) {
 
3489
        if (!this._preComputing) this._begin();
 
3490
        var height = element.offsetHeight;
 
3491
        if (!this._preComputing) this._end();
 
3492
        return height;
 
3493
      },
 
3494
 
 
3495
      'border-box-width': function(element) {
 
3496
        if (!this._preComputing) this._begin();
 
3497
        var width = element.offsetWidth;
 
3498
        if (!this._preComputing) this._end();
 
3499
        return width;
 
3500
      },
 
3501
 
 
3502
      'margin-box-height': function(element) {
 
3503
        var bHeight = this.get('border-box-height'),
 
3504
         mTop = this.get('margin-top'),
 
3505
         mBottom = this.get('margin-bottom');
 
3506
 
 
3507
        if (bHeight <= 0) return 0;
 
3508
 
 
3509
        return bHeight + mTop + mBottom;
 
3510
      },
 
3511
 
 
3512
      'margin-box-width': function(element) {
 
3513
        var bWidth = this.get('border-box-width'),
 
3514
         mLeft = this.get('margin-left'),
 
3515
         mRight = this.get('margin-right');
 
3516
 
 
3517
        if (bWidth <= 0) return 0;
 
3518
 
 
3519
        return bWidth + mLeft + mRight;
 
3520
      },
 
3521
 
 
3522
      'top': function(element) {
 
3523
        var offset = element.positionedOffset();
 
3524
        return offset.top;
 
3525
      },
 
3526
 
 
3527
      'bottom': function(element) {
 
3528
        var offset = element.positionedOffset(),
 
3529
         parent = element.getOffsetParent(),
 
3530
         pHeight = parent.measure('height');
 
3531
 
 
3532
        var mHeight = this.get('border-box-height');
 
3533
 
 
3534
        return pHeight - mHeight - offset.top;
 
3535
      },
 
3536
 
 
3537
      'left': function(element) {
 
3538
        var offset = element.positionedOffset();
 
3539
        return offset.left;
 
3540
      },
 
3541
 
 
3542
      'right': function(element) {
 
3543
        var offset = element.positionedOffset(),
 
3544
         parent = element.getOffsetParent(),
 
3545
         pWidth = parent.measure('width');
 
3546
 
 
3547
        var mWidth = this.get('border-box-width');
 
3548
 
 
3549
        return pWidth - mWidth - offset.left;
 
3550
      },
 
3551
 
 
3552
      'padding-top': function(element) {
 
3553
        return getPixelValue(element, 'paddingTop');
 
3554
      },
 
3555
 
 
3556
      'padding-bottom': function(element) {
 
3557
        return getPixelValue(element, 'paddingBottom');
 
3558
      },
 
3559
 
 
3560
      'padding-left': function(element) {
 
3561
        return getPixelValue(element, 'paddingLeft');
 
3562
      },
 
3563
 
 
3564
      'padding-right': function(element) {
 
3565
        return getPixelValue(element, 'paddingRight');
 
3566
      },
 
3567
 
 
3568
      'border-top': function(element) {
 
3569
        return getPixelValue(element, 'borderTopWidth');
 
3570
      },
 
3571
 
 
3572
      'border-bottom': function(element) {
 
3573
        return getPixelValue(element, 'borderBottomWidth');
 
3574
      },
 
3575
 
 
3576
      'border-left': function(element) {
 
3577
        return getPixelValue(element, 'borderLeftWidth');
 
3578
      },
 
3579
 
 
3580
      'border-right': function(element) {
 
3581
        return getPixelValue(element, 'borderRightWidth');
 
3582
      },
 
3583
 
 
3584
      'margin-top': function(element) {
 
3585
        return getPixelValue(element, 'marginTop');
 
3586
      },
 
3587
 
 
3588
      'margin-bottom': function(element) {
 
3589
        return getPixelValue(element, 'marginBottom');
 
3590
      },
 
3591
 
 
3592
      'margin-left': function(element) {
 
3593
        return getPixelValue(element, 'marginLeft');
 
3594
      },
 
3595
 
 
3596
      'margin-right': function(element) {
 
3597
        return getPixelValue(element, 'marginRight');
 
3598
      }
 
3599
    }
 
3600
  });
 
3601
 
 
3602
  if ('getBoundingClientRect' in document.documentElement) {
 
3603
    Object.extend(Element.Layout.COMPUTATIONS, {
 
3604
      'right': function(element) {
 
3605
        var parent = hasLayout(element.getOffsetParent());
 
3606
        var rect = element.getBoundingClientRect(),
 
3607
         pRect = parent.getBoundingClientRect();
 
3608
 
 
3609
        return (pRect.right - rect.right).round();
 
3610
      },
 
3611
 
 
3612
      'bottom': function(element) {
 
3613
        var parent = hasLayout(element.getOffsetParent());
 
3614
        var rect = element.getBoundingClientRect(),
 
3615
         pRect = parent.getBoundingClientRect();
 
3616
 
 
3617
        return (pRect.bottom - rect.bottom).round();
 
3618
      }
 
3619
    });
 
3620
  }
 
3621
 
 
3622
  Element.Offset = Class.create({
 
3623
    initialize: function(left, top) {
 
3624
      this.left = left.round();
 
3625
      this.top  = top.round();
 
3626
 
 
3627
      this[0] = this.left;
 
3628
      this[1] = this.top;
 
3629
    },
 
3630
 
 
3631
    relativeTo: function(offset) {
 
3632
      return new Element.Offset(
 
3633
        this.left - offset.left,
 
3634
        this.top  - offset.top
 
3635
      );
 
3636
    },
 
3637
 
 
3638
    inspect: function() {
 
3639
      return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
 
3640
    },
 
3641
 
 
3642
    toString: function() {
 
3643
      return "[#{left}, #{top}]".interpolate(this);
 
3644
    },
 
3645
 
 
3646
    toArray: function() {
 
3647
      return [this.left, this.top];
 
3648
    }
 
3649
  });
 
3650
 
 
3651
  function getLayout(element, preCompute) {
 
3652
    return new Element.Layout(element, preCompute);
 
3653
  }
 
3654
 
 
3655
  function measure(element, property) {
 
3656
    return $(element).getLayout().get(property);
 
3657
  }
 
3658
 
 
3659
  function getDimensions(element) {
 
3660
    element = $(element);
 
3661
    var display = Element.getStyle(element, 'display');
 
3662
 
 
3663
    if (display && display !== 'none') {
 
3664
      return { width: element.offsetWidth, height: element.offsetHeight };
 
3665
    }
 
3666
 
 
3667
    var style = element.style;
 
3668
    var originalStyles = {
 
3669
      visibility: style.visibility,
 
3670
      position:   style.position,
 
3671
      display:    style.display
 
3672
    };
 
3673
 
 
3674
    var newStyles = {
 
3675
      visibility: 'hidden',
 
3676
      display:    'block'
 
3677
    };
 
3678
 
 
3679
    if (originalStyles.position !== 'fixed')
 
3680
      newStyles.position = 'absolute';
 
3681
 
 
3682
    Element.setStyle(element, newStyles);
 
3683
 
 
3684
    var dimensions = {
 
3685
      width:  element.offsetWidth,
 
3686
      height: element.offsetHeight
 
3687
    };
 
3688
 
 
3689
    Element.setStyle(element, originalStyles);
 
3690
 
 
3691
    return dimensions;
 
3692
  }
 
3693
 
 
3694
  function getOffsetParent(element) {
 
3695
    element = $(element);
 
3696
 
 
3697
    if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
 
3698
      return $(document.body);
 
3699
 
 
3700
    var isInline = (Element.getStyle(element, 'display') === 'inline');
 
3701
    if (!isInline && element.offsetParent) return $(element.offsetParent);
 
3702
 
 
3703
    while ((element = element.parentNode) && element !== document.body) {
 
3704
      if (Element.getStyle(element, 'position') !== 'static') {
 
3705
        return isHtml(element) ? $(document.body) : $(element);
 
3706
      }
 
3707
    }
 
3708
 
 
3709
    return $(document.body);
 
3710
  }
 
3711
 
 
3712
 
 
3713
  function cumulativeOffset(element) {
 
3714
    element = $(element);
 
3715
    var valueT = 0, valueL = 0;
 
3716
    if (element.parentNode) {
 
3717
      do {
 
3718
        valueT += element.offsetTop  || 0;
 
3719
        valueL += element.offsetLeft || 0;
 
3720
        element = element.offsetParent;
 
3721
      } while (element);
 
3722
    }
 
3723
    return new Element.Offset(valueL, valueT);
 
3724
  }
 
3725
 
 
3726
  function positionedOffset(element) {
 
3727
    element = $(element);
 
3728
 
 
3729
    var layout = element.getLayout();
 
3730
 
 
3731
    var valueT = 0, valueL = 0;
 
3732
    do {
 
3733
      valueT += element.offsetTop  || 0;
 
3734
      valueL += element.offsetLeft || 0;
 
3735
      element = element.offsetParent;
 
3736
      if (element) {
 
3737
        if (isBody(element)) break;
 
3738
        var p = Element.getStyle(element, 'position');
 
3739
        if (p !== 'static') break;
 
3740
      }
 
3741
    } while (element);
 
3742
 
 
3743
    valueL -= layout.get('margin-top');
 
3744
    valueT -= layout.get('margin-left');
 
3745
 
 
3746
    return new Element.Offset(valueL, valueT);
 
3747
  }
 
3748
 
 
3749
  function cumulativeScrollOffset(element) {
 
3750
    var valueT = 0, valueL = 0;
 
3751
    do {
 
3752
      valueT += element.scrollTop  || 0;
 
3753
      valueL += element.scrollLeft || 0;
 
3754
      element = element.parentNode;
 
3755
    } while (element);
 
3756
    return new Element.Offset(valueL, valueT);
 
3757
  }
 
3758
 
 
3759
  function viewportOffset(forElement) {
 
3760
    element = $(element);
 
3761
    var valueT = 0, valueL = 0, docBody = document.body;
 
3762
 
 
3763
    var element = forElement;
 
3764
    do {
 
3765
      valueT += element.offsetTop  || 0;
 
3766
      valueL += element.offsetLeft || 0;
 
3767
      if (element.offsetParent == docBody &&
 
3768
        Element.getStyle(element, 'position') == 'absolute') break;
 
3769
    } while (element = element.offsetParent);
 
3770
 
 
3771
    element = forElement;
 
3772
    do {
 
3773
      if (element != docBody) {
 
3774
        valueT -= element.scrollTop  || 0;
 
3775
        valueL -= element.scrollLeft || 0;
 
3776
      }
 
3777
    } while (element = element.parentNode);
 
3778
    return new Element.Offset(valueL, valueT);
 
3779
  }
 
3780
 
 
3781
  function absolutize(element) {
 
3782
    element = $(element);
 
3783
 
 
3784
    if (Element.getStyle(element, 'position') === 'absolute') {
 
3785
      return element;
 
3786
    }
 
3787
 
 
3788
    var offsetParent = getOffsetParent(element);
 
3789
    var eOffset = element.viewportOffset(),
 
3790
     pOffset = offsetParent.viewportOffset();
 
3791
 
 
3792
    var offset = eOffset.relativeTo(pOffset);
 
3793
    var layout = element.getLayout();
 
3794
 
 
3795
    element.store('prototype_absolutize_original_styles', {
 
3796
      left:   element.getStyle('left'),
 
3797
      top:    element.getStyle('top'),
 
3798
      width:  element.getStyle('width'),
 
3799
      height: element.getStyle('height')
 
3800
    });
 
3801
 
 
3802
    element.setStyle({
 
3803
      position: 'absolute',
 
3804
      top:    offset.top + 'px',
 
3805
      left:   offset.left + 'px',
 
3806
      width:  layout.get('width') + 'px',
 
3807
      height: layout.get('height') + 'px'
 
3808
    });
 
3809
 
 
3810
    return element;
 
3811
  }
 
3812
 
 
3813
  function relativize(element) {
 
3814
    element = $(element);
 
3815
    if (Element.getStyle(element, 'position') === 'relative') {
 
3816
      return element;
 
3817
    }
 
3818
 
 
3819
    var originalStyles =
 
3820
     element.retrieve('prototype_absolutize_original_styles');
 
3821
 
 
3822
    if (originalStyles) element.setStyle(originalStyles);
 
3823
    return element;
 
3824
  }
 
3825
 
 
3826
  if (Prototype.Browser.IE) {
 
3827
    getOffsetParent = getOffsetParent.wrap(
 
3828
      function(proceed, element) {
 
3829
        element = $(element);
 
3830
 
 
3831
        if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
 
3832
          return $(document.body);
 
3833
 
 
3834
        var position = element.getStyle('position');
 
3835
        if (position !== 'static') return proceed(element);
 
3836
 
 
3837
        element.setStyle({ position: 'relative' });
 
3838
        var value = proceed(element);
 
3839
        element.setStyle({ position: position });
 
3840
        return value;
 
3841
      }
 
3842
    );
 
3843
 
 
3844
    positionedOffset = positionedOffset.wrap(function(proceed, element) {
 
3845
      element = $(element);
 
3846
      if (!element.parentNode) return new Element.Offset(0, 0);
 
3847
      var position = element.getStyle('position');
 
3848
      if (position !== 'static') return proceed(element);
 
3849
 
 
3850
      var offsetParent = element.getOffsetParent();
 
3851
      if (offsetParent && offsetParent.getStyle('position') === 'fixed')
 
3852
        hasLayout(offsetParent);
 
3853
 
 
3854
      element.setStyle({ position: 'relative' });
 
3855
      var value = proceed(element);
 
3856
      element.setStyle({ position: position });
 
3857
      return value;
 
3858
    });
 
3859
  } else if (Prototype.Browser.Webkit) {
 
3860
    cumulativeOffset = function(element) {
 
3861
      element = $(element);
 
3862
      var valueT = 0, valueL = 0;
 
3863
      do {
 
3864
        valueT += element.offsetTop  || 0;
 
3865
        valueL += element.offsetLeft || 0;
 
3866
        if (element.offsetParent == document.body)
 
3867
          if (Element.getStyle(element, 'position') == 'absolute') break;
 
3868
 
 
3869
        element = element.offsetParent;
 
3870
      } while (element);
 
3871
 
 
3872
      return new Element.Offset(valueL, valueT);
 
3873
    };
 
3874
  }
 
3875
 
 
3876
 
 
3877
  Element.addMethods({
 
3878
    getLayout:              getLayout,
 
3879
    measure:                measure,
 
3880
    getDimensions:          getDimensions,
 
3881
    getOffsetParent:        getOffsetParent,
 
3882
    cumulativeOffset:       cumulativeOffset,
 
3883
    positionedOffset:       positionedOffset,
 
3884
    cumulativeScrollOffset: cumulativeScrollOffset,
 
3885
    viewportOffset:         viewportOffset,
 
3886
    absolutize:             absolutize,
 
3887
    relativize:             relativize
 
3888
  });
 
3889
 
 
3890
  function isBody(element) {
 
3891
    return element.nodeName.toUpperCase() === 'BODY';
 
3892
  }
 
3893
 
 
3894
  function isHtml(element) {
 
3895
    return element.nodeName.toUpperCase() === 'HTML';
 
3896
  }
 
3897
 
 
3898
  function isDocument(element) {
 
3899
    return element.nodeType === Node.DOCUMENT_NODE;
 
3900
  }
 
3901
 
 
3902
  function isDetached(element) {
 
3903
    return element !== document.body &&
 
3904
     !Element.descendantOf(element, document.body);
 
3905
  }
 
3906
 
 
3907
  if ('getBoundingClientRect' in document.documentElement) {
 
3908
    Element.addMethods({
 
3909
      viewportOffset: function(element) {
 
3910
        element = $(element);
 
3911
        if (isDetached(element)) return new Element.Offset(0, 0);
 
3912
 
 
3913
        var rect = element.getBoundingClientRect(),
 
3914
         docEl = document.documentElement;
 
3915
        return new Element.Offset(rect.left - docEl.clientLeft,
 
3916
         rect.top - docEl.clientTop);
 
3917
      }
 
3918
    });
 
3919
  }
 
3920
})();
 
3921
window.$$ = function() {
 
3922
  var expression = $A(arguments).join(', ');
 
3923
  return Prototype.Selector.select(expression, document);
 
3924
};
 
3925
 
 
3926
Prototype.Selector = (function() {
 
3927
 
 
3928
  function select() {
 
3929
    throw new Error('Method "Prototype.Selector.select" must be defined.');
 
3930
  }
 
3931
 
 
3932
  function match() {
 
3933
    throw new Error('Method "Prototype.Selector.match" must be defined.');
 
3934
  }
 
3935
 
 
3936
  function find(elements, expression, index) {
 
3937
    index = index || 0;
 
3938
    var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
 
3939
 
 
3940
    for (i = 0; i < length; i++) {
 
3941
      if (match(elements[i], expression) && index == matchIndex++) {
 
3942
        return Element.extend(elements[i]);
 
3943
      }
 
3944
    }
 
3945
  }
 
3946
 
 
3947
  function extendElements(elements) {
 
3948
    for (var i = 0, length = elements.length; i < length; i++) {
 
3949
      Element.extend(elements[i]);
 
3950
    }
 
3951
    return elements;
 
3952
  }
 
3953
 
 
3954
 
 
3955
  var K = Prototype.K;
 
3956
 
 
3957
  return {
 
3958
    select: select,
 
3959
    match: match,
 
3960
    find: find,
 
3961
    extendElements: (Element.extend === K) ? K : extendElements,
 
3962
    extendElement: Element.extend
3318
3963
  };
3319
 
}
3320
 
 
3321
 
function $$() {
3322
 
  return Selector.findChildElements(document, $A(arguments));
3323
 
}
 
3964
})();
 
3965
Prototype._original_property = window.Sizzle;
 
3966
/*!
 
3967
 * Sizzle CSS Selector Engine - v1.0
 
3968
 *  Copyright 2009, The Dojo Foundation
 
3969
 *  Released under the MIT, BSD, and GPL Licenses.
 
3970
 *  More information: http://sizzlejs.com/
 
3971
 */
 
3972
(function(){
 
3973
 
 
3974
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
 
3975
        done = 0,
 
3976
        toString = Object.prototype.toString,
 
3977
        hasDuplicate = false,
 
3978
        baseHasDuplicate = true;
 
3979
 
 
3980
[0, 0].sort(function(){
 
3981
        baseHasDuplicate = false;
 
3982
        return 0;
 
3983
});
 
3984
 
 
3985
var Sizzle = function(selector, context, results, seed) {
 
3986
        results = results || [];
 
3987
        var origContext = context = context || document;
 
3988
 
 
3989
        if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
 
3990
                return [];
 
3991
        }
 
3992
 
 
3993
        if ( !selector || typeof selector !== "string" ) {
 
3994
                return results;
 
3995
        }
 
3996
 
 
3997
        var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
 
3998
                soFar = selector;
 
3999
 
 
4000
        while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
 
4001
                soFar = m[3];
 
4002
 
 
4003
                parts.push( m[1] );
 
4004
 
 
4005
                if ( m[2] ) {
 
4006
                        extra = m[3];
 
4007
                        break;
 
4008
                }
 
4009
        }
 
4010
 
 
4011
        if ( parts.length > 1 && origPOS.exec( selector ) ) {
 
4012
                if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
 
4013
                        set = posProcess( parts[0] + parts[1], context );
 
4014
                } else {
 
4015
                        set = Expr.relative[ parts[0] ] ?
 
4016
                                [ context ] :
 
4017
                                Sizzle( parts.shift(), context );
 
4018
 
 
4019
                        while ( parts.length ) {
 
4020
                                selector = parts.shift();
 
4021
 
 
4022
                                if ( Expr.relative[ selector ] )
 
4023
                                        selector += parts.shift();
 
4024
 
 
4025
                                set = posProcess( selector, set );
 
4026
                        }
 
4027
                }
 
4028
        } else {
 
4029
                if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
 
4030
                                Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
 
4031
                        var ret = Sizzle.find( parts.shift(), context, contextXML );
 
4032
                        context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
 
4033
                }
 
4034
 
 
4035
                if ( context ) {
 
4036
                        var ret = seed ?
 
4037
                                { expr: parts.pop(), set: makeArray(seed) } :
 
4038
                                Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
 
4039
                        set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
 
4040
 
 
4041
                        if ( parts.length > 0 ) {
 
4042
                                checkSet = makeArray(set);
 
4043
                        } else {
 
4044
                                prune = false;
 
4045
                        }
 
4046
 
 
4047
                        while ( parts.length ) {
 
4048
                                var cur = parts.pop(), pop = cur;
 
4049
 
 
4050
                                if ( !Expr.relative[ cur ] ) {
 
4051
                                        cur = "";
 
4052
                                } else {
 
4053
                                        pop = parts.pop();
 
4054
                                }
 
4055
 
 
4056
                                if ( pop == null ) {
 
4057
                                        pop = context;
 
4058
                                }
 
4059
 
 
4060
                                Expr.relative[ cur ]( checkSet, pop, contextXML );
 
4061
                        }
 
4062
                } else {
 
4063
                        checkSet = parts = [];
 
4064
                }
 
4065
        }
 
4066
 
 
4067
        if ( !checkSet ) {
 
4068
                checkSet = set;
 
4069
        }
 
4070
 
 
4071
        if ( !checkSet ) {
 
4072
                throw "Syntax error, unrecognized expression: " + (cur || selector);
 
4073
        }
 
4074
 
 
4075
        if ( toString.call(checkSet) === "[object Array]" ) {
 
4076
                if ( !prune ) {
 
4077
                        results.push.apply( results, checkSet );
 
4078
                } else if ( context && context.nodeType === 1 ) {
 
4079
                        for ( var i = 0; checkSet[i] != null; i++ ) {
 
4080
                                if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
 
4081
                                        results.push( set[i] );
 
4082
                                }
 
4083
                        }
 
4084
                } else {
 
4085
                        for ( var i = 0; checkSet[i] != null; i++ ) {
 
4086
                                if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
 
4087
                                        results.push( set[i] );
 
4088
                                }
 
4089
                        }
 
4090
                }
 
4091
        } else {
 
4092
                makeArray( checkSet, results );
 
4093
        }
 
4094
 
 
4095
        if ( extra ) {
 
4096
                Sizzle( extra, origContext, results, seed );
 
4097
                Sizzle.uniqueSort( results );
 
4098
        }
 
4099
 
 
4100
        return results;
 
4101
};
 
4102
 
 
4103
Sizzle.uniqueSort = function(results){
 
4104
        if ( sortOrder ) {
 
4105
                hasDuplicate = baseHasDuplicate;
 
4106
                results.sort(sortOrder);
 
4107
 
 
4108
                if ( hasDuplicate ) {
 
4109
                        for ( var i = 1; i < results.length; i++ ) {
 
4110
                                if ( results[i] === results[i-1] ) {
 
4111
                                        results.splice(i--, 1);
 
4112
                                }
 
4113
                        }
 
4114
                }
 
4115
        }
 
4116
 
 
4117
        return results;
 
4118
};
 
4119
 
 
4120
Sizzle.matches = function(expr, set){
 
4121
        return Sizzle(expr, null, null, set);
 
4122
};
 
4123
 
 
4124
Sizzle.find = function(expr, context, isXML){
 
4125
        var set, match;
 
4126
 
 
4127
        if ( !expr ) {
 
4128
                return [];
 
4129
        }
 
4130
 
 
4131
        for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
 
4132
                var type = Expr.order[i], match;
 
4133
 
 
4134
                if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
 
4135
                        var left = match[1];
 
4136
                        match.splice(1,1);
 
4137
 
 
4138
                        if ( left.substr( left.length - 1 ) !== "\\" ) {
 
4139
                                match[1] = (match[1] || "").replace(/\\/g, "");
 
4140
                                set = Expr.find[ type ]( match, context, isXML );
 
4141
                                if ( set != null ) {
 
4142
                                        expr = expr.replace( Expr.match[ type ], "" );
 
4143
                                        break;
 
4144
                                }
 
4145
                        }
 
4146
                }
 
4147
        }
 
4148
 
 
4149
        if ( !set ) {
 
4150
                set = context.getElementsByTagName("*");
 
4151
        }
 
4152
 
 
4153
        return {set: set, expr: expr};
 
4154
};
 
4155
 
 
4156
Sizzle.filter = function(expr, set, inplace, not){
 
4157
        var old = expr, result = [], curLoop = set, match, anyFound,
 
4158
                isXMLFilter = set && set[0] && isXML(set[0]);
 
4159
 
 
4160
        while ( expr && set.length ) {
 
4161
                for ( var type in Expr.filter ) {
 
4162
                        if ( (match = Expr.match[ type ].exec( expr )) != null ) {
 
4163
                                var filter = Expr.filter[ type ], found, item;
 
4164
                                anyFound = false;
 
4165
 
 
4166
                                if ( curLoop == result ) {
 
4167
                                        result = [];
 
4168
                                }
 
4169
 
 
4170
                                if ( Expr.preFilter[ type ] ) {
 
4171
                                        match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
 
4172
 
 
4173
                                        if ( !match ) {
 
4174
                                                anyFound = found = true;
 
4175
                                        } else if ( match === true ) {
 
4176
                                                continue;
 
4177
                                        }
 
4178
                                }
 
4179
 
 
4180
                                if ( match ) {
 
4181
                                        for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
 
4182
                                                if ( item ) {
 
4183
                                                        found = filter( item, match, i, curLoop );
 
4184
                                                        var pass = not ^ !!found;
 
4185
 
 
4186
                                                        if ( inplace && found != null ) {
 
4187
                                                                if ( pass ) {
 
4188
                                                                        anyFound = true;
 
4189
                                                                } else {
 
4190
                                                                        curLoop[i] = false;
 
4191
                                                                }
 
4192
                                                        } else if ( pass ) {
 
4193
                                                                result.push( item );
 
4194
                                                                anyFound = true;
 
4195
                                                        }
 
4196
                                                }
 
4197
                                        }
 
4198
                                }
 
4199
 
 
4200
                                if ( found !== undefined ) {
 
4201
                                        if ( !inplace ) {
 
4202
                                                curLoop = result;
 
4203
                                        }
 
4204
 
 
4205
                                        expr = expr.replace( Expr.match[ type ], "" );
 
4206
 
 
4207
                                        if ( !anyFound ) {
 
4208
                                                return [];
 
4209
                                        }
 
4210
 
 
4211
                                        break;
 
4212
                                }
 
4213
                        }
 
4214
                }
 
4215
 
 
4216
                if ( expr == old ) {
 
4217
                        if ( anyFound == null ) {
 
4218
                                throw "Syntax error, unrecognized expression: " + expr;
 
4219
                        } else {
 
4220
                                break;
 
4221
                        }
 
4222
                }
 
4223
 
 
4224
                old = expr;
 
4225
        }
 
4226
 
 
4227
        return curLoop;
 
4228
};
 
4229
 
 
4230
var Expr = Sizzle.selectors = {
 
4231
        order: [ "ID", "NAME", "TAG" ],
 
4232
        match: {
 
4233
                ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
 
4234
                CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
 
4235
                NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
 
4236
                ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
 
4237
                TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
 
4238
                CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
 
4239
                POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
 
4240
                PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
 
4241
        },
 
4242
        leftMatch: {},
 
4243
        attrMap: {
 
4244
                "class": "className",
 
4245
                "for": "htmlFor"
 
4246
        },
 
4247
        attrHandle: {
 
4248
                href: function(elem){
 
4249
                        return elem.getAttribute("href");
 
4250
                }
 
4251
        },
 
4252
        relative: {
 
4253
                "+": function(checkSet, part, isXML){
 
4254
                        var isPartStr = typeof part === "string",
 
4255
                                isTag = isPartStr && !/\W/.test(part),
 
4256
                                isPartStrNotTag = isPartStr && !isTag;
 
4257
 
 
4258
                        if ( isTag && !isXML ) {
 
4259
                                part = part.toUpperCase();
 
4260
                        }
 
4261
 
 
4262
                        for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
 
4263
                                if ( (elem = checkSet[i]) ) {
 
4264
                                        while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
 
4265
 
 
4266
                                        checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
 
4267
                                                elem || false :
 
4268
                                                elem === part;
 
4269
                                }
 
4270
                        }
 
4271
 
 
4272
                        if ( isPartStrNotTag ) {
 
4273
                                Sizzle.filter( part, checkSet, true );
 
4274
                        }
 
4275
                },
 
4276
                ">": function(checkSet, part, isXML){
 
4277
                        var isPartStr = typeof part === "string";
 
4278
 
 
4279
                        if ( isPartStr && !/\W/.test(part) ) {
 
4280
                                part = isXML ? part : part.toUpperCase();
 
4281
 
 
4282
                                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
4283
                                        var elem = checkSet[i];
 
4284
                                        if ( elem ) {
 
4285
                                                var parent = elem.parentNode;
 
4286
                                                checkSet[i] = parent.nodeName === part ? parent : false;
 
4287
                                        }
 
4288
                                }
 
4289
                        } else {
 
4290
                                for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
4291
                                        var elem = checkSet[i];
 
4292
                                        if ( elem ) {
 
4293
                                                checkSet[i] = isPartStr ?
 
4294
                                                        elem.parentNode :
 
4295
                                                        elem.parentNode === part;
 
4296
                                        }
 
4297
                                }
 
4298
 
 
4299
                                if ( isPartStr ) {
 
4300
                                        Sizzle.filter( part, checkSet, true );
 
4301
                                }
 
4302
                        }
 
4303
                },
 
4304
                "": function(checkSet, part, isXML){
 
4305
                        var doneName = done++, checkFn = dirCheck;
 
4306
 
 
4307
                        if ( !/\W/.test(part) ) {
 
4308
                                var nodeCheck = part = isXML ? part : part.toUpperCase();
 
4309
                                checkFn = dirNodeCheck;
 
4310
                        }
 
4311
 
 
4312
                        checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
 
4313
                },
 
4314
                "~": function(checkSet, part, isXML){
 
4315
                        var doneName = done++, checkFn = dirCheck;
 
4316
 
 
4317
                        if ( typeof part === "string" && !/\W/.test(part) ) {
 
4318
                                var nodeCheck = part = isXML ? part : part.toUpperCase();
 
4319
                                checkFn = dirNodeCheck;
 
4320
                        }
 
4321
 
 
4322
                        checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
 
4323
                }
 
4324
        },
 
4325
        find: {
 
4326
                ID: function(match, context, isXML){
 
4327
                        if ( typeof context.getElementById !== "undefined" && !isXML ) {
 
4328
                                var m = context.getElementById(match[1]);
 
4329
                                return m ? [m] : [];
 
4330
                        }
 
4331
                },
 
4332
                NAME: function(match, context, isXML){
 
4333
                        if ( typeof context.getElementsByName !== "undefined" ) {
 
4334
                                var ret = [], results = context.getElementsByName(match[1]);
 
4335
 
 
4336
                                for ( var i = 0, l = results.length; i < l; i++ ) {
 
4337
                                        if ( results[i].getAttribute("name") === match[1] ) {
 
4338
                                                ret.push( results[i] );
 
4339
                                        }
 
4340
                                }
 
4341
 
 
4342
                                return ret.length === 0 ? null : ret;
 
4343
                        }
 
4344
                },
 
4345
                TAG: function(match, context){
 
4346
                        return context.getElementsByTagName(match[1]);
 
4347
                }
 
4348
        },
 
4349
        preFilter: {
 
4350
                CLASS: function(match, curLoop, inplace, result, not, isXML){
 
4351
                        match = " " + match[1].replace(/\\/g, "") + " ";
 
4352
 
 
4353
                        if ( isXML ) {
 
4354
                                return match;
 
4355
                        }
 
4356
 
 
4357
                        for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
 
4358
                                if ( elem ) {
 
4359
                                        if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
 
4360
                                                if ( !inplace )
 
4361
                                                        result.push( elem );
 
4362
                                        } else if ( inplace ) {
 
4363
                                                curLoop[i] = false;
 
4364
                                        }
 
4365
                                }
 
4366
                        }
 
4367
 
 
4368
                        return false;
 
4369
                },
 
4370
                ID: function(match){
 
4371
                        return match[1].replace(/\\/g, "");
 
4372
                },
 
4373
                TAG: function(match, curLoop){
 
4374
                        for ( var i = 0; curLoop[i] === false; i++ ){}
 
4375
                        return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
 
4376
                },
 
4377
                CHILD: function(match){
 
4378
                        if ( match[1] == "nth" ) {
 
4379
                                var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
 
4380
                                        match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
 
4381
                                        !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
 
4382
 
 
4383
                                match[2] = (test[1] + (test[2] || 1)) - 0;
 
4384
                                match[3] = test[3] - 0;
 
4385
                        }
 
4386
 
 
4387
                        match[0] = done++;
 
4388
 
 
4389
                        return match;
 
4390
                },
 
4391
                ATTR: function(match, curLoop, inplace, result, not, isXML){
 
4392
                        var name = match[1].replace(/\\/g, "");
 
4393
 
 
4394
                        if ( !isXML && Expr.attrMap[name] ) {
 
4395
                                match[1] = Expr.attrMap[name];
 
4396
                        }
 
4397
 
 
4398
                        if ( match[2] === "~=" ) {
 
4399
                                match[4] = " " + match[4] + " ";
 
4400
                        }
 
4401
 
 
4402
                        return match;
 
4403
                },
 
4404
                PSEUDO: function(match, curLoop, inplace, result, not){
 
4405
                        if ( match[1] === "not" ) {
 
4406
                                if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
 
4407
                                        match[3] = Sizzle(match[3], null, null, curLoop);
 
4408
                                } else {
 
4409
                                        var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
 
4410
                                        if ( !inplace ) {
 
4411
                                                result.push.apply( result, ret );
 
4412
                                        }
 
4413
                                        return false;
 
4414
                                }
 
4415
                        } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
 
4416
                                return true;
 
4417
                        }
 
4418
 
 
4419
                        return match;
 
4420
                },
 
4421
                POS: function(match){
 
4422
                        match.unshift( true );
 
4423
                        return match;
 
4424
                }
 
4425
        },
 
4426
        filters: {
 
4427
                enabled: function(elem){
 
4428
                        return elem.disabled === false && elem.type !== "hidden";
 
4429
                },
 
4430
                disabled: function(elem){
 
4431
                        return elem.disabled === true;
 
4432
                },
 
4433
                checked: function(elem){
 
4434
                        return elem.checked === true;
 
4435
                },
 
4436
                selected: function(elem){
 
4437
                        elem.parentNode.selectedIndex;
 
4438
                        return elem.selected === true;
 
4439
                },
 
4440
                parent: function(elem){
 
4441
                        return !!elem.firstChild;
 
4442
                },
 
4443
                empty: function(elem){
 
4444
                        return !elem.firstChild;
 
4445
                },
 
4446
                has: function(elem, i, match){
 
4447
                        return !!Sizzle( match[3], elem ).length;
 
4448
                },
 
4449
                header: function(elem){
 
4450
                        return /h\d/i.test( elem.nodeName );
 
4451
                },
 
4452
                text: function(elem){
 
4453
                        return "text" === elem.type;
 
4454
                },
 
4455
                radio: function(elem){
 
4456
                        return "radio" === elem.type;
 
4457
                },
 
4458
                checkbox: function(elem){
 
4459
                        return "checkbox" === elem.type;
 
4460
                },
 
4461
                file: function(elem){
 
4462
                        return "file" === elem.type;
 
4463
                },
 
4464
                password: function(elem){
 
4465
                        return "password" === elem.type;
 
4466
                },
 
4467
                submit: function(elem){
 
4468
                        return "submit" === elem.type;
 
4469
                },
 
4470
                image: function(elem){
 
4471
                        return "image" === elem.type;
 
4472
                },
 
4473
                reset: function(elem){
 
4474
                        return "reset" === elem.type;
 
4475
                },
 
4476
                button: function(elem){
 
4477
                        return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
 
4478
                },
 
4479
                input: function(elem){
 
4480
                        return /input|select|textarea|button/i.test(elem.nodeName);
 
4481
                }
 
4482
        },
 
4483
        setFilters: {
 
4484
                first: function(elem, i){
 
4485
                        return i === 0;
 
4486
                },
 
4487
                last: function(elem, i, match, array){
 
4488
                        return i === array.length - 1;
 
4489
                },
 
4490
                even: function(elem, i){
 
4491
                        return i % 2 === 0;
 
4492
                },
 
4493
                odd: function(elem, i){
 
4494
                        return i % 2 === 1;
 
4495
                },
 
4496
                lt: function(elem, i, match){
 
4497
                        return i < match[3] - 0;
 
4498
                },
 
4499
                gt: function(elem, i, match){
 
4500
                        return i > match[3] - 0;
 
4501
                },
 
4502
                nth: function(elem, i, match){
 
4503
                        return match[3] - 0 == i;
 
4504
                },
 
4505
                eq: function(elem, i, match){
 
4506
                        return match[3] - 0 == i;
 
4507
                }
 
4508
        },
 
4509
        filter: {
 
4510
                PSEUDO: function(elem, match, i, array){
 
4511
                        var name = match[1], filter = Expr.filters[ name ];
 
4512
 
 
4513
                        if ( filter ) {
 
4514
                                return filter( elem, i, match, array );
 
4515
                        } else if ( name === "contains" ) {
 
4516
                                return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
 
4517
                        } else if ( name === "not" ) {
 
4518
                                var not = match[3];
 
4519
 
 
4520
                                for ( var i = 0, l = not.length; i < l; i++ ) {
 
4521
                                        if ( not[i] === elem ) {
 
4522
                                                return false;
 
4523
                                        }
 
4524
                                }
 
4525
 
 
4526
                                return true;
 
4527
                        }
 
4528
                },
 
4529
                CHILD: function(elem, match){
 
4530
                        var type = match[1], node = elem;
 
4531
                        switch (type) {
 
4532
                                case 'only':
 
4533
                                case 'first':
 
4534
                                        while ( (node = node.previousSibling) )  {
 
4535
                                                if ( node.nodeType === 1 ) return false;
 
4536
                                        }
 
4537
                                        if ( type == 'first') return true;
 
4538
                                        node = elem;
 
4539
                                case 'last':
 
4540
                                        while ( (node = node.nextSibling) )  {
 
4541
                                                if ( node.nodeType === 1 ) return false;
 
4542
                                        }
 
4543
                                        return true;
 
4544
                                case 'nth':
 
4545
                                        var first = match[2], last = match[3];
 
4546
 
 
4547
                                        if ( first == 1 && last == 0 ) {
 
4548
                                                return true;
 
4549
                                        }
 
4550
 
 
4551
                                        var doneName = match[0],
 
4552
                                                parent = elem.parentNode;
 
4553
 
 
4554
                                        if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
 
4555
                                                var count = 0;
 
4556
                                                for ( node = parent.firstChild; node; node = node.nextSibling ) {
 
4557
                                                        if ( node.nodeType === 1 ) {
 
4558
                                                                node.nodeIndex = ++count;
 
4559
                                                        }
 
4560
                                                }
 
4561
                                                parent.sizcache = doneName;
 
4562
                                        }
 
4563
 
 
4564
                                        var diff = elem.nodeIndex - last;
 
4565
                                        if ( first == 0 ) {
 
4566
                                                return diff == 0;
 
4567
                                        } else {
 
4568
                                                return ( diff % first == 0 && diff / first >= 0 );
 
4569
                                        }
 
4570
                        }
 
4571
                },
 
4572
                ID: function(elem, match){
 
4573
                        return elem.nodeType === 1 && elem.getAttribute("id") === match;
 
4574
                },
 
4575
                TAG: function(elem, match){
 
4576
                        return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
 
4577
                },
 
4578
                CLASS: function(elem, match){
 
4579
                        return (" " + (elem.className || elem.getAttribute("class")) + " ")
 
4580
                                .indexOf( match ) > -1;
 
4581
                },
 
4582
                ATTR: function(elem, match){
 
4583
                        var name = match[1],
 
4584
                                result = Expr.attrHandle[ name ] ?
 
4585
                                        Expr.attrHandle[ name ]( elem ) :
 
4586
                                        elem[ name ] != null ?
 
4587
                                                elem[ name ] :
 
4588
                                                elem.getAttribute( name ),
 
4589
                                value = result + "",
 
4590
                                type = match[2],
 
4591
                                check = match[4];
 
4592
 
 
4593
                        return result == null ?
 
4594
                                type === "!=" :
 
4595
                                type === "=" ?
 
4596
                                value === check :
 
4597
                                type === "*=" ?
 
4598
                                value.indexOf(check) >= 0 :
 
4599
                                type === "~=" ?
 
4600
                                (" " + value + " ").indexOf(check) >= 0 :
 
4601
                                !check ?
 
4602
                                value && result !== false :
 
4603
                                type === "!=" ?
 
4604
                                value != check :
 
4605
                                type === "^=" ?
 
4606
                                value.indexOf(check) === 0 :
 
4607
                                type === "$=" ?
 
4608
                                value.substr(value.length - check.length) === check :
 
4609
                                type === "|=" ?
 
4610
                                value === check || value.substr(0, check.length + 1) === check + "-" :
 
4611
                                false;
 
4612
                },
 
4613
                POS: function(elem, match, i, array){
 
4614
                        var name = match[2], filter = Expr.setFilters[ name ];
 
4615
 
 
4616
                        if ( filter ) {
 
4617
                                return filter( elem, i, match, array );
 
4618
                        }
 
4619
                }
 
4620
        }
 
4621
};
 
4622
 
 
4623
var origPOS = Expr.match.POS;
 
4624
 
 
4625
for ( var type in Expr.match ) {
 
4626
        Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
 
4627
        Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
 
4628
}
 
4629
 
 
4630
var makeArray = function(array, results) {
 
4631
        array = Array.prototype.slice.call( array, 0 );
 
4632
 
 
4633
        if ( results ) {
 
4634
                results.push.apply( results, array );
 
4635
                return results;
 
4636
        }
 
4637
 
 
4638
        return array;
 
4639
};
 
4640
 
 
4641
try {
 
4642
        Array.prototype.slice.call( document.documentElement.childNodes, 0 );
 
4643
 
 
4644
} catch(e){
 
4645
        makeArray = function(array, results) {
 
4646
                var ret = results || [];
 
4647
 
 
4648
                if ( toString.call(array) === "[object Array]" ) {
 
4649
                        Array.prototype.push.apply( ret, array );
 
4650
                } else {
 
4651
                        if ( typeof array.length === "number" ) {
 
4652
                                for ( var i = 0, l = array.length; i < l; i++ ) {
 
4653
                                        ret.push( array[i] );
 
4654
                                }
 
4655
                        } else {
 
4656
                                for ( var i = 0; array[i]; i++ ) {
 
4657
                                        ret.push( array[i] );
 
4658
                                }
 
4659
                        }
 
4660
                }
 
4661
 
 
4662
                return ret;
 
4663
        };
 
4664
}
 
4665
 
 
4666
var sortOrder;
 
4667
 
 
4668
if ( document.documentElement.compareDocumentPosition ) {
 
4669
        sortOrder = function( a, b ) {
 
4670
                if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
 
4671
                        if ( a == b ) {
 
4672
                                hasDuplicate = true;
 
4673
                        }
 
4674
                        return 0;
 
4675
                }
 
4676
 
 
4677
                var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
 
4678
                if ( ret === 0 ) {
 
4679
                        hasDuplicate = true;
 
4680
                }
 
4681
                return ret;
 
4682
        };
 
4683
} else if ( "sourceIndex" in document.documentElement ) {
 
4684
        sortOrder = function( a, b ) {
 
4685
                if ( !a.sourceIndex || !b.sourceIndex ) {
 
4686
                        if ( a == b ) {
 
4687
                                hasDuplicate = true;
 
4688
                        }
 
4689
                        return 0;
 
4690
                }
 
4691
 
 
4692
                var ret = a.sourceIndex - b.sourceIndex;
 
4693
                if ( ret === 0 ) {
 
4694
                        hasDuplicate = true;
 
4695
                }
 
4696
                return ret;
 
4697
        };
 
4698
} else if ( document.createRange ) {
 
4699
        sortOrder = function( a, b ) {
 
4700
                if ( !a.ownerDocument || !b.ownerDocument ) {
 
4701
                        if ( a == b ) {
 
4702
                                hasDuplicate = true;
 
4703
                        }
 
4704
                        return 0;
 
4705
                }
 
4706
 
 
4707
                var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
 
4708
                aRange.setStart(a, 0);
 
4709
                aRange.setEnd(a, 0);
 
4710
                bRange.setStart(b, 0);
 
4711
                bRange.setEnd(b, 0);
 
4712
                var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
 
4713
                if ( ret === 0 ) {
 
4714
                        hasDuplicate = true;
 
4715
                }
 
4716
                return ret;
 
4717
        };
 
4718
}
 
4719
 
 
4720
(function(){
 
4721
        var form = document.createElement("div"),
 
4722
                id = "script" + (new Date).getTime();
 
4723
        form.innerHTML = "<a name='" + id + "'/>";
 
4724
 
 
4725
        var root = document.documentElement;
 
4726
        root.insertBefore( form, root.firstChild );
 
4727
 
 
4728
        if ( !!document.getElementById( id ) ) {
 
4729
                Expr.find.ID = function(match, context, isXML){
 
4730
                        if ( typeof context.getElementById !== "undefined" && !isXML ) {
 
4731
                                var m = context.getElementById(match[1]);
 
4732
                                return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
 
4733
                        }
 
4734
                };
 
4735
 
 
4736
                Expr.filter.ID = function(elem, match){
 
4737
                        var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
 
4738
                        return elem.nodeType === 1 && node && node.nodeValue === match;
 
4739
                };
 
4740
        }
 
4741
 
 
4742
        root.removeChild( form );
 
4743
        root = form = null; // release memory in IE
 
4744
})();
 
4745
 
 
4746
(function(){
 
4747
 
 
4748
        var div = document.createElement("div");
 
4749
        div.appendChild( document.createComment("") );
 
4750
 
 
4751
        if ( div.getElementsByTagName("*").length > 0 ) {
 
4752
                Expr.find.TAG = function(match, context){
 
4753
                        var results = context.getElementsByTagName(match[1]);
 
4754
 
 
4755
                        if ( match[1] === "*" ) {
 
4756
                                var tmp = [];
 
4757
 
 
4758
                                for ( var i = 0; results[i]; i++ ) {
 
4759
                                        if ( results[i].nodeType === 1 ) {
 
4760
                                                tmp.push( results[i] );
 
4761
                                        }
 
4762
                                }
 
4763
 
 
4764
                                results = tmp;
 
4765
                        }
 
4766
 
 
4767
                        return results;
 
4768
                };
 
4769
        }
 
4770
 
 
4771
        div.innerHTML = "<a href='#'></a>";
 
4772
        if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
 
4773
                        div.firstChild.getAttribute("href") !== "#" ) {
 
4774
                Expr.attrHandle.href = function(elem){
 
4775
                        return elem.getAttribute("href", 2);
 
4776
                };
 
4777
        }
 
4778
 
 
4779
        div = null; // release memory in IE
 
4780
})();
 
4781
 
 
4782
if ( document.querySelectorAll ) (function(){
 
4783
        var oldSizzle = Sizzle, div = document.createElement("div");
 
4784
        div.innerHTML = "<p class='TEST'></p>";
 
4785
 
 
4786
        if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
 
4787
                return;
 
4788
        }
 
4789
 
 
4790
        Sizzle = function(query, context, extra, seed){
 
4791
                context = context || document;
 
4792
 
 
4793
                if ( !seed && context.nodeType === 9 && !isXML(context) ) {
 
4794
                        try {
 
4795
                                return makeArray( context.querySelectorAll(query), extra );
 
4796
                        } catch(e){}
 
4797
                }
 
4798
 
 
4799
                return oldSizzle(query, context, extra, seed);
 
4800
        };
 
4801
 
 
4802
        for ( var prop in oldSizzle ) {
 
4803
                Sizzle[ prop ] = oldSizzle[ prop ];
 
4804
        }
 
4805
 
 
4806
        div = null; // release memory in IE
 
4807
})();
 
4808
 
 
4809
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
 
4810
        var div = document.createElement("div");
 
4811
        div.innerHTML = "<div class='test e'></div><div class='test'></div>";
 
4812
 
 
4813
        if ( div.getElementsByClassName("e").length === 0 )
 
4814
                return;
 
4815
 
 
4816
        div.lastChild.className = "e";
 
4817
 
 
4818
        if ( div.getElementsByClassName("e").length === 1 )
 
4819
                return;
 
4820
 
 
4821
        Expr.order.splice(1, 0, "CLASS");
 
4822
        Expr.find.CLASS = function(match, context, isXML) {
 
4823
                if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
 
4824
                        return context.getElementsByClassName(match[1]);
 
4825
                }
 
4826
        };
 
4827
 
 
4828
        div = null; // release memory in IE
 
4829
})();
 
4830
 
 
4831
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
 
4832
        var sibDir = dir == "previousSibling" && !isXML;
 
4833
        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
4834
                var elem = checkSet[i];
 
4835
                if ( elem ) {
 
4836
                        if ( sibDir && elem.nodeType === 1 ){
 
4837
                                elem.sizcache = doneName;
 
4838
                                elem.sizset = i;
 
4839
                        }
 
4840
                        elem = elem[dir];
 
4841
                        var match = false;
 
4842
 
 
4843
                        while ( elem ) {
 
4844
                                if ( elem.sizcache === doneName ) {
 
4845
                                        match = checkSet[elem.sizset];
 
4846
                                        break;
 
4847
                                }
 
4848
 
 
4849
                                if ( elem.nodeType === 1 && !isXML ){
 
4850
                                        elem.sizcache = doneName;
 
4851
                                        elem.sizset = i;
 
4852
                                }
 
4853
 
 
4854
                                if ( elem.nodeName === cur ) {
 
4855
                                        match = elem;
 
4856
                                        break;
 
4857
                                }
 
4858
 
 
4859
                                elem = elem[dir];
 
4860
                        }
 
4861
 
 
4862
                        checkSet[i] = match;
 
4863
                }
 
4864
        }
 
4865
}
 
4866
 
 
4867
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
 
4868
        var sibDir = dir == "previousSibling" && !isXML;
 
4869
        for ( var i = 0, l = checkSet.length; i < l; i++ ) {
 
4870
                var elem = checkSet[i];
 
4871
                if ( elem ) {
 
4872
                        if ( sibDir && elem.nodeType === 1 ) {
 
4873
                                elem.sizcache = doneName;
 
4874
                                elem.sizset = i;
 
4875
                        }
 
4876
                        elem = elem[dir];
 
4877
                        var match = false;
 
4878
 
 
4879
                        while ( elem ) {
 
4880
                                if ( elem.sizcache === doneName ) {
 
4881
                                        match = checkSet[elem.sizset];
 
4882
                                        break;
 
4883
                                }
 
4884
 
 
4885
                                if ( elem.nodeType === 1 ) {
 
4886
                                        if ( !isXML ) {
 
4887
                                                elem.sizcache = doneName;
 
4888
                                                elem.sizset = i;
 
4889
                                        }
 
4890
                                        if ( typeof cur !== "string" ) {
 
4891
                                                if ( elem === cur ) {
 
4892
                                                        match = true;
 
4893
                                                        break;
 
4894
                                                }
 
4895
 
 
4896
                                        } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
 
4897
                                                match = elem;
 
4898
                                                break;
 
4899
                                        }
 
4900
                                }
 
4901
 
 
4902
                                elem = elem[dir];
 
4903
                        }
 
4904
 
 
4905
                        checkSet[i] = match;
 
4906
                }
 
4907
        }
 
4908
}
 
4909
 
 
4910
var contains = document.compareDocumentPosition ?  function(a, b){
 
4911
        return a.compareDocumentPosition(b) & 16;
 
4912
} : function(a, b){
 
4913
        return a !== b && (a.contains ? a.contains(b) : true);
 
4914
};
 
4915
 
 
4916
var isXML = function(elem){
 
4917
        return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
 
4918
                !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
 
4919
};
 
4920
 
 
4921
var posProcess = function(selector, context){
 
4922
        var tmpSet = [], later = "", match,
 
4923
                root = context.nodeType ? [context] : context;
 
4924
 
 
4925
        while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
 
4926
                later += match[0];
 
4927
                selector = selector.replace( Expr.match.PSEUDO, "" );
 
4928
        }
 
4929
 
 
4930
        selector = Expr.relative[selector] ? selector + "*" : selector;
 
4931
 
 
4932
        for ( var i = 0, l = root.length; i < l; i++ ) {
 
4933
                Sizzle( selector, root[i], tmpSet );
 
4934
        }
 
4935
 
 
4936
        return Sizzle.filter( later, tmpSet );
 
4937
};
 
4938
 
 
4939
 
 
4940
window.Sizzle = Sizzle;
 
4941
 
 
4942
})();
 
4943
 
 
4944
;(function(engine) {
 
4945
  var extendElements = Prototype.Selector.extendElements;
 
4946
 
 
4947
  function select(selector, scope) {
 
4948
    return extendElements(engine(selector, scope || document));
 
4949
  }
 
4950
 
 
4951
  function match(element, selector) {
 
4952
    return engine.matches(selector, [element]).length == 1;
 
4953
  }
 
4954
 
 
4955
  Prototype.Selector.engine = engine;
 
4956
  Prototype.Selector.select = select;
 
4957
  Prototype.Selector.match = match;
 
4958
})(Sizzle);
 
4959
 
 
4960
window.Sizzle = Prototype._original_property;
 
4961
delete Prototype._original_property;
 
4962
 
3324
4963
var Form = {
3325
4964
  reset: function(form) {
3326
 
    $(form).reset();
 
4965
    form = $(form);
 
4966
    form.reset();
3327
4967
    return form;
3328
4968
  },
3329
4969
 
3330
4970
  serializeElements: function(elements, options) {
3331
4971
    if (typeof options != 'object') options = { hash: !!options };
3332
4972
    else if (Object.isUndefined(options.hash)) options.hash = true;
3333
 
    var key, value, submitted = false, submit = options.submit;
3334
 
 
3335
 
    var data = elements.inject({ }, function(result, element) {
 
4973
    var key, value, submitted = false, submit = options.submit, accumulator, initial;
 
4974
 
 
4975
    if (options.hash) {
 
4976
      initial = {};
 
4977
      accumulator = function(result, key, value) {
 
4978
        if (key in result) {
 
4979
          if (!Object.isArray(result[key])) result[key] = [result[key]];
 
4980
          result[key].push(value);
 
4981
        } else result[key] = value;
 
4982
        return result;
 
4983
      };
 
4984
    } else {
 
4985
      initial = '';
 
4986
      accumulator = function(result, key, value) {
 
4987
        return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
 
4988
      }
 
4989
    }
 
4990
 
 
4991
    return elements.inject(initial, function(result, element) {
3336
4992
      if (!element.disabled && element.name) {
3337
4993
        key = element.name; value = $(element).getValue();
3338
 
        if (value != null && (element.type != 'submit' || (!submitted &&
 
4994
        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
3339
4995
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
3340
 
          if (key in result) {
3341
 
            // a key is already present; construct an array of values
3342
 
            if (!Object.isArray(result[key])) result[key] = [result[key]];
3343
 
            result[key].push(value);
3344
 
          }
3345
 
          else result[key] = value;
 
4996
          result = accumulator(result, key, value);
3346
4997
        }
3347
4998
      }
3348
4999
      return result;
3349
5000
    });
3350
 
 
3351
 
    return options.hash ? data : Object.toQueryString(data);
3352
5001
  }
3353
5002
};
3354
5003
 
3358
5007
  },
3359
5008
 
3360
5009
  getElements: function(form) {
3361
 
    return $A($(form).getElementsByTagName('*')).inject([],
3362
 
      function(elements, child) {
3363
 
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
3364
 
          elements.push(Element.extend(child));
3365
 
        return elements;
3366
 
      }
3367
 
    );
 
5010
    var elements = $(form).getElementsByTagName('*'),
 
5011
        element,
 
5012
        arr = [ ],
 
5013
        serializers = Form.Element.Serializers;
 
5014
    for (var i = 0; element = elements[i]; i++) {
 
5015
      arr.push(element);
 
5016
    }
 
5017
    return arr.inject([], function(elements, child) {
 
5018
      if (serializers[child.tagName.toLowerCase()])
 
5019
        elements.push(Element.extend(child));
 
5020
      return elements;
 
5021
    })
3368
5022
  },
3369
5023
 
3370
5024
  getInputs: function(form, typeName, name) {
3404
5058
    }).sortBy(function(element) { return element.tabIndex }).first();
3405
5059
 
3406
5060
    return firstByIndex ? firstByIndex : elements.find(function(element) {
3407
 
      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
 
5061
      return /^(?:input|select|textarea)$/i.test(element.tagName);
3408
5062
    });
3409
5063
  },
3410
5064
 
3411
5065
  focusFirstElement: function(form) {
3412
5066
    form = $(form);
3413
 
    form.findFirstElement().activate();
 
5067
    var element = form.findFirstElement();
 
5068
    if (element) element.activate();
3414
5069
    return form;
3415
5070
  },
3416
5071
 
3435
5090
 
3436
5091
/*--------------------------------------------------------------------------*/
3437
5092
 
 
5093
 
3438
5094
Form.Element = {
3439
5095
  focus: function(element) {
3440
5096
    $(element).focus();
3448
5104
};
3449
5105
 
3450
5106
Form.Element.Methods = {
 
5107
 
3451
5108
  serialize: function(element) {
3452
5109
    element = $(element);
3453
5110
    if (!element.disabled && element.name) {
3488
5145
    try {
3489
5146
      element.focus();
3490
5147
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
3491
 
          !['button', 'reset', 'submit'].include(element.type)))
 
5148
          !(/^(?:button|reset|submit)$/i.test(element.type))))
3492
5149
        element.select();
3493
5150
    } catch (e) { }
3494
5151
    return element;
3496
5153
 
3497
5154
  disable: function(element) {
3498
5155
    element = $(element);
3499
 
    element.blur();
3500
5156
    element.disabled = true;
3501
5157
    return element;
3502
5158
  },
3511
5167
/*--------------------------------------------------------------------------*/
3512
5168
 
3513
5169
var Field = Form.Element;
 
5170
 
3514
5171
var $F = Form.Element.Methods.getValue;
3515
5172
 
3516
5173
/*--------------------------------------------------------------------------*/
3517
5174
 
3518
 
Form.Element.Serializers = {
3519
 
  input: function(element, value) {
 
5175
Form.Element.Serializers = (function() {
 
5176
  function input(element, value) {
3520
5177
    switch (element.type.toLowerCase()) {
3521
5178
      case 'checkbox':
3522
5179
      case 'radio':
3523
 
        return Form.Element.Serializers.inputSelector(element, value);
 
5180
        return inputSelector(element, value);
3524
5181
      default:
3525
 
        return Form.Element.Serializers.textarea(element, value);
 
5182
        return valueSelector(element, value);
3526
5183
    }
3527
 
  },
 
5184
  }
3528
5185
 
3529
 
  inputSelector: function(element, value) {
3530
 
    if (Object.isUndefined(value)) return element.checked ? element.value : null;
 
5186
  function inputSelector(element, value) {
 
5187
    if (Object.isUndefined(value))
 
5188
      return element.checked ? element.value : null;
3531
5189
    else element.checked = !!value;
3532
 
  },
 
5190
  }
3533
5191
 
3534
 
  textarea: function(element, value) {
 
5192
  function valueSelector(element, value) {
3535
5193
    if (Object.isUndefined(value)) return element.value;
3536
5194
    else element.value = value;
3537
 
  },
3538
 
 
3539
 
  select: function(element, index) {
3540
 
    if (Object.isUndefined(index))
3541
 
      return this[element.type == 'select-one' ?
3542
 
        'selectOne' : 'selectMany'](element);
3543
 
    else {
3544
 
      var opt, value, single = !Object.isArray(index);
3545
 
      for (var i = 0, length = element.length; i < length; i++) {
3546
 
        opt = element.options[i];
3547
 
        value = this.optionValue(opt);
3548
 
        if (single) {
3549
 
          if (value == index) {
3550
 
            opt.selected = true;
3551
 
            return;
3552
 
          }
 
5195
  }
 
5196
 
 
5197
  function select(element, value) {
 
5198
    if (Object.isUndefined(value))
 
5199
      return (element.type === 'select-one' ? selectOne : selectMany)(element);
 
5200
 
 
5201
    var opt, currentValue, single = !Object.isArray(value);
 
5202
    for (var i = 0, length = element.length; i < length; i++) {
 
5203
      opt = element.options[i];
 
5204
      currentValue = this.optionValue(opt);
 
5205
      if (single) {
 
5206
        if (currentValue == value) {
 
5207
          opt.selected = true;
 
5208
          return;
3553
5209
        }
3554
 
        else opt.selected = index.include(value);
3555
5210
      }
 
5211
      else opt.selected = value.include(currentValue);
3556
5212
    }
3557
 
  },
 
5213
  }
3558
5214
 
3559
 
  selectOne: function(element) {
 
5215
  function selectOne(element) {
3560
5216
    var index = element.selectedIndex;
3561
 
    return index >= 0 ? this.optionValue(element.options[index]) : null;
3562
 
  },
 
5217
    return index >= 0 ? optionValue(element.options[index]) : null;
 
5218
  }
3563
5219
 
3564
 
  selectMany: function(element) {
 
5220
  function selectMany(element) {
3565
5221
    var values, length = element.length;
3566
5222
    if (!length) return null;
3567
5223
 
3568
5224
    for (var i = 0, values = []; i < length; i++) {
3569
5225
      var opt = element.options[i];
3570
 
      if (opt.selected) values.push(this.optionValue(opt));
 
5226
      if (opt.selected) values.push(optionValue(opt));
3571
5227
    }
3572
5228
    return values;
3573
 
  },
3574
 
 
3575
 
  optionValue: function(opt) {
3576
 
    // extend element because hasAttribute may not be native
3577
 
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
3578
 
  }
3579
 
};
 
5229
  }
 
5230
 
 
5231
  function optionValue(opt) {
 
5232
    return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
 
5233
  }
 
5234
 
 
5235
  return {
 
5236
    input:         input,
 
5237
    inputSelector: inputSelector,
 
5238
    textarea:      valueSelector,
 
5239
    select:        select,
 
5240
    selectOne:     selectOne,
 
5241
    selectMany:    selectMany,
 
5242
    optionValue:   optionValue,
 
5243
    button:        valueSelector
 
5244
  };
 
5245
})();
3580
5246
 
3581
5247
/*--------------------------------------------------------------------------*/
3582
5248
 
 
5249
 
3583
5250
Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
3584
5251
  initialize: function($super, element, frequency, callback) {
3585
5252
    $super(callback, frequency);
3661
5328
    return Form.serialize(this.element);
3662
5329
  }
3663
5330
});
3664
 
if (!window.Event) var Event = { };
3665
 
 
3666
 
Object.extend(Event, {
3667
 
  KEY_BACKSPACE: 8,
3668
 
  KEY_TAB:       9,
3669
 
  KEY_RETURN:   13,
3670
 
  KEY_ESC:      27,
3671
 
  KEY_LEFT:     37,
3672
 
  KEY_UP:       38,
3673
 
  KEY_RIGHT:    39,
3674
 
  KEY_DOWN:     40,
3675
 
  KEY_DELETE:   46,
3676
 
  KEY_HOME:     36,
3677
 
  KEY_END:      35,
3678
 
  KEY_PAGEUP:   33,
3679
 
  KEY_PAGEDOWN: 34,
3680
 
  KEY_INSERT:   45,
3681
 
 
3682
 
  cache: { },
3683
 
 
3684
 
  relatedTarget: function(event) {
3685
 
    var element;
3686
 
    switch(event.type) {
3687
 
      case 'mouseover': element = event.fromElement; break;
3688
 
      case 'mouseout':  element = event.toElement;   break;
3689
 
      default: return null;
3690
 
    }
3691
 
    return Element.extend(element);
3692
 
  }
3693
 
});
3694
 
 
3695
 
Event.Methods = (function() {
3696
 
  var isButton;
3697
 
 
3698
 
  if (Prototype.Browser.IE) {
3699
 
    var buttonMap = { 0: 1, 1: 4, 2: 2 };
3700
 
    isButton = function(event, code) {
3701
 
      return event.button == buttonMap[code];
3702
 
    };
3703
 
 
 
5331
(function() {
 
5332
 
 
5333
  var Event = {
 
5334
    KEY_BACKSPACE: 8,
 
5335
    KEY_TAB:       9,
 
5336
    KEY_RETURN:   13,
 
5337
    KEY_ESC:      27,
 
5338
    KEY_LEFT:     37,
 
5339
    KEY_UP:       38,
 
5340
    KEY_RIGHT:    39,
 
5341
    KEY_DOWN:     40,
 
5342
    KEY_DELETE:   46,
 
5343
    KEY_HOME:     36,
 
5344
    KEY_END:      35,
 
5345
    KEY_PAGEUP:   33,
 
5346
    KEY_PAGEDOWN: 34,
 
5347
    KEY_INSERT:   45,
 
5348
 
 
5349
    cache: {}
 
5350
  };
 
5351
 
 
5352
  var docEl = document.documentElement;
 
5353
  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
 
5354
    && 'onmouseleave' in docEl;
 
5355
 
 
5356
 
 
5357
 
 
5358
  var isIELegacyEvent = function(event) { return false; };
 
5359
 
 
5360
  if (window.attachEvent) {
 
5361
    if (window.addEventListener) {
 
5362
      isIELegacyEvent = function(event) {
 
5363
        return !(event instanceof window.Event);
 
5364
      };
 
5365
    } else {
 
5366
      isIELegacyEvent = function(event) { return true; };
 
5367
    }
 
5368
  }
 
5369
 
 
5370
  var _isButton;
 
5371
 
 
5372
  function _isButtonForDOMEvents(event, code) {
 
5373
    return event.which ? (event.which === code + 1) : (event.button === code);
 
5374
  }
 
5375
 
 
5376
  var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
 
5377
  function _isButtonForLegacyEvents(event, code) {
 
5378
    return event.button === legacyButtonMap[code];
 
5379
  }
 
5380
 
 
5381
  function _isButtonForWebKit(event, code) {
 
5382
    switch (code) {
 
5383
      case 0: return event.which == 1 && !event.metaKey;
 
5384
      case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
 
5385
      case 2: return event.which == 3;
 
5386
      default: return false;
 
5387
    }
 
5388
  }
 
5389
 
 
5390
  if (window.attachEvent) {
 
5391
    if (!window.addEventListener) {
 
5392
      _isButton = _isButtonForLegacyEvents;
 
5393
    } else {
 
5394
      _isButton = function(event, code) {
 
5395
        return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
 
5396
         _isButtonForDOMEvents(event, code);
 
5397
      }
 
5398
    }
3704
5399
  } else if (Prototype.Browser.WebKit) {
3705
 
    isButton = function(event, code) {
3706
 
      switch (code) {
3707
 
        case 0: return event.which == 1 && !event.metaKey;
3708
 
        case 1: return event.which == 1 && event.metaKey;
3709
 
        default: return false;
 
5400
    _isButton = _isButtonForWebKit;
 
5401
  } else {
 
5402
    _isButton = _isButtonForDOMEvents;
 
5403
  }
 
5404
 
 
5405
  function isLeftClick(event)   { return _isButton(event, 0) }
 
5406
 
 
5407
  function isMiddleClick(event) { return _isButton(event, 1) }
 
5408
 
 
5409
  function isRightClick(event)  { return _isButton(event, 2) }
 
5410
 
 
5411
  function element(event) {
 
5412
    event = Event.extend(event);
 
5413
 
 
5414
    var node = event.target, type = event.type,
 
5415
     currentTarget = event.currentTarget;
 
5416
 
 
5417
    if (currentTarget && currentTarget.tagName) {
 
5418
      if (type === 'load' || type === 'error' ||
 
5419
        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
 
5420
          && currentTarget.type === 'radio'))
 
5421
            node = currentTarget;
 
5422
    }
 
5423
 
 
5424
    if (node.nodeType == Node.TEXT_NODE)
 
5425
      node = node.parentNode;
 
5426
 
 
5427
    return Element.extend(node);
 
5428
  }
 
5429
 
 
5430
  function findElement(event, expression) {
 
5431
    var element = Event.element(event);
 
5432
 
 
5433
    if (!expression) return element;
 
5434
    while (element) {
 
5435
      if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
 
5436
        return Element.extend(element);
3710
5437
      }
3711
 
    };
3712
 
 
3713
 
  } else {
3714
 
    isButton = function(event, code) {
3715
 
      return event.which ? (event.which === code + 1) : (event.button === code);
3716
 
    };
3717
 
  }
3718
 
 
3719
 
  return {
3720
 
    isLeftClick:   function(event) { return isButton(event, 0) },
3721
 
    isMiddleClick: function(event) { return isButton(event, 1) },
3722
 
    isRightClick:  function(event) { return isButton(event, 2) },
3723
 
 
3724
 
    element: function(event) {
3725
 
      var node = Event.extend(event).target;
3726
 
      return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
3727
 
    },
3728
 
 
3729
 
    findElement: function(event, expression) {
3730
 
      var element = Event.element(event);
3731
 
      if (!expression) return element;
3732
 
      var elements = [element].concat(element.ancestors());
3733
 
      return Selector.findElement(elements, expression, 0);
3734
 
    },
3735
 
 
3736
 
    pointer: function(event) {
3737
 
      return {
3738
 
        x: event.pageX || (event.clientX +
3739
 
          (document.documentElement.scrollLeft || document.body.scrollLeft)),
3740
 
        y: event.pageY || (event.clientY +
3741
 
          (document.documentElement.scrollTop || document.body.scrollTop))
3742
 
      };
3743
 
    },
3744
 
 
3745
 
    pointerX: function(event) { return Event.pointer(event).x },
3746
 
    pointerY: function(event) { return Event.pointer(event).y },
3747
 
 
3748
 
    stop: function(event) {
3749
 
      Event.extend(event);
3750
 
      event.preventDefault();
3751
 
      event.stopPropagation();
3752
 
      event.stopped = true;
 
5438
      element = element.parentNode;
3753
5439
    }
 
5440
  }
 
5441
 
 
5442
  function pointer(event) {
 
5443
    return { x: pointerX(event), y: pointerY(event) };
 
5444
  }
 
5445
 
 
5446
  function pointerX(event) {
 
5447
    var docElement = document.documentElement,
 
5448
     body = document.body || { scrollLeft: 0 };
 
5449
 
 
5450
    return event.pageX || (event.clientX +
 
5451
      (docElement.scrollLeft || body.scrollLeft) -
 
5452
      (docElement.clientLeft || 0));
 
5453
  }
 
5454
 
 
5455
  function pointerY(event) {
 
5456
    var docElement = document.documentElement,
 
5457
     body = document.body || { scrollTop: 0 };
 
5458
 
 
5459
    return  event.pageY || (event.clientY +
 
5460
       (docElement.scrollTop || body.scrollTop) -
 
5461
       (docElement.clientTop || 0));
 
5462
  }
 
5463
 
 
5464
 
 
5465
  function stop(event) {
 
5466
    Event.extend(event);
 
5467
    event.preventDefault();
 
5468
    event.stopPropagation();
 
5469
 
 
5470
    event.stopped = true;
 
5471
  }
 
5472
 
 
5473
 
 
5474
  Event.Methods = {
 
5475
    isLeftClick:   isLeftClick,
 
5476
    isMiddleClick: isMiddleClick,
 
5477
    isRightClick:  isRightClick,
 
5478
 
 
5479
    element:     element,
 
5480
    findElement: findElement,
 
5481
 
 
5482
    pointer:  pointer,
 
5483
    pointerX: pointerX,
 
5484
    pointerY: pointerY,
 
5485
 
 
5486
    stop: stop
3754
5487
  };
3755
 
})();
3756
5488
 
3757
 
Event.extend = (function() {
3758
5489
  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
3759
5490
    m[name] = Event.Methods[name].methodize();
3760
5491
    return m;
3761
5492
  });
3762
5493
 
3763
 
  if (Prototype.Browser.IE) {
3764
 
    Object.extend(methods, {
 
5494
  if (window.attachEvent) {
 
5495
    function _relatedTarget(event) {
 
5496
      var element;
 
5497
      switch (event.type) {
 
5498
        case 'mouseover':
 
5499
        case 'mouseenter':
 
5500
          element = event.fromElement;
 
5501
          break;
 
5502
        case 'mouseout':
 
5503
        case 'mouseleave':
 
5504
          element = event.toElement;
 
5505
          break;
 
5506
        default:
 
5507
          return null;
 
5508
      }
 
5509
      return Element.extend(element);
 
5510
    }
 
5511
 
 
5512
    var additionalMethods = {
3765
5513
      stopPropagation: function() { this.cancelBubble = true },
3766
5514
      preventDefault:  function() { this.returnValue = false },
3767
 
      inspect: function() { return "[object Event]" }
3768
 
    });
 
5515
      inspect: function() { return '[object Event]' }
 
5516
    };
3769
5517
 
3770
 
    return function(event) {
 
5518
    Event.extend = function(event, element) {
3771
5519
      if (!event) return false;
 
5520
 
 
5521
      if (!isIELegacyEvent(event)) return event;
 
5522
 
3772
5523
      if (event._extendedByPrototype) return event;
3773
 
 
3774
5524
      event._extendedByPrototype = Prototype.emptyFunction;
 
5525
 
3775
5526
      var pointer = Event.pointer(event);
 
5527
 
3776
5528
      Object.extend(event, {
3777
 
        target: event.srcElement,
3778
 
        relatedTarget: Event.relatedTarget(event),
 
5529
        target: event.srcElement || element,
 
5530
        relatedTarget: _relatedTarget(event),
3779
5531
        pageX:  pointer.x,
3780
5532
        pageY:  pointer.y
3781
5533
      });
3782
 
      return Object.extend(event, methods);
 
5534
 
 
5535
      Object.extend(event, methods);
 
5536
      Object.extend(event, additionalMethods);
 
5537
 
 
5538
      return event;
3783
5539
    };
3784
 
 
3785
5540
  } else {
3786
 
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
 
5541
    Event.extend = Prototype.K;
 
5542
  }
 
5543
 
 
5544
  if (window.addEventListener) {
 
5545
    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
3787
5546
    Object.extend(Event.prototype, methods);
3788
 
    return Prototype.K;
3789
 
  }
 
5547
  }
 
5548
 
 
5549
  function _createResponder(element, eventName, handler) {
 
5550
    var registry = Element.retrieve(element, 'prototype_event_registry');
 
5551
 
 
5552
    if (Object.isUndefined(registry)) {
 
5553
      CACHE.push(element);
 
5554
      registry = Element.retrieve(element, 'prototype_event_registry', $H());
 
5555
    }
 
5556
 
 
5557
    var respondersForEvent = registry.get(eventName);
 
5558
    if (Object.isUndefined(respondersForEvent)) {
 
5559
      respondersForEvent = [];
 
5560
      registry.set(eventName, respondersForEvent);
 
5561
    }
 
5562
 
 
5563
    if (respondersForEvent.pluck('handler').include(handler)) return false;
 
5564
 
 
5565
    var responder;
 
5566
    if (eventName.include(":")) {
 
5567
      responder = function(event) {
 
5568
        if (Object.isUndefined(event.eventName))
 
5569
          return false;
 
5570
 
 
5571
        if (event.eventName !== eventName)
 
5572
          return false;
 
5573
 
 
5574
        Event.extend(event, element);
 
5575
        handler.call(element, event);
 
5576
      };
 
5577
    } else {
 
5578
      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
 
5579
       (eventName === "mouseenter" || eventName === "mouseleave")) {
 
5580
        if (eventName === "mouseenter" || eventName === "mouseleave") {
 
5581
          responder = function(event) {
 
5582
            Event.extend(event, element);
 
5583
 
 
5584
            var parent = event.relatedTarget;
 
5585
            while (parent && parent !== element) {
 
5586
              try { parent = parent.parentNode; }
 
5587
              catch(e) { parent = element; }
 
5588
            }
 
5589
 
 
5590
            if (parent === element) return;
 
5591
 
 
5592
            handler.call(element, event);
 
5593
          };
 
5594
        }
 
5595
      } else {
 
5596
        responder = function(event) {
 
5597
          Event.extend(event, element);
 
5598
          handler.call(element, event);
 
5599
        };
 
5600
      }
 
5601
    }
 
5602
 
 
5603
    responder.handler = handler;
 
5604
    respondersForEvent.push(responder);
 
5605
    return responder;
 
5606
  }
 
5607
 
 
5608
  function _destroyCache() {
 
5609
    for (var i = 0, length = CACHE.length; i < length; i++) {
 
5610
      Event.stopObserving(CACHE[i]);
 
5611
      CACHE[i] = null;
 
5612
    }
 
5613
  }
 
5614
 
 
5615
  var CACHE = [];
 
5616
 
 
5617
  if (Prototype.Browser.IE)
 
5618
    window.attachEvent('onunload', _destroyCache);
 
5619
 
 
5620
  if (Prototype.Browser.WebKit)
 
5621
    window.addEventListener('unload', Prototype.emptyFunction, false);
 
5622
 
 
5623
 
 
5624
  var _getDOMEventName = Prototype.K,
 
5625
      translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
 
5626
 
 
5627
  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
 
5628
    _getDOMEventName = function(eventName) {
 
5629
      return (translations[eventName] || eventName);
 
5630
    };
 
5631
  }
 
5632
 
 
5633
  function observe(element, eventName, handler) {
 
5634
    element = $(element);
 
5635
 
 
5636
    var responder = _createResponder(element, eventName, handler);
 
5637
 
 
5638
    if (!responder) return element;
 
5639
 
 
5640
    if (eventName.include(':')) {
 
5641
      if (element.addEventListener)
 
5642
        element.addEventListener("dataavailable", responder, false);
 
5643
      else {
 
5644
        element.attachEvent("ondataavailable", responder);
 
5645
        element.attachEvent("onlosecapture", responder);
 
5646
      }
 
5647
    } else {
 
5648
      var actualEventName = _getDOMEventName(eventName);
 
5649
 
 
5650
      if (element.addEventListener)
 
5651
        element.addEventListener(actualEventName, responder, false);
 
5652
      else
 
5653
        element.attachEvent("on" + actualEventName, responder);
 
5654
    }
 
5655
 
 
5656
    return element;
 
5657
  }
 
5658
 
 
5659
  function stopObserving(element, eventName, handler) {
 
5660
    element = $(element);
 
5661
 
 
5662
    var registry = Element.retrieve(element, 'prototype_event_registry');
 
5663
    if (!registry) return element;
 
5664
 
 
5665
    if (!eventName) {
 
5666
      registry.each( function(pair) {
 
5667
        var eventName = pair.key;
 
5668
        stopObserving(element, eventName);
 
5669
      });
 
5670
      return element;
 
5671
    }
 
5672
 
 
5673
    var responders = registry.get(eventName);
 
5674
    if (!responders) return element;
 
5675
 
 
5676
    if (!handler) {
 
5677
      responders.each(function(r) {
 
5678
        stopObserving(element, eventName, r.handler);
 
5679
      });
 
5680
      return element;
 
5681
    }
 
5682
 
 
5683
    var i = responders.length, responder;
 
5684
    while (i--) {
 
5685
      if (responders[i].handler === handler) {
 
5686
        responder = responders[i];
 
5687
        break;
 
5688
      }
 
5689
    }
 
5690
    if (!responder) return element;
 
5691
 
 
5692
    if (eventName.include(':')) {
 
5693
      if (element.removeEventListener)
 
5694
        element.removeEventListener("dataavailable", responder, false);
 
5695
      else {
 
5696
        element.detachEvent("ondataavailable", responder);
 
5697
        element.detachEvent("onlosecapture", responder);
 
5698
      }
 
5699
    } else {
 
5700
      var actualEventName = _getDOMEventName(eventName);
 
5701
      if (element.removeEventListener)
 
5702
        element.removeEventListener(actualEventName, responder, false);
 
5703
      else
 
5704
        element.detachEvent('on' + actualEventName, responder);
 
5705
    }
 
5706
 
 
5707
    registry.set(eventName, responders.without(responder));
 
5708
 
 
5709
    return element;
 
5710
  }
 
5711
 
 
5712
  function fire(element, eventName, memo, bubble) {
 
5713
    element = $(element);
 
5714
 
 
5715
    if (Object.isUndefined(bubble))
 
5716
      bubble = true;
 
5717
 
 
5718
    if (element == document && document.createEvent && !element.dispatchEvent)
 
5719
      element = document.documentElement;
 
5720
 
 
5721
    var event;
 
5722
    if (document.createEvent) {
 
5723
      event = document.createEvent('HTMLEvents');
 
5724
      event.initEvent('dataavailable', bubble, true);
 
5725
    } else {
 
5726
      event = document.createEventObject();
 
5727
      event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
 
5728
    }
 
5729
 
 
5730
    event.eventName = eventName;
 
5731
    event.memo = memo || { };
 
5732
 
 
5733
    if (document.createEvent)
 
5734
      element.dispatchEvent(event);
 
5735
    else
 
5736
      element.fireEvent(event.eventType, event);
 
5737
 
 
5738
    return Event.extend(event);
 
5739
  }
 
5740
 
 
5741
  Event.Handler = Class.create({
 
5742
    initialize: function(element, eventName, selector, callback) {
 
5743
      this.element   = $(element);
 
5744
      this.eventName = eventName;
 
5745
      this.selector  = selector;
 
5746
      this.callback  = callback;
 
5747
      this.handler   = this.handleEvent.bind(this);
 
5748
    },
 
5749
 
 
5750
    start: function() {
 
5751
      Event.observe(this.element, this.eventName, this.handler);
 
5752
      return this;
 
5753
    },
 
5754
 
 
5755
    stop: function() {
 
5756
      Event.stopObserving(this.element, this.eventName, this.handler);
 
5757
      return this;
 
5758
    },
 
5759
 
 
5760
    handleEvent: function(event) {
 
5761
      var element = Event.findElement(event, this.selector);
 
5762
      if (element) this.callback.call(this.element, event, element);
 
5763
    }
 
5764
  });
 
5765
 
 
5766
  function on(element, eventName, selector, callback) {
 
5767
    element = $(element);
 
5768
    if (Object.isFunction(selector) && Object.isUndefined(callback)) {
 
5769
      callback = selector, selector = null;
 
5770
    }
 
5771
 
 
5772
    return new Event.Handler(element, eventName, selector, callback).start();
 
5773
  }
 
5774
 
 
5775
  Object.extend(Event, Event.Methods);
 
5776
 
 
5777
  Object.extend(Event, {
 
5778
    fire:          fire,
 
5779
    observe:       observe,
 
5780
    stopObserving: stopObserving,
 
5781
    on:            on
 
5782
  });
 
5783
 
 
5784
  Element.addMethods({
 
5785
    fire:          fire,
 
5786
 
 
5787
    observe:       observe,
 
5788
 
 
5789
    stopObserving: stopObserving,
 
5790
 
 
5791
    on:            on
 
5792
  });
 
5793
 
 
5794
  Object.extend(document, {
 
5795
    fire:          fire.methodize(),
 
5796
 
 
5797
    observe:       observe.methodize(),
 
5798
 
 
5799
    stopObserving: stopObserving.methodize(),
 
5800
 
 
5801
    on:            on.methodize(),
 
5802
 
 
5803
    loaded:        false
 
5804
  });
 
5805
 
 
5806
  if (window.Event) Object.extend(window.Event, Event);
 
5807
  else window.Event = Event;
3790
5808
})();
3791
5809
 
3792
 
Object.extend(Event, (function() {
3793
 
  var cache = Event.cache;
3794
 
 
3795
 
  function getEventID(element) {
3796
 
    if (element._eventID) return element._eventID;
3797
 
    arguments.callee.id = arguments.callee.id || 1;
3798
 
    return element._eventID = ++arguments.callee.id;
3799
 
  }
3800
 
 
3801
 
  function getDOMEventName(eventName) {
3802
 
    if (eventName && eventName.include(':')) return "dataavailable";
3803
 
    return eventName;
3804
 
  }
3805
 
 
3806
 
  function getCacheForID(id) {
3807
 
    return cache[id] = cache[id] || { };
3808
 
  }
3809
 
 
3810
 
  function getWrappersForEventName(id, eventName) {
3811
 
    var c = getCacheForID(id);
3812
 
    return c[eventName] = c[eventName] || [];
3813
 
  }
3814
 
 
3815
 
  function createWrapper(element, eventName, handler) {
3816
 
    var id = getEventID(element);
3817
 
    var c = getWrappersForEventName(id, eventName);
3818
 
    if (c.pluck("handler").include(handler)) return false;
3819
 
 
3820
 
    var wrapper = function(event) {
3821
 
      if (!Event || !Event.extend ||
3822
 
        (event.eventName && event.eventName != eventName))
3823
 
          return false;
3824
 
 
3825
 
      Event.extend(event);
3826
 
      handler.call(element, event);
3827
 
    };
3828
 
 
3829
 
    wrapper.handler = handler;
3830
 
    c.push(wrapper);
3831
 
    return wrapper;
3832
 
  }
3833
 
 
3834
 
  function findWrapper(id, eventName, handler) {
3835
 
    var c = getWrappersForEventName(id, eventName);
3836
 
    return c.find(function(wrapper) { return wrapper.handler == handler });
3837
 
  }
3838
 
 
3839
 
  function destroyWrapper(id, eventName, handler) {
3840
 
    var c = getCacheForID(id);
3841
 
    if (!c[eventName]) return false;
3842
 
    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
3843
 
  }
3844
 
 
3845
 
  function destroyCache() {
3846
 
    for (var id in cache)
3847
 
      for (var eventName in cache[id])
3848
 
        cache[id][eventName] = null;
3849
 
  }
3850
 
 
3851
 
  if (window.attachEvent) {
3852
 
    window.attachEvent("onunload", destroyCache);
3853
 
  }
3854
 
 
3855
 
  return {
3856
 
    observe: function(element, eventName, handler) {
3857
 
      element = $(element);
3858
 
      var name = getDOMEventName(eventName);
3859
 
 
3860
 
      var wrapper = createWrapper(element, eventName, handler);
3861
 
      if (!wrapper) return element;
3862
 
 
3863
 
      if (element.addEventListener) {
3864
 
        element.addEventListener(name, wrapper, false);
3865
 
      } else {
3866
 
        element.attachEvent("on" + name, wrapper);
3867
 
      }
3868
 
 
3869
 
      return element;
3870
 
    },
3871
 
 
3872
 
    stopObserving: function(element, eventName, handler) {
3873
 
      element = $(element);
3874
 
      var id = getEventID(element), name = getDOMEventName(eventName);
3875
 
 
3876
 
      if (!handler && eventName) {
3877
 
        getWrappersForEventName(id, eventName).each(function(wrapper) {
3878
 
          element.stopObserving(eventName, wrapper.handler);
3879
 
        });
3880
 
        return element;
3881
 
 
3882
 
      } else if (!eventName) {
3883
 
        Object.keys(getCacheForID(id)).each(function(eventName) {
3884
 
          element.stopObserving(eventName);
3885
 
        });
3886
 
        return element;
3887
 
      }
3888
 
 
3889
 
      var wrapper = findWrapper(id, eventName, handler);
3890
 
      if (!wrapper) return element;
3891
 
 
3892
 
      if (element.removeEventListener) {
3893
 
        element.removeEventListener(name, wrapper, false);
3894
 
      } else {
3895
 
        element.detachEvent("on" + name, wrapper);
3896
 
      }
3897
 
 
3898
 
      destroyWrapper(id, eventName, handler);
3899
 
 
3900
 
      return element;
3901
 
    },
3902
 
 
3903
 
    fire: function(element, eventName, memo) {
3904
 
      element = $(element);
3905
 
      if (element == document && document.createEvent && !element.dispatchEvent)
3906
 
        element = document.documentElement;
3907
 
 
3908
 
      var event;
3909
 
      if (document.createEvent) {
3910
 
        event = document.createEvent("HTMLEvents");
3911
 
        event.initEvent("dataavailable", true, true);
3912
 
      } else {
3913
 
        event = document.createEventObject();
3914
 
        event.eventType = "ondataavailable";
3915
 
      }
3916
 
 
3917
 
      event.eventName = eventName;
3918
 
      event.memo = memo || { };
3919
 
 
3920
 
      if (document.createEvent) {
3921
 
        element.dispatchEvent(event);
3922
 
      } else {
3923
 
        element.fireEvent(event.eventType, event);
3924
 
      }
3925
 
 
3926
 
      return Event.extend(event);
3927
 
    }
3928
 
  };
3929
 
})());
3930
 
 
3931
 
Object.extend(Event, Event.Methods);
3932
 
 
3933
 
Element.addMethods({
3934
 
  fire:          Event.fire,
3935
 
  observe:       Event.observe,
3936
 
  stopObserving: Event.stopObserving
3937
 
});
3938
 
 
3939
 
Object.extend(document, {
3940
 
  fire:          Element.Methods.fire.methodize(),
3941
 
  observe:       Element.Methods.observe.methodize(),
3942
 
  stopObserving: Element.Methods.stopObserving.methodize(),
3943
 
  loaded:        false
3944
 
});
3945
 
 
3946
5810
(function() {
3947
5811
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
3948
 
     Matthias Miller, Dean Edwards and John Resig. */
 
5812
     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
3949
5813
 
3950
5814
  var timer;
3951
5815
 
3952
5816
  function fireContentLoadedEvent() {
3953
5817
    if (document.loaded) return;
3954
 
    if (timer) window.clearInterval(timer);
3955
 
    document.fire("dom:loaded");
 
5818
    if (timer) window.clearTimeout(timer);
3956
5819
    document.loaded = true;
 
5820
    document.fire('dom:loaded');
 
5821
  }
 
5822
 
 
5823
  function checkReadyState() {
 
5824
    if (document.readyState === 'complete') {
 
5825
      document.stopObserving('readystatechange', checkReadyState);
 
5826
      fireContentLoadedEvent();
 
5827
    }
 
5828
  }
 
5829
 
 
5830
  function pollDoScroll() {
 
5831
    try { document.documentElement.doScroll('left'); }
 
5832
    catch(e) {
 
5833
      timer = pollDoScroll.defer();
 
5834
      return;
 
5835
    }
 
5836
    fireContentLoadedEvent();
3957
5837
  }
3958
5838
 
3959
5839
  if (document.addEventListener) {
3960
 
    if (Prototype.Browser.WebKit) {
3961
 
      timer = window.setInterval(function() {
3962
 
        if (/loaded|complete/.test(document.readyState))
3963
 
          fireContentLoadedEvent();
3964
 
      }, 0);
3965
 
 
3966
 
      Event.observe(window, "load", fireContentLoadedEvent);
3967
 
 
3968
 
    } else {
3969
 
      document.addEventListener("DOMContentLoaded",
3970
 
        fireContentLoadedEvent, false);
3971
 
    }
3972
 
 
 
5840
    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
3973
5841
  } else {
3974
 
    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
3975
 
    $("__onDOMContentLoaded").onreadystatechange = function() {
3976
 
      if (this.readyState == "complete") {
3977
 
        this.onreadystatechange = null;
3978
 
        fireContentLoadedEvent();
3979
 
      }
3980
 
    };
 
5842
    document.observe('readystatechange', checkReadyState);
 
5843
    if (window == top)
 
5844
      timer = pollDoScroll.defer();
3981
5845
  }
 
5846
 
 
5847
  Event.observe(window, 'load', fireContentLoadedEvent);
3982
5848
})();
 
5849
 
 
5850
Element.addMethods();
 
5851
 
3983
5852
/*------------------------------- DEPRECATED -------------------------------*/
3984
5853
 
3985
5854
Hash.toQueryString = Object.toQueryString;
4008
5877
 
4009
5878
var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
4010
5879
 
4011
 
// This should be moved to script.aculo.us; notice the deprecated methods
4012
 
// further below, that map to the newer Element methods.
4013
5880
var Position = {
4014
 
  // set to true if needed, warning: firefox performance problems
4015
 
  // NOT neeeded for page scrolling, only if draggable contained in
4016
 
  // scrollable elements
4017
5881
  includeScrollOffsets: false,
4018
5882
 
4019
 
  // must be called before calling withinIncludingScrolloffset, every time the
4020
 
  // page is scrolled
4021
5883
  prepare: function() {
4022
5884
    this.deltaX =  window.pageXOffset
4023
5885
                || document.documentElement.scrollLeft
4029
5891
                || 0;
4030
5892
  },
4031
5893
 
4032
 
  // caches x/y coordinate pair to use with overlap
4033
5894
  within: function(element, x, y) {
4034
5895
    if (this.includeScrollOffsets)
4035
5896
      return this.withinIncludingScrolloffsets(element, x, y);
4056
5917
            this.xcomp <  this.offset[0] + element.offsetWidth);
4057
5918
  },
4058
5919
 
4059
 
  // within must be called directly before
4060
5920
  overlap: function(mode, element) {
4061
5921
    if (!mode) return 0;
4062
5922
    if (mode == 'vertical')
4067
5927
        element.offsetWidth;
4068
5928
  },
4069
5929
 
4070
 
  // Deprecation layer -- use newer Element methods now (1.5.2).
4071
5930
 
4072
5931
  cumulativeOffset: Element.Methods.cumulativeOffset,
4073
5932
 
4167
6026
 
4168
6027
/*--------------------------------------------------------------------------*/
4169
6028
 
4170
 
Element.addMethods();
 
 
b'\\ No newline at end of file'
 
6029
(function() {
 
6030
  window.Selector = Class.create({
 
6031
    initialize: function(expression) {
 
6032
      this.expression = expression.strip();
 
6033
    },
 
6034
 
 
6035
    findElements: function(rootElement) {
 
6036
      return Prototype.Selector.select(this.expression, rootElement);
 
6037
    },
 
6038
 
 
6039
    match: function(element) {
 
6040
      return Prototype.Selector.match(element, this.expression);
 
6041
    },
 
6042
 
 
6043
    toString: function() {
 
6044
      return this.expression;
 
6045
    },
 
6046
 
 
6047
    inspect: function() {
 
6048
      return "#<Selector: " + this.expression + ">";
 
6049
    }
 
6050
  });
 
6051
 
 
6052
  Object.extend(Selector, {
 
6053
    matchElements: function(elements, expression) {
 
6054
      var match = Prototype.Selector.match,
 
6055
          results = [];
 
6056
 
 
6057
      for (var i = 0, length = elements.length; i < length; i++) {
 
6058
        var element = elements[i];
 
6059
        if (match(element, expression)) {
 
6060
          results.push(Element.extend(element));
 
6061
        }
 
6062
      }
 
6063
      return results;
 
6064
    },
 
6065
 
 
6066
    findElement: function(elements, expression, index) {
 
6067
      index = index || 0;
 
6068
      var matchIndex = 0, element;
 
6069
      for (var i = 0, length = elements.length; i < length; i++) {
 
6070
        element = elements[i];
 
6071
        if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
 
6072
          return Element.extend(element);
 
6073
        }
 
6074
      }
 
6075
    },
 
6076
 
 
6077
    findChildElements: function(element, expressions) {
 
6078
      var selector = expressions.toArray().join(', ');
 
6079
      return Prototype.Selector.select(selector, element || document);
 
6080
    }
 
6081
  });
 
6082
})();