var API, global = this;
API = API || {};
(function() {
  var doc, html;
  var reFeaturedMethod = new RegExp('^function|object$', 'i');
  var isRealObjectProperty = function(o, p) {
    return !!(typeof o[p] == 'object' && o[p]);
  };
  API.isRealObjectProperty = isRealObjectProperty;
  var isHostMethod = function(o, m) {
    var t = typeof o[m];
    return !!((reFeaturedMethod.test(t) && o[m]) || t == 'unknown');
  };
  API.isHostMethod = isHostMethod;
  var isHostObjectProperty = function(o, p) {
    var t = typeof o[p];
    return !!(reFeaturedMethod.test(t) && o[p]);
  };
  API.isHostObjectProperty = isHostObjectProperty;
  var areFeatures = function() {
    var i = arguments.length;
    while (i--) {
      if (!API[arguments[i]]) { return false; }
    }
    return true;
  };
  API.areFeatures = areFeatures;
  var isOwnProperty = function(o, p) {
    return typeof o.constructor.prototype[p] == 'undefined';
  };
  API.isOwnProperty = isOwnProperty;
  if (isRealObjectProperty(this, 'document')) {
    doc = this.document;
  }
  function toArray(o) {
    var a = [];
    var i = o.length;
    while (i--) { a[i] = o[i]; }
    return a;			
  }
  API.toArray = toArray;
  var elementUniqueId = (function() {
    var it = 0;
    return function(el) { return el.uniqueID || (el.uniqueID = '_api' + it++); };
  })();
  API.elementUniqueId = elementUniqueId;
  var attachDocumentReadyListener, bReady, documentReady, documentReadyListener, readyListeners = [];
  var canAddDocumentReadyListener, canAddWindowLoadListener, canAttachWindowLoadListener;
  if (doc) {
    canAddDocumentReadyListener = isHostMethod(doc, 'addEventListener');
    canAddWindowLoadListener = isHostMethod(this, 'addEventListener');
    canAttachWindowLoadListener = isHostMethod(this, 'attachEvent');
    if (canAddDocumentReadyListener || canAddWindowLoadListener || canAttachWindowLoadListener) {
      bReady = false;
      documentReady = function() { return bReady; };
      documentReadyListener = function(e) {
        if (!bReady) {
          bReady = true;
          var i = readyListeners.length;
          var m = i - 1;
          while (i--) { readyListeners[m - i](e); }
        }
      };
      attachDocumentReadyListener = function(fn, docNode) {
        docNode = docNode || global.document;
        if (docNode == global.document) {
          if (!readyListeners.length) {
            if (canAddDocumentReadyListener) {
              docNode.addEventListener('DOMContentLoaded', documentReadyListener, false);
            }
            if (canAddWindowLoadListener) {
              global.addEventListener('load', documentReadyListener, false);
            } else {
              if (canAttachWindowLoadListener) {
                global.attachEvent('onload', documentReadyListener);
              }
            }
          }
          readyListeners[readyListeners.length] = fn;
          return true;
        } else {
          if (canAddDocumentReadyListener) {
            docNode.addEventListener('DOMContentLoaded', fn, false);
            return true;
          }
          return false;
        }
      };
      API.documentReady = documentReady;
      API.documentReadyListener = documentReadyListener;
      API.attachDocumentReadyListener = attachDocumentReadyListener;
    }
  }
  var hasAttribute;
  var addOption, addOptions, getOptionValue, formChanged, inputValue, inputChanged, removeOptions, serializeFormUrlencoded, urlencode;
  var getAnchor, getAnchors, getForm, getForms, getImage, getImages, getLink, getLinks;
  var getDOMCollectionFactory, getDOMCollectionItemFactory;
  var addElementHtml, elTemp, htmlToNodes, select, selectsBroken, setElementHtml, setElementOuterHtml, setSelectHtml, setTempHtml, transferTempHtml;
  var constructElementHtml, getDocumentHtml, getElementHtml, getElementOuterHtml, reAmp, reCollapsibleAttributes, reLT, reGT, reSelfClosing, reQuot;
  var createElement, isXmlParseMode;
  var allElements, commonElementsByTagName, disableElements, getAttribute, getChildren, getEBI, getEBTN, getHeadElement;
  var attributeAliases = {'for':'htmlFor', accesskey:'accessKey', maxlength:'maxLength', 'class':'className', readonly:'readOnly', longdesc:'longDesc', tabindex:'tabIndex', rowspan:'rowSpan', colspan:'colSpan', codebase:'codeBase', ismap:'isMap'};
  var attributesBad;
  var camelize, reNotEmpty, reCamel = new RegExp('([^-]*)-(.)(.*)');
  var findReplacedElement;
  var addElementText, getElementText, setElementText;
  var getDocumentWindow;
  if (doc) {
    getDocumentWindow = (function() {
      if (isRealObjectProperty(doc, 'parentWindow')) {
        return function(docNode) {
          return (docNode || global.document).parentWindow;
        };
      }
      if (isRealObjectProperty(doc, 'defaultView') && doc.defaultView == this) { // defaultView is not always window/global object (e.g. IceBrowser, Safari 2)
        return function(docNode) {
          return (docNode || global.document).defaultView;
        };
      }
      if (isRealObjectProperty(doc, '__parent__')) { // IceBrowser
        return function(docNode) {
          return (docNode || global.document).__parent__;
        };
      }
    })();
  }
  API.getDocumentWindow = getDocumentWindow;
  var purgeListeners;
  function getElementSize(el) { return [el.offsetHeight || 0, el.offsetWidth || 0, el.clientHeight || 0, el.clientWidth || 0, el.scrollHeight || 0, el.scrollWidth || 0]; }
  API.getElementSize = getElementSize;
  function getElementDocument(el) {
    if (el.ownerDocument) {
      return el.ownerDocument;
    }
    if (el.parentNode) {
      while (el.parentNode) {
        el = el.parentNode;
      }
      return (el.nodeType == 9 || (!el.nodeType && !el.tagName))?el:null;
    }
  }
  API.getElementDocument = getElementDocument;
  function getElementParentElement(el) {
    return (el.parentNode && (el.parentNode.tagName || el.parentNode.nodeType == 1))?el.parentNode:(el.parentElement || null);
  }
  API.getElementParentElement = getElementParentElement;
  function getElementNodeName(el) {
    var nn = (el.tagName || el.nodeName).toLowerCase();
    return (!nn.indexOf('html:'))?nn.substring(5):nn;
  }
  API.getElementNodeName = getElementNodeName;
  var transferListeners;
  findReplacedElement = function(el, parent, uid) {
    var m;
    m = parent.childNodes.length;
    while (m--) {
      if (parent.childNodes[m].id == el.id) {
        if (typeof transferListeners == 'function') { transferListeners(el, parent.childNodes[m]); }
        el = parent.childNodes[m];
        break;
      }
    }
    if (el.id == uid) { el.id = ''; }
    return el;
  };
  function elementCanHaveChildren(el) {
    return typeof el.canHaveChildren == 'undefined' || el.canHaveChildren;
  }
  var canAdjustStyle, isStyleCapable, iStyle, styles;
  var getAnElement, getHtmlElement;
  if (doc) {
    getHtmlElement = function(docNode, bAnyElement) {
      var h, all;
      docNode = docNode || global.document;
      h = isRealObjectProperty(docNode, 'documentElement')?docNode.documentElement:((getEBTN)?getEBTN('html', docNode)[0]:null);
      if (!h && allElements) {
        all = allElements(docNode); // Don't bother to filter for this
        h = all[(all[0].tagName == '!')?1:0];
        if (h && !bAnyElement && h.tagName.toLowerCase() != 'html') { h = null; }
      }
      return h;
    };
    API.getHtmlElement = getHtmlElement;
    getAnElement = function(docNode) {
      return getHtmlElement(docNode, true);
    };
    API.getAnElement = getAnElement;
    html = getAnElement();
  }
  if (doc) {
    attributesBad = !!(html && isHostMethod(html, 'getAttribute') && html.getAttribute('style') && typeof html.getAttribute('style') == 'object');
    hasAttribute = (function() {
      var attributeSpecified, v;
      if (html && isHostMethod(html, 'hasAttribute')) {
        return function(el, name) { return el.hasAttribute(name); };
      }
      if (html && isHostMethod(html, 'attributes')) {
        attributeSpecified = function(el, name) {
          v = el.attributes[name];
          return !!(v && v.specified);
        };
        if (attributesBad) {
          return function(el, name) {
            var doc = arguments[2] || getElementDocument(el);
            if (doc && typeof(doc.selectNodes) != 'undefined') { return attributeSpecified(el, name); } // XML document
            var nameL = name.toLowerCase();
            var alias = attributeAliases[nameL];
            if (alias && alias.toLowerCase() == nameL) {
              nameL = alias; // maxlength => maxLength, readonly => readOnly, etc.
            }
            return attributeSpecified(el, nameL);
          };
        }
        return attributeSpecified;
      }
    })();
    API.hasAttribute = hasAttribute;
    disableElements = function() {
      var b, i = arguments.length;
      if (typeof arguments[i] == 'boolean') {
        b = arguments[i - 1];
        i--;
      }
      while (i--) { arguments[i].disabled = !b; }
    };
    API.disableElements = disableElements;
    getEBI = (function() {
      function idCheck(el, id) {
        return (el && el.id == id)?el:null;
      }
      if (isHostMethod(doc, 'getElementById')) {
        return function(id, docNode) { return idCheck((docNode || global.document).getElementById(id), id); };
      }
      if (isHostMethod(doc, 'all')) {
        return function(id, docNode) { return idCheck((docNode || global.document).all[id], id); };
      }
    })();
    API.getEBI = getEBI;
    if (isHostObjectProperty(doc, 'all')) {
      allElements = (function() {
        return function(el, bFilter) {
          var i, a, n, r;
          if (!bFilter) {
            return el.all;
          } else {
            a = toArray(el.all);
            i = a.length;
            r = [];
            while (i--) {
              n = a[i];
              if ((n.nodeType == 1 && n.tagName != '!') || (!n.nodeType && n.tagName)) {
                r[r.length] = a[i];
              }
            }
            return r.reverse();
          }
        };
      })();
    }
    commonElementsByTagName = (function() {
      if (allElements) {
        return function (el, t) {
          return(t == '*' && el.all)?allElements(el, true):el.getElementsByTagName(t);
        };
      }
      return function (el, t) { return el.getElementsByTagName(t); };
    })();
    getEBTN = (function() {
      var els;
      if (isHostMethod(doc, 'getElementsByTagName')) {
        els = doc.getElementsByTagName('*');
        if (els && (els.length || allElements)) {
          return function(t, docNode) {
            return commonElementsByTagName(docNode || global.document, t);
          };
        }
      }
      if (isHostObjectProperty(doc, 'all') && isHostMethod(doc.all, 'tags')) {
        return function(t, docNode) {
          return (docNode || global.document).all.tags(t);
        };
      }
    })();
    API.getEBTN = getEBTN;
    if (getEBTN) {
      getHeadElement = function(docNode) {
        return getEBTN('head', docNode || global.document)[0] || null;
      };
    }
    API.getHeadElement = getHeadElement;
    camelize = function(name) {
      var m = name.match(reCamel);
      return (m)?([m[1], m[2].toUpperCase(), m[3]].join('')):name;
    };
    getAttribute = (function() {
      var att, alias, nameC, nn, reEvent, reNewLine, reFunction, reURI;
      if (html && isHostMethod(html, 'getAttribute')) {
        if (attributesBad) {
          if (hasAttribute) {
            reEvent = new RegExp('^on');
            reNewLine = new RegExp('[\\n\\r]', 'g');
            reFunction = new RegExp('^function anonymous\\(\\) *{(.*)}$');
            reURI = new RegExp('(href|src|data)');
            return function(el, name) {
              var doc = arguments[2] || getElementDocument(el);
              if (doc && typeof(doc.selectNodes) != 'undefined') { return el.getAttribute(name); } // XML document
              if (hasAttribute(el, name)) {               
                name = name.toLowerCase();
                alias = attributeAliases[name];
                if (!alias) {
                  if (name == 'style') { return (el.style)?(el.style.cssText || ''):''; }
                  if (reURI.test(name)) { return el.getAttribute(name, 2); }
                  if (reEvent.test(name) && el[name]) {
                    att = el[name].toString();
                    if (att) {
                      att = att.replace(reNewLine, '');
                      if (reFunction.test(att)) { return att.replace(reFunction, '$1'); }
                    }
                    return null;
                  }
                  nn = el.tagName.toLowerCase();
                  if (nn == 'select' && name == 'type') { return null; }
                  if (nn == 'form' && el.getAttributeNode) {
                    att = el.getAttributeNode(name);
                    return (att && att.nodeValue)?att.nodeValue:'';
                  }
                }
                nameC = camelize(alias || name);
                if (typeof el[nameC] == 'unknown') {
                  return '[unknown]';
                }
                else {
                  if (name == 'longdesc') {
                    return el.getAttribute(name, 2);
                  }
                  if (typeof el[nameC] == 'boolean') {
                    return (el[nameC])?'':null;
                  }
	          return (typeof el[nameC] != 'string' && typeof el[nameC] != 'undefined' && el[nameC] !== null && el[nameC].toString)?el[nameC].toString():el[nameC];
                }
              }
              return null;
            };
          }
        }
        return function(el, name) { return el.getAttribute(name); };
      }
    })();
    API.getAttribute = getAttribute;
    if (html) {
      getChildren = (function() {
        if (isRealObjectProperty(html, 'children')) {
          return function(el) {
            return el.children;
          };
        }
        if (isHostMethod(html, 'childNodes')) {
          return function(el) {
            var n, nl = el.childNodes, r = [];
            var i = nl.length;
            while (i--) {
              n = nl[i];
              if ((n.nodeType == 1 && n.tagName != '!') || (!n.nodeType && n.tagName)) {
                r.push(nl[i]);
              }
            }
            return r.reverse();
          };
        }
      })();
    }
    API.getChildren = getChildren;
    reNotEmpty = new RegExp('[^\\t\\n\\r ]');
    API.isEmptyTextNode = function(n) {
      return !reNotEmpty.test(n.data);
    };
    isXmlParseMode = function(docNode) {
      var i, content, hasCENS, metaTags, xml;
      docNode = docNode || global.document;
      if (typeof docNode.contentType == 'string') {
        return docNode.contentType.indexOf('xml') != -1;
      } else {
        hasCENS = isHostMethod(docNode, 'createElementNS');
        if (!hasCENS) {
          return false;
        }
        if (typeof docNode.body == 'undefined') {
          return true;
        }
        if (isHostMethod(docNode, 'getElementsByTagName')) {
          metaTags = docNode.getElementsByTagName('meta');
          i = metaTags.length;
          if (i && isHostMethod(metaTags[0], 'getAttribute')) {
            xml = true;
            while (i-- && xml) {
              if (metaTags[i].getAttribute('http-equiv') == 'Content-Type') {
                content = metaTags[i].getAttribute('content');
                if (content) {
                  xml = (content.indexOf('html') == -1);
                }
              }
            }
            return xml;
          }
          return hasCENS;
        }
      }
    };
    API.isXmlParseMode = isXmlParseMode;
    createElement = (function() {
      if (isHostMethod(doc, 'createElement')) {
        return (function() {
          if (isXmlParseMode() && isHostMethod(doc, 'createElementNS')) {
            return function(tag, docNode) {
              return (docNode || global.document).createElementNS('http://www.w3.org/1999/xhtml', 'html:' + tag);
            };
          }
          return function(tag, docNode) {
            return (docNode || global.document).createElement(tag);
          };
        })();
      }
    })();
    API.createElement = createElement;
    getDOMCollectionFactory = function(name, tag, fnFilter) {
      if (isHostMethod(doc, name)) {
        return function(docNode) { return (docNode || global.document)[name]; };
      }
      if (getEBTN && (!fnFilter || typeof filter == 'function')) {
        return function(docNode) {
          var col, i;

          if (typeof tag == 'string') {
            col = getEBTN(tag, docNode);
          }
          else {
            col = [];
            i = tag.length;
            while (i--) {
              col = col.concat(toArray(getEBTN(tag[i], docNode)));
            }
          }
          return (fnFilter)?filter(col, fnFilter):col;
        };
      }
    };
    getDOMCollectionItemFactory = function(name, tag, fnCollection) {
      if (isHostMethod(doc, name)) {
        return function(i, docNode) { return (docNode || global.document)[name][i]; };
      }
      if (getEBI) {
        return function(i, docNode) {
          var el, col, j, nn;
          if (typeof i == 'string') {
            el = getEBI(i, docNode);
            if (el && (!el.name || el.name == i)) {
              if (typeof tag == 'string') {
                if (getElementNodeName(el) == tag) { return el; }
              }
              else {
                j = tag.length;
                nn = getElementNodeName(el);
                while (j--) {
                  if (nn == tag[j]) { return el; }
                }
              }
            }
          }
          col = fnCollection();
          if (typeof i == 'string') {
            j = col.length;
            while (j--) {
              if (col[j].name == i || (!col[j].name && col[j].id == i)) {
                return col[j];
              }
            }
            return null;
          }
          return col[i] || null;
        };
      }
    };
    getImages = API.getImages = getDOMCollectionFactory('images', 'img');
    if (getImages) {
      getImage = API.getImage = getDOMCollectionItemFactory('images', 'img', getImages);
    }
    getForms = API.getForms = getDOMCollectionFactory('forms', 'form');
    if (getForms) {
      getForm = API.getForm = getDOMCollectionItemFactory('forms', 'form', getForms);
    }
    getAnchors = API.getAnchors = getDOMCollectionFactory('anchors', 'a', function(el) { return typeof el.href != 'unknown' && !el.href; });
    if (getAnchors) {
      getAnchor = API.getAnchor = getDOMCollectionItemFactory('anchors', 'a', getAnchors);
    }
    getLinks = API.getLinks = getDOMCollectionFactory('links', ['a', 'area'],  function(el) { return typeof el.href == 'unknown' || el.href; });
    if (getLinks) {
      getLink = API.getLink = getDOMCollectionItemFactory('links', ['a', 'area'], getLinks);
    }
    if (hasAttribute) {
      getOptionValue = function(o) {    
        return (o.value || (hasAttribute(o, 'value')?o.value:o.text)); 
      };
    }
    API.getOptionValue = getOptionValue;
    if (isHostMethod(global, 'Option')) {
      addOption = function(el, text, value) {
        var o = new global.Option();
        o.text = text;
        if (typeof value != 'undefined') { o.value = value; }
        if (el.options.add) {
          el.options.add(o, el.options.length);
        }
        else {
          el.options[el.options.length] = o;
        }
        return o;
      };
      API.addOption = addOption;
      addOptions = function(el, options) {
        var i;
        for (i in options) { if (isOwnProperty(options, i)) { addOption(el, i, options[i]); } }
      };
      API.addOptions = addOptions;
    }
    removeOptions = function(el) {
      el.options.length = 0;
      var l = el.options.length;		
      while (l--) { el.options[l] = null; }
    };
    API.removeOptions = removeOptions;
    urlencode = (function() {
      var f = function(s) {
      return encodeURIComponent(s).replace(/%20/,'+').replace(/(.{0,3})(%0A)/g,
        function(m, a, b) {return a+(a=='%0D'?'':'%0D')+b;}).replace(/(%0D)(.{0,3})/g,
        function(m, a, b) {return a+(b=='%0A'?'':'%0A')+b;});
      };
      if (typeof encodeURIComponent != 'undefined' && String.prototype.replace && f('\n \r') == '%0D%0A+%0D%0A') {
         return f;
      }
    })();
    API.urlencode = urlencode;
    if (hasAttribute) {
    inputValue = function(el, bDefault) {
      var a, o, t = el.type;
      if (!t.indexOf('select')) {
        a = [];
        for (var j = 0, jlen = el.options.length; j < jlen; j++) {
          o = el.options[j];
          if (o[(bDefault)?'defaultSelected':'selected']) {
            a[a.length] = getOptionValue(o);
          }
        }
        if (a.length == 1) { a = a[0]; }
        return a;
      }
      switch(t) {
      case 'checkbox':
      case 'radio':
        return (el[(bDefault)?'defaultChecked':'checked'])?el.value || 'on':'';
      default:
        return el[(bDefault)?'defaultValue':'value'];
      }      
    };
    API.inputValue = inputValue;
    inputChanged = function(el) {
      var i;
      var d = inputValue(el, true);
      var v = inputValue(el);
      if (typeof d == 'string') {
        return (d == v);
      }
      i = d.length;
      while (i--) {
        if (d[i] != v[i]) { return true; }
      }
      return false;
    };
    API.inputChanged = inputChanged;
    formChanged = function(el) {
      var i, els = el.elements;
      i = els.length;
      while (i--) {
        if (inputChanged(els[i])) { return true; }
      }
      return false;
    };
    }
    if (urlencode && getOptionValue) {
      serializeFormUrlencoded = function(f) {
        var e, n, t, o, es = f.elements, c = [];
        var reCheck = new RegExp('^checkbox|radio$');
        var reText = new RegExp('^text|password|hidden|textarea$');
        function add(n, v) {
          c[c.length] = urlencode(n) + "=" + urlencode(v);
        }
        for (var i=0, ilen=es.length; i<ilen; i++) {
          e = es[i];
          n = e.name;
          if (n && !e.disabled) {
            t = e.type;
            if (!t.indexOf('select')) {
              if (t == 'select-one' || e.multiple === false) {
                if (e.selectedIndex >= 0) {
                  add(n, getOptionValue(e.options[e.selectedIndex]));
                }
              } else {
                for (var j = 0, jlen = e.options.length; j < jlen; j++) {
                  o = e.options[j];
                  if (o.selected) {
                    add(n, getOptionValue(o));
                  }
                }
              } 
            } else if (reCheck.test(t)) {
              if (e.checked) {
                add(n, e.value || 'on');
              }          
            } else if (reText.test(t)) {
              add(n, e.value);
            }
          }
        }
        return c.join('&');
      };
    }
    API.serializeFormUrlencoded = serializeFormUrlencoded;
    if (html) {
      getElementText = (function() {
        if (typeof html.innerText == 'string') { return function(el) { return el.innerText; }; }
        if (typeof html.textContent == 'string') { return function(el) { return el.textContent; }; }
        if (isRealObjectProperty(html, 'firstChild')) {
          return function(el) {
            var text = [];
            var c = el.firstChild;
            while (c) {
              if (c.nodeType == 3 || c.nodeType == 4) {
                if (reNotEmpty.test(c.data)) { text[text.length] = c.data; }
              }
              else {
                if (c.nodeType == 1) { text[text.length] = getElementText(c); }
              }
              c = c.nextSibling;
            }
            return text.join('');
          };
        }
      })();
      API.getElementText = getElementText;
      setElementText = (function() {
        var reLT, reGT, reAmp;
        if (typeof html.innerText == 'string') { return function(el, text) { el.innerText = text; }; }
        if (isHostMethod(html, 'removeChild') && isHostMethod(doc, 'createTextNode')) {
          return function(el, text) {
            var docNode = getElementDocument(el);
            while (el.firstChild) { el.removeChild(el.firstChild); }
            el.appendChild(docNode.createTextNode(text));
          };
        }
        if (typeof html.innerHTML == 'string') {
          reLT = new RegExp('<', 'g');
          reGT = new RegExp('>', 'g');
          reAmp = new RegExp('&', 'g');
          return function(el, text) { el.innerHTML = text.replace(reAmp, "&amp;").replace(reLT, "&lt;").replace(reGT, "&gt;"); };
        }
      })();
      API.setElementText = setElementText;
    }
    if (setElementText && getElementText) {
      addElementText = function(el, text) { setElementText(el, getElementText(el) + text); };
      API.addElementText = addElementText;
    }
    if (html && typeof html.innerHTML == 'string') {
      if (createElement && !isXmlParseMode()) {
        select = createElement('select');
        if (select) {
          select.innerHTML = '<option>T</option>';
          selectsBroken = (!select.options.length);
        }
      }
      if (selectsBroken && typeof html.outerHTML == 'string' && isHostMethod(html, 'childNodes')) {
        setSelectHtml = function(el, html) {
          var uid = elementUniqueId(el);
          el.id = el.id || uid;
          var pn = el.parentNode;
          el.innerHTML = '';
          el.outerHTML = el.outerHTML.replace('>', '>' + html + '</select>');					
          if (el.parentNode !== pn) {
            el = findReplacedElement(el, pn, uid);
          }
          return el;
        };
      }
      setTempHtml = (function() {
        var nn;
        var reScriptFirst = new RegExp('^[^<]*<script', 'i');
        function preProcess(html, docNode) {
          switch(nn) {
          case 'table':
            elTemp = createElement('div', docNode);
            return '<table>' + html + '</table>';
          case 'caption':
          case 'colgroup':
          case 'col':
          case 'thead':
          case 'tbody':
          case 'tfoot':
            elTemp = createElement('div', docNode);
            return ['<table><', nn, '>', html, '</', nn, '></table>'].join('');
          case 'form':
            elTemp = createElement('div', docNode);							
          }
          return html;
        }

        function postProcess(html) {
          switch(nn) {
          case 'table':
            return elTemp.firstChild;
          case 'caption':
          case 'colgroup':
          case 'col':
          case 'thead':
          case 'tbody':
          case 'tfoot':
            return elTemp.firstChild.firstChild;
          default:
            return elTemp;
          }
        }
        if (isHostMethod(html, 'insertAdjacentHTML')) {
          return function(html, bAppend) {
            nn = getElementNodeName(elTemp);
            if (!bAppend && reScriptFirst.test(html) && !isXmlParseMode()) { html = '&nbsp;' + html; }
            html = preProcess(html);
            elTemp.insertAdjacentHTML('afterBegin', html);
            elTemp = postProcess(html);
          };
        }
        return function(html, bAppend) {
          nn = getElementNodeName(elTemp);
          if (!bAppend && reScriptFirst.test(html) && !isXmlParseMode()) { html = '&nbsp;' + html; }
          html = preProcess(html);
          elTemp.innerHTML = html;
          elTemp = postProcess(html);
        };
      })();
      if (isHostMethod(html, 'removeChild') && createElement && isRealObjectProperty(html, 'firstChild')) {
        transferTempHtml = function(el, html, docNode, bAppend) {
          var nn = getElementNodeName(el);
          if (nn == 'head') { nn = 'div'; }
          elTemp = createElement(nn, docNode);
          if (elTemp) {
            setTempHtml(html, bAppend);
            while (elTemp.firstChild) {
              el.appendChild(elTemp.firstChild);
            }
            elTemp = null;
          }
        };
        addElementHtml = function(el, html, docNode) {
          if (elementCanHaveChildren(el)) {
            transferTempHtml(el, html, getElementDocument(el), true);
          }
        };
        API.addElementHtml = addElementHtml;
      }
      htmlToNodes = function(html, docNode) {
        var c;
        elTemp = createElement('div', docNode);
        if (elTemp) {
          setTempHtml(html);
          c = elTemp.childNodes;
          elTemp = null;
        }
        return c;
      };
      API.htmlToNodes = htmlToNodes;
      setElementHtml = (function() {				
        if (transferTempHtml) {
          return function(el, html) {
            if (setSelectHtml && getElementNodeName(el) == 'select') {
              return setSelectHtml(el, html);
            }
            if (elementCanHaveChildren(el)) {
              if (typeof purgeListeners == 'function') { purgeListeners(el, true, true); } // Purge children only
              while (el.firstChild) {
                el.removeChild(el.firstChild);
              }
              transferTempHtml(el, html, getElementDocument(el));
            }
            return el;
          };
        }
      })();
      API.setElementHtml = setElementHtml;
      setElementOuterHtml = (function() {
        if (typeof html.outerHTML == 'string') {
          return function(el, html) {
            if (typeof purgeListeners == 'function') { purgeListeners(el, true); }
            el.outerHTML = html;
            return el;
          };
        }
        if (isHostMethod(html, 'insertBefore') && isRealObjectProperty(html, 'firstChild')) {
          return function(el, html) {
            var nodeNew;
            var docNode = getElementDocument(el);
            var parent = getElementParentElement(el);
            var next = el.nextSibling;
            if (typeof purgeListeners == 'function') { purgeListeners(el); }
            elTemp = createElement('div', docNode);
            if (elTemp && parent) {
              setTempHtml(html, docNode);
              parent.removeChild(el);
              nodeNew = elTemp.firstChild;
              if (next) {
                parent.insertBefore(elTemp.firstChild, next);
              } else {
                parent.appendChild(elTemp.firstChild);
              }
              elTemp = null;
              return nodeNew;
            }
            return el;
          };
        }
      })();
      API.setElementOuterHtml = setElementOuterHtml;
    }
    if (html && isRealObjectProperty(html, 'firstChild') && typeof html.nodeType == 'number' && getAttribute && hasAttribute) {
      reSelfClosing = new RegExp('^br|hr|img|meta|link|input|base|param|col|area$');
      reCollapsibleAttributes = new RegExp('^checked|selected|disabled|multiple|ismap|readonly$');
      reLT = new RegExp('<', 'g');
      reGT = new RegExp('>', 'g');
      reAmp = new RegExp('&', 'g');
      reQuot = new RegExp('"', 'g');
      constructElementHtml = function(el, bOuter, bXHTML, docNode) {
        var i, nn, name, value, result, selfClose = (bXHTML)?' />':'>';
        var attributes = [];
        switch (el.nodeType) {
          case 1:
            nn = getElementNodeName(el);
            result = [];
            if (el.attributes && el.attributes.length) {
              i = el.attributes.length;
              while (i--) {
                name = el.attributes[i].nodeName.toLowerCase();
                value = getAttribute(el, name, docNode); // Third argument skips getElementDocument call in getAttribute
                if (value === '' && reCollapsibleAttributes.test(name) && hasAttribute(el, name)) { // Last test in case implementation returns empty string instead of null for missing attributes
                  value = name;
                }
                if (value !== null) { attributes[i] = [' ', name, '="', value.replace(reLT, '&lt;').replace(reGT, '&gt;').replace(reAmp, '&amp;').replace(reQuot, '&quot;'), '"'].join(''); }
              }
            }
            if (reSelfClosing.test(nn)) {
              result = (bOuter)?['<', nn].concat(attributes, selfClose):[''];
            } else {
              result = [];
              if (nn == '!') { return result; } // IE5 thinks comments are elements
              if (el.childNodes && el.childNodes.length) {
                i = el.childNodes.length;
                while (i--) {
                  result = constructElementHtml(el.childNodes[i], true, bXHTML, docNode).concat(result);
                }
                result = (bOuter)?['<', nn].concat(attributes, '>', result, '</', nn, '>'):result;
              } else {
                if (nn == 'style') {
                  if (el.styleSheet && el.styleSheet.cssText) {
                    result = [el.styleSheet.cssText];
                  }
                } else {
                  if (el.innerText) {
                    result = [el.innerText];
                  } else {
                    if (el.text) { result = [el.text]; }
                  }
                }
                result = (bOuter)?['<', nn].concat(attributes, '>', result, '</', nn, '>'):[''];
              }
            }
            return result;
          case 3:
            return (reNotEmpty.test(el.nodeValue))?[el.nodeValue]:[''];
          case 4:
            return ['<![CDATA[', el.nodeValue, ']]>'];
          case 8:
            return ['<!--', el.nodeValue, '-->'];
          case 10:
            return [el.nodeValue];
          default:
            return [];
        }
      };
      getElementHtml = function(el, bXHTML, bUseNative) {
        var docNode = getElementDocument(el);
	var isXML = isXmlParseMode(docNode);
        if (typeof el.innerHTML == 'string' && bUseNative && bXHTML === isXML) {
          return el.innerHTML;
        }
        if (typeof bXHTML == 'undefined') {
          bXHTML = isXML;
        }
        return constructElementHtml(el, false, bXHTML, docNode).join('');
      };
      API.getElementHtml = getElementHtml;
      getElementOuterHtml = function(el, bXHTML, bUseNative) {
        var docNode = getElementDocument(el);
	var isXML = isXmlParseMode(docNode);
        if (typeof el.outerHTML == 'string' && bUseNative && bXHTML === isXML) {
          return el.outerHTML;
        }
        if (typeof bXHTML == 'undefined') {
          bXHTML = isXML;
        }
        return constructElementHtml(el, true, bXHTML, docNode).join('');
      };
      API.getElementOuterHtml = getElementOuterHtml;
      getDocumentHtml = function(bXHTML, bUseNative, docNode) {
        docNode = docNode || global.document;
        var sHTML, el = getHtmlElement(docNode);
        if (el) {
          sHTML = getElementOuterHtml(el);
        }
        return sHTML;
      };
      API.getDocumentHtml = getDocumentHtml;
    }
  }
  isStyleCapable = !!(html && isRealObjectProperty(html, 'style'));
  if (isStyleCapable) {
    canAdjustStyle = {};
    styles = ['display', 'visibility', 'position'];
    iStyle = 3;
    while (iStyle--) {
      canAdjustStyle[styles[iStyle]] = typeof html.style[styles[iStyle]] == 'string';
    }
    API.canAdjustStyle = function(style) { return canAdjustStyle[style]; };
  }
  var floatStyle, getCascadedStyle, getKomputedStyle, getInlineStyle, getObjectStyle, getOverrideStyle, getStyle, getStylePixels, setStyle, setStyles;
  var getPositionedParent, isPositionable, isPresent, isVisible;
  var colorHex, hexByte, hexNibble, hexRGB;
  var rePixels = new RegExp('^(-)?[\\d\\.]*px$', 'i');
  var reOtherUnits = new RegExp('^(-)?[\\d\\.]*(em|pt)$', 'i');
  var reColor = new RegExp('color', 'i');
  var reRGB = new RegExp('rgb[a]*\\((\\d*),[\\s]*(\\d*),[\\s]*(\\d*)[),]', 'i');
  var reTransparent = new RegExp('^rgba\\(\\d+,\\s*,\\d+,\\s*\\d,\\s*0\\)$', 'i');
  var colors = { aqua:'00FFFF', green:'008000', navy:'000080', silver:'C0C0C0', black:'000000', gray:'808080', olive:'808000', teal:'008080', blue:'0000FF', lime: '00FF00', purple:'800080', white:'FFFFFF', fuchsia:'FF00FF', maroon:'800000', red:'FF0000', yellow:'FFFF00' };
  var addClass, hasClass, removeClass;
  if (html) {
    if (isStyleCapable) {
      floatStyle = (typeof html.style.cssFloat == 'string')?'cssFloat':'styleFloat';
      getObjectStyle = function(o, style) {
        if (style == 'float') { style = floatStyle; }
        return (o)?o[style] || null:null;
      };
      getCascadedStyle = (function() {
        if (isRealObjectProperty(html, 'currentStyle')) {
          return function(el, style) {
            return getObjectStyle(el.currentStyle, style);
          };
        }
      })();
      API.getCascadedStyle = getCascadedStyle;
      getKomputedStyle = (function() {
        var rePositioned = new RegExp('^absolute|fixed$');
        var rePixelConvert = new RegExp('^height|width|left|top|right|bottom|margin.+|border.+|padding.+$', 'i');
        if (isRealObjectProperty(doc, 'defaultView') && isHostMethod(doc.defaultView, 'getComputedStyle')) {
          return function(el, style) {
            var docNode = getElementDocument(el);
            var s = docNode.defaultView.getComputedStyle(el, null);
            return getObjectStyle(s, style);
          };
        }
        if (getCascadedStyle) {
          return function(el, style) {
            var floatS, parent, position, styleInline, styleRuntime;
            var value = getCascadedStyle(el, style);
            if (value == 'inherit') {
              parent = getElementParentElement(el);
              if (parent) {
                return getKomputedStyle(parent, style);
              }
            }
            switch(style) {
            case 'float':
              position = getKomputedStyle(el, 'position');
              return (position && rePositioned.test(position))?'none':value;
            case 'display':
              if (value != 'none') {
                parent = getElementParentElement(el);
                while (parent) {
                  if (getCascadedStyle(parent, 'display') == 'none') {
                    return 'none';
                  }
                  parent = getElementParentElement(parent);
                }
                position = getKomputedStyle(el, 'position');
                if (position && rePositioned.test(position)) {
                  value = 'block';
                }
                else {
                  floatS = getCascadedStyle(el, 'float');
                  if (floatS && floatS != 'none') {
                    value = 'block';
                  }
                }
              }
              return value;
            }
            if (rePixels.test(value)) { return value; }
            if (reOtherUnits.test(value)) {
              if (rePixelConvert.test(style)) {
                if (parseFloat(value)) {
                  if (isRealObjectProperty(el, 'runtimeStyle')) {
                    styleInline = el.style.left;
                    styleRuntime = el.runtimeStyle.left;
                    el.runtimeStyle.left = el.currentStyle.left;
                    el.style.left = value;
                    value = el.style.pixelLeft;
                    el.style.left = styleInline;
                    el.runtimeStyle.left = styleRuntime;
                    return value + 'px';
                  }
                } else {
                  return '0px';
                }
              }
              return null;
            }
            return ((value == 'auto' && style != 'overflow') || value == 'inherit')?null:value;
          };
        }
      })();
      API.getComputedStyle = getKomputedStyle;
      getInlineStyle = function(el, style) {
        var value = getObjectStyle(el.style, style);
        if (typeof value == 'number') { value += 'px'; }
	return value;
      };
      API.getInlineStyle = getInlineStyle;
      getOverrideStyle = (function() {
        if (isRealObjectProperty(doc, 'defaultView') && isHostMethod(doc.defaultView, 'getOverrideStyle')) {
          return function(el, style) {
            var s = getElementDocument(el).defaultView.getOverrideStyle(el, null);
            return getObjectStyle(s, style);
          };
        }
        if (isRealObjectProperty(html, 'runtimeStyle')) {
          return function(el, style) {
            return getObjectStyle(el.runtimeStyle, style);
          };
        }
      })();
      API.getOverrideStyle = getOverrideStyle;
      hexNibble = function(d) {
        return '0123456789ABCDEF'.substring(d, d + 1);
      };
      hexByte = function(d) {
        return hexNibble(Math.floor(d / 16)) + hexNibble(d % 16);
      };
      hexRGB = function(rgb) {
        return [hexByte(rgb[0]), hexByte(rgb[1]), hexByte(rgb[2])].join('');
      };
      colorHex = function(color) {
        var m = reRGB.exec(color);
        if (m) { return ['#', hexByte(parseInt(m[1], 10)), hexByte(parseInt(m[2], 10)), hexByte(parseInt(m[3], 10))].join(''); }
        if (reTransparent.test(color)) { return 'transparent'; }
        return (colors[color])?'#' + colors[color]:null;
      };
      getStyle = (function() {
        var get = (function() {
          if (getKomputedStyle) {
            return function(el, style) {
              var styleO, styleI, styleC;
              if (getOverrideStyle) {
                styleO = getOverrideStyle(el, style);
              }
              if (styleO) { return styleO; }
              styleC = getKomputedStyle(el, style);
              if (styleC) {
                return styleC;
              } else {
                styleI = getInlineStyle(el, style);
                styleC = getCascadedStyle(el, style); // Computed value is changed to null for some rules in IE (e.g. font-size:1em)
                if (styleC) {
                  return styleC;
                }
                return ((style == 'display')?'none':styleI) || null;
              }
            };
          }
          return function(el, style) {
            var parent, s = getInlineStyle(el, style);
            if (style == 'display' && (s != 'none')) {
              parent = getElementParentElement(el);
              while (parent) {
                if (parent.style.display == 'none') {
                  return 'none';
                }
                parent = getElementParentElement(parent);
              }
            }				
            return s;
          };
        })();
        return function(el, style) {
          var value = get(el, style);
          return (reColor.test(style))?colorHex(value) || value:value;
        };
      })();
      API.getStyle = getStyle;
      setStyle = function(el, style, value) {       
        if (style == 'float') { style = floatStyle; }
        el.style[style] = value;
      };
      API.setStyle = setStyle;
      setStyles = function(el, styles) {
        var s;
        for (s in styles) { if (isOwnProperty(styles, s)) { setStyle(el, s, styles[s]); } }
      };
      API.setStyles = setStyles;
      getStylePixels = function(el, style) {
        var p = getStyle(el, style);
        if (rePixels.test(p)) { return parseFloat(p); }
        if (reOtherUnits.test(p) && !parseFloat(p)) { return 0; } // 0pt
        return null;
      };
      API.getStylePixels = getStylePixels;
      getPositionedParent = function(el) {
        var style;
        if (getStyle(el, 'position') != 'fixed' && isRealObjectProperty(el, 'offsetParent')) {
          do {
            el = el.offsetParent;
            if (el) { style = getStyle(el, 'position'); }
          }
          while (el && (!style || style == 'static'));
          return el;
        }
      };
      API.getPositionedParent = getPositionedParent;
      isVisible = function(el) {
        return getStyle(el, 'visibility') != 'hidden';
      };
      API.isVisible = isVisible;
      isPresent = function(el) {
        return getStyle(el, 'display') != 'none';
      };
      API.isPresent = isPresent;
      isPositionable = function(el) {
         var style = getStyle(el, 'position');
         return (style)?(style != 'static'):false;
      };
      API.isPositionable = isPositionable;
      addClass = function(el, className) {
        var re;
        if (!el.className) {
          el.className = className;
        }
        else {
          re = new RegExp('(^|\\s)' + className + '(\\s|$)');
          if (!re.test(el.className)) { el.className += ' ' + className; }
        }
      };
      API.addClass = addClass;
      removeClass = function(el, className) {
        var re, m;
        if (el.className) {
          if (el.className == className) {
            el.className = '';
          }
          else {		
            re = new RegExp('(^|\\s)' + className + '(\\s|$)');
            m = el.className.match(re);
            if (m && m.length == 3) { el.className = el.className.replace(re, (m[1] && m[2])?' ':''); }
          }
        }
      };
      API.removeClass = removeClass;
      hasClass = function(el, className) {
        return (new RegExp('(^|\\s)' + className + '(\\s|$)')).test(el.className);
      };
      API.hasClass = hasClass;
    }
  }
  var attachListener, attachDocumentListener, attachWindowListener, detachListener, detachDocumentListener, detachWindowListener;
  var cancelPropagation, cancelDefault, getEventTarget, getEventTargetRelated, getKeyboardKey, getMouseButtons;
  var normalizedListeners = {}, originalListeners = {};
  var fnId = 0;
  function cleanup() {
    var i = API.attachedListeners.length;
    while (i--) {
      API.attachedListeners[i].el.detachEvent('on' + API.attachedListeners[i].ev, API.attachedListeners[i].fn);
    }
    API.attachedListeners = null;
    global.detachEvent('onunload', cleanup);
  }
  function cleanupLegacy() {
    var i = API.attachedListeners.length;
    while (i--) {
      API.attachedListeners[i].el['on' + API.attachedListeners[i].ev] = null;
    }
    API.attachedListeners = null;
    global.onunload = null;
  }
  var uniqueTargetHandle = 0;
  function getTargetId(el) {
    if (el.tagName) {
      return elementUniqueId(el);
    } else {
      if (el == global) { return '_apiwin'; } // Don't pollute primary global namespace (window listeners)
      return (el._targetId = el._targetId || ('_api' + uniqueTargetHandle++)); // Use expando for documents
    }
  }
  function addNormalizedListener(el, ev, fnId, fnNormalized, fnOriginal, context) {
    var uid = getTargetId(el);
    if (!normalizedListeners[uid]) { normalizedListeners[uid] = {}; }
    if (!normalizedListeners[uid][ev]) { normalizedListeners[uid][ev] = {}; }
    normalizedListeners[uid][ev][fnId] = fnNormalized;
    originalListeners[fnId] = { fn:fnOriginal, context:context };
  }
  function getNormalizedListener(el, ev, fnId) {
    var uid = getTargetId(el);
    return (normalizedListeners[uid] && normalizedListeners[uid][ev] && normalizedListeners[uid][ev][fnId]);
  }
  function removeNormalizedListener(el, ev, fnId) {
    var uid = getTargetId(el);
    if (normalizedListeners[uid] && normalizedListeners[uid][ev]) {
      normalizedListeners[uid][ev][fnId] = null;
    }
  }
  function combineNormalizedListeners(el, ev) {
    var fn, i, listeners, uid = elementUniqueId(el);
    if (normalizedListeners[uid] && normalizedListeners[uid][ev]) {
      listeners = normalizedListeners[uid][ev];
      for (i in listeners) {
        if (isOwnProperty(listeners, i) && listeners[i]) {
          fn = (fn)?(function(fn1, fn2) { var r1, r2; r1 = fn1(); r2 = fn2(); return (r1 !== false && r2 !== false); })(listeners[i], fn):listeners[i];
        }
      }
    }
    return fn || null;
  }
  API.eventContexts = [];
  var eventContextHandle = 0;
  var attachListenerFactory = function(d) {
    return (function() {
      var normalizeFunction = (function() {
        if (Function.prototype.call) {
          return function(fn, handle) {
            return function(e) { return fn.call(API.eventContexts[handle].context, e || API.eventContexts[handle].globalContext.event); };
          };
        } else {    
          return function(fn, handle) {
            return function(e) { var context = API.eventContexts[handle].context; context.__mylibevent = fn; var r = context.__mylibevent(e || API.eventContexts[handle].globalContext.event); context.__mylibevent = null; return r; };
          };
        }
      })();
      var attach;
      if (isHostMethod(d, 'addEventListener')) {
        return function(d, ev, fn, context) {
          var fnNormalized = (context)?function(e) { return fn.call(context, e); }:fn;
          if (!fn._fnId) {
            fn._fnId = ++fnId;
          }
          addNormalizedListener(d, ev, fn._fnId, fnNormalized, fn, context);
          return d.addEventListener(ev, fnNormalized, false);
        };
      }
      if (isHostMethod(d, 'attachEvent')) {
        attach = function(d, ev, fn, fnNormalized, context) {
          if (!API.attachedListeners) {
            API.attachedListeners = [];
            global.attachEvent('onunload', cleanup);
          }
          addNormalizedListener(d, ev, fn._fnId, fnNormalized, fn, context);
          d.attachEvent('on' + ev, fnNormalized);
          if (!(ev == 'unload' && d == global)) { API.attachedListeners[API.attachedListeners.length] = { el:d, ev:ev, fn:fnNormalized }; }
          d = null;
        };
      } else {
        attach = function(d, ev, fn, fnNormalized, context) {
          if (!API.attachedListeners) {
            API.attachedListeners = [];
            global.onunload = (function(oldOnunload) { return function(e) { e = e || global.event; if (typeof oldOnunload == 'function') { oldOnunload(e); } cleanupLegacy(e); }; })(global.onunload);
          }
          addNormalizedListener(d, ev, fn._fnId, fnNormalized, fn, context);
          d['on' + ev] = combineNormalizedListeners(d, ev);
          if (!(ev == 'unload' && d == global)) { API.attachedListeners[API.attachedListeners.length] = { el:d, ev:ev }; }
          d = null;
        };
      }
      return function(d, ev, fn, context) {
        var globalContext, docNode = getElementDocument(d);
        if ((docNode || d) == global.document) {
          globalContext = global;
        } else {
          if (getDocumentWindow) {
            globalContext = (docNode && getDocumentWindow(docNode)) || getDocumentWindow(d) || d; // element, document or window
          }
        }
        if (globalContext) {
          API.eventContexts[eventContextHandle] = { context:context || d, globalContext:globalContext };
          var fnNormalized = normalizeFunction(fn, eventContextHandle++);
          if (!fn._fnId) {
            fn._fnId = ++fnId;
          }
          if (!getNormalizedListener(d, ev, fn._fnId)) {
            attach(d, ev, fn, fnNormalized, context);
          }
          return true;
        }
        return false;
      };
    })();
  };
  var detachListenerFactory = function(d) {
     var detach = (function() {
       if (isHostMethod(d, 'removeEventListener')) {
         return function(d, ev, fn) {
           d.removeEventListener(ev, fn, false);
         };
       }
       if (isHostMethod(d, 'detachEvent')) {
         return function(d, ev, fn) {
           d.detachEvent('on' + ev, fn);
         };
       }
       return function(d, ev, fn) {
         d['on' + ev] = combineNormalizedListeners(d, ev);
       };
     })();
     if (detach) {
       return function(d, ev, fn) {
         var fnNormalized;
         if (fn._fnId) {
           fnNormalized = getNormalizedListener(d, ev, fn._fnId);
           if (fnNormalized) {
             removeNormalizedListener(d, ev, fn._fnId);
             detach(d, ev, fnNormalized);
           }
         }
         else {
           detach(d, ev, fn);
         }
       };
     }
  };
  function attachSpecificListenerFactory(obj) {
    var fnAttach = attachListenerFactory(obj);
    return fnAttach && function(ev, fn, objAlt, context) { return fnAttach(objAlt || obj, ev, fn, context); };
  }
  function detachSpecificListenerFactory(obj) {
    var fnDetach = detachListenerFactory(obj);
    return fnDetach && function(ev, fn, objAlt) { return fnDetach(objAlt || obj, ev, fn); };
  }
  if (html) {
    attachListener = attachListenerFactory(html);
    if (attachListener) { detachListener = detachListenerFactory(html); }
    API.attachListener = attachListener;
    API.detachListener = detachListener;
  }
  if (doc) {
    attachDocumentListener = attachSpecificListenerFactory(doc);
    if (attachDocumentListener) { detachDocumentListener = detachSpecificListenerFactory(doc); }
    API.attachDocumentListener = attachDocumentListener;
    API.detachDocumentListener = detachDocumentListener;
  }
  attachWindowListener = attachSpecificListenerFactory(this);
  if (attachWindowListener) { detachWindowListener = detachSpecificListenerFactory(this); }
  API.attachWindowListener = attachWindowListener;
  API.detachWindowListener = detachWindowListener;
  transferListeners = function(elFrom, elTo) {
    var i, j, original, uid = elementUniqueId(elFrom), uidTo = elementUniqueId(elTo), nl = normalizedListeners[uid];
    if (nl && uid != uidTo) {
      for (i in nl) {
        if (isOwnProperty(nl, i)) {
          for (j in nl[i]) {
            if (isOwnProperty(nl[i], j) && nl[i][j]) {
              original = originalListeners[j];
              if (original) {
                detachListener(elFrom, i, original.fn);
                attachListener(elTo, i, original.fn, original.context);
              }
            }            
          }
        }
      }
    }
  };
  purgeListeners = function(el, bChildren, bChildrenOnly) {
    var i, j, original, uid = elementUniqueId(el), nl = normalizedListeners[uid];
    if (!bChildrenOnly) {
      if (nl) {
        for (i in nl) {
          if (isOwnProperty(nl, i)) {
            for (j in nl[i]) {
              if (isOwnProperty(nl[i], j) && nl[i][j]) {
                original = originalListeners[j];
                if (original) {
                  detachListener(el, i, original.fn);
                }
              }            
            }
          }
        }
      }
    }
    if (bChildren && el.childNodes) {
      i = el.childNodes.length;
      while (i--) {
        if (el.childNodes[i].nodeType == 1) { purgeListeners(el.childNodes[i], true); }
      } 
    }
  };
  API.purgeListeners = purgeListeners;
  if (attachListener) {
    getKeyboardKey = function(e) {
      return (e.type == 'keypress')?e.charCode || e.keyCode || e.which:e.which || e.keyCode;
    };
    API.getKeyboardKey = getKeyboardKey;
    cancelPropagation = function(e) {
      if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; }
    };
    API.cancelPropagation = cancelPropagation;
    cancelDefault = function(e) {
      if (e.preventDefault) { e.preventDefault(); }
      if (global.event) { global.event.returnValue = false; }
      return false;
    };
    API.cancelDefault = cancelDefault;
    getMouseButtons = function(e) {
      var b = {};
      if (typeof e.which != 'undefined') {
        b.left = (e.which == 1);
        b.middle = (e.which == 2);
        b.right = (e.which == 3);
      } else {
        b.left = (e.button & 1);
        b.middle = (e.button & 4);
        b.right = (e.button & 2);
      }
      return b;
    };
    API.getMouseButtons = getMouseButtons;
    getEventTarget = function(e) {
      return (e.target)?((e.target.nodeType == 3)?e.target.parentNode:e.target):e.srcElement;
    };
    API.getEventTarget = getEventTarget;
    getEventTargetRelated = function(e) {
      if (e.relatedTarget) { return (e.relatedTarget.nodeType == 3)?e.relatedTarget.parentNode:e.relatedTarget; }
      if (e.srcElement) {
        if (e.srcElement == e.fromElement) { return e.toElement; }
        if (e.srcElement == e.toElement) { return e.fromElement; }
      }
      return null;
    };
    API.getEventTargetRelated = getEventTargetRelated;
  }
  var getBodyElement, getContainerElement;
  if (attachDocumentReadyListener) {
    attachDocumentReadyListener(function() {
      var body, containerElement;
      getBodyElement = function(docNode) {
        docNode = docNode || global.document;
        if (isRealObjectProperty(docNode, 'body')) { return docNode.body; }
        if (typeof getEBTN == 'function') { return getEBTN('body', docNode)[0] || null; }
        return null;
      };
      API.getBodyElement = getBodyElement;
      body = getBodyElement();
      getContainerElement = function(docNode) {
        docNode = docNode || global.document;
        return (docNode.documentElement && (!docNode.compatMode || docNode.compatMode.indexOf('CSS') != -1))?docNode.documentElement:getBodyElement(docNode);
      };
      API.getContainerElement = getContainerElement;
      containerElement = getContainerElement();
      if (canAdjustStyle) {}
      body = containerElement = null;
    });
  }
  var getEBCN, getEBXP, parseAtom, resolve, selectByXPath, xPathChildSelectorsBad;
  if (doc) {
    if (isHostMethod(doc, 'evaluate')) {
      resolve = function() { return 'http://www.w3.org/1999/xhtml'; };
      getEBXP = function(s, d) {
        d = d || global.document;
        var i, q = [], r, docNode = (d.nodeType == 9)?d:(d.ownerDocument);
        r = docNode.evaluate(s, d,
                             (isXmlParseMode(docNode))?resolve:null,
                             global.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
                             null);
        i = r.snapshotLength;
        while (i--) { q[i] = r.snapshotItem(i); }
        return q;
      };
      API.getEBXP = getEBXP;
    }
    parseAtom = function(s) {
      var ai, m, mv, ml;
      var o = {};
      s = s.replace(/\x00/g, ' '); // Change nulls back to spaces
      m = s.match(/^([>\+~])/);
      if (m) {
        o.combinator = m[1];
        s = s.substring(1);
      }
      m = s.match(/^([^#\.\[:]+)/);
      o.tag = m ? m[1] : '*';
      m = s.match(/#([^\.]+)/);
      o.id = m ? m[1] : null;
      m = s.match(/\.([^\[\:]+)/);
      o.cls = m ? m[1] : null;
      m = s.match(/:(.+)$/);
      o.pseudo = m ? m[1] : null;
      m = s.match(/\[[^\]]+\]/g);
      if (m) {
        ml = m.length;
        o.attributes = [];
        o.attributeValues = [];
        o.attributeOperators = [];
        for (ai = 0; ai < ml; ai++) {
          o.attributes[ai] = m[ai].substring(1, m[ai].length - 1);
          m[ai] = m[ai].replace(/^%/, '');
          mv = m[ai].match(/(~|!)?="*([^"\]]*)"*/);
          if (mv) {
            o.attributeOperators[ai] = mv[1];
            o.attributeValues[ai] = mv[2];
            o.attributes[ai] = o.attributes[ai].replace(/(~|!)?=.*/, '');
          }
        }
      }
      return o;
    };
    if (typeof getEBXP != 'undefined') {
      selectByXPath = function(d, a) {
        var atts, m, o, s;
        var docNode = (d.nodeType == 9)?d:getElementDocument(d);
        var i = a.length;
        while (i--) {
          o = parseAtom(a[i]);
          if (s) {
            if (o.combinator) {
              s += (o.combinator == '>')?'/':(o.combinator == '~')?'/preceding-sibling::':'/following-sibling::';
            }
            else {
              s += '//';
            }
          }
          else {
            s = './/';
          }
          s = [s, ((isXmlParseMode(docNode))?'html:':''), (o.pseudo)?'*':o.tag, ((o.cls)?"[contains(concat(' ', @class, ' '), ' " + o.cls + " ')]":'')].join('');
          if (o.pseudo) {
            s += ((o.pseudo == 'last-child')?'[last()]':'[1]') + '[self::' + o.tag + ']';
          }
          if (o.id) {
            s += ['[@id="', o.id, '"]'].join('');
          }
          if (o.attributes) {
            atts = [];
            m = o.attributes.length;
            while (m--) {
              switch(o.attributeOperators[m]) {
              case '~':
                atts.push(['contains(@', o.attributes[m], ',"', o.attributeValues[m], '")'].join(''));
                break;
              case '!':
                atts.push(['not(@', o.attributes[m], '="', o.attributeValues[m], '")'].join(''));
                break;
              default:
                atts.push((o.attributeValues[m])?['@', o.attributes[m], '="', o.attributeValues[m], '"'].join(''):['@', o.attributes[m]].join(''));
              }
            }
            s = [s, '[', atts.join(' and '), ']'].join('');
          }
        }
        return getEBXP(s, d);                          
      };
    }
    var getEBCS = (function() {
      var html = getHtmlElement();
      var els, ns, o, docNode, cache = {}, aCache = {}, qid = 0, bAll = (isHostMethod(html, 'all'));
      function getDocNode(d) {
        return (d.nodeType == 9 || (!d.nodeType && !d.tagName))?d:getElementDocument(d);
      }
      var previousAtom; 
      var selectAtomFactory = function(id, tag, cls, combinator, attributes, attributeValues, attributeOperators, pseudo) {
        var ai, al, att, b, c, d, el, i, j, k, m, r, sibling;
        return function(a, docNode) {
          if (attributes) { al = attributes.length; }
          r = [];
          k = a.length;
          qid++;
          while (k--) {
            d = a[k];
            if (id) {
              if (!d.tagName || (combinator && combinator != '>')) {
                els = (el = getEBI(id, docNode)) ? [el] : [];
              } else {
                els = (bAll && (el = d.all[id]))?[el]:((combinator == '>')?getChildren(d):getEBTN(tag, d));
              }
            } else {
              els = (combinator == '>')?getChildren(d):getEBTN(tag, d);
            }
            i = els.length;
            while (i--) {
              el = els[i];
              b = ((!cls || ((m = el.className) &&
                  (' ' + m + ' ').indexOf(cls) > -1)) &&
                  (!id || el.id == id)
              );
              if (b) {
                switch (combinator) {
                case '~':
                case '+':
                  sibling = el;
                  do {
                    sibling = (combinator == '~')?sibling.nextSibling:sibling.previousSibling;
                  }
                  while (sibling && sibling.nodeType != 1);
                  b = b && (sibling && ((!previousAtom.id || previousAtom.id == sibling.id) && (previousAtom.tag == '*' || sibling.tagName.toLowerCase() == previousAtom.tag) && (!previousAtom.cls || ((m = sibling.className) && (' ' + m + ' ').indexOf(previousAtom.cls) > -1))));
                  break;
                default:
                  b = b && (tag == '*' || (!combinator && !id) || el.tagName.toLowerCase() == tag);
                }
                if (pseudo && el.parentNode) {
                  c = el.parentNode.children || el.parentNode.childNodes;
                  switch (pseudo) {
                  case 'first-child':
                    j = 0;
                    while (j < c.length) {
                      if (c[j++].tagName != '!' || c[j].nodeType == 1) { break; }
                    }
                    b = b && (c[j - 1] == el);
                    break;
                  case 'last-child':
                    j = c.length;
                    while (j--) {
                      if (c[j].tagName != '!' || c[j].nodeType == 1) { break; }
                    }
                    b = b && (c[j] == el);
                  }
                }
                if (attributes) {
                  ai = al;
                  while (ai-- && b) {
                    switch(attributeOperators[ai]) {
                    case '~':
                      att = getAttribute(el, attributes[ai], docNode);
                      b = b && att && att.indexOf(attributeValues[ai]) != -1;
                      break;
                    case '!':
                      b = b && getAttribute(el, attributes[ai], docNode) != attributeValues[ai];
                      break;
                    default:
                      b = b && (attributeValues[ai])?getAttribute(el, attributes[ai], docNode) == attributeValues[ai]:(!hasAttribute && getAttribute(el, attributes[ai], docNode)) || hasAttribute(el, attributes[ai], docNode);
                    }
                  }
                }
                if (b && el._qid != qid) { r[r.length] = el; el._qid = qid; if (id) { break; } }
              }
            }
          }
          return r;
        };
      };
      var selectFactory = function(a) {
         var i, j;
         return function(d) {
           i = a.length;
           j = 1;
           docNode = getDocNode(d);
           ns = [[d]];
           while (i--) {
             o = parseAtom(a[i]);
             if (!aCache['_' + a[i]]) {
               aCache['_' + a[i]] = selectAtomFactory(o.id, o.tag.toLowerCase(), (o.cls)?' ' + o.cls + ' ':null, o.combinator, o.attributes, o.attributeValues, o.attributeOperators, o.pseudo);
             }
             ns[j] = aCache['_' + a[i]](ns[j - 1], docNode);
             previousAtom = o;
             j++;
           }
           return ns[j - 1].reverse();
         };
      };
      var get = (function() {
        var el, getD, r;
        if (typeof getEBI != 'undefined' &&
            typeof getEBTN != 'undefined' &&
            typeof getChildren != 'undefined' &&
            typeof getAttribute != 'undefined' && (global.document.expando || typeof global.document.expando == 'undefined')) {
          getD = function(d, a, s, qid) {
            if (a.length == 1) {
              o = parseAtom(a[0]);
              if (!o.pseudo && !o.attributes) {
                if (o.id && !o.pseudo && !o.cls && !o.attributes) {
                  // Optimization for #foo
                  el = getEBI(o.id, getDocNode(d));
                  return (el && (o.tag == '*' || o.tag == el.tagName.toLowerCase()))?[el]:[];
                }
                if (!o.id && !o.cls) {
                  // Optimization for foo
                  r = getEBTN(o.tag, d);
                  return (typeof r.reverse == 'function')?r:toArray(r);
                }
              }
            }
	    s = '_' + s; // avoid toString conflict
            if (!cache[s]) {
              cache[s] = selectFactory(a);
            }
            return cache[s](d, qid);
          };
        }
        if (getD) {
          return function(d, a, s, qid) {
            if (selectByXPath && !xPathChildSelectorsBad) {
              return (get = selectByXPath)(d, a, s);
            } else {
              return (get = getD)(d, a, s, qid);
            }
          };
        }
      })();
      if (get) {
        return function(s, d) {
          var a = [], aSel = [], chr, i, inQuotes, r = [], used = {};
          d = d || global.document;
          s = s.replace(/^\s+/,'').replace(/\s+$/,''); // trim
          s = s.replace(/\s+,/g, ',').replace(/,\s+/g, ','); // remove spaces before and after commas
          i = s.length;
          while (i--) {
            chr = s.charAt(i);
            switch (chr) {
            case ',':
              if (inQuotes) {
                aSel[aSel.length] = chr;
              }
              else {
                a[a.length] = aSel.reverse().join('');
                aSel = [];
              }
              break;
            case ' ':
              aSel[aSel.length] = (inQuotes)?'\x00':' ';
              break;
            case '"':
              inQuotes = !inQuotes;
              aSel[aSel.length] = chr;
              break;
            default:
              aSel[aSel.length] = chr;
            }
          }
          if (aSel.length) { a[a.length] = aSel.reverse().join(''); }
          a.reverse();
          i = a.length;
          while (i--) {
	    a[i] = a[i].replace(/\s+/g, ' '); // collapse multiple spaces
            a[i] = a[i].replace(/([^\s])([>\+])/g, '$1 $2');
            a[i] = a[i].replace(/([^\s])([~])[^=]/g, '$1 $2');
            a[i] = a[i].replace(/([>\+~])\s/g, '$1');
            if (!used['_' + a[i]]) { // prevent dupes (e.g. div, div, div)
              r = r.concat(get(d, a[i].split(' ').reverse(), a[i]));
            }
            used['_' + a[i]] = 1;
          }
          return r;
        };
      }
      html = null;
    })();
    if (getEBCS) {
      getEBCN = function(s, d) {
        return getEBCS('.' + s, d);
      };
      API.getEBCN = getEBCN;
    }
    if (attachDocumentReadyListener && getEBXP) {
      attachDocumentReadyListener(function() {
        xPathChildSelectorsBad = !!getEBXP('.//*[1][self::body]').length;
      });
    }
  }
  doc = null;
  html = null;
})();

var LIB;
LIB = LIB || {};
LIB.Ajax = function(method, url, options) {
  this.setOptions(options);
  this.method = method.toUpperCase();
  this.request = LIB.Ajax.newXMLHttpRequest();
  if (!this.request) {return true;}
  this.aborted = false;
  var self = this;
  if (this.options.timeout) {
    this.timer = setTimeout(function() {self.onTimeout();}, this.options.timeout);
  }
  this.request.onreadystatechange = function() {self.onReadyStateChange();};
  this.body = this.options.body || {};
  this.setMethod();
  this.body = (function(oBody) {
    var aBody = [];
    for (var p in oBody) {
      aBody.push(encodeURIComponent(p) + "=" + encodeURIComponent(oBody[p]));      
    }
    return ((aBody.length > 0) ? aBody.join("&") : null);
  })(this.body);
  var serialization = null;
  if (this.options.form) {
    serialization = LIB.Ajax.serializeForm(this.options.form);
  }
  if (this.body && serialization) {
    this.body = serialization + "&" + this.body;
  } else if (serialization) {
    this.body = serialization;
  }
  if (this.method === 'GET') {
    if (this.body) {
      url = url + ( url.match(/\?/) ? '&' : '?') + this.body;
    }
    this.body = null;
  }
  this.request.open(this.method, url, true);
  if (this.method === "POST") {
    this.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  }
  if (this.options.headers) {
    for (p in this.options.headers) {
      this.request.setRequestHeader(p, this.options.headers[p]);
    }
  }
  this.request.send(this.body);
};
LIB.Ajax.prototype.setOptions = function(options) {
  this.options = options || {};
};
LIB.Ajax.prototype.setMethod = function() {
  if (this.method === 'GET') {
    this.body._uniqueId = (new Date()).getTime() + "" + LIB.Ajax.transactionId++;
  }
};
LIB.Ajax.transactionId = 0;
LIB.Ajax.newXMLHttpRequest = function() {
  var fs = [
    function() { return new ActiveXObject("Microsoft.XMLHTTP"); },
    function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
    function() { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); },
    function() { return new XMLHttpRequest(); }
  ];
  for (var i=fs.length; i--; ) {
    try {
      var r = fs[i]();
      if (r) {
        LIB.Ajax.newXMLHttpRequest = fs[i];
        return r;
      }
    } catch (e) {}
  }
  (LIB.Ajax.newXMLHttpRequest = function() {return null;})();
};
LIB.Ajax.serializeForm = function(f) {
	if (typeof f == 'string') {
		f = document.getElementById(f) || document.forms[f];
	}
	var els = f.elements, cereal = []; // the serialization of the form data into a string
	function add(n, v) { 
		cereal.push(encodeURIComponent(n) + "=" + encodeURIComponent(v));
	}
	for (var i=0, ilen=els.length; i<ilen; i++) {
		var el = els[i];
		if (!el.disabled) {
			switch (el.type) {
				case 'text': case 'password': case 'hidden': case 'textarea':
					add(el.name, el.value);
					break;
				case 'select-one':
					if (el.selectedIndex >= 0) {
						add(el.name, el.options[el.selectedIndex].value);
					}
					break;
				case 'select-multiple':
					for (var j=0, jlen=el.options.length; j<jlen; j++) {
					  var opt = el.options[j];
						if (opt.selected) {
							add(el.name, opt.value);
						}
					}
					break;
				case 'checkbox': case 'radio':
					if (el.checked) {
						add(el.name, el.value);
					}
					break;
			}
		}
	}
	if (this.button) {
	  add(this.button.name, this.button.value);
	  this.button = null;
	}
	return ((cereal.length > 0) ? cereal.join("&") : null);
};
LIB.Ajax.setButton = function(el) {
  this.button = {name:el.name, value:el.value};
};
LIB.Ajax.prototype.doCallback = function(sMethod) {
  if (this.options.scope) {
		this.options[sMethod].call(this.options.scope, this.request, this.options.argument);
	} else {
		this.options[sMethod](this.request, this.options.argument);
	}
};
LIB.Ajax.prototype.onReadyStateChange = function() {
  if (!this.aborted && this.request.readyState === 4) {
    if (this.timer) {clearTimeout(this.timer);}
    if (this.request) { // why this conditional?
      this.handleReadyState4();
    }
    this.request.onreadystatechange = LIB.Ajax.emptyFnc;
  }
};
LIB.Ajax.emptyFnc = function(){};
LIB.Ajax.prototype.handleReadyState4 = function() {
  var request = this.request, options = this.options;
	var status; // holds the request status
	try {
		status = request.status;
	} catch(e) {
		status = 13030;
	}
  if (status == 12002 || status == 12029 || status == 12030 || status == 12031 || status == 12152 || status == 13030) {
    this.request = {status: 0, statusText: "communication failure", argument: options.argument};
  }
  if (options.before) {
		this.doCallback("before");
  }
  this.status = status;
  this.middleCallback();
	if (options.after) {
		this.doCallback("after");
  }
};
LIB.Ajax.prototype.middleCallback = function() {
  if (this.options["on"+this.status]) {
		this.doCallback("on"+this.status);
  } else if (this.status >= 200 && this.status < 300 && this.options.onSuccess) {
		this.doCallback("onSuccess");
	} else if ((this.status < 200 || this.status >= 300) && this.options.onFailure) {
    this.doCallback("onFailure");	
	}	else if (this.options.onComplete) {
		this.doCallback("onComplete");
	}	
};
LIB.Ajax.prototype.abort = function() {
  this.aborted = true;
  this.request.abort();
  request.onreadystatechange = LIB.Ajax.emptyFnc;
};
LIB.Ajax.prototype.onTimeout = function() {
  this.aborted = true;
  this.request.abort();
  this.handleTimeout();
  this.request = null;
};
LIB.Ajax.prototype.handleTimeout = function() {
  if (this.options.before) {
    this.doCallback("before");
  }
  if (this.options.onTimeout) {
    this.doCallback("onTimeout");
  }
	if (this.options.after) {
	  this.doCallback("after");
	}
};
LIB.Ajax.isSupported = (function(){
  var en = false, x;
  try {
    if (typeof (function(){}).call === "function" &&
        (x = LIB.Ajax.newXMLHttpRequest()) && // yes just one equals sign
        x.readyState === 0) {
      en = true;
    }
  } catch(e) {
    en = false;
  }
  try {
    if (!x.setRequestHeader) {
      en = false;
    }
  } catch(e) {}
  function cannotPost() {
    var xhr = new XMLHttpRequest();
    try {
      xhr.send("asdf");
    } catch (e) {
      if (-1 !== e.toString().indexOf("Could not convert JavaScript argument arg 0 [nsIXMLHttpRequest.send]")) {
        return true;
      }
    }
    return false;
  }
  if (this.XMLHttpRequest && cannotPost()) {
    en = false;
  }
  return function(){return en;};
})();
API.xhr = function(url, method, options) {
  return new LIB.Ajax(url, method, options);
};
function Animation(a){if(this==window){return new Animation(a)}else{this.obj=a;this._reset_state();this.queue=[];this.last_attr=null}}Animation.resolution=20;Animation.offset=0;Animation.prototype._reset_state=function(){this.state={attrs:{},duration:500}};Animation.prototype.stop=function(){this._reset_state();this.queue=[];return this};Animation.prototype._build_container=function(){if(this.container_div){this._refresh_container();return}if(this.obj.firstChild&&this.obj.firstChild.__animation_refs){this.container_div=this.obj.firstChild;this.container_div.__animation_refs++;this._refresh_container();return}var a=document.createElement('div');a.style.padding='0px';a.style.margin='0px';a.style.border='0px';a.__animation_refs=1;var b=this.obj.childNodes;while(b.length){a.appendChild(b[0])}this.obj.appendChild(a);this.obj.style.overflow='hidden';this.container_div=a;this._refresh_container()};Animation.prototype._refresh_container=function(){this.container_div.style.height='auto';this.container_div.style.width='auto';this.container_div.style.height=this.container_div.offsetHeight+'px';this.container_div.style.width=this.container_div.offsetWidth+'px'};Animation.prototype._destroy_container=function(){if(!this.container_div){return}if(!--this.container_div.__animation_refs){var a=this.container_div.childNodes;while(a.length){this.obj.appendChild(a[0])}this.obj.removeChild(this.container_div)}this.container_div=null};Animation.ATTR_TO=1;Animation.ATTR_BY=2;Animation.ATTR_FROM=3;Animation.prototype._attr=function(a,b,c){a=a.replace(/-[a-z]/gi,function(l){return l.substring(1).toUpperCase()});var d=false;switch(a){case'background':this._attr('backgroundColor',b,c);return this;case'margin':b=Animation.parse_group(b);this._attr('marginBottom',b[0],c);this._attr('marginLeft',b[1],c);this._attr('marginRight',b[2],c);this._attr('marginTop',b[3],c);return this;case'padding':b=Animation.parse_group(b);this._attr('paddingBottom',b[0],c);this._attr('paddingLeft',b[1],c);this._attr('paddingRight',b[2],c);this._attr('paddingTop',b[3],c);return this;case'backgroundColor':case'borderColor':case'color':b=Animation.parse_color(b);break;case'opacity':b=parseFloat(b,10);break;case'height':case'width':if(b=='auto'){d=true}else{b=parseInt(b,10)}break;case'borderWidth':case'lineHeight':case'fontSize':case'marginBottom':case'marginLeft':case'marginRight':case'marginTop':case'paddingBottom':case'paddingLeft':case'paddingRight':case'paddingTop':case'bottom':case'left':case'right':case'top':case'scrollTop':case'scrollLeft':b=parseInt(b,10);break;default:throw new Error(a+' is not a supported attribute!');}if(this.state.attrs[a]===undefined){this.state.attrs[a]={}}if(d){this.state.attrs[a].auto=true}switch(c){case Animation.ATTR_FROM:this.state.attrs[a].start=b;break;case Animation.ATTR_BY:this.state.attrs[a].by=true;case Animation.ATTR_TO:this.state.attrs[a].value=b;break}};Animation.prototype.to=function(a,b){if(b===undefined){this._attr(this.last_attr,a,Animation.ATTR_TO)}else{this._attr(a,b,Animation.ATTR_TO);this.last_attr=a}return this};Animation.prototype.by=function(a,b){if(b===undefined){this._attr(this.last_attr,a,Animation.ATTR_BY)}else{this._attr(a,b,Animation.ATTR_BY);this.last_attr=a}return this};Animation.prototype.from=function(a,b){if(b===undefined){this._attr(this.last_attr,a,Animation.ATTR_FROM)}else{this._attr(a,b,Animation.ATTR_FROM);this.last_attr=a}return this};Animation.prototype.duration=function(a){this.state.duration=a?a:0;return this};Animation.prototype.checkpoint=function(a,b){if(a===undefined){a=1}this.state.checkpoint=a;this.state.checkpointcb=b;this.queue.push(this.state);this._reset_state();return this};Animation.prototype.blind=function(){this.state.blind=true;return this};Animation.prototype.hide=function(){this.state.hide=true;return this};Animation.prototype.show=function(){this.state.show=true;return this};Animation.prototype.ease=function(a){this.state.ease=a;return this};Animation.prototype.go=function(){var a=(new Date()).getTime();this.queue.push(this.state);for(var i=0;i<this.queue.length;i++){this.queue[i].start=a-Animation.offset;if(this.queue[i].checkpoint){a+=this.queue[i].checkpoint*this.queue[i].duration}}Animation.push(this);return this};Animation.prototype._frame=function(b){var c=true;var d=false;var f=false;for(var i=0;i<this.queue.length;i++){var g=this.queue[i];if(g.start>b){c=false;continue}else if(g.checkpointcb&&(g.checkpoint*g.duration+g.start>b)){this._callback(g.checkpointcb,b-g.start-g.checkpoint*g.duration);g.checkpointcb=null}if(g.started===undefined){if(g.show){this.obj.style.display='block'}for(var a in g.attrs){if(g.attrs[a].start!==undefined){continue}switch(a){case'backgroundColor':case'borderColor':case'color':var h=Animation.parse_color(Animation.get_style(this.obj,a=='borderColor'?'borderLeftColor':a));if(g.attrs[a].by){g.attrs[a].value[0]=Math.min(255,Math.max(0,g.attrs[a].value[0]+h[0]));g.attrs[a].value[1]=Math.min(255,Math.max(0,g.attrs[a].value[1]+h[1]));g.attrs[a].value[2]=Math.min(255,Math.max(0,g.attrs[a].value[2]+h[2]))}break;case'opacity':var h=((h=Animation.get_style(this.obj,'opacity'))&&parseFloat(h))||((h=Animation.get_style(this.obj,'opacity'))&&(h=/(\d+(?:\.\d+)?)/.exec(h))&&parseFloat(h.pop())/100)||1;if(g.attrs[a].by){g.attrs[a].value=Math.min(1,Math.max(0,g.attrs[a].value+h))}break;case'height':case'width':var h=Animation['get_'+a](this.obj);if(g.attrs[a].by){g.attrs[a].value+=h}break;case'scrollLeft':case'scrollTop':var h=(this.obj==document.body)?(document.documentElement[a]||document.body[a]):this.obj[a];if(g.attrs[a].by){g.attrs[a].value+=h}g['last'+a]=h;break;default:var h=parseInt(Animation.get_style(this.obj,a),10);if(g.attrs[a].by){g.attrs[a].value+=h}break}g.attrs[a].start=h}if((g.attrs.height&&g.attrs.height.auto)||(g.attrs.width&&g.attrs.width.auto)){if(/Firefox\/[12]\./.test(navigator.userAgent)){f=true}this._destroy_container();for(var a in{height:1,width:1,fontSize:1,borderLeftWidth:1,borderRightWidth:1,borderTopWidth:1,borderBottomWidth:1,paddingLeft:1,paddingRight:1,paddingTop:1,paddingBottom:1}){if(g.attrs[a]){this.obj.style[a]=g.attrs[a].value+(typeof g.attrs[a].value=='number'?'px':'')}}if(g.attrs.height&&g.attrs.height.auto){g.attrs.height.value=Animation.get_height(this.obj)}if(g.attrs.width&&g.attrs.width.auto){g.attrs.width.value=Animation.get_width(this.obj)}}g.started=true;if(g.blind){this._build_container()}}var p=(b-g.start)/g.duration;if(p>=1){p=1;if(g.hide){this.obj.style.display='none'}}else{c=false}var j=g.ease?g.ease(p):p;if(!d&&p!=1&&g.blind){d=true}if(f&&this.obj.parentNode){var k=this.obj.parentNode;var l=this.obj.nextSibling;k.removeChild(this.obj)}for(var a in g.attrs){switch(a){case'backgroundColor':case'borderColor':case'color':this.obj.style[a]='rgb('+Animation.calc_tween(j,g.attrs[a].start[0],g.attrs[a].value[0],true)+','+Animation.calc_tween(j,g.attrs[a].start[1],g.attrs[a].value[1],true)+','+Animation.calc_tween(j,g.attrs[a].start[2],g.attrs[a].value[2],true)+')';break;case'opacity':var m=Animation.calc_tween(j,g.attrs[a].start,g.attrs[a].value);try{this.obj.style.opacity=(m==1?'':m);this.obj.style.filter=(m==1?'':'alpha(opacity='+m*100+')')}catch(e){}break;case'height':case'width':this.obj.style[a]=j==1&&g.attrs[a].auto?'auto':Animation.calc_tween(j,g.attrs[a].start,g.attrs[a].value,true)+'px';break;case'scrollLeft':case'scrollTop':var h=(this.obj==document.body)?(document.documentElement[a]||document.body[a]):this.obj[a];if(g['last'+a]!=h){delete g.attrs[a]}else{var n=Animation.calc_tween(j,g.attrs[a].start,g.attrs[a].value,true)-h;if(a=='scrollLeft'){window.scrollBy(n,0)}else{window.scrollBy(0,n)}g['last'+a]=n+h}break;default:this.obj.style[a]=Animation.calc_tween(j,g.attrs[a].start,g.attrs[a].value,true)+'px';break}}if(p==1){this.queue.splice(i--,1);this._callback(g.ondone,b-g.start-g.duration)}}if(f){k[l?'insertBefore':'appendChild'](this.obj,l)}if(!d&&this.container_div){this._destroy_container()}return!c};Animation.prototype.ondone=function(a){this.state.ondone=a;return this};Animation.prototype._callback=function(a,b){if(a){Animation.offset=b;a.call(this);Animation.offset=0}};Animation.calc_tween=function(p,a,b,c){return(c?parseInt:parseFloat)((b-a)*p+a,10)};Animation.parse_color=function(a){var b=/^#([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})$/i.exec(a);if(b){return[parseInt(b[1].length==1?b[1]+b[1]:b[1],16),parseInt(b[2].length==1?b[2]+b[2]:b[2],16),parseInt(b[3].length==1?b[3]+b[3]:b[3],16)]}else{var c=/^rgba? *\(([0-9]+), *([0-9]+), *([0-9]+)(?:, *([0-9]+))?\)$/.exec(a);if(c){if(c[4]==='0'){return[255,255,255]}else{return[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]}}else if(a=='transparent'){return[255,255,255]}else{throw'Named color attributes are not supported.';}}};Animation.parse_group=function(a){var a=trim(a).split(/ +/);if(a.length==4){return a}else if(a.length==3){return[a[0],a[1],a[2],a[1]]}else if(a.length==2){return[a[0],a[1],a[0],a[1]]}else{return[a[0],a[0],a[0],a[0]]}};Animation.get_height=function(a){var b=parseInt(Animation.get_style(a,'paddingTop'),10),pB=parseInt(Animation.get_style(a,'paddingBottom'),10),bT=parseInt(Animation.get_style(a,'borderTopWidth'),10),bW=parseInt(Animation.get_style(a,'borderBottomWidth'),10);return a.offsetHeight-(b?b:0)-(pB?pB:0)-(bT?bT:0)-(bW?bW:0)};Animation.get_width=function(a){var b=parseInt(Animation.get_style(a,'paddingLeft'),10),pR=parseInt(Animation.get_style(a,'paddingRight'),10),bL=parseInt(Animation.get_style(a,'borderLeftWidth'),10),bR=parseInt(Animation.get_style(a,'borderRightWidth'),10);return a.offsetWidth-(b?b:0)-(pR?pR:0)-(bL?bL:0)-(bR?bR:0)};Animation.get_style=function(b,c){var d;return(window.getComputedStyle&&window.getComputedStyle(b,null).getPropertyValue(c.replace(/[A-Z]/g,function(a){return'-'+a.toLowerCase()})))||(document.defaultView&&document.defaultView.getComputedStyle&&(d=document.defaultView.getComputedStyle(b,null))&&d.getPropertyValue(c.replace(/[A-Z]/g,function(a){return'-'+a.toLowerCase()})))||(b.currentStyle&&b.currentStyle[c])||b.style[c]};Animation.push=function(a){if(!Animation.active){Animation.active=[]};Animation.active.push(a);if(!Animation.timeout){Animation.timeout=setInterval(Animation.animate,Animation.resolution)}};Animation.animate=function(){var a=true;var b=(new Date()).getTime();for(var i=0;i<Animation.active.length;i++){if(Animation.active[i]._frame(b)){a=false}else{Animation.active.splice(i--,1)}}if(a){clearInterval(Animation.timeout);Animation.timeout=null}};Animation.ease={};Animation.ease.begin=function(p){return p*p};Animation.ease.end=function(p){p-=1;return-(p*p)+1};Animation.ease.both=function(p){if(p<=0.5){return(p*p)*2}else{p-=1;return(p*p)*-2+1}};

