/* Javascript by Daniel Cohen Gindi (c) danielgindi@gmail.com 054-5655765 */
/* Version: 2010-04-08 */

$isElement = function(o) { return o && o.nodeType == 1 };
$isArray = function(o) { return o != null && typeof o == 'object' && 'splice' in o && 'join' in o };
$isFunction = function(o) { return typeof o == 'function' };
$isString = function(o) { return typeof o == 'string' };
$isNumber = function(o) { return typeof o == 'number' };

Array.prototype.iterate = function(fn, bind) { for (var i = 0, j = this.length; i < j; i++) if (bind) { fn.call(bind, this[i], i, this) } else { fn(this[i]) } }
Array.fromElement = function(el) { var arr = []; for (var i = 0, j = el.length; i < j; i++) arr[i] = el[i]; return arr; }
Array.prototype.indexOf = function(item, from) {
  var len = this.length;
  for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++) {
    if (this[i] === item) return i
  }
  return -1
};
Array.prototype.contains = function(item, from) { return this.indexOf(item, from) != -1 };
Array.prototype.copy = function(start, length) {
  start = start || 0;
  if (start < 0) start = this.length + start;
  length = length || (this.length - start);
  var newArray = [];
  for (var i = 0; i < length; i++) newArray[i] = this[start++];
  return newArray
};
Array.prototype.remove = function(item) {
  var i = 0, len = this.length;
  while (i < len) {
    if (this[i] === item) { this.splice(i, 1); len-- } else { i++ }
  }
  return this
};
Function.prototype.bind = function(bind, args) { var fn = this; return function() { return fn.apply(bind, args || arguments) } };
String.prototype.escapeForJs = function() {
  if (this === undefined || this === null) return '';
  else return this.replace(/\\/g, '\\\\').replace(/\'/g, '\\\'').replace(/\"/g, '\\\"').replace(/\r/g, '\\r').replace(/\n/g, '\\n');
};

if (window.ActiveXObject) {
  if (navigator.appVersion.indexOf("MSIE 8.0") >= 0) window.ie = window.ie8 = 8;
  else if (navigator.appVersion.indexOf("MSIE 7.0") >= 0) window.ie = window.ie7 = 7;
  else if (navigator.appVersion.indexOf("MSIE 6.0") >= 0) window.ie = window.ie6 = 6;
  else if (document.all && document.getElementById) window.ie = window.ie5 = 5;
  else window.ie = window.ie4 = 4;
}
window.gecko = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1;
window.webkit = navigator.userAgent.indexOf('AppleWebKit/') > -1;

window.getClientHeight = function() { return ((document.documentElement && document.documentElement.clientHeight) ? document.documentElement.clientHeight : ((document.body && document.body.clientHeight) ? document.body.clientHeight : window.innerHeight)); }
window.getClientWidth = function() { return ((document.documentElement && document.documentElement.clientWidth) ? document.documentElement.clientWidth : ((document.body && document.body.clientWidth) ? document.body.clientWidth : window.innerWidth)); }
window.getClientScrollHeight = function() { return ((document.documentElement && document.documentElement.scrollHeight) ? document.documentElement.scrollHeight : ((document.body && document.body.scrollHeight) ? document.body.scrollHeight : window.scrollHeight)); }
window.getClientScrollWidth = function() { return ((document.documentElement && document.documentElement.scrollWidth) ? document.documentElement.scrollWidth : ((document.body && document.body.scrollWidth) ? document.body.scrollWidth : window.scrollWidth)); }
window.getScrollOffsets = function() {
  var ret = [window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft, window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop];
  ret.left = ret[0];
  ret.top = ret[1];
  return ret;
}

ajax = {};
ajax.$ = function(el) {
  if (!el) return el;
  if (el && el.nodeType == 1) return el;
  return document.getElementById ? document.getElementById(el) : (document.layers ? document.layers[el] : document.all[el]);
};
ajax.loadScriptFromUrl = function(url, uniqueName, useCounter) {
  // uniqueName, useCounter: safeties against script caching
  var scriptTag = null;
  var headTag = document.getElementsByTagName('head')[0];
  if (uniqueName) {
    var newCounter = false;
    uniqueName = '$ajax_load_' + uniqueName;
    scriptTag = this.$(uniqueName);
    if (scriptTag) headTag.removeChild(scriptTag);
    else newCounter = true;
    scriptTag = document.createElement('script');
    scriptTag.id = uniqueName;

    if (useCounter) {
      uniqueName += '_counter$';
      var counter;
      if (newCounter) counter = 0;
      else counter = eval(uniqueName);
      counter++;
      eval(uniqueName + '=' + counter);
      if (url.indexOf('?') >= 0) url += '&_counter$=' + counter;
      else url += '?_counter$=' + counter;
    }
  }
  else {
    scriptTag = document.createElement('script');
  }
  headTag.appendChild(scriptTag);
  scriptTag.src = url;
}
ajax.parseXmlString = function(xml) {
  var xmlDoc = null;
  if (window.ActiveXObject) {
    try {
      xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
      xmlDoc.async = false;
      xmlDoc.loadXML(xml);
    } catch (e) {
    }
  }
  else if (DOMParser) {
    var parser = new DOMParser();
    xmlDoc = parser.parseFromString(xml, "application/xml");
  }
  if (xmlDoc && xmlDoc.documentElement) return xmlDoc.documentElement;
};
ajax.parseXmlFile = function(url) {
  var xmlDoc = null;
  if (window.ActiveXObject) {
    try {
      xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    } catch (e) {
      try {
        xmlDoc = document.implementation.createDocument("", "", null);
      } catch (e) {
      }
    }
  }
  xmlDoc.async = false;
  xmlDoc.load(url);
  if (xmlDoc && xmlDoc.documentElement) return xmlDoc.documentElement;
};
ajax.loadUrl = function(url, callback, getResponseFn) {
		var async = !!callback;

    var xhr = null;

    if (!window.ie || location.protocol != 'file:')
        try { xhr = new XMLHttpRequest(); } catch (e) { }
    if (xhr == null) {
        try { xhr = new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { }
    }
    if (xhr == null) {
        try { xhr = new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) { }
    }
    if (!xhr) return null;
    xhr.open('GET', url, async);
    if (async) {
			xhr.onreadystatechange = function()
			{
				if ( xhr.readyState == 4 )
				{
					callback( getResponseFn( xhr ) );
					xhr = null;
				}
			};    	
    }
    try { xhr.send(null); } catch (e) { return null; }
        
    return async ? '' : getResponseFn( xhr );
};
ajax.loadUrl.checkStatus = function( xhr )
{
		//	 2xx : Success
		//	 304 : Not Modified
		//	   0 : Returned when running locally (file://)
		//	1223 : IE may change 204 to 1223 (see http://dev.jquery.com/ticket/1450)

		return ( xhr.readyState == 4 &&
				(	( xhr.status >= 200 && xhr.status < 300 ) ||
					xhr.status == 304 ||
					xhr.status === 0 ||
					xhr.status == 1223 ) );
};
ajax.loadUrlText = function(url, callback)
{
	var getResponseText = function( xhr )
	{
		if ( ajax.loadUrl.checkStatus( xhr ) )
			return xhr.responseText;
		return null;
	};
	return ajax.loadUrl(url, callback, getResponseText);
};
ajax.loadUrlXml = function(url, callback)
{
	var getResponseText = function( xhr )
	{
		if ( ajax.loadUrl.checkStatus( xhr ) )
		{
			var xml = xhr.responseXML;
			return (xml && xml.firstChild) ? xml : ajax.parseXmlString(xhr.responseText);
		}
		return null;
	};
	return ajax.loadUrl(url, callback, getResponseText);
};
ajax.browser = {
  preventBack: function() {
    function preventBackCallback() { window.history.forward(); };
    setTimeout(preventBackCallback, 0);
    ajax.events.register(window, 'unload', function() { null; });
  },
  isChrome: function() { return document.getElementById && navigator.appVersion.indexOf("Chrome") >= 0 },
  winPopup: function(URL, width, height, wndName, forceReload) {
    if (wndName == undefined || wndName == null) wndName = "";
    var newWnd = window.open("", wndName, config = "height=" + height + ",width=" + width + ",resizable=no,toolbars=no,address=no,status=no,menubar=no,location=no,toolbar=no,scrollbars=no")
    try {
      if (forceReload == true) {
        newWnd.document.close();
        newWnd.document.open();
      }
    } catch (E) { }
    newWnd.document.location = URL;
    newWnd.window.focus();
    return newWnd;
  },
  simulateInnerAnchorClick: function(item, level) {
    for (var i = 0; i < level; i++) {
      if (i < level && !item.firstChild) return;
      else if (i == level && !item.href) return;
      if (i < level) item = item.firstChild;
    }
    if (item.href) {
      if (item.target && item.target.length > 0) window.open(item.href, item.target);
      else document.location = item.href;
      return false;
    };
  }
};
ajax.layout = {
  offset: function(el) { if (el.pageX) return [el.pageLeft, el.pageTop]; else { var l = 0, t = 0; while (el) { l += el.offsetLeft; t += el.offsetTop; el = el.offsetParent; } return [l, t]; }; },
  height: function(el) {
    if (el) {
      var ret =
    ((el.clip && el.clip.bottom) ? (el.clip.bottom - el.clip.top) :
     ((el.document && el.document.height) ? el.document.height : null)) ||
    el.style.height || el.clientHeight || el.height || el.offsetHeight || el.style.pixelHeight ||
    (el.parentNode ? (el.parentNode.style.height || el.parentNode.clientHeight || el.parentNode.height) : null)
      if (ret) return parseInt(ret, 10); else return null;
    }
    return null
  },
  width: function(el) {
    if (el) {
      var ret =
    ((el.clip && el.clip.right) ? (el.clip.right - el.clip.left) :
     ((el.document && el.document.width) ? el.document.width : null)) ||
    el.style.width || el.clientWidth || el.width || el.offsetWidth ||
    (el.parentNode ? (el.parentNode.style.width || el.parentNode.clientWidth || el.parentNode.width) : null)
      if (ret) return parseInt(ret, 10); else return null;
    }
    return null
  },
  setOpacity: function(el, opacity) {
    opacity = parseFloat(opacity);
    opacity = (opacity < 0.00001) ? 0 : opacity;
    if (window.ie) {
      if (opacity >= 1 && el.style.filter.match(/alpha\(\s*opacity\s*=\s*(.*)\s*\)/)) {
        var tmpEl = document.createElement('div');
        el.style.filter = tmpEl.style.filter;
        delete tmpEl;
      } else {
        el.style.filter = el.style.filter.replace(/alpha\([^\)]*\)/gi, '') + ((opacity == 1) ? '' : ('alpha(opacity=' + (opacity * 100) + ')'));
      }
    }
    if (opacity == 1) opacity = '';
    el.style.opacity = opacity;
    el.style.MozOpacity = opacity;
    el.style.KhtmlOpacity = opacity;
    return this;
  },
  getOpacity: function(el) {
    if (el.style.opacity) return parseFloat(el.style.opacity);
    else if (el.style.MozOpacity) return parseFloat(el.style.MozOpacity);
    else if (el.style.KhtmlOpacity) return parseFloat(el.style.KhtmlOpacity);
    else if (el.style.filter) {
      var value;
      if (value = el.style.filter.match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
    }
    return 1.0;
  },
  elementHasChild: function(parent, child) {
    var els = parent.getElementsByTagName('*');
    for (var idx=0; idx<els.length; idx++) { if (els[idx]==child) return true; }
    return false;
  },
  setText: function(element, text) {
    if (element) {
      if (element.textContent != undefined) element.textContent = text;
      else if (element.innerText != undefined) element.innerText = text;
      else element.value = text;
    }
  }
};
ajax.tables = {
  clear: function(tbl) {
    while (tbl.childNodes.length) { tbl.removeChild(tbl.childNodes[0]); }
  },
  clearArea: function(tbl, areaName) {
    for (var i = 0; i < tbl.childNodes.length; i++) {
      if (tbl.childNodes[i].nodeName.toLowerCase() == areaName.toString().toLowerCase()) {
        var el = tbl.childNodes[i];
        while (el.childNodes.length) el.removeChild(el.firstChild);
      }
    }
  },
  removeArea: function(tbl, areaName) {
    for (var i = 0; i < tbl.childNodes.length; i++) {
      if (tbl.childNodes[i].nodeName.toLowerCase() == areaName.toString().toLowerCase()) {
        tbl.removeChild(tbl.childNodes[i]);
        i--;
      }
    }
  },
  removeRows: function(tbl) {
    while (tbl.rows.length) { tbl.deleteRow(0); }
  }
};
ajax.cookies = {
  save: function(id, value, expires) {
    if (expires) {
      var date = new Date();
      date.setTime(date.getTime() + (parseInt(expires, 10) * (24 * 60 * 60 * 1000)));
      expires = date.toUTCString();
    }
    else expires = null;
    document.cookie = id + '=' + escape(value) + '; path=/' + ((expires == null) ? '' : '; expires=' + expires);
  },
  read: function(id) {
    var dc = document.cookie;
    id = id + '=';

    if (dc.length > 0) {
      begin = dc.indexOf(id);
      if (begin != -1) {
        begin += id.length;
        end = dc.indexOf(';', begin);
        if (end == -1) end = dc.length;
        return unescape(dc.substring(begin, end));
      }
    }
    return null;
  }
};
ajax.events = {
  register: function(element, eventName, ev_func, capture) {
    if (element == null) return;
    if (eventName.indexOf('dom:', 0) == 0) {
      function ff(e) { var evt = e || event; if (eventName == evt.eventName) ev_func(evt) };
      if (element.addEventListener) element.addEventListener('dataavailable', ff, capture ? true : false);
      else if (element.attachEvent) element.attachEvent('ondataavailable', ff);
    } else {
      if (element.addEventListener) element.addEventListener(eventName, ev_func, capture ? true : false);
      else if (element.attachEvent) element.attachEvent('on' + eventName, ev_func);
    }
    return ev_func;
  },
  unregister: function(element, eventName, ev_func, capture) {
    if (element == null) return;
    if (element.removeEventListener) element.removeEventListener(eventName, ev_func, capture ? true : false);
    else if (element.detachEvent) element.detachEvent('on' + eventName, ev_func);
  },
  fire: function(element, eventName) {
    if (element == document && document.createEvent && !element.dispatchEvent)
        element = document.documentElement;
    var event;
    if (document.createEvent) {
      event = document.createEvent('HTMLEvents');
      event.initEvent('dataavailable', true, true);
    } else {
      event = document.createEventObject();
      event.eventType = 'ondataavailable';
    }

    event.eventName = eventName;

    if (document.createEvent) {
      element.dispatchEvent(event);
    } else {
      element.fireEvent(event.eventType, event);
    }

    return event;
  },
  Event: function() { return this.initialize.apply(this, arguments) },
  keys: {
    'enter': 13,
    'up': 38,
    'down': 40,
    'left': 37,
    'right': 39,
    'esc': 27,
    'space': 32,
    'backspace': 8,
    'tab': 9,
    'delete': 46
  }
};
ajax.events.Event.fix = {
  relatedTarget: function() {
    if (this.relatedTarget && this.relatedTarget.nodeType == 3) this.relatedTarget = this.relatedTarget.parentNode
  },
  relatedTargetGecko: function() {
    try {
      ajax.events.Event.fix.relatedTarget.call(this)
    } catch (e) {
      this.relatedTarget = this.target
    }
  }
};
ajax.events.Event.prototype = {
  initialize: function(event) {
    if (event && event.$extended) return event;
    this.$extended = true;
    event = event || window.event;
    this.event = event;
    this.type = event.type;
    this.target = event.target || event.srcElement;
    if (this.target.nodeType == 3) this.target = this.target.parentNode;
    this.shift = event.shiftKey;
    this.control = event.ctrlKey;
    this.alt = event.altKey;
    this.meta = event.metaKey;
    if (['DOMMouseScroll', 'mousewheel'].contains(this.type)) {
      this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3
    } else if (this.type.indexOf('key') > -1) {
      this.code = event.which || event.keyCode;
      for (var name in ajax.events.keys) {
        if (ajax.events.keys[name] == this.code) {
          this.key = name;
          break
        }
      }
      if (this.type == 'keydown') {
        var fKey = this.code - 111;
        if (fKey > 0 && fKey < 13) this.key = 'f' + fKey
      }
      this.key = this.key || String.fromCharCode(this.code).toLowerCase()
    } else if (/(click|mouse|menu)/.test(this.type)) {
      this.page = {
        'x': event.pageX || event.clientX + document.documentElement.scrollLeft,
        'y': event.pageY || event.clientY + document.documentElement.scrollTop
      };
      this.client = {
        'x': event.pageX ? event.pageX - window.pageXOffset : event.clientX,
        'y': event.pageY ? event.pageY - window.pageYOffset : event.clientY
      };
      this.rightClick = (event.which == 3) || (event.button == 2);
      switch (this.type) {
        case 'mouseover':
          this.relatedTarget = event.relatedTarget || event.fromElement;
          break;
        case 'mouseout':
          this.relatedTarget = event.relatedTarget || event.toElement
      }
      this.fixRelatedTarget();
    }
    return this;
  },
  stop: function() {
    return this.stopPropagation().preventDefault()
  },
  stopPropagation: function() {
    if (this.event.stopPropagation) this.event.stopPropagation();
    else this.event.cancelBubble = true;
    return this
  },
  preventDefault: function() {
    if (this.event.preventDefault) this.event.preventDefault();
    else this.event.returnValue = false;
    return this
  },
  fixRelatedTarget: (window.gecko) ? ajax.events.Event.fix.relatedTargetGecko : ajax.events.Event.fix.relatedTarget
};

(function() {
    var timer;

    function fireContentLoadedEvent() {
        if (document.$domOnLoadFired) return;
        if (timer) window.clearInterval(timer);
        document.$domOnLoadFired = true;
        document.isDomLoaded = true;
        ajax.events.fire(document, 'dom:onLoad');
    }

    if (document.addEventListener) {
        if (window.webkit) {
            timer = window.setInterval(function() {
                if (/loaded|complete/.test(document.readyState))
                    fireContentLoadedEvent();
            }, 0);

            ajax.events.register(window, 'load', fireContentLoadedEvent, false);
        } else {
            document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
        }
    } else {
        document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
        ajax.$("__onDOMContentLoaded").onreadystatechange = function() {
            if (this.readyState == "complete") {
                this.onreadystatechange = null;
                fireContentLoadedEvent();
            }
        };
    }
})();