/* Prototype JavaScript framework, version 1.4.0 * (c) 2005 Sam Stephenson <sam@conio.net> * * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff * against the source tree, available from the Prototype darcs repository. * * Prototype is freely distributable under the terms of an MIT-style license. * * For details, see the Prototype web site: http://prototype.conio.net/ */*--------------------------------------------------------------------------*/var Prototype = { Version: '1.4.0', ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', emptyFunction: function() {}, K: function(x) {return x}}var Class = { create: function() { return function() {  this.initialize.apply(this, arguments); } }}var Abstract = new Object();Object.extend = function(destination, source) { for (property in source) { destination[property] = source[property]; } return destination;}Object.inspect = function(object) { try { if (object == undefined) return 'undefined'; if (object == null) return 'null'; return object.inspect ? object.inspect() : object.toString(); } catch (e) { if (e instanceof RangeError) return '...'; throw e; }}Function.prototype.bind = function() { var __method = this, args = $A(arguments), object = args.shift(); return function() { return __method.apply(object, args.concat($A(arguments))); }}Function.prototype.bindAsEventListener = function(object) { var __method = this; return function(event) { return __method.call(object, event || window.event); }}Object.extend(Number.prototype, { toColorPart: function() { var digits = this.toString(16); if (this < 16) return '0' + digits; return digits; }, succ: function() { return this + 1; }, times: function(iterator) { $R(0, this, true).each(iterator); return this; }});var Try = { these: function() { var returnValue; for (var i = 0; i < arguments.length; i++) {  var lambda = arguments[i];  try {  returnValue = lambda();  break;  } catch (e) {} } return returnValue; }}/*--------------------------------------------------------------------------*/var PeriodicalExecuter = Class.create();PeriodicalExecuter.prototype = { initialize: function(callback, frequency) { this.callback = callback; this.frequency = frequency; this.currentlyExecuting = false; this.registerCallback(); }, registerCallback: function() { setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, onTimerEvent: function() { if (!this.currentlyExecuting) {  try {  this.currentlyExecuting = true;  this.callback();  } finally {  this.currentlyExecuting = false;  } } }}/*--------------------------------------------------------------------------*/function $() { var elements = new Array(); for (var i = 0; i < arguments.length; i++) { var element = arguments[i]; if (typeof element == 'string')  element = document.getElementById(element); if (arguments.length == 1)  return element; elements.push(element); } return elements;}Object.extend(String.prototype, { stripTags: function() { return this.replace(/<\/?[^>]+>/gi, ''); }, stripScripts: function() { return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); }, extractScripts: function() { var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); return (this.match(matchAll) || []).map(function(scriptTag) {  return (scriptTag.match(matchOne) || ['', ''])[1]; }); }, evalScripts: function() { return this.extractScripts().map(eval); }, escapeHTML: function() { var div = document.createElement('div'); var text = document.createTextNode(this); div.appendChild(text); return div.innerHTML; }, unescapeHTML: function() { var div = document.createElement('div'); div.innerHTML = this.stripTags(); return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; }, toQueryParams: function() { var pairs = this.match(/^\??(.*)$/)[1].split('&'); return pairs.inject({}, function(params, pairString) {  var pair = pairString.split('=');  params[pair[0]] = pair[1];  return params; }); }, toArray: function() { return this.split(''); }, camelize: function() { var oStringList = this.split('-'); if (oStringList.length == 1) return oStringList[0]; var camelizedString = this.indexOf('-') == 0  ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)  : oStringList[0]; for (var i = 1, len = oStringList.length; i < len; i++) {  var s = oStringList[i];  camelizedString += s.charAt(0).toUpperCase() + s.substring(1); } return camelizedString; }, inspect: function() { return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; }});String.prototype.parseQuery = String.prototype.toQueryParams;var $break = new Object();var $continue = new Object();var Enumerable = { each: function(iterator) { var index = 0; try {  this._each(function(value) {  try {   iterator(value, index++);  } catch (e) {   if (e != $continue) throw e;  }  }); } catch (e) {  if (e != $break) throw e; } }, all: function(iterator) { var result = true; this.each(function(value, index) {  result = result && !!(iterator || Prototype.K)(value, index);  if (!result) throw $break; }); return result; }, any: function(iterator) { var result = true; this.each(function(value, index) {  if (result = !!(iterator || Prototype.K)(value, index))  throw $break; }); return result; }, collect: function(iterator) { var results = []; this.each(function(value, index) {  results.push(iterator(value, index)); }); return results; }, detect: function (iterator) { var result; this.each(function(value, index) {  if (iterator(value, index)) {  result = value;  throw $break;  } }); return result; }, findAll: function(iterator) { var results = []; this.each(function(value, index) {  if (iterator(value, index))  results.push(value); }); return results; }, grep: function(pattern, iterator) { var results = []; this.each(function(value, index) {  var stringValue = value.toString();  if (stringValue.match(pattern))  results.push((iterator || Prototype.K)(value, index)); }) return results; }, include: function(object) { var found = false; this.each(function(value) {  if (value == object) {  found = true;  throw $break;  } }); return found; }, inject: function(memo, iterator) { this.each(function(value, index) {  memo = iterator(memo, value, index); }); return memo; }, invoke: function(method) { var args = $A(arguments).slice(1); return this.collect(function(value) {  return value[method].apply(value, args); }); }, max: function(iterator) { var result; this.each(function(value, index) {  value = (iterator || Prototype.K)(value, index);  if (value >= (result || value))  result = value; }); return result; }, min: function(iterator) { var result; this.each(function(value, index) {  value = (iterator || Prototype.K)(value, index);  if (value <= (result || value))  result = value; });  return result; }, partition: function(iterator) {  var trues = [], falses = [];  this.each(function(value, index) {   ((iterator || Prototype.K)(value, index) ?    trues : falses).push(value);  });  return [trues, falses]; }, pluck: function(property) {  var results = [];  this.each(function(value, index) {   results.push(value[property]);  });  return results; }, reject: function(iterator) {  var results = [];  this.each(function(value, index) {   if (!iterator(value, index))    results.push(value);  });  return results; }, sortBy: function(iterator) {  return this.collect(function(value, index) {   return {value: value, criteria: iterator(value, index)};  }).sort(function(left, right) {   var a = left.criteria, b = right.criteria;   return a < b ? -1 : a > b ? 1 : 0;  }).pluck('value'); }, toArray: function() {  return this.collect(Prototype.K); }, zip: function() {  var iterator = Prototype.K, args = $A(arguments);  if (typeof args.last() == 'function')   iterator = args.pop();  var collections = [this].concat(args).map($A);  return this.map(function(value, index) {   iterator(value = collections.pluck(index));   return value;  }); }, inspect: function() {  return '#<Enumerable:' + this.toArray().inspect() + '>'; }}Object.extend(Enumerable, { map:   Enumerable.collect, find:  Enumerable.detect, select: Enumerable.findAll, member: Enumerable.include, entries: Enumerable.toArray});var $A = Array.from = function(iterable) { if (!iterable) return []; if (iterable.toArray) {  return iterable.toArray(); } else {  var results = [];  for (var i = 0; i < iterable.length; i++)   results.push(iterable[i]);  return results; }}Object.extend(Array.prototype, Enumerable);Array.prototype._reverse = Array.prototype.reverse;Object.extend(Array.prototype, { _each: function(iterator) {  for (var i = 0; i < this.length; i++)   iterator(this[i]); }, clear: function() {  this.length = 0;  return this; }, first: function() {  return this[0]; }, last: function() {  return this[this.length - 1]; }, compact: function() {  return this.select(function(value) {   return value != undefined || value != null;  }); }, flatten: function() {  return this.inject([], function(array, value) {   return array.concat(value.constructor == Array ?    value.flatten() : [value]);  }); }, without: function() {  var values = $A(arguments);  return this.select(function(value) {   return !values.include(value);  }); }, indexOf: function(object) {  for (var i = 0; i < this.length; i++)   if (this[i] == object) return i;  return -1; }, reverse: function(inline) {  return (inline !== false ? this : this.toArray())._reverse(); }, shift: function() {  var result = this[0];  for (var i = 0; i < this.length - 1; i++)   this[i] = this[i + 1];  this.length--;  return result; }, inspect: function() {  return '[' + this.map(Object.inspect).join(', ') + ']'; }});var Hash = { _each: function(iterator) {  for (key in this) {   var value = this[key];   if (typeof value == 'function') continue;   var pair = [key, value];   pair.key = key;   pair.value = value;   iterator(pair);  } }, keys: function() {  return this.pluck('key'); }, values: function() {  return this.pluck('value'); }, merge: function(hash) {  return $H(hash).inject($H(this), function(mergedHash, pair) {   mergedHash[pair.key] = pair.value;   return mergedHash;  }); }, toQueryString: function() {  return this.map(function(pair) {   return pair.map(encodeURIComponent).join('=');  }).join('&'); }, inspect: function() {  return '#<Hash:{' + this.map(function(pair) {   return pair.map(Object.inspect).join(': ');  }).join(', ') + '}>'; }}function $H(object) { var hash = Object.extend({}, object || {}); Object.extend(hash, Enumerable); Object.extend(hash, Hash); return hash;}ObjectRange = Class.create();Object.extend(ObjectRange.prototype, Enumerable);Object.extend(ObjectRange.prototype, { initialize: function(start, end, exclusive) {  this.start = start;  this.end = end;  this.exclusive = exclusive; }, _each: function(iterator) {  var value = this.start;  do {   iterator(value);   value = value.succ();  } while (this.include(value)); }, include: function(value) {  if (value < this.start)   return false;  if (this.exclusive)   return value < this.end;  return value <= this.end; }});var $R = function(start, end, exclusive) { return new ObjectRange(start, end, exclusive);}var Ajax = { getTransport: function() {  return Try.these(   function() {return new ActiveXObject('Msxml2.XMLHTTP')},   function() {return new ActiveXObject('Microsoft.XMLHTTP')},   function() {return new XMLHttpRequest()}  ) || false; }, activeRequestCount: 0}Ajax.Responders = { responders: [], _each: function(iterator) {  this.responders._each(iterator); }, register: function(responderToAdd) {  if (!this.include(responderToAdd))   this.responders.push(responderToAdd); }, unregister: function(responderToRemove) {  this.responders = this.responders.without(responderToRemove); }, dispatch: function(callback, request, transport, json) {  this.each(function(responder) {   if (responder[callback] && typeof responder[callback] == 'function') {    try {     responder[callback].apply(responder, [request, transport, json]);    } catch (e) {}   }  }); }};Object.extend(Ajax.Responders, Enumerable);Ajax.Responders.register({ onCreate: function() {  Ajax.activeRequestCount++; }, onComplete: function() {  Ajax.activeRequestCount--; }});Ajax.Base = function() {};Ajax.Base.prototype = { setOptions: function(options) {  this.options = {   method:    'post',   asynchronous: true,   parameters:  ''  }  Object.extend(this.options, options || {}); }, responseIsSuccess: function() {  return this.transport.status == undefined    || this.transport.status == 0    || (this.transport.status >= 200 && this.transport.status < 300); }, responseIsFailure: function() {  return !this.responseIsSuccess(); }}Ajax.Request = Class.create();Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];Ajax.Request.prototype = Object.extend(new Ajax.Base(), { initialize: function(url, options) {  this.transport = Ajax.getTransport();  this.setOptions(options);  this.request(url); }, request: function(url) {  var parameters = this.options.parameters || '';  if (parameters.length > 0) parameters += '&_=';  try {   this.url = url;   if (this.options.method == 'get' && parameters.length > 0)    this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;   Ajax.Responders.dispatch('onCreate', this, this.transport);   this.transport.open(this.options.method, this.url,    this.options.asynchronous);   if (this.options.asynchronous) {    this.transport.onreadystatechange = this.onStateChange.bind(this);    setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);   }   this.setRequestHeaders();   var body = this.options.postBody ? this.options.postBody : parameters;   this.transport.send(this.options.method == 'post' ? body : null);  } catch (e) {   this.dispatchException(e);  } }, setRequestHeaders: function() {  var requestHeaders =   ['X-Requested-With', 'XMLHttpRequest',    'X-Prototype-Version', Prototype.Version];  if (this.options.method == 'post') {   requestHeaders.push('Content-type',    'application/x-www-form-urlencoded');   /* Force "Connection: close" for Mozilla browsers to work around    * a bug where XMLHttpReqeuest sends an incorrect Content-length    * header. See Mozilla Bugzilla #246651.    */   if (this.transport.overrideMimeType)    requestHeaders.push('Connection', 'close');  }  if (this.options.requestHeaders)   requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);  for (var i = 0; i < requestHeaders.length; i += 2)   this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]); }, onStateChange: function() {  var readyState = this.transport.readyState;  if (readyState != 1)   this.respondToReadyState(this.transport.readyState); }, header: function(name) {  try {   return this.transport.getResponseHeader(name);  } catch (e) {} }, evalJSON: function() {  try {   return eval(this.header('X-JSON'));  } catch (e) {} }, evalResponse: function() {  try {   return eval(this.transport.responseText);  } catch (e) {   this.dispatchException(e);  } }, respondToReadyState: function(readyState) {  var event = Ajax.Request.Events[readyState];  var transport = this.transport, json = this.evalJSON();  if (event == 'Complete') {   try {    (this.options['on' + this.transport.status]     || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]     || Prototype.emptyFunction)(transport, json);   } catch (e) {    this.dispatchException(e);   }   if ((this.header('Content-type') || '').match(/^text\/javascript/i))    this.evalResponse();  }  try {   (this.options['on' + event] || Prototype.emptyFunction)(transport, json);   Ajax.Responders.dispatch('on' + event, this, transport, json);  } catch (e) {   this.dispatchException(e);  }  /* Avoid memory leak in MSIE: clean up the oncomplete event handler */  if (event == 'Complete')   this.transport.onreadystatechange = Prototype.emptyFunction; }, dispatchException: function(exception) {  (this.options.onException || Prototype.emptyFunction)(this, exception);  Ajax.Responders.dispatch('onException', this, exception); }});Ajax.Updater = Class.create();Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { initialize: function(container, url, options) {  this.containers = {   success: container.success ? $(container.success) : $(container),   failure: container.failure ? $(container.failure) :    (container.success ? null : $(container))  }  this.transport = Ajax.getTransport();  this.setOptions(options);  var onComplete = this.options.onComplete || Prototype.emptyFunction;  this.options.onComplete = (function(transport, object) {   this.updateContent();   onComplete(transport, object);  }).bind(this);  this.request(url); }, updateContent: function() {  var receiver = this.responseIsSuccess() ?   this.containers.success : this.containers.failure;  var response = this.transport.responseText;  if (!this.options.evalScripts)   response = response.stripScripts();  if (receiver) {   if (this.options.insertion) {    new this.options.insertion(receiver, response);   } else {    Element.update(receiver, response);   }  }  if (this.responseIsSuccess()) {   if (this.onComplete)    setTimeout(this.onComplete.bind(this), 10);  } }});Ajax.PeriodicalUpdater = Class.create();Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { initialize: function(container, url, options) {  this.setOptions(options);  this.onComplete = this.options.onComplete;  this.frequency = (this.options.frequency || 2);  this.decay = (this.options.decay || 1);  this.updater = {};  this.container = container;  this.url = url;  this.start(); }, start: function() {  this.options.onComplete = this.updateComplete.bind(this);  this.onTimerEvent(); }, stop: function() {  this.updater.onComplete = undefined;  clearTimeout(this.timer);  (this.onComplete || Prototype.emptyFunction).apply(this, arguments); }, updateComplete: function(request) {  if (this.options.decay) {   this.decay = (request.responseText == this.lastText ?    this.decay * this.options.decay : 1);   this.lastText = request.responseText;  }  this.timer = setTimeout(this.onTimerEvent.bind(this),   this.decay * this.frequency * 1000); }, onTimerEvent: function() {  this.updater = new Ajax.Updater(this.container, this.url, this.options); }});document.getElementsByClassName = function(className, parentElement) { var children = ($(parentElement) || document.body).getElementsByTagName('*'); return $A(children).inject([], function(elements, child) {  if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))   elements.push(child);  return elements; });}/*--------------------------------------------------------------------------*/if (!window.Element) { var Element = new Object();}Object.extend(Element, { visible: function(element) {  return $(element).style.display != 'none'; }, toggle: function() {  for (var i = 0; i < arguments.length; i++) {   var element = $(arguments[i]);   Element[Element.visible(element) ? 'hide' : 'show'](element);  } }, hide: function() {  for (var i = 0; i < arguments.length; i++) {   var element = $(arguments[i]);   element.style.display = 'none';  } }, show: function() {  for (var i = 0; i < arguments.length; i++) {   var element = $(arguments[i]);   element.style.display = '';  } }, remove: function(element) {  element = $(element);  element.parentNode.removeChild(element); }, update: function(element, html) {  $(element).innerHTML = html.stripScripts();  setTimeout(function() {html.evalScripts()}, 10); }, getHeight: function(element) {  element = $(element);  return element.offsetHeight; }, classNames: function(element) {  return new Element.ClassNames(element); }, hasClassName: function(element, className) {  if (!(element = $(element))) return;  return Element.classNames(element).include(className); }, addClassName: function(element, className) {  if (!(element = $(element))) return;  return Element.classNames(element).add(className); }, removeClassName: function(element, className) {  if (!(element = $(element))) return;  return Element.classNames(element).remove(className); }, // removes whitespace-only text node children cleanWhitespace: function(element) {  element = $(element);  for (var i = 0; i < element.childNodes.length; i++) {   var node = element.childNodes[i];   if (node.nodeType == 3 && !/\S/.test(node.nodeValue))    Element.remove(node);  } }, empty: function(element) {  return $(element).innerHTML.match(/^\s*$/); }, scrollTo: function(element) {  element = $(element);  var x = element.x ? element.x : element.offsetLeft,    y = element.y ? element.y : element.offsetTop;  window.scrollTo(x, y); }, getStyle: function(element, style) {  element = $(element);  var value = element.style[style.camelize()];  if (!value) {   if (document.defaultView && document.defaultView.getComputedStyle) {    var css = document.defaultView.getComputedStyle(element, null);    value = css ? css.getPropertyValue(style) : null;   } else if (element.currentStyle) {    value = element.currentStyle[style.camelize()];   }  }  if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))   if (Element.getStyle(element, 'position') == 'static') value = 'auto';  return value == 'auto' ? null : value; }, setStyle: function(element, style) {  element = $(element);  for (name in style)   element.style[name.camelize()] = style[name]; }, getDimensions: function(element) {  element = $(element);  if (Element.getStyle(element, 'display') != 'none')   return {width: element.offsetWidth, height: element.offsetHeight};  // All *Width and *Height properties give 0 on elements with display none,  // so enable the element temporarily  var els = element.style;  var originalVisibility = els.visibility;  var originalPosition = els.position;  els.visibility = 'hidden';  els.position = 'absolute';  els.display = '';  var originalWidth = element.clientWidth;  var originalHeight = element.clientHeight;  els.display = 'none';  els.position = originalPosition;  els.visibility = originalVisibility;  return {width: originalWidth, height: originalHeight}; }, makePositioned: function(element) {  element = $(element);  var pos = Element.getStyle(element, 'position');  if (pos == 'static' || !pos) {   element._madePositioned = true;   element.style.position = 'relative';   // Opera returns the offset relative to the positioning context, when an   // element is position relative but top and left have not been defined   if (window.opera) {    element.style.top = 0;    element.style.left = 0;   }  } }, undoPositioned: function(element) {  element = $(element);  if (element._madePositioned) {   element._madePositioned = undefined;   element.style.position =    element.style.top =    element.style.left =    element.style.bottom =    element.style.right = '';  } }, makeClipping: function(element) {  element = $(element);  if (element._overflow) return;  element._overflow = element.style.overflow;  if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')   element.style.overflow = 'hidden'; }, undoClipping: function(element) {  element = $(element);  if (element._overflow) return;  element.style.overflow = element._overflow;  element._overflow = undefined; }});var Toggle = new Object();Toggle.display = Element.toggle;/*--------------------------------------------------------------------------*/Abstract.Insertion = function(adjacency) { this.adjacency = adjacency;}Abstract.Insertion.prototype = { initialize: function(element, content) {  this.element = $(element);  this.content = content.stripScripts();  if (this.adjacency && this.element.insertAdjacentHTML) {   try {    this.element.insertAdjacentHTML(this.adjacency, this.content);   } catch (e) {    if (this.element.tagName.toLowerCase() == 'tbody') {     this.insertContent(this.contentFromAnonymousTable());    } else {     throw e;    }   }  } else {   this.range = this.element.ownerDocument.createRange();   if (this.initializeRange) this.initializeRange();   this.insertContent([this.range.createContextualFragment(this.content)]);  }  setTimeout(function() {content.evalScripts()}, 10); }, contentFromAnonymousTable: function() {  var div = document.createElement('div');  div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';  return $A(div.childNodes[0].childNodes[0].childNodes); }}var Insertion = new Object();Insertion.Before = Class.create();Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), { initializeRange: function() {  this.range.setStartBefore(this.element); }, insertContent: function(fragments) {  fragments.each((function(fragment) {   this.element.parentNode.insertBefore(fragment, this.element);  }).bind(this)); }});Insertion.Top = Class.create();Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), { initializeRange: function() {  this.range.selectNodeContents(this.element);  this.range.collapse(true); }, insertContent: function(fragments) {  fragments.reverse(false).each((function(fragment) {   this.element.insertBefore(fragment, this.element.firstChild);  }).bind(this)); }});Insertion.Bottom = Class.create();Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), { initializeRange: function() {  this.range.selectNodeContents(this.element);  this.range.collapse(this.element); }, insertContent: function(fragments) {  fragments.each((function(fragment) {   this.element.appendChild(fragment);  }).bind(this)); }});Insertion.After = Class.create();Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), { initializeRange: function() {  this.range.setStartAfter(this.element); }, insertContent: function(fragments) {  fragments.each((function(fragment) {   this.element.parentNode.insertBefore(fragment,    this.element.nextSibling);  }).bind(this)); }});/*--------------------------------------------------------------------------*/Element.ClassNames = Class.create();Element.ClassNames.prototype = { initialize: function(element) {  this.element = $(element); }, _each: function(iterator) {  this.element.className.split(/\s+/).select(function(name) {   return name.length > 0;  })._each(iterator); }, set: function(className) {  this.element.className = className; }, add: function(classNameToAdd) {  if (this.include(classNameToAdd)) return;  this.set(this.toArray().concat(classNameToAdd).join(' ')); }, remove: function(classNameToRemove) {  if (!this.include(classNameToRemove)) return;  this.set(this.select(function(className) {   return className != classNameToRemove;  }).join(' ')); }, toString: function() {  return this.toArray().join(' '); }}Object.extend(Element.ClassNames.prototype, Enumerable);var Field = { clear: function() {  for (var i = 0; i < arguments.length; i++)   $(arguments[i]).value = ''; }, focus: function(element) {  $(element).focus(); }, present: function() {  for (var i = 0; i < arguments.length; i++)   if ($(arguments[i]).value == '') return false;  return true; }, select: function(element) {  $(element).select(); }, activate: function(element) {  element = $(element);  element.focus();  if (element.select)   element.select(); }}/*--------------------------------------------------------------------------*/var Form = { serialize: function(form) {  var elements = Form.getElements($(form));  var queryComponents = new Array();  for (var i = 0; i < elements.length; i++) {   var queryComponent = Form.Element.serialize(elements[i]);   if (queryComponent)    queryComponents.push(queryComponent);  }  return queryComponents.join('&'); }, getElements: function(form) {  form = $(form);  var elements = new Array();  for (tagName in Form.Element.Serializers) {   var tagElements = form.getElementsByTagName(tagName);   for (var j = 0; j < tagElements.length; j++)    elements.push(tagElements[j]);  }  return elements; }, getInputs: function(form, typeName, name) {  form = $(form);  var inputs = form.getElementsByTagName('input');  if (!typeName && !name)   return inputs;  var matchingInputs = new Array();  for (var i = 0; i < inputs.length; i++) {   var input = inputs[i];   if ((typeName && input.type != typeName) ||     (name && input.name != name))    continue;   matchingInputs.push(input);  }  return matchingInputs; }, disable: function(form) {  var elements = Form.getElements(form);  for (var i = 0; i < elements.length; i++) {   var element = elements[i];   element.blur();   element.disabled = 'true';  } }, enable: function(form) {  var elements = Form.getElements(form);  for (var i = 0; i < elements.length; i++) {   var element = elements[i];   element.disabled = '';  } }, findFirstElement: function(form) {  return Form.getElements(form).find(function(element) {   return element.type != 'hidden' && !element.disabled &&    ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());  }); }, focusFirstElement: function(form) {  Field.activate(Form.findFirstElement(form)); }, reset: function(form) {  $(form).reset(); }}Form.Element = { serialize: function(element) {  element = $(element);  var method = element.tagName.toLowerCase();  var parameter = Form.Element.Serializers[method](element);  if (parameter) {   var key = encodeURIComponent(parameter[0]);   if (key.length == 0) return;   if (parameter[1].constructor != Array)    parameter[1] = [parameter[1]];   return parameter[1].map(function(value) {    return key + '=' + encodeURIComponent(value);   }).join('&');  } }, getValue: function(element) {  element = $(element);  var method = element.tagName.toLowerCase();  var parameter = Form.Element.Serializers[method](element);  if (parameter)   return parameter[1]; }}Form.Element.Serializers = { input: function(element) {  switch (element.type.toLowerCase()) {   case 'submit':   case 'hidden':   case 'password':   case 'text':    return Form.Element.Serializers.textarea(element);   case 'checkbox':   case 'radio':    return Form.Element.Serializers.inputSelector(element);  }  return false; }, inputSelector: function(element) {  if (element.checked)   return [element.name, element.value]; }, textarea: function(element) {  return [element.name, element.value]; }, select: function(element) {  return Form.Element.Serializers[element.type == 'select-one' ?   'selectOne' : 'selectMany'](element); }, selectOne: function(element) {  var value = '', opt, index = element.selectedIndex;  if (index >= 0) {   opt = element.options[index];   value = opt.value;   if (!value && !('value' in opt))    value = opt.text;  }  return [element.name, value]; }, selectMany: function(element) {  var value = new Array();  for (var i = 0; i < element.length; i++) {   var opt = element.options[i];   if (opt.selected) {    var optValue = opt.value;    if (!optValue && !('value' in opt))     optValue = opt.text;    value.push(optValue);   }  }  return [element.name, value]; }}/*--------------------------------------------------------------------------*/var $F = Form.Element.getValue;/*--------------------------------------------------------------------------*/Abstract.TimedObserver = function() {}Abstract.TimedObserver.prototype = { initialize: function(element, frequency, callback) {  this.frequency = frequency;  this.element  = $(element);  this.callback = callback;  this.lastValue = this.getValue();  this.registerCallback(); }, registerCallback: function() {  setInterval(this.onTimerEvent.bind(this), this.frequency * 1000); }, onTimerEvent: function() {  var value = this.getValue();  if (this.lastValue != value) {   this.callback(this.element, value);   this.lastValue = value;  } }}Form.Element.Observer = Class.create();Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { getValue: function() {  return Form.Element.getValue(this.element); }});Form.Observer = Class.create();Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), { getValue: function() {  return Form.serialize(this.element); }});/*--------------------------------------------------------------------------*/Abstract.EventObserver = function() {}Abstract.EventObserver.prototype = { initialize: function(element, callback) {  this.element = $(element);  this.callback = callback;  this.lastValue = this.getValue();  if (this.element.tagName.toLowerCase() == 'form')   this.registerFormCallbacks();  else   this.registerCallback(this.element); }, onElementEvent: function() {  var value = this.getValue();  if (this.lastValue != value) {   this.callback(this.element, value);   this.lastValue = value;  } }, registerFormCallbacks: function() {  var elements = Form.getElements(this.element);  for (var i = 0; i < elements.length; i++)   this.registerCallback(elements[i]); }, registerCallback: function(element) {  if (element.type) {   switch (element.type.toLowerCase()) {    case 'checkbox':    case 'radio':     Event.observe(element, 'click', this.onElementEvent.bind(this));     break;    case 'password':    case 'text':    case 'textarea':    case 'select-one':    case 'select-multiple':     Event.observe(element, 'change', this.onElementEvent.bind(this));     break;   }  } }}Form.Element.EventObserver = Class.create();Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { getValue: function() {  return Form.Element.getValue(this.element); }});Form.EventObserver = Class.create();Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), { getValue: function() {  return Form.serialize(this.element); }});if (!window.Event) { var Event = new Object();}Object.extend(Event, { KEY_BACKSPACE: 8, KEY_TAB:    9, KEY_RETURN:  13, KEY_ESC:   27, KEY_LEFT:   37, KEY_UP:    38, KEY_RIGHT:  39, KEY_DOWN:   40, KEY_DELETE:  46, element: function(event) {  return event.target || event.srcElement; }, isLeftClick: function(event) {  return (((event.which) && (event.which == 1)) ||      ((event.button) && (event.button == 1))); }, pointerX: function(event) {  return event.pageX || (event.clientX +   (document.documentElement.scrollLeft || document.body.scrollLeft)); }, pointerY: function(event) {  return event.pageY || (event.clientY +   (document.documentElement.scrollTop || document.body.scrollTop)); }, stop: function(event) {  if (event.preventDefault) {   event.preventDefault();   event.stopPropagation();  } else {   event.returnValue = false;   event.cancelBubble = true;  } }, // find the first node with the given tagName, starting from the // node the event was triggered on; traverses the DOM upwards findElement: function(event, tagName) {  var element = Event.element(event);  while (element.parentNode && (!element.tagName ||    (element.tagName.toUpperCase() != tagName.toUpperCase())))   element = element.parentNode;  return element; }, observers: false, _observeAndCache: function(element, name, observer, useCapture) {  if (!this.observers) this.observers = [];  if (element.addEventListener) {   this.observers.push([element, name, observer, useCapture]);   element.addEventListener(name, observer, useCapture);  } else if (element.attachEvent) {   this.observers.push([element, name, observer, useCapture]);   element.attachEvent('on' + name, observer);  } }, unloadCache: function() {  if (!Event.observers) return;  for (var i = 0; i < Event.observers.length; i++) {   Event.stopObserving.apply(this, Event.observers[i]);   Event.observers[i][0] = null;  }  Event.observers = false; }, observe: function(element, name, observer, useCapture) {  var element = $(element);  useCapture = useCapture || false;  if (name == 'keypress' &&    (navigator.appVersion.match(/Konqueror|Safari|KHTML/)    || element.attachEvent))   name = 'keydown';  this._observeAndCache(element, name, observer, useCapture); }, stopObserving: function(element, name, observer, useCapture) {  var element = $(element);  useCapture = useCapture || false;  if (name == 'keypress' &&    (navigator.appVersion.match(/Konqueror|Safari|KHTML/)    || element.detachEvent))   name = 'keydown';  if (element.removeEventListener) {   element.removeEventListener(name, observer, useCapture);  } else if (element.detachEvent) {   element.detachEvent('on' + name, observer);  } }});/* prevent memory leaks in IE */Event.observe(window, 'unload', Event.unloadCache, false);var Position = { // set to true if needed, warning: firefox performance problems // NOT neeeded for page scrolling, only if draggable contained in // scrollable elements includeScrollOffsets: false, // must be called before calling withinIncludingScrolloffset, every time the // page is scrolled prepare: function() {  this.deltaX = window.pageXOffset        || document.documentElement.scrollLeft        || document.body.scrollLeft        || 0;  this.deltaY = window.pageYOffset        || document.documentElement.scrollTop        || document.body.scrollTop        || 0; }, realOffset: function(element) {  var valueT = 0, valueL = 0;  do {   valueT += element.scrollTop || 0;   valueL += element.scrollLeft || 0;   element = element.parentNode;  } while (element);  return [valueL, valueT]; }, cumulativeOffset: function(element) {  var valueT = 0, valueL = 0;  do {   valueT += element.offsetTop || 0;   valueL += element.offsetLeft || 0;   element = element.offsetParent;  } while (element);  return [valueL, valueT]; }, positionedOffset: function(element) {  var valueT = 0, valueL = 0;  do {   valueT += element.offsetTop || 0;   valueL += element.offsetLeft || 0;   element = element.offsetParent;   if (element) {    p = Element.getStyle(element, 'position');    if (p == 'relative' || p == 'absolute') break;   }  } while (element);  return [valueL, valueT]; }, offsetParent: function(element) {  if (element.offsetParent) return element.offsetParent;  if (element == document.body) return element;  while ((element = element.parentNode) && element != document.body)   if (Element.getStyle(element, 'position') != 'static')    return element;  return document.body; }, // caches x/y coordinate pair to use with overlap within: function(element, x, y) {  if (this.includeScrollOffsets)   return this.withinIncludingScrolloffsets(element, x, y);  this.xcomp = x;  this.ycomp = y;  this.offset = this.cumulativeOffset(element);  return (y >= this.offset[1] &&      y < this.offset[1] + element.offsetHeight &&      x >= this.offset[0] &&      x < this.offset[0] + element.offsetWidth); }, withinIncludingScrolloffsets: function(element, x, y) {  var offsetcache = this.realOffset(element);  this.xcomp = x + offsetcache[0] - this.deltaX;  this.ycomp = y + offsetcache[1] - this.deltaY;  this.offset = this.cumulativeOffset(element);  return (this.ycomp >= this.offset[1] &&      this.ycomp < this.offset[1] + element.offsetHeight &&      this.xcomp >= this.offset[0] &&      this.xcomp < this.offset[0] + element.offsetWidth); }, // within must be called directly before overlap: function(mode, element) {  if (!mode) return 0;  if (mode == 'vertical')   return ((this.offset[1] + element.offsetHeight) - this.ycomp) /    element.offsetHeight;  if (mode == 'horizontal')   return ((this.offset[0] + element.offsetWidth) - this.xcomp) /    element.offsetWidth; }, clone: function(source, target) {  source = $(source);  target = $(target);  target.style.position = 'absolute';  var offsets = this.cumulativeOffset(source);  target.style.top  = offsets[1] + 'px';  target.style.left  = offsets[0] + 'px';  target.style.width = source.offsetWidth + 'px';  target.style.height = source.offsetHeight + 'px'; }, page: function(forElement) {  var valueT = 0, valueL = 0;  var element = forElement;  do {   valueT += element.offsetTop || 0;   valueL += element.offsetLeft || 0;   // Safari fix   if (element.offsetParent==document.body)    if (Element.getStyle(element,'position')=='absolute') break;  } while (element = element.offsetParent);  element = forElement;  do {   valueT -= element.scrollTop || 0;   valueL -= element.scrollLeft || 0;  } while (element = element.parentNode);  return [valueL, valueT]; }, clone: function(source, target) {  var options = Object.extend({   setLeft:  true,   setTop:   true,   setWidth:  true,   setHeight: true,   offsetTop: 0,   offsetLeft: 0  }, arguments[2] || {})  // find page position of source  source = $(source);  var p = Position.page(source);  // find coordinate system to use  target = $(target);  var delta = [0, 0];  var parent = null;  // delta [0,0] will do fine with position: fixed elements,  // position:absolute needs offsetParent deltas  if (Element.getStyle(target,'position') == 'absolute') {   parent = Position.offsetParent(target);   delta = Position.page(parent);  }  // correct by body offsets (fixes Safari)  if (parent == document.body) {   delta[0] -= document.body.offsetLeft;   delta[1] -= document.body.offsetTop;  }  // set position  if(options.setLeft)  target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';  if(options.setTop)  target.style.top  = (p[1] - delta[1] + options.offsetTop) + 'px';  if(options.setWidth) target.style.width = source.offsetWidth + 'px';  if(options.setHeight) target.style.height = source.offsetHeight + 'px'; }, absolutize: function(element) {  element = $(element);  if (element.style.position == 'absolute') return;  Position.prepare();  var offsets = Position.positionedOffset(element);  var top   = offsets[1];  var left  = offsets[0];  var width  = element.clientWidth;  var height = element.clientHeight;  element._originalLeft  = left - parseFloat(element.style.left || 0);  element._originalTop  = top - parseFloat(element.style.top || 0);  element._originalWidth = element.style.width;  element._originalHeight = element.style.height;  element.style.position = 'absolute';  element.style.top  = top + 'px';;  element.style.left  = left + 'px';;  element.style.width = width + 'px';;  element.style.height = height + 'px';; }, relativize: function(element) {  element = $(element);  if (element.style.position == 'relative') return;  Position.prepare();  element.style.position = 'relative';  var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);  var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);  element.style.top  = top + 'px';  element.style.left  = left + 'px';  element.style.height = element._originalHeight;  element.style.width = element._originalWidth; }}// Safari returns margins on body which is incorrect if the child is absolutely// positioned. For performance reasons, redefine Position.cumulativeOffset for// KHTML/WebKit only.if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) { Position.cumulativeOffset = function(element) {  var valueT = 0, valueL = 0;  do {   valueT += element.offsetTop || 0;   valueL += element.offsetLeft || 0;   if (element.offsetParent == document.body)    if (Element.getStyle(element, 'position') == 'absolute') break;   element = element.offsetParent;  } while (element);  return [valueL, valueT]; }}