new function () {

function generic (c) {
  Array.prototype.slice.call(arguments, 1).forEach(function (n) {
    if (!c[n]) c[n] = function () {
      return Function.prototype.call.apply(c.prototype[n], arguments);
    }
  });
}
/* -------------------------------------------------------------------- Array */
var p = Array.prototype;
if (!p.forEach) {
  p.forEach = function (fn, thisp) {
    for (var l = this.length, i = 0; --l >= 0; i++)
      if (i in this) fn.call(thisp, this[i], i, this);
  }
}
if (!p.indexOf) {
  p.indexOf = function (e, i) {
    var l = this.length;
    i = (i < 0) ? Math.ceil(i) : (i > 0) ? Math.floor(i) : 0;
    if (i < 0) i+= l;
    for (; i < l; i++)
      if (i in this && this[i] === e) return i;
    return -1;
  }
}
if (!p.map) {
  p.map = function (fn, thisp) {
    for (var r = new Array(l), l = this.length, i = 0; --l >= 0; i++)
      if (i in this) r[i] = fn.call(thisp, this[i], i, this);
    return r;
  }
}
generic(Array, 'forEach', 'indexOf', 'map');
/* --------------------------------------------------------------------- DOM */
window.DOM = {
  addEventListener: function (o, t, fn) {
    if (o.addEventListener) o.addEventListener(t, fn, false);
    else if (o.attachEvent) o.attachEvent('on'+t, fn);
    else o['on'+t] = fn;
  },
  removeEventListener: function (o, t, fn) {
    if (o.removeEventListener) o.removeEventListener(t, fn, false);
    else if (o.detachEvent) o.detachEvent('on'+t, o);
    else if (o[t = 'on'+t] === this) o[t] = null;
  },
  removeChildren: function (e) {
    with (e) while (firstChild) removeChild(firstChild);
    return e;
  },
  hasClass: function (e, c) {
    var s = e.className, i = s.indexOf(c);
    return i != -1 && (s.charCodeAt(i - 1) || 32) == 32 && (s.charCodeAt(i + c.length) || 32) == 32;
  },
  addClass: function (e, c) {
    if (!DOM.hasClass(e, c)) {
      e.className += ' '+c;
      return true;
    }
  },
  removeClass: function (e, c) {
    var s = e.className, i = s.indexOf(c), l = c.length;
    if (i != -1 && (s.charCodeAt(i - 1) || 32) == 32 && (s.charCodeAt(i + l) || 32) == 32) {
      e.className = s.substr(0, i)+s.substr(i + l);
      return true;
    }
  }
  /*
  cancelEvent: function (e) {
    var e = e||window.event;
    if (e.stopPropagation) e.stopPropagation();
    else e.cancelBubble = true;
    if (e.preventDefault) e.preventDefault();
    else e.returnValue = false;
    return false;
  },
  addBookmark: function (title, url) {
    if (window.sidebar && window.sidebar.addPanel) // Firefox
      window.sidebar.addPanel(title, url, '');
    else if (window.opera) { // Opera
      with (document.createElement('A')) {
        rel = 'sidebar';
        target = '_search';
        title = title;
        href = url;
        click();
      }
    }
    else if (window.external && window.external.addFavorite) // IE
      window.external.addFavorite(url, title);
  }
  */
}
/* --------------------------------------------------------------------- JSON */
if (!window.JSON) new function () {
  var r = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, 
      m = { '\b':'\\b', '\t':'\\t', '\n':'\\n', '\f':'\\f', '\r':'\\r', '"':'\\"', '\\':'\\\\' };
  function q (s) {
    return '"'+s.replace(r, function (c) {
      return m[c] || '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4);
    })+'"';
  }
  window.JSON = {
    parse: function (s) {
      if (typeof s === 'string' && s.length) 
        return new Function('return ('+s+')')();
    },
    stringify: function (v) {
      switch (typeof v) {
        case 'string':
          return q(v);
        case 'boolean':
          return String(v);
        case 'number':
          return isFinite(v) ? String(v) : 'null';
        case 'object':
          if (v) {
            var r = [];
            if (Object.prototype.toString.apply(v) === '[object Array]') {
              for (var i = v.length; --i >= 0; r[i] = JSON.stringify(v[i]));
              return '['+r.join(',')+']';
            }
            for (var k in v) {
              if (Object.hasOwnProperty.call(v, k))
                r[r.length] = q(String(k))+':'+JSON.stringify(v[k]);
            }
            return '{'+r.join(',')+'}';
          }
        case 'null':
        case 'undefined':
          return 'null';
        default:
          throw new TypeError('Illegal type for JSON: ' + typeof v);
      }
    }
  }
}
/* ----------------------------------------------------------- XMLHttpRequest */
if (!window.XMLHttpRequest && window.ActiveXObject) {
  window.XMLHttpRequest = function () {
    var x = function (p) {
      try { return new ActiveXObject(p) } catch(e) {}
    }
    return x('MSXML3.XMLHTTP')
        || x("MSXML2.XMLHTTP.6.0")
        || x("MSXML2.XMLHTTP.3.0")
        || x("MSXML2.XMLHTTP")
        || x("Microsoft.XMLHTTP");
  };
}
/* ----------------------------------------------------------------- innerText */
if (window.Element) {
  var p = window.Element.prototype;
  if (!('innerText' in p)) {
    p.__defineGetter__('innerText', function () {
      return this.textContent;
    });
    p.__defineSetter__('innerText', function (t) {
      this.textContent = t;
    });
  }
}

}
