/*
 New BSD License <http://creativecommons.org/licenses/BSD/>
 Public Domain
 @author Benjamin Arthur Lupton <contact@balupton.com>
 @author James Padolsey <https://gist.github.com/527683>
 Public Domain
 @author Benjamin Arthur Lupton <contact@balupton.com>
*/
(function(i,l){i.History=i.History||{};var k=i.console||l,h=i.document,c={},b=i.History,m=i.history;if(typeof b.emulated!=="undefined")throw Error("History.js has already been emulated...");b.init=function(){b.options={hashChangeCheckerDelay:100,busyDelay:250};b.debug=function(){b.debug.enable&&b.log.apply(b,arguments)};b.debug.enable=false;b.log=function(){var a=typeof k!=="undefined",d=h.getElementById("log"),e="\n"+arguments[0]+"\n",f;if(a){f=Array.prototype.slice.call(arguments);e=f.shift();typeof k.debug!==
"undefined"?k.debug.apply(k,[e,f]):k.log.apply(k,[e,f])}f=1;for(n=arguments.length;f<n;++f){var g=arguments[f];if(typeof g==="object"&&typeof JSON!=="undefined")try{g=JSON.stringify(g)}catch(j){}e+="\n"+g+"\n"}if(d){d.value+=e+"\n-----\n";d.scrollTop=d.scrollHeight-d.clientHeight}else a||alert(e);return true};c.getInternetExplorerMajorVersion=function(){return c.getInternetExplorerMajorVersion.cached=typeof c.getInternetExplorerMajorVersion.cached!=="undefined"?c.getInternetExplorerMajorVersion.cached:
function(){for(var a=3,d=h.createElement("div"),e=d.getElementsByTagName("i");d.innerHTML="<\!--[if gt IE "+ ++a+"]><i></i><![endif]--\>",e[0];);return a>4?a:void 0}()};c.isInternetExplorer=function(){return c.isInternetExplorer.cached=typeof c.isInternetExplorer.cached!=="undefined"?c.isInternetExplorer.cached:c.getInternetExplorerMajorVersion()!==0};b.emulated={pushState:!Boolean(i.history&&i.history.pushState&&i.history.replaceState),hashChange:Boolean(!("onhashchange"in i||"onhashchange"in h)||
c.isInternetExplorer()&&c.getInternetExplorerMajorVersion()<8)};c.isEmptyObject=function(a){for(var d in a)if(this.hasOwnProperty(d))return false;return true};c.cloneObject=function(a){if(a){a=JSON.stringify(a);a=JSON.parse(a)}else a={};return a};b.setHash=function(a,d){if(d!==false&&b.busy()){b.debug("History.setHash: we must wait",arguments);b.pushQueue({scope:b,callback:b.setHash,args:arguments,queue:d});return false}var e=c.escapeHash(a);b.debug("History.setHash",this,arguments,"hash:",a,"adjustedHash:",
e,"oldHash:",h.location.hash);b.busy(true);h.location.hash=e;return a};b.getHash=function(){return c.unescapeHash(h.location.hash)};c.escapeHash=function(a){a=c.normalizeHash(a);if(/[^a-zA-Z0-9\/\-\_\%\.]/.test(a))a=escape(a);return a};c.unescapeHash=function(a){a=c.normalizeHash(a);if(/[\%]/.test(a))a=unescape(a);return a};c.normalizeHash=function(a){return a.replace(/[^#]*#/,"").replace(/#.*/,"")};b.extractHashFromUrl=function(a){a=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return a=c.unescapeHash(a)};
b.isTraditionalAnchor=function(a){a=b.extractHashFromUrl(a);return typeof h.getElementById(a)!=="undefined"};b.contractUrl=function(a){a=b.expandUrl(a);var d=h.location.protocol+"//"+(h.location.hostname||h.location.host);if(h.location.port)d+=":"+h.location.port;d+="/";return a=a.replace(d,"/")};b.expandUrl=function(a){a=a||"";if(!/[a-z]+\:\/\//.test(a))if(a.length===0||a.substring(0,1)==="?")a=h.location.href.replace(/[#\?].*/,"")+a;else{var d=h.getElementsByTagName("base"),e=null;e="";if(d.length===
1){e=d[0];e=e.href;if(e[e.length-1]!=="/")e+="/";a=e+a.replace(/^\//,"")}else if(a.substring(0,1)==="."){d=h.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,"");if(d[d.length-1]!=="/")d+="/";a=d+a}else{d=h.location.protocol+"//"+(h.location.hostname||h.location.host);if(h.location.port)d+=":"+h.location.port;d+="/";a=d+a.replace(/^\//,"")}}return a};b.expandState=function(a){a=a||{};a={data:a.data||{},url:b.expandUrl(a.url||""),title:a.title||""};a.data.title=a.data.title||a.title;a.data.url=
a.data.url||a.url;return a};b.createStateObject=function(a,d,e){a={data:a,title:d,url:e};return a=b.expandState(a)};b.expandHash=function(a){var d=null;try{d=JSON.parse(a)}catch(e){var f=/(.*)\/uid=([0-9]+)$/.exec(a);if(f=f?String(f[2]||""):"")d=c.getStateByUid(f)||null;if(!d&&/\//.test(a)){a=b.expandUrl(a);d=b.createStateObject(null,null,a)}}return d=d?b.expandState(d):null};b.contractState=function(a){if(!a)return null;var d=null;if(a=c.cloneObject(a)){a.data=a.data||{};delete a.data.title;delete a.data.url;
if(c.isEmptyObject(a)&&!a.title)d=b.contractUrl(a.url);else{d=JSON.stringify(a);var e;if(typeof c.hashesToUids[d]!=="undefined")e=c.hashesToUids[d];else for(;;){e=String(Math.floor(Math.random()*1E3));if(typeof c.uidsToStates[e]==="undefined")break}c.hashesToUids[d]=e;c.uidsToStates[e]=a;d=b.contractUrl(a.url)+"/uid="+e}}return d};c.uidsToStates={};c.hashesToUids={};c.getStateByUid=function(a){return c.uidsToStates[String(a)]||l};c.statesByUrl={};c.duplicateStateUrls={};c.statesByHash={};c.savedStates=
[];b.getState=function(){return c.getStateByIndex()};b.getStateHash=function(){return b.contractState(b.getState())};c.getStateByUrl=function(a){return c.statesByUrl[a]||l};c.getStateByHash=function(a){return c.statesByHash[a]||l};c.storeState=function(a){var d=b.contractState(a),e=c.getStateByUrl(a.url);if(typeof e!=="undefined")if(b.contractState(e)!==d)c.duplicateStateUrls[a.url]=true;c.statesByUrl[a.url]=c.statesByHash[d]=a;return true};c.isLastState=function(a){a=b.contractState(a);var d=b.getStateHash();
return c.savedStates.length&&a===d};c.saveState=function(a){if(c.isLastState(a))return false;c.savedStates.push(a);return true};c.getStateByIndex=function(a){var d=null;return d=typeof a==="undefined"?c.savedStates[c.savedStates.length-1]:a<0?c.savedStates[c.savedStates.length+a]:c.savedStates[a]};c.stateUrlExists=function(a){return typeof c.statesByUrl[a]!=="undefined"};c.urlDuplicateExists=function(a){return typeof c.duplicateStateUrls[a]!=="undefined"};c.savedHashes=[];c.isLastHash=function(a){var d=
c.getHashByIndex();return a===d};c.saveHash=function(a){if(c.isLastHash(a))return false;c.savedHashes.push(a);return true};c.getHashByIndex=function(a){var d=null;return d=typeof a==="undefined"?c.savedHashes[c.savedHashes.length-1]:a<0?c.savedHashes[c.savedHashes.length+a]:c.savedHashes[a]};c.stateHashExists=function(a){return typeof c.statesByHash[a]!=="undefined"};c.discardedHashes={};c.discardedStates={};c.discardState=function(a,d,e){b.debug("History.discardState",this,arguments);var f=b.contractState(a);
c.discardedStates[f]={discardedState:a,backState:e,forwardState:d};return true};c.discardHash=function(a,d,e){b.debug("History.discardState",this,arguments);c.discardedHashes[a]={discardedHash:a,backState:e,forwardState:d};return true};c.discardedState=function(a){a=b.contractState(a);return c.discardedStates[a]||false};c.discardedHash=function(a){return c.discardedHashes[a]||false};c.recycleState=function(a){b.debug("History.recycleState",this,arguments);var d=b.contractState(a);c.discardedState(a)&&
delete c.discardedStates[d];return true};b.queues=[];b.busy=function(a){b.debug("History.busy: called: changing ["+(b.busy.flag||false)+"] to ["+(a||false)+"]",b.queues);if(typeof a!=="undefined")b.busy.flag=a;else if(typeof b.busy.flag==="undefined")b.busy.flag=false;if(!b.busy.flag){clearTimeout(b.busy.timeout);var d=function(){if(!b.busy.flag)for(var e=b.queues.length-1;e>=0;--e){var f=b.queues[e];if(f.length!==0){f=f.shift();b.debug("History.busy: firing",f);b.fireQueueItem(f);b.busy.timeout=
setTimeout(d,b.options.busyDelay)}}};b.busy.timeout=setTimeout(d,b.options.busyDelay)}return b.busy.flag};b.fireQueueItem=function(a){return a.callback.apply(a.scope||b,a.args||[])};b.pushQueue=function(a){b.debug("History.pushQueue: called",arguments);b.queues[a.queue||0]=b.queues[a.queue||0]||[];b.queues[a.queue||0].push(a);return true};b.queue=function(a,d){if(typeof a==="function")a={callback:a};if(typeof d!=="undefined")a.queue=d;b.busy()?b.pushQueue(a):b.fireQueueItem(a);return true};b.back=
function(a){b.debug("History.back: called",arguments);if(a!==false&&b.busy()){b.debug("History.back: we must wait",arguments);b.pushQueue({scope:b,callback:b.back,args:arguments,queue:a});return false}b.busy(true);if(b.emulated.hashChange&&c.isInternetExplorer()){var d=b.getHash();setTimeout(function(){if(b.getHash()===d){b.debug("History.back: trying again");return b.back(false)}return true},b.options.hashChangeCheckerDelay*5)}m.go(-1);return true};b.forward=function(a){b.debug("History.forward: called",
arguments);if(a!==false&&b.busy()){b.debug("History.forward: we must wait",arguments);b.pushQueue({scope:b,callback:b.forward,args:arguments,queue:a});return false}b.busy(true);if(b.emulated.hashChange&&c.isInternetExplorer()){var d=b.getHash();setTimeout(function(){if(b.getHash()===d){b.debug("History.forward: trying again");return b.forward(false)}return true},b.options.hashChangeCheckerDelay*5)}m.go(1);return true};b.go=function(a,d){b.debug("History.go: called",arguments);if(a>0)for(var e=1;e<=
a;++e)b.forward(d);else if(a<0)for(e=-1;e>=a;--e)b.back(d);else throw Error("History.go: History.go requires a positive or negative integer passed.");return true};if(b.emulated.hashChange)b.Adapter.onDomLoad(function(){c.checkerFunction=null;if(c.isInternetExplorer()){var a=h.createElement("iframe");a.setAttribute("id","historyjs-iframe");a.style.display="none";h.body.appendChild(a);a.contentWindow.document.open();a.contentWindow.document.close();var d=null,e=null,f=false;c.checkerFunction=function(){if(f){b.debug("hashchange.checker: checker is running");
return false}f=true;var g=b.getHash(),j=c.unescapeHash(a.contentWindow.document.location.hash);if(g!==d){d=g;if(j!==g){b.debug("hashchange.checker: iframe hash change","documentHash (new):",g,"iframeHash (old):",j);e=g;a.contentWindow.document.open();a.contentWindow.document.close();a.contentWindow.document.location.hash=c.escapeHash(g)}b.Adapter.trigger(i,"hashchange")}else if(j!==e){b.debug("hashchange.checker: iframe hash out of sync","iframeHash (new):",j,"documentHash (old):",g);e=j;b.setHash(j,
false)}f=false;return true}}else{d=null;c.checkerFunction=function(){var g=b.getHash();if(g!==d){d=g;b.Adapter.trigger(i,"hashchange")}return true}}setInterval(c.checkerFunction,b.options.hashChangeCheckerDelay);return true});if(b.emulated.pushState){c.onHashChange=function(a){b.debug("_History.onHashChange",this,arguments);currentHash=unescape(b.extractHashFromUrl(a&&a.newURL||h.location.href));currentStateHashExits=currentStateHash=currentState=null;if(c.isLastHash(currentHash)){b.debug("_History.onHashChange: no change");
b.busy(false);return false}c.saveHash(currentHash);currentState=b.expandHash(currentHash);if(!currentState){b.debug("_History.onHashChange: traditional anchor");b.Adapter.trigger(i,"anchorchange");b.busy(false);return false}if(c.isLastState(currentState)){b.debug("_History.onHashChange: no change");b.busy(false);return false}currentStateHash=b.contractState(currentState);b.debug("_History.onHashChange: ","currentStateHash",currentStateHash,"Hash -1",c.getHashByIndex(-1),"Hash -2",c.getHashByIndex(-2),
"Hash -3",c.getHashByIndex(-3),"Hash -4",c.getHashByIndex(-4),"Hash -5",c.getHashByIndex(-5),"Hash -6",c.getHashByIndex(-6),"Hash -7",c.getHashByIndex(-7));var d=c.discardedState(currentState);if(d){b.debug("forwardState:",b.contractState(d.forwardState),"backState:",b.contractState(d.backState));if(c.getHashByIndex(-2)===b.contractState(d.forwardState)){b.debug("_History.onHashChange: go backwards");b.back(false)}else{b.debug("_History.onHashChange: go forwards");b.forward(false)}b.busy(false);return false}b.debug("_History.onHashChange: success hashchange");
b.pushState(currentState.data,currentState.title,currentState.url,false);return true};b.Adapter.bind(i,"hashchange",c.onHashChange);b.pushState=function(a,d,e,f){b.debug("History.pushState",this,arguments);if(b.extractHashFromUrl(e))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==false&&b.busy()){b.debug("History.pushState: we must wait",arguments);b.pushQueue({scope:b,callback:b.pushState,args:arguments,queue:f});return false}b.busy(true);var g=
b.createStateObject(a,d,e),j=b.contractState(g);b.getState();var o=b.getStateHash(),p=unescape(b.getHash());c.storeState(g);c.recycleState(g);if(h.title!==g.title){h.title=g.title;try{h.getElementsByTagName("title")[0].innerHTML=g.title}catch(q){}}b.debug("History.pushState: details","newStateHash:",j,"oldStateHash:",o,"html4Hash:",p);if(j===o){b.debug("History.pushState: no change",j);return false}if(j!==p){b.debug("History.pushState: update hash",j);b.setHash(j,false);return false}c.saveState(g);
b.debug("History.pushState: trigger popstate");b.Adapter.trigger(i,"statechange");b.busy(false);return true};b.replaceState=function(a,d,e,f){b.debug("History.replaceState",this,arguments);if(b.extractHashFromUrl(e))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==false&&b.busy()){b.debug("History.replaceState: we must wait",arguments);b.pushQueue({scope:b,callback:b.replaceState,args:arguments,queue:f});return false}b.busy(true);var g=b.createStateObject(a,
d,e),j=b.getState(),o=c.getStateByIndex(-2);c.discardState(j,g,o);b.pushState(g.data,g.title,g.url,false);return true};if(!h.location.hash||h.location.hash==="#")b.Adapter.onDomLoad(function(){b.debug("Internet Explorer Initial State Change Fix");var a=b.createStateObject({},"",h.location.href);b.pushState(a.data,a.title,a.url)});else if(!b.emulated.hashChange){b.debug("Firefox Initial State Change Fix");b.Adapter.onDomLoad(function(){c.onHashChange()})}}else{c.onPopState=function(a){b.debug("_History.onPopState",
this,arguments);var d=unescape(b.getHash());if(d){var e=b.expandHash(d);if(e){b.debug("_History.onPopState: state anchor",d,e);b.replaceState(e.data,e.tite,e.url,false)}else{b.debug("_History.onPopState: traditional anchor",d);b.Adapter.trigger(i,"anchorchange");b.busy(false)}return false}d={};var f=e=null;d=null;a=a||{};if(typeof a.state==="undefined")if(typeof a.originalEvent!=="undefined"&&typeof a.originalEvent.state!=="undefined")a.state=a.originalEvent.state;else if(typeof a.event!=="undefined"&&
typeof a.event.state!=="undefined")a.state=a.event.state;if(a.state===null)d=a.state;else if(typeof a.state!=="undefined"){e=b.expandUrl(h.location.href);d=c.getStateByUrl(e);e=c.urlDuplicateExists(e);d=typeof d!=="undefined"&&!e?d.data:a.state}else{e=b.expandUrl(h.location.href);if((d=c.getStateByUrl(e))&&e==d.url)d=d.data;else throw Error("Unknown state");}d=typeof d!=="object"||d===null?{}:d;e=d.title||"";f=d.url||h.location.href;d=b.createStateObject(d,e,f);if(c.isLastState(d)){b.debug("_History.onPopState: no change",
d,c.savedStates);b.busy(false);return false}b.debug("_History.onPopState","newState:",d,"oldState:",c.getStateByUrl(b.expandUrl(h.location.href)),"duplicateExists:",c.urlDuplicateExists(b.expandUrl(h.location.href)));c.storeState(d);c.saveState(d);if(d.title)h.title=d.title;b.Adapter.trigger(i,"statechange");b.busy(false);return true};b.Adapter.bind(i,"popstate",c.onPopState);b.pushState=function(a,d,e,f){if(b.extractHashFromUrl(e))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");
if(f!==false&&b.busy()){b.debug("History.pushState: we must wait",arguments);b.pushQueue({scope:b,callback:b.pushState,args:arguments,queue:f});return false}b.busy(true);var g=b.createStateObject(a,d,e);c.storeState(g);m.pushState(g.data,g.title,g.url);b.Adapter.trigger(i,"popstate");return true};b.replaceState=function(a,d,e,f){if(b.extractHashFromUrl(e))throw Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==false&&b.busy()){b.debug("History.replaceState: we must wait",
arguments);b.pushQueue({scope:b,callback:b.replaceState,args:arguments,queue:f});return false}b.busy(true);var g=b.createStateObject(a,d,e);c.storeState(g);m.replaceState(g.data,g.title,g.url);b.Adapter.trigger(i,"popstate");return true};if(navigator.vendor==="Apple Computer, Inc."){b.Adapter.onDomLoad(function(){b.debug("Safari Initial State Change Fix");var a=b.createStateObject({},"",h.location.href);b.pushState(a.data,a.title,a.url)});b.Adapter.bind(i,"hashchange",function(){b.Adapter.trigger(i,
"popstate")})}}};typeof b.Adapter!=="undefined"&&b.init()})(window);

