
function $(selector){if(Contract.is_string(selector)){switch(selector[0]){case'#':return document.getElementById(selector.substr(1));break;case'.':var elements=new Array;var body=b();var classname=selector.substr(1);if(Contract.is_not_null(body)){body.each_descendant(function(element){elements.push(element);},function(element){return(element.className==classname);});}
return elements;break;}}
return document.getElementsByTagName(selector);}
function b(){var body=document.getElementsByTagName('body');if(body.length<1)return null;return body[0];}
Object.prototype.extend=function(obj)
{for(i in obj){this[i]=obj[i];}
return this;}
Contract=new Object();Contract.extend({assert:function(truth,description){if(!truth){throw new ContractViolation(description);}},enforce:function(obj,contract){Contract.enforce(contract,Contract.is_function);Contract.assert(contract(obj));return this;},_satisfy_template:function(obj,contracts,truth_evaluation,start_from){Contract.enforce(contracts,Contract.is_array).enforce(truth_evaluation,Contract.is_function).enforce(start_from,Contract.is_boolean);var satisfied=start_from;contracts.each(function(contract){satisfied=truth_evaluation(satisfied,contract(obj));},Contract.is_function);return statisfied;},satisfy_all:function(obj,contracts){return Contract._satisfy_template(obj,contracts,function(a,b){return a&&b},true);},satisfy_one:function(obj,contracts){return Contract._satisfy_template(obj,contracts,function(a,b){return a||b},false);},is_a:function(obj,cons){return(Contract.is_not_null(obj)&&(obj.constructor==cons));},is_string:function(obj){return Contract.is_a(obj,String);},is_array:function(obj){return Contract.is_a(obj,Array);},is_boolean:function(obj){return Contract.is_a(obj,Boolean);},is_object:function(obj){return Contract.is_a(obj,Object);},is_not_null:function(obj){return!(Contract.is_null(obj));},is_null:function(obj){return(null==obj);},is_function:function(obj){return Contract.is_a(obj,Function);},has_property:function(obj,property,contract){if(Contract.is_not_null(obj)){contract=Contract.is_function(contract)?contract:Contract.is_not_null;return contract(obj[property]);}else{return false;}},respond_to:function(obj,property){return Contract.has_property(obj,property,Contract.is_function);},combinator:function(){var contracts=arguments;return function(e){return Contract.satisfy_all(e,contracts);}},brace:function(do_block,final_block){if(!(Contract.is_function(do_block)&&Contract.is_function(final_block)))return null;var retval=null;try{retval=do_block();}catch(e){if(e.constructor!=ContractViolation){throw e;}
retval=e;}
final_block();return retval;}});function ContractViolation(description){this.description="Contract violation";if(Contract.is_not_null(description)){this.description+=": "+description;}
this.shout_out=function(){alert(this.description);}}
Array.prototype.extend({each:function(f,contract){if(Contract.is_function(f)){var enforce_contract=Contract.is_function(contract);for(var i=0;i<this.length;i++){if((!enforce_contract)||(contract(this[i]))){f(this[i],i);}}}
return this;},map:function(f,contract){if(Contract.is_function(f)){var me=this;this.each(function(value,key){me[key]=f(value);},contract);}
return this;},filter:function(contract){if(Contract.is_function(contract)){var new_array=new Array;this.each(function(e){new_array.push(e);},contract);}else{return[];}},remove:function(index){if((this.length-1)>=index)
{return this.splice(index,1);}else{return null;}}});Object.prototype.extend({each:function(f,contract){if(Contract.is_function(f)){var enforce_contract=Contract.is_function(contract);for(member in this){if((!enforce_contract)||(contract(this[member]))){f(this[member],member);}}}
return this;},map:function(f,contract){if(Contract.is_function(f)){var me=this;this.each(function(value,key){me[key]=f(value);},contract);}
return this;}});Element.prototype.extend({each_child:function(f,contract){this.childNodes.each(f,contract);return this;},each_descendant:function(f,contract){if(Contract.is_function(f)){var enforce_contract=Contract.is_function(contract);this.each_child(function(item){if((!enforce_contract)||contract(item)){f(item);}
if(Contract.respond_to(item,"each_descendant")){item.each_descendant(f,contract);}});}
return this;}});Debug=new Object;Debug.extend({consoles:new Array,register_console:function(console){if(-1==Debug.consoles.indexOf(console)){Debug.consoles.push(console);return console;}},unregister_console:function(console){if((idx=Debug.consoles.indexOf(console))>=0){return Debug.consoles.remove(idx);}},print:function(text){Debug.consoles.each(function(console){console.print(text);},function(e){return Contract.respond_to(e,"print");});}});DebugConsole=function(){this.container=document.createElement('div');Debug.register_console(this);this.container.style.position="relative";this.container.style.width="100%";this.container.style.top="0px";this.container.style.left="0px";this.container.style.border="thin red solid";this.container.style.height="150px";this.container.style.overflow="scroll";this.container.style.backgroundColor="#000000";this.container.style.color="#FFFFFF";this.print=function(text){this.container.innerHTML+=text+"<br/>";}
var body=b();if(Contract.is_not_null(body)){if(0!=body.childNodes.length){body.insertBefore(this.container,body.childNodes[0]);}else{body.appendChild(this.container);}}}
