Function.prototype.bind = function(obj) {
  var method = this;
  for (var i=1, args=[]; i<arguments.length; i++)
    args.push(arguments[i]);
  return function() {
    method.apply(obj, args);
  };
}
Function.prototype.bindListener = function(obj) {
  var method = this;
  return function(e) {
    method.call(obj, e);
  };
}

var $C = function(tag){ return document.createElement(tag); }

var Ajax = function() {
  this.initialize.apply(this, arguments);
}
Ajax.prototype = {
  initialize: function(url){
    this.url = url;
    if (window.XMLHttpRequest) { // Mozilla, Firefox, Safari, Opera, IE7
      this.req = new XMLHttpRequest();
    } else { // IE5,6
      try {
        this.req = new ActiveXObject("Msxml2.XMLHTTP");
      } catch (e) {
        this.req = new ActiveXObject("Microsoft.XMLHTTP");
      }
    }
  },
  get: function(callback){
    var req = this.req;
    req.open("GET", this.url, true);
    if (callback) {
      req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200)
          callback(req.responseText);
      }
    }
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send(null);
  },
  post: function(param, callback){
    var req = this.req;
    req.open("POST", this.url, true);
    if (callback) {
      req.onreadystatechange = function() {
        if (req.readyState == 4 && req.status == 200)
          callback(req.responseText);
      }
    }
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    req.send(param);
  }
}

var Event = {
  stop: function(e) {
    e.stopPropagation ? e.stopPropagation() : (e.cancelBubble = true);
  },
  cancel: function(e) {
    e.preventDefault ? e.preventDefault() : (e.returnValue = true);
  },
  target: function(e) {
    return e.target || e.srcElement;
  }
}

var addListener = (function() {
  if ( window.addEventListener )
    return function(el, type, fn) { el.addEventListener(type, fn, false); };
  else if ( window.attachEvent )
    return function(el, type, fn) { el.attachEvent('on'+type, fn); };
  else
    return function(el, type, fn) { el['on'+type] = fn; }
})();

var removeListener = (function() {
  if (window.removeEventListener)
    return function(el, type, fn) { el.removeEventListener(type, fn, false); };
  else if (window.attachEvent)
    return function(el, type, fn) { el.detachEvent('on'+type, fn); };
  else
    return function(el, type, fn) { el['on'+type] = fn; }
})();

