
(String.prototype.trim || (String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }));

(Array.prototype.push || (Array.prototype.push = function(x) { this[this.length]=x; return this.length; }) );

(Function.prototype.extend || (Function.prototype.extend = function( superc, overrides) {
    if (!superc)  throw new Error("extend failed, please check that all dependencies are included.");        
    var F = function() {};
    F.prototype=superc.prototype;
    this.prototype=new F();
    this.prototype.constructor=this;
    this.superclass=superc.prototype;
    if (superc.prototype.constructor == Object.prototype.constructor) {
        superc.prototype.constructor=superc;
    }    
    if (overrides) {
        for (var i in overrides) {
            this.prototype[i]=overrides[i];
        }
    }
}));

(Array.prototype.contains || (Array.prototype.contains = function(x) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == x) return true;
	}
	return false;
}
));

(window.$ || (window.$ = function(id) { return (id.nodeName) ? id : document.getElementById(id) } ));

(window.$d || (window.$d = function(d) { return new Date(d) } ));

var Browser = {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
};
if (Browser.IE) {
	Browser.version =parseFloat(navigator.userAgent.split("MSIE")[1]);
} else if (Browser.WebKit) {
	Browser.version =parseFloat(navigator.userAgent.split("WebKit/")[1]);
} else if (Browser.Gecko) {
	Browser.version =parseFloat(navigator.userAgent.split("Gecko/")[1]);
} else if (Browser.Opera) {
	Browser.version =parseFloat(navigator.userAgent.split("Opera/")[1]);
} else {
	Browser.version =parseFloat(navigator.appVersion);
}

function Event(source,type) {
	this.source=source;
	this.type=type;
}

Event.addListener = function(obj,evt,callback,capt) {
 	if (!obj) return;
 	if (obj.addEventListener) obj.addEventListener(evt, callback, capt);
    else if (obj.attachEvent) {
        obj.attachEvent("on"+evt, callback.__wrapper = function() { return callback.call(obj,window.event) } );
    } else {
	 	if (!obj.__listeners) obj.__listeners = {}; 	 
	 	var listeners = obj.__listeners[evt];
	 	if (!listeners) {
	 	   obj.__listeners[evt] = listeners = []; 	 	   	 	   
	 	}
	 	listeners.push(callback);
 	}
};

Event.removeListener = function(obj,evt,callback,capt) {
 	if (obj.removeEventListener) obj.removeEventListener(evt, callback, capt);
 	else if (obj.detachEvent) obj.detachEvent("on"+evt, callback.__wrapper);
 	else {
	 	if (obj.__listeners) {
	 		var listeners = obj.__listeners[evt];
	 		if (listeners) {
	 			for (var i=0;i<listeners.length;i++) {
					if (listeners[i] == callback) {
						listeners[i]=null;
						return;
					}
				}
	 		}
	 	}
 	}
};

Event.fire = function(source,type) {	
 	(new Event(source,type)).fire();	
};

Event.prototype.fire = function() {	
 	if (this.source && this.source.__listeners) {	 		 	
	 	var listeners = this.source.__listeners[this.type];	 	
	 	if (listeners) {
	 		var rebuild = false;
	 		for (var i=0;i<listeners.length;i++) {
				if (listeners[i]!=null) {				
					listeners[i].apply( this.source, [ this ] );
				} else {
					rebuild=true;
				}
			}
			if (rebuild) {
				var newlist =[];
				for (var i=0,len=listeners.length;i<len;i++) {
					if (listeners[i]) newlist.push(listeners[i]);
				}
				listeners=newlist;
			}
			
			
			
	 	} 	
	}	
};

var DOM = {
	ready: false,
	whenReady: function( listener ) {
		if (DOM.ready) listener();
		else {
			var rdy = function() { Event.removeListener(DOM,'ready',rdy); listener();  };
			Event.addListener(DOM,'ready',rdy);
		}		
	}
	
};



(function() {
	var windowLoaded = function() {		
		Event.removeListener(window,'load',windowLoaded);
		if (!DOM.ready) domLoaded();		
	}
	var domContentLoaded = function() {
		Event.removeListener(document,'DOMContentLoaded',domLoaded);
		if (!DOM.ready) domLoaded();
	}
	var domLoaded = function(t) {
		if (!DOM.ready) {
			DOM.ready=true;			
			Event.fire(DOM,'ready');
		}
	}	
	var _dri = null;
	if (Browser.IE) {
		_dri = setInterval(function() {
            var n = document.createElement('p');  
            try {
                // throws an error if doc is not ready
                n.doScroll('left');
                clearInterval(_dri);
                _dri = null;
                domLoaded(true);
                n = null;
            } catch (ex) { 
            	n = null;
            }
        }, 20); 		
		Event.addListener(window,'load',windowLoaded);
	} else if (Browser.WebKit && Browser.version < 525) {
		_dri = setInterval(function() {
                var rs=document.readyState;
                if ("loaded" == rs || "complete" == rs) {
                    clearInterval(_dri);
                    _dri = null;
                    domLoaded();
                }
            }, 20);
        Event.addListener(window,'load',windowLoaded);
	} else {
		Event.addListener(document,'DOMContentLoaded',domContentLoaded);		
	}
})();











