var HistoryManager={options:{observeDelay:100,stateSeparator:";",iframeSrc:"blank.html",onStart:Class.empty,onRegister:Class.empty,onUnregister:Class.empty,onStart:Class.empty,onUpdate:Class.empty,onStateChange:Class.empty,onObserverChange:Class.empty},dataOptions:{skipDefaultMatch:true,defaults:[],regexpParams:""},initialize:function(A){if(this.modules){return this}this.setOptions(A);this.modules=$H({});this.count=history.length;this.states=[];this.states[this.count]=this.getHash();this.state=null;return this},start:function(){this.observe.periodical(this.options.observeDelay,this);this.started=true;this.observe();this.update();this.fireEvent("onStart",[this.state]);return this},register:function(B,G,C,F,E,A){if(!this.modules){this.initialize()}var D=$merge(this.dataOptions,A||{},{defaults:G,onMatch:C,onGenerate:F,regexp:E});D.regexp=D.regexp||B+"-([\\w_-]*)";if(typeof D.regexp=="string"){D.regexp=new RegExp(D.regexp,D.regexpParams)}D.onGenerate=D.onGenerate||function(H){return B+"-"+H[0]};D.values=D.defaults.copy();this.modules.set(B,D);this.fireEvent("onUnregister",[B,D]);return{setValues:function(H){return this.setValues(B,H)}.bind(this),setValue:function(H,I){return this.setValue(B,H,I)}.bind(this),generate:function(H){return this.generate(B,H)}.bind(this),unregister:function(){return this.unregister(B)}.bind(this)}},unregister:function(A){this.fireEvent("onRegister",[A]);this.modules.remove(A)},setValues:function(B,A){var C=this.modules.get(B);if(!C||C.values.isSimilar(A)){return this}C.values=A;this.update();return this},setValue:function(B,A,D){var C=this.modules.get(B);if(!C||C.values[A]==D){return this}C.values[A]=D;this.update();return this},generate:function(B,A){var D=this.modules.get(B);var E=D.values.copy();D.values=A;var C=this.generateState();D.values=E;return"#"+C},observe:function(){if(this.timeout){return }var A=this.getState();if(this.state==A){return }if((window.ie||window.webkit419)&&(this.state!==null)){this.setState(A,true)}else{this.state=A}this.modules.each(function(D,B){var C=A.match(D.regexp);if(C){C.splice(0,1);C.complement(D.defaults);if(!C.isSimilar(D.defaults)){D.values=C}}else{D.values=D.defaults.copy()}D.onMatch(D.values,D.defaults)});this.fireEvent("onStateChange",[A]).fireEvent("onObserverChange",[A])},generateState:function(){var A=[];this.modules.each(function(C,B){if(C.skipDefaultMatch&&C.values.isSimilar(C.defaults)){return }A.push(C.onGenerate(C.values))});return A.join(this.options.stateSeparator)},update:function(){if(!this.started){return this}var A=this.generateState();if((!this.state&&!A)||(this.state==A)){return this}this.setState(A);this.fireEvent("onStateChange",[A]).fireEvent("onUpdate",[A]);return this},observeTimeout:function(){if(this.timeout){this.timeout=$clear(this.timeout)}else{this.timeout=this.observeTimeout.delay(200,this)}},getHash:function(){var A=top.location.href;var B=A.indexOf("#")+1;return(B)?A.substr(B):""},getState:function(){var B=this.getHash();if(this.iframe){var C=this.iframe.contentWindow.document;if(C&&C.body.id=="state"){var A=C.body.innerText;if(this.state==B){return A}this.istateOld=true}else{return this.istate}}if(window.webkit419&&history.length!=this.count){this.count=history.length;return $pick(this.states[this.count-1],B)}return B},setState:function(C,A){C=$pick(C,"");var B=(C==="")?[window.getScrollLeft(),window.getScrollTop()]:false;if(window.webkit419){if(!this.form){this.form=new Element("form",{method:"get"}).injectInside(document.body)}this.count=history.length;this.states[this.count]=C;this.observeTimeout();this.form.setProperty("action","#"+C).submit()}else{top.location.hash=B?"#":C}if(B){window.scrollTo(B[0],B[1])}if(window.ie&&(!A||this.istateOld)){if(!this.iframe){this.iframe=new Element("iframe",{src:this.options.iframeSrc,styles:"visibility: hidden;"}).injectInside(document.body);this.istate=this.state}try{var E=this.iframe.contentWindow.document;E.open();E.write('<html><body id="state">'+C+"</body></html>");E.close();this.istateOld=false}catch(D){}}this.state=C},extend:$extend};HistoryManager.extend(Events.prototype);HistoryManager.extend(Options.prototype);Array.extend({isSimilar:function(A){return(this.toString()==A.toString())},complement:function(C){for(var B=0,A=this.length;B<A;B++){this[B]=$pick(this[B],C[B]||null)}return this}});