﻿var Prototype = {
  Version: '1.5.1',
  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      (document.createElement('div').__proto__ !==
       document.createElement('form').__proto__)
  },

  ScriptFragment: '<script[^>]*>([\u0001-\uFFFF]*?)</script>',
  JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};
var Browser = {
    isMozilla : (typeof document.implementation != 'undefined') && (typeof document.implementation.createDocument != 'undefined') && (typeof HTMLDocument!='undefined'),
    isIE:     !!(window.attachEvent && !window.opera),
    isFirefox : (navigator.userAgent.toLowerCase().indexOf("firefox")!=-1),
    isOpera:  !!window.opera,
    isWebKit: navigator.userAgent.toLowerCase().indexOf('applewebkit/') > -1,
    isGecko:  navigator.userAgent.toLowerCase().indexOf('gecko') > -1 && navigator.userAgent.toLowerCase().indexOf('khtml') == -1
};

var Class={
	create: function(){
		return function(){
			this.initialize.apply(this,arguments);
		}
	}
};
if(typeof webjs=="undefined"){
    webjs={
    }
    ;
}
webjs.loader={
    _timer:{
    }
    ,isLoading:function(win){
        if(!win){
            win=window;
        }
        if(!win.document){
            return false;
        }
        if(Browser.isGecko){
            return !!win.document.body;
        }
        else{
            return win.document.readyState=="complete";
        }
    }
    ,load:function(_1,_2,_3){
        try{
            if(!_3){
                _3=window;
            }
            else{
                _3=eval(_3);
            }
            if(!this.isLoading()){
                webjs.loader._timer[_1]=window.setTimeout(function(){
                    return webjs.loader.load(_1,_2,_3);
                }
                ,500);
                return 1;
            }
            if(webjs.loader._timer[_1]){
                window.clearTimeout(webjs.loader._timer[_1]);
                delete webjs.loader._timer[_1];
            }
            if(typeof _2=="function"){
               _2();
               return false;
            };
            return 0;
        }
        catch(e){
            return -6;
        }
    }
    ,unload:function(_b,_c){
        try{
            if(!_c){
                _c=window;
            }
            else{
                _c=eval(_c);
            }
            if(webjs.loader._timer[_b]){
                window.clearTimeout(webjs.loader._timer[_b]);
                delete webjs.loader._timer[_b];
            }
            var _d=_c.document.getElementById(_b);
            if(!_d){
                return -1;
            }
            _c.document.body.removeChild(_d);
            eval("try{ delete "+_b+"; }catch(e){}");
            return 0;
        }
        catch(e){
        }
        return -2;
    }
}
;
if(!Object.extend){
    Object.extend = function(destination, source) {
      for (var property in source) {
        destination[property] = source[property];
      }
      return destination;
    };
}
var Abstract = new Object();

Object.extend(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;
    }
  },

  toJSON: function(object) {
    var type = typeof object;
    switch(type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }
    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (object.ownerDocument === document) return;
    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (value !== undefined)
        results.push(property.toJSON() + ': ' + value);
    }
    return '{' + results.join(', ') + '}';
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({}, object);
  }
});
Object.extend(Function.prototype,{
    bind:function(){
        var __method=this, args=$A(arguments), object=args.shift();
    	return function(){
    		return __method.apply(object,args.concat($A(arguments)));
    	};
    }
    ,bindAsEventListener:function(){
        var _c=this,args=$A(arguments),object=args.shift();
        return function(_d){
            return _c.apply(object,[_d||window.event].concat(args));
        }
        ;
    }
    ,callWith:function(){
        var _e=this,args=$A(arguments);
        return function(){
            return _e.apply(this,args.concat($A(arguments)));
        }
        ;
    }
}
);
Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

Date.prototype.toJSON = function() {
  return '"' + this.getFullYear() + '-' +
    (this.getMonth() + 1).toPaddedString(2) + '-' +
    this.getDate().toPaddedString(2) + 'T' +
    this.getHours().toPaddedString(2) + ':' +
    this.getMinutes().toPaddedString(2) + ':' +
    this.getSeconds().toPaddedString(2) + '"';
};

function $(){
	var results=[], element;
	for(var i=0; i<arguments.length; i++){
		element=arguments[i];
		if(typeof element=='string')
		{
			element=(document.getElementById) ? document.getElementById(element)
                                   : document.all[element];
            if(typeof(element)=='undefined') element = document.getElementsByName(element)[0];
		}
		results.push(Element.extend(element));
	}
	return results.length<2 ? results[0] : results;
};

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(query.snapshotItem(i));
    return results;
  };

  document.getElementsByClassName = function(className, parentElement) {
    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
    return document._getElementsByXPath(q, parentElement);
  }

} else document.getElementsByClassName = function(className, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  var elements = [], child;
  for (var i = 0, length = children.length; i < length; i++) {
    child = children[i];
    if (Element.hasClassName(child, className))
      elements.push(Element.extend(child));
  }
  return elements;
};

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }

    return returnValue;
  }
};

var $break = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');

var Enumerable = {
  each: function(iterator) {
    var index = 0;
    try {
      this._each(function(value) {
        iterator(value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator) {
    var index = -number, slices = [], array = this.toArray();
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.map(iterator);
  },

  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 = false;
    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 || Prototype.K)(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;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = fillWith === undefined ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  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.map(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 (result == undefined || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (result == undefined || value < result)
        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.map(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.map();
  },

  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) {
      return iterator(collections.pluck(index));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  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, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}

if (Browser.isWebKit) {
  $A = Array.from = function(iterable) {
    if (!iterable) return [];
    if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
      iterable.toArray) {
      return iterable.toArray();
    } else {
      var results = [];
      for (var i = 0, length = iterable.length; i < length; i++)
        results.push(iterable[i]);
      return results;
    }
  }
}

Object.extend(Array.prototype, Enumerable);
if (!Array.prototype._reverse)
  Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < 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 != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(value && 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, length = this.length; i < length; i++)
      if (this[i] == object) return i;
    return -1;
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (value !== undefined) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

Array.prototype.toArray = Array.prototype.clone;
function $w(string) {
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}
//数据内值混乱 
if (!Array.prototype.shuffle)
{
    Array.prototype.shuffle = function()
    {
        for(var j, x, i = this.length; i; j = parseInt(Math.random() * i), x = this[--i], this[i] = this[j], this[j] = x);
        return this;
    };
}
if (Browser.isOpera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (arguments[i].constructor == Array) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  }
}

var Hash = function(object) {
  if (object instanceof Hash) this.merge(object);
  else Object.extend(this, object || {});
};

Object.extend(Hash, {
  toQueryString: function(obj) {
    var parts = [];
    parts.add = arguments.callee.addPair;

    this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;
      var value = pair.value;

      if (value && typeof value == 'object') {
        if (value.constructor == Array) value.each(function(value) {
          parts.add(pair.key, value);
        });
        return;
      }
      parts.add(pair.key, value);
    });

    return parts.join('&');
  },

  toJSON: function(object) {
    var results = [];
    this.prototype._each.call(object, function(pair) {
      var value = Object.toJSON(pair.value);
      if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
    });
    return '{' + results.join(', ') + '}';
  }
});

Hash.toQueryString.addPair = function(key, value, prefix) {
  key = encodeURIComponent(key);
  if (value === undefined) this.push(key);
  else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
}

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
  _each: function(iterator) {
    for (var key in this) {
      var value = this[key];
      if (value && value == Hash.prototype[key]) 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(this, function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  remove: function() {
    var result;
    for(var i = 0, length = arguments.length; i < length; i++) {
      var value = this[arguments[i]];
      if (value !== undefined){
        if (result === undefined) result = value;
        else {
          if (result.constructor != Array) result = [result];
          result.push(value)
        }
      }
      delete this[arguments[i]];
    }
    return result;
  },

  toQueryString: function() {
    return Hash.toQueryString(this);
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  },

  toJSON: function() {
    return Hash.toJSON(this);
  }
});

function $H(object) {
  if (object instanceof Hash) return object;
  return new Hash(object);
};

// Safari iterates over shadowed properties
if (function() {
  var i = 0, Test = function(value) { this.key = value };
  Test.prototype.key = 'foo';
  for (var property in new Test('bar')) i++;
  return i > 1;
}()) Hash.prototype._each = function(iterator) {
  var cache = [];
  for (var key in this) {
    var value = this[key];
    if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
    cache.push(key);
    var pair = [key, value];
    pair.key = key;
    pair.value = value;
    iterator(pair);
  }
};
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;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  },

  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);
}
/*-----------------------------Ajax-----------------------------------------*/
var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
}

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (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,
      contentType: 'application/x-www-form-urlencoded',
      //encoding:     'UTF-8',
      parameters:   ''
    }
    Object.extend(this.options, options || {});

    this.options.method = this.options.method.toLowerCase();
    if (typeof this.options.parameters == 'string')
      this.options.parameters = this.options.parameters.toQueryParams();
  }
}

Ajax.Request = Class.create();
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
  _complete: false,
  initialize: function(url,options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
    this.request(url);
  },
  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }
    this.parameters = params;

    if (params = Hash.toQueryString(params)) {
      // when GET, append parameters to URL
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      if (this.options.onCreate) this.options.onCreate(this.transport);
      Ajax.Responders.dispatch('onCreate', this, this.transport);
      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous)
        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (typeof extras.push == 'function')
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    return !this.transport.status
        || (this.transport.status >= 200 && this.transport.status < 300);
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState];
    var transport = this.transport, json = this.evalJSON();

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + this.transport.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(transport, json);
      } catch (e) {
        this.dispatchException(e);
      }

      var contentType = this.getHeader('Content-type');
      if (contentType && contentType.strip().
        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
          this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
      Ajax.Responders.dispatch('on' + state, this, transport, json);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      // avoid memory leak in MSIE: clean up
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) { return null }
  },

  evalJSON: function() {
    try {
      var json = this.getHeader('X-JSON');
      return json ? json.evalJSON() : null;
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  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.container = {
      success: (container.success || 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, param) {
      this.updateContent();
      onComplete(transport, param);
    }).bind(this);

    this.request(url);
  },

  updateContent: function() {
    var receiver = this.container[this.success() ? 'success' : 'failure'];
    var response = this.transport.responseText;

    if (!this.options.evalScripts) response = response.stripScripts();

    if (receiver = $(receiver)) {
      if (this.options.insertion)
        new this.options.insertion(receiver, response);
      else
        receiver.update(response);
    }

    if (this.success()) {
      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.options.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);
  }
});
/*--------------------------------------------------------------------------*/
if(!window.Element)
	var Element=new Object();
var _nativeExtensions=false;
Element.extend=function(element){
	if(!element) return;
	if(_nativeExtensions) return element;
	if(!element._extended&&element.tagName&&element!=window){
		var methods=Element.Methods, cache=Element.extend.cache;
		for(var property in methods){
			var value=methods[property];
			if(typeof value=='function')
				element[property]=cache.findOrStore(value);
		}
	}
	element._extended=true;
	return element;
};
Element.extend.cache={
	findOrStore: function(value){
		return this[value]=this[value]||function(){
			return value.apply(null,[this].concat($A(arguments)));
		}
	}
};
Object.extend=function(destination,source){
	for(var property in source){
		destination[property]=source[property];
	}
	return destination;
};

Element.Methods={
	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) {
        html = typeof html == 'undefined' ? '' : html.toString();
        $(element).innerHTML = html.stripScripts();
        setTimeout(function() {html.evalScripts()}, 10);
        return element;
    },
    replace: function(element, html) {
        element = $(element);
        html = typeof html == 'undefined' ? '' : html.toString();
        if (element.outerHTML) {
          element.outerHTML = html.stripScripts();
        } else {
          var range = element.ownerDocument.createRange();
          range.selectNodeContents(element);
          element.parentNode.replaceChild(
            range.createContextualFragment(html.stripScripts()), element);
        }
        setTimeout(function() {html.evalScripts()}, 10);
        return element;
    },
    previousSiblings: function(element) {
         return $(element).recursivelyCollect('previousSibling');
    },
    nextSiblings: function(element) {
        return $(element).recursivelyCollect('nextSibling');
    },
    match: function(element, selector) {
        if (typeof selector == 'string')
          selector = new Selector(selector);
        return selector.match($(element));
    },
    up: function(element, expression, index) {
        element = $(element);
        if (arguments.length == 1) return $(element.parentNode);
        var ancestors = element.ancestors();
        return expression ? Selector.findElement(ancestors, expression, index) :
          ancestors[index || 0];
    },
    down: function(element, expression, index) {
        element = $(element);
        if (arguments.length == 1) return element.firstDescendant();
        var descendants = element.descendants();
        return expression ? Selector.findElement(descendants, expression, index) :
          descendants[index || 0];
    },
    previous: function(element, expression, index) {
        element = $(element);
        if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
        var previousSiblings = element.previousSiblings();
        return expression ? Selector.findElement(previousSiblings, expression, index) :
          previousSiblings[index || 0];
    },
    
    next: function(element, expression, index) {
        element = $(element);
        if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
        var nextSiblings = element.nextSiblings();
        return expression ? Selector.findElement(nextSiblings, expression, index) :
          nextSiblings[index || 0];
    },
    
    getElementsBySelector: function() {
        var args = $A(arguments), element = $(args.shift());
        return Selector.findChildElements(element, args);
    },
    
    getElementsByClassName: function(element, className) {
        return document.getElementsByClassName(className, element);
    },
    
    readAttribute: function(element, name) {
        element = $(element);
        if (Browser.isIE) {
          if (!element.attributes) return null;
          var t = Element._attributeTranslations;
          if (t.values[name]) return t.values[name](element, name);
          if (t.names[name])  name = t.names[name];
          var attribute = element.attributes[name];
          return attribute ? attribute.nodeValue : null;
        }
        return element.getAttribute(name);
    },
    
    getHeight: function(element) {
        return $(element).getDimensions().height;
    },
    
    getWidth: function(element) {
        return $(element).getDimensions().width;
    },
    
    classNames: function(element) {
        return new Element.ClassNames(element);
    },
    
    hasClassName: function(element, className) {
        if (!(element = $(element))) return;
        var elementClassName = element.className;
        if (elementClassName.length == 0) return false;
        if (elementClassName == className ||
            elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
          return true;
        return false;
    },
    
    addClassName: function(element, className) {
        if (!(element = $(element))) return;
        Element.classNames(element).add(className);
        return element;
    },
    
    removeClassName: function(element, className) {
        if (!(element = $(element))) return;
        Element.classNames(element).remove(className);
        return element;
    },
    
    toggleClassName: function(element, className) {
        if (!(element = $(element))) return;
        Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
        return element;
        },
        scrollTo: function(element) {
        element = $(element);
        var pos = Position.cumulativeOffset(element);
        window.scrollTo(pos[0], pos[1]);
        return element;
    },
    
    getStyle: function(element, style) {
        element = $(element);
        style = style == 'float' ? 'cssFloat' : style.camelize();
        var value = element.style[style];
     
        if (!value) {
          try
          {
          var css = document.defaultView.getComputedStyle(element, null);
          value = css ? css[style] : null;
          }catch(e){}
        }
        if (style == 'opacity') return value ? parseFloat(value) : 1.0;
        return value == 'auto' ? null : value;
        },
        
        getOpacity: function(element) {
        return $(element).getStyle('opacity');
    },
    
    setStyle: function(element, styles, camelized) {
        element = $(element);
        var elementStyle = element.style;
        
        for (var property in styles)
          if (property == 'opacity') element.setOpacity(styles[property])
          else
            elementStyle[(property == 'float' || property == 'cssFloat') ?
              (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
              (camelized ? property : property.camelize())] = styles[property];
        
        return element;
    },
    
    setOpacity: function(element, value) {
            element = $(element);
            element.style.opacity = (value == 1 || value === '') ? '' :
              (value < 0.00001) ? 0 : value;
            return element;
    },
    getDimensions: function(element) {
        element = $(element);
        var display = $(element).getStyle('display');
        if (display != 'none' && display != null) // Safari bug
          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;
        var originalDisplay = els.display;
        els.visibility = 'hidden';
        els.position = 'absolute';
        els.display = 'block';
        var originalWidth = element.clientWidth;
        var originalHeight = element.clientHeight;
        els.display = originalDisplay;
        els.position = originalPosition;
        els.visibility = originalVisibility;
        return {width: originalWidth, height: originalHeight};
    }
};
Object.extend(Element,Element.Methods);
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;
		}
	},
	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(!element) return;
		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);
		if(element==null) return;
		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);
		}
	}
});
if(navigator.appVersion.match(/\bMSIE\b/))
	Event.observe(window,'unload',Event.unloadCache,false);
var Position={
	includeScrollOffsets: false,
	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){
				var 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;
	},
	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);
	},
	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;
	},
	page: function(forElement){
		var valueT=0, valueL=0;
		var element=forElement;
		do {
			valueT+=element.offsetTop||0;
			valueL+=element.offsetLeft||0;
			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]||{});
		source=$(source);
		var p=Position.page(source);
		target=$(target);
		var delta=[0, 0];
		var parent=null;
		if(Element.getStyle(target,'position')=='absolute'){
			parent=Position.offsetParent(target);
			delta=Position.page(parent);
		}
		if(parent==document.body){
			delta[0]-=document.body.offsetLeft;
			delta[1]-=document.body.offsetTop;
		}
		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;
	}
};
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];
	}
}
Object.extend(Element.Methods, {
  childOf: Element.Methods.descendantOf,
  childElements: Element.Methods.immediateDescendants
});

if (Browser.isOpera) {
  Element.Methods._getStyle = Element.Methods.getStyle;
  Element.Methods.getStyle = function(element, style) {
    switch(style) {
      case 'left':
      case 'top':
      case 'right':
      case 'bottom':
        if (Element._getStyle(element, 'position') == 'static') return null;
      default: return Element._getStyle(element, style);
    }
  };
}
else if (Browser.isIE) {
  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset'+style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  // IE is missing .innerHTML support for TABLE-related elements
  Element.Methods.update = function(element, html) {
    element = $(element);
    html = typeof html == 'undefined' ? '' : html.toString();
    var tagName = element.tagName.toUpperCase();
    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
      var div = document.createElement('div');
      switch (tagName) {
        case 'THEAD':
        case 'TBODY':
          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
          depth = 2;
          break;
        case 'TR':
          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
          depth = 3;
          break;
        case 'TD':
          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
          depth = 4;
      }
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
      depth.times(function() { div = div.firstChild });
      $A(div.childNodes).each(function(node) { element.appendChild(node) });
    } else {
      element.innerHTML = html.stripScripts();
    }
    setTimeout(function() { html.evalScripts() }, 10);
    return element;
  }
}
else if (Browser.isGecko) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}
Element._attributeTranslations = {
  names: {
    colspan:   "colSpan",
    rowspan:   "rowSpan",
    valign:    "vAlign",
    datetime:  "dateTime",
    accesskey: "accessKey",
    tabindex:  "tabIndex",
    enctype:   "encType",
    maxlength: "maxLength",
    readonly:  "readOnly",
    longdesc:  "longDesc"
  },
  values: {
    _getAttr: function(element, attribute) {
      return element.getAttribute(attribute, 2);
    },
    _flag: function(element, attribute) {
      return $(element).hasAttribute(attribute) ? attribute : null;
    },
    style: function(element) {
      return element.style.cssText.toLowerCase();
    },
    title: function(element) {
      var node = element.getAttributeNode('title');
      return node.specified ? node.nodeValue : null;
    }
  }
};

(function() {
  Object.extend(this, {
    href: this._getAttr,
    src:  this._getAttr,
    type: this._getAttr,
    disabled: this._flag,
    checked:  this._flag,
    readonly: this._flag,
    multiple: this._flag
  });
}).call(Element._attributeTranslations.values);

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    var t = Element._attributeTranslations, node;
    attribute = t.names[attribute] || attribute;
    node = $(element).getAttributeNode(attribute);
    return node && node.specified;
  }
};

Element.Methods.ByTag = {};

Object.extend(Element, Element.Methods);

if (!!!window.HTMLElement &&
 document.createElement('div').__proto__) {
  window.HTMLElement = {};
  window.HTMLElement.prototype = document.createElement('div').__proto__;
  window.HTMLElement = true;
}

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || {});
  else {
    if (tagName.constructor == Array) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = {};
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    var cache = Element.extend.cache;
    for (var property in methods) {
      var value = methods[property];
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = cache.findOrStore(value);
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    window[klass] = {};
    window[klass].prototype = document.createElement(tagName).__proto__;
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (typeof klass == "undefined") continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;
};

var Toggle = { display: Element.toggle };

/*--------------------------------------------------------------------------*/
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($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);

var Selector = Class.create();

Selector.prototype = {
  initialize: function(expression) {
    this.expression = expression.strip();
    this.compileMatcher();
  },

  compileMatcher: function() {
    // Selectors with namespaced attributes can't use the XPath version
    if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
      return this.compileXPathMatcher();

    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e]; return;
    }
    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
    	      new Template(c[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le,  m;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
            new Template(x[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
    return this.matcher(root);
  },

  match: function(element) {
    return this.findElements(document).include(element);
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
};

Object.extend(Selector, {
  _cache: {},

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: "[@#{1}]",
    attr: function(m) {
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (typeof h === 'function') return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
      'checked':     "[@checked]",
      'disabled':    "[@disabled]",
      'enabled':     "[not(@disabled)]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, m, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
    className:    'n = h.className(n, r, "#{1}", c); c = false;',
    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
    },
    pseudo:       function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
    attrPresence: /^\[([\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
  },

  handlers: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    index: function(parentNode, reverse, ofType) {
      parentNode._counted = true;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._counted) {
          n._counted = true;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
	      if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      tagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() == tagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;
      if (!nodes && root == document) return targetNode ? [targetNode] : [];
      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr) {
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    // handles the an+b logic
    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._counted) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._counted) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled) results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv.startsWith(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
  },

  matchElements: function(elements, expression) {
    var matches = new Selector(expression).findElements(), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._counted) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (typeof expression == 'number') {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    var exprs = expressions.join(','), expressions = [];
    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, getHash) {
    var data = elements.inject({}, function(result, element) {
      if (!element.disabled && element.name) {
        var key = element.name, value = $(element).getValue();
        if (value != null) {
         	if (key in result) {
            if (result[key].constructor != Array) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return getHash ? data : Hash.toQueryString(data);
  }
};
/*--------------------------------------------------------------------------*/
Form.Methods = {
  serialize: function(form, getHash) {
    return Form.serializeElements(Form.getElements(form), getHash);
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    return form;
  },

  findFirstElement: function(form) {
    return $(form).getElements().find(function(element) {
      return element.type != 'hidden' && !element.disabled &&
        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || {});

    var params = options.parameters;
    options.parameters = form.serialize(true);

    if (params) {
      if (typeof params == 'string') params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(form.readAttribute('action'), options);
  }
};

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = {};
        pair[element.name] = value;
        return Hash.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
        !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) {}
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
};

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
      default:
        return Form.Element.Serializers.textarea(element);
    }
  },

  inputSelector: function(element) {
    return element.checked ? element.value : null;
  },

  textarea: function(element) {
    return element.value;
  },

  select: function(element) {
    return this[element.type == 'select-one' ?
      'selectOne' : 'selectMany'](element);
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    // extend element because hasAttribute may not be native
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
};
/*--------------------------------------------------------------------------*/
var Abstract = new Object();
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();
    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
      ? this.lastValue != value : String(this.lastValue) != String(value));
    if (changed) {
      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() {
    Form.getElements(this.element).each(this.registerCallback.bind(this));
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          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);
  }
});
/*--------------------------------------------------------------------------*/
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = count === undefined ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return this;
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : this;
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  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(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var self = arguments.callee;
    self.text.data = this;
    return self.div.innerHTML;
  },

  unescapeHTML: function() {
    var div = document.createElement('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return {};

    return match[1].split(separator || '&').inject({}, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (hash[key].constructor != Array) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    var result = '';
    for (var i = 0; i < count; i++) result += this;
    return result;
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || (/^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/.test(json)))
        return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  }
});
if (Browser.isWebKit || Browser.isIE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (typeof replacement == 'function') return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
}

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

with (String.prototype.escapeHTML) div.appendChild(text);


function isUndefined(variable) {
	return typeof variable == 'undefined' ? true : false;
};
_pi = function(str) {
	return parseInt(str);
};
_gObj = function(id) {
    return $(id);
};

String.prototype.chop = function() {
	return this;
};

String.prototype.nl2br = function() {
	return this.split('\n').join('<br \/>\n');
};

String.prototype.escapeForXML = function() {
	return this.replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
};

String.prototype.escapeForDisplay = function() {
	return this.replace(/</g, '&lt;');
};

function _escape(v) {
    var es=window.encodeURIComponent?encodeURIComponent:escape;
	return es(v);
};


//?len
String.prototype.len = function()
{
	return this.replace(/[^\x00-\xff]/g,"aa").length;
};

function startsWith(s, s0) {
    if (s) return (s.substring(0, s0.length) == s0);
};

function endsWith(s, s0) {
    if (s) return (s.substring(s.length - s0.length) == s0);
};


function checkFlash() {
	if (actualVersion>=6) return true;
	return false;
};

function IsDigit(){
  return ((event.keyCode >= 48) && (event.keyCode <= 57));
};

String.prototype.getRealLength=function(){return this.replace(/[^\x00-\xff]/g,"aa").length;};

String.prototype.trim=function(){
	return this.replace(/^\s+|\s+$/,"");
};
function okForXMLHTTPREQUEST(){
	if (!window.XMLHttpRequest) return false;
	if (navigator.appVersion.toLowerCase().indexOf("mac") > 0 && navigator.userAgent.indexOf('MSIE') > 0 && navigator.userAgent.indexOf('Opera') == -1) return false;
	return true;
};

function getEventSrc(e){
	if (e){ return e.target; }
	if (window.event){ return window.event.srcElement; }
	return null;
};

function getKeyCode(e){
	if (e){ return e.which; }
	if (window.event){ return window.event.keyCode; }
	return null;
};

function setFocus(obj)
{	
	$(obj).focus();	
};

function  setCaretAtEnd(field){  
   if  (field.createTextRange)  {  
       var  r  =  field.createTextRange();  
       r.moveStart('character',  field.value.length);  
       r.collapse();  
       r.select();  
   }
};

function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft;
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	
	return curleft;
};

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop;
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;

	return curtop;
};

function in_array(needle, haystack)
{
	if(typeof needle == 'string' || typeof needle == 'number') {
		for(var i in haystack) {
			if(haystack[i] == needle) {
					return true;
			}
		}
	}
	return false;
};

function get_extname(s)
{
	var s = new String(s);
	s = s.toLowerCase();
	if ((s.lastIndexOf(".")>-1) &&((s.length-1)>s.lastIndexOf("."))) 
	{		
		return s.substring(s.lastIndexOf(".")+1);
	}
	else
	{
		return false;
	}	
};

function trim(s) {
  return s.trim();
};

function getParameterDef(varName)
{
	var query = location.search;
	if(query.indexOf("?")!=-1)
	{
	    var query = query.substr(1);
        if(query!="")
        {
    		var qArray = query.split("&");
    		var len = qArray.length;
    		if (len > 0)
    		{
    			for (var i=0; i<len; i++)
    			{
    				var sArray = qArray[i].split("=", 2);
    				if (sArray[0] && sArray[1] && sArray[0].toLowerCase() == varName)
    				{
    					return unescape(sArray[1].replace("#",""));
    				}
    			}
    		}
		}
	}
	return null;
};

function isNull(s)
{
	if (s+"123" == "123")
	{
		return true;
	}
	return false;
};
function debug(msg)
{
	if((typeof(is_debug)!="undefined") && (is_debug==1))
	{
		alert(msg);
	}
};

function getDataTime()
{
	var strDate,strTime;
	strDate = new Date();
	strTime = strDate.getTime();
	return strTime;
};

function getWidth()
{
	var strWidth,clientWidth,bodyWidth;
	clientWidth = document.documentElement.clientWidth;
	bodyWidth = document.body.clientWidth;
	if(bodyWidth > clientWidth){
		strWidth = bodyWidth + 20;
	} else {
		strWidth = clientWidth;
	}
	return strWidth;
};
function getHeight()
{
	var strHeight,eclientHeight,bodyHeight;
	eclientHeight = document.documentElement.clientHeight;
	bodyHeight = document.body.clientHeight;
	if(bodyHeight > eclientHeight){
		strHeight = bodyHeight + 30;
	} else {
		strHeight = eclientHeight;
	}
	return strHeight;
} ;

function getScrollTop()
{
	var scrollPos; 
    if (typeof window.pageYOffset != 'undefined') { 
       scrollPos = window.pageYOffset; 
    } 
    else if (typeof document.compatMode != 'undefined' && 
         document.compatMode != 'BackCompat') { 
       scrollPos = document.documentElement.scrollTop; 
    } 
    else if (typeof document.body != 'undefined') { 
       scrollPos = document.body.scrollTop; 
    }
    return scrollPos;
};
getPagePosition=function(_3f){
    var ret={
    }
    ;
    ret.scrollLeft=_3f.pageXOffset||_3f.document.documentElement.scrollLeft||_3f.document.body.scrollLeft||0;
    ret.scrollTop=_3f.pageYOffset||_3f.document.documentElement.scrollTop||_3f.document.body.scrollTop||0;
    ret.clientWidth=_3f.innerWidth||_3f.document.documentElement.clientWidth||_3f.document.body.clientWidth||0;
    ret.clientHeight=_3f.innerHeight||_3f.document.documentElement.clientHeight||_3f.document.body.clientHeight||0;
    return ret;
}
;
function DisplayDIV(xleft,xtop,div)
{
    var seltext = $(div);
    var scrollPos=getScrollTop();
    var alphat=50,clientX,clientY;
    try{
       clientX = event.clientX; 
    }catch(e){ clientX=300;}
    try{
       clientY = event.clientY; 
    }catch(e){ clientY=250;}
    
    var mleft = clientX + Number(xleft);
    var mtop = scrollPos+clientY + Number(xtop);
    var bodywidth=getWidth();
    var bodyheight=getHeight();
    if(mleft<=2) mleft=2;

    if(mleft+seltext.offsetWidth>bodywidth) mleft=bodywidth-seltext.offsetWidth;
    if(mtop<scrollPos) mtop = scrollPos;
    if(mtop+seltext.offsetHeight>bodyheight) mtop = bodyheight-seltext.offsetHeight;
    seltext.style.top=mtop+"px";
    seltext.style.left=mleft+"px";
    seltext.style.display = 'block';
};
function VisionDIV(div)
{
    $(div).show();
};
function HiddenDIV(div)
{
   $(div).hide();
};

function loading(act)
{
   if(act == 'open')
   {
      $('Loading').show();
      $('Loading').style.top = 0;
      $('Loading').style.left = getWidth() - 140;
   }
   if(act == 'close')
   {
      $('Loading').hide();
   }
};

function preloadimages(){
    var myimages=new Array();
    for (i=0;i<preloadimages.arguments.length;i++){
    myimages[i]=new Image();
    myimages[i].src=preloadimages.arguments[i];
    }
};

function AlertDIV(id,msg,align)
{
    var o=$(id);
    if(!o) return ;
    if(typeof msg=='undefined') msg="<img src=/public/images/loading.gif  border=0/>";
    var dw = o.offsetWidth?o.offsetWidth:o.width;
    var dh = o.offsetHeight?o.offsetHeight:o.height;
    var offsets=Position.positionedOffset(o);
	var top=offsets[1];
	var left=offsets[0];
    if(!dw || !dh) return ;
	align = align || "center";
	if (align == "top") {
	    if (dh > 80) dh = 80;
	}
    var createAlertPop = function(){
        var _div=document.createElement("div");
        _div.id="alertDIV";
        _div.style.backgroundColor = "#ffffff";
        _div.style.fontSize =  "12px";
        _div.style.position = "absolute";
        _div.style.width    = dw;
        _div.style.height   = dh;
        _div.style.left     = left + "px";
        _div.style.top      = top + "px";
        _div.style.display  = "none";
        _div.style.overflow = "hidden";
        _div.style.textAlign = "center";
        _div.style.filter   = "alpha(opacity=70)";
        _div.innerHTML= "<span style=\"width:0; height:100%; display:inline-block; vertical-align:middle;\"></span><span style=\"text-align:center; width:100%; display:inline-block; vertical-align:middle;\">"+msg+"</span>";
        //o.style.position = "relative";
        var first = o.firstChild;
	    o.insertBefore(_div, first);
        //o.appendChild(_div);
        return _div;
    };
    this.AlertPop=createAlertPop();
    this.AlertPop.style.display = "block";
    return this.AlertPop;
};

function _sendx(a,aa,x,p,sendXML){
    new Ajax.Request(a,
      {
         method : p||'get',
         postBody : sendXML,
         //parameters : '',
         //onSuccess
         onComplete : function(ab)
         {
            var v = ab.responseText;
			aa(x,v);
         }
      }
   );
};

function toSCPXML(CommandXML,AppXML)
{
		var xmlns = getXMLNS();
		
		var respxml="<?xml version=\"1.0\" encoding=\"GB2312\"?>\n\n";
		respxml=respxml+"<scp "+xmlns+">\n";
		respxml=respxml+"   <command><action>API:"+CommandXML+"\n";
		respxml=respxml+"   </action></command>\n";
		respxml=respxml+"   <security>"+AppXML+"\n";
		respxml=respxml+"   </security>\n";
		respxml=respxml+"</scp>";
		return respxml;
};

function getXMLNS()
{
		var xmlns = "xmlns=\"urn:scp:params:xml:ns:scp-3.0\"	\n\n";
		xmlns=xmlns+ " xmlns:domain=\"urn:5lin.com:domain\"	\n\n";
		xmlns=xmlns+ " xmlns:contact=\"urn:5lin.com:contact\"	\n\n";
		xmlns=xmlns+ " xmlns:registrant=\"urn:5lin.com:registrant\"	\n\n";
		xmlns=xmlns+ " xmlns:host=\"urn:5lin.com:host\"";
		return xmlns;
};

function getCode(responseXML)
{
	var code="";
	start_pos = responseXML.indexOf("<result code=");

	if(start_pos>0)
		code = responseXML.substring(start_pos + 14, start_pos + 18);

	return code;
};
function getMessage(CutXml,svalue)
{
	key = svalue;
	str1 = "<"+svalue+">";
	str2 = "</"+svalue+">";
	start_pos = CutXml.toLowerCase().indexOf(str1.toLowerCase())+str1.length;
	if( start_pos > 0 )
	{
		over_pos = CutXml.toLowerCase().indexOf(str2.toLowerCase());
		resValue = CutXml.substring(start_pos, over_pos);
	}
	
	return resValue;
};
function startDragLogin(handle)
{
   drag.init(handle);
}
;

var drag =
{
   body : null, style : null, x : null, y : null,
   init : function(sId)
   {
      if (event.button == 0 || event.button == 1)
      {
         dragobj = $(sId);
         var AppendDiv = document.getElementsByTagName("body").item(0);
         var attributeDiv = document.createElement("div");
         attributeDiv.setAttribute("id", "drag_effect");
         attributeDiv.style.position = "absolute";
         attributeDiv.style.zIndex = dragobj.style.zIndex-1;
         attributeDiv.style.zoldIndex = dragobj.style.zIndex;
         attributeDiv.onselectstart = function()
         {
            return false;
         }
         ;
         var _6 = Position.cumulativeOffset(dragobj);
         var _7 = {
             x: _6[0], y: _6[1]
         }
        ;

         attributeDiv.style.display = "block";
         attributeDiv.style.top = parseInt(getScrollTop()+_7.y) - 1 + "px";
         attributeDiv.style.left = parseInt(_7.x) - 1 + "px";
         attributeDiv.style.border = "1px dashed #1D8302";
         attributeDiv.style.height = parseInt(dragobj.offsetHeight)+"px";
         attributeDiv.style.width = parseInt(dragobj.offsetWidth)+"px";
         attributeDiv.style.cursor = "move";
         AppendDiv.appendChild(attributeDiv);
         obj = $("drag_effect");
         
         // dragobj.style.display = "none";
         body = Browser.isIE ?  document.documentElement : document.body;
         style = obj.style;
         x = event.clientX - parseInt(style.left);
         y = event.clientY - parseInt(style.top);
         Event.observe(body,"mousemove",drag.start);
         Event.observe(body,"mouseup",drag.end);
         Event.observe(body,"selectstart",drag.select);
         Event.stop(event);
         // style.filter = "alpha(opacity=80)";
         // style.opacity = "0.8";
      }
      return false;
   }
   ,
   select : function ()
   {
      return false;
   }
   ,
   start : function ()
   {
      if (event.button == 0 || event.button == 1)
      {
         style.left = (event.clientX - x) + "px";
         style.top = (event.clientY - y) + "px";
         //if(style.zIndex<style.zoldIndex)
         //    style.zIndex = style.zIndex+4;
      }
      else
      {
         drag.end();
      }
      Event.stop(event);
   }
   ,
   end : function ()
   {
      style.cursor = "";
      //style.zIndex = style.zIndex-4;
      // obj.style.filter = "alpha(opacity=100)";
      // obj.style.opacity = "1.0";
      dragobj.style.top = parseInt(obj.style.top)-getScrollTop()+1+"px";
      dragobj.style.left = parseInt(obj.style.left)+1+"px";
      obj.removeNode(true);
      // dragobj.style.display = "block";
      Event.stopObserving(body,"mousemove",drag.start);
      Event.stopObserving(body,"mouseup",drag.end);
      Event.stopObserving(body,"selectstart",drag.select);
      Event.stop(event);
   }
}
;


function setCookie(name, value, days)
{
	$cookie(name, value, {expires:days,domain:"5lin.com",path:"/"});//外网 
	//$cookie(name, value, {expires:days,path:"/"});//内网 
};

function getCookie(name) {
  return $cookie(name);
}
;
function deleteCookie(name) {
  setCookie(name, "",0);
}
;

$cookie = function(name, value, options) {
    if (typeof value != 'undefined') {
        options = options || {};
        if (value === null) {
            value = '';
            options.expires = -1;
        };
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString();
        };
        var path = options.path ? '; path=' + options.path : '';
        var domain = options.domain ? '; domain=' + options.domain : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else {
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var search = name + "=";
            var offset = document.cookie.indexOf(search); 
            if (offset != -1) {
                offset += search.length ;
                end = document.cookie.indexOf(";", offset);
                if (end == -1) end = document.cookie.length;
                end = document.cookie.indexOf("&", offset);
                if (end == -1) end = document.cookie.length;
                var cookieValue = document.cookie.substring(offset, end);
                if(cookieValue.indexOf(";")!=-1)
                {
                    cookieValue = cookieValue.substring(0,cookieValue.indexOf(";"));
                };
             };
        };
        
        return decodeURIComponent(cookieValue);
    };
};

function isLogOut()
{
    var e = event;
	var getMess=getCookie("azsz%5FUserMess");
	if (e.keyCode == 116 || e.keyCode == 82)
	{
		Isout = false;
	}
};


function doClose()
{
    //var getMess=getCookie("azsz%5FUserMess");
    setCookie("azsz%5FUserMess","false",7);
    /*if (Isout && (event.clientX > document.body.clientWidth && event.clientY < 0 || event.clientY > document.documentElement.clientHeight) || (event.altKey))
	{
	    //doLogout();
	}*/
};

function doLogout()
{
   _sendx("/Public/Logout.aspx?a=offonline&tmp="+getDataTime(), function(p, v){}, null);

};

