if(!Array.prototype.push)Array.prototype.push=function(){for(var i=0;i<arguments.length;i++)this[this.length]=arguments[i];return this.length;}
Array.prototype.find=function(value,start){start=start||0;for(var i=start;i<this.length;i++)
if(this[i]==value)
return i;return-1;}
Array.prototype.has=function(value){return this.find(value)!==-1;}
function map(list,func){var result=[];func=func||function(v){return v};for(var i=0;i<list.length;i++)result.push(func(list[i],i,list));return result;}
function filter(list,func){var result=[];func=func||function(v){return v};map(list,function(v){if(func(v))result.push(v)});return result;}
function getElem(elem){if(document.getElementById){if(typeof elem=="string"){elem=document.getElementById(elem);if(elem===null)throw'cannot get element: element does not exist';}else if(typeof elem!="object"){throw'cannot get element: invalid datatype';}}else throw'cannot get element: unsupported DOM';return elem;}
function hasClass(elem,className){return getElem(elem).className.split(' ').has(className);}
function getElementsByClass(className,tagName,parentNode){parentNode=!isUndefined(parentNode)?getElem(parentNode):document;if(isUndefined(tagName))tagName='*';return filter(parentNode.getElementsByTagName(tagName),function(elem){return hasClass(elem,className)});}
function listen(event,elem,func){elem=getElem(elem);if(elem.addEventListener)
elem.addEventListener(event,func,false);else if(elem.attachEvent)
elem.attachEvent('on'+event,function(){func(new W3CDOM_Event(elem))});else throw'cannot add event listener';}
function mlisten(event,elem_list,func){map(elem_list,function(elem){listen(event,elem,func)});}
function W3CDOM_Event(currentTarget){this.currentTarget=currentTarget;this.preventDefault=function(){window.event.returnValue=false}
return this;}
function isUndefined(v){var undef;return v===undef;}
