hat-trick 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@
6
6
  *
7
7
  * http://www.thecodemine.org
8
8
  *
9
- * Licensed under the MIT licens:
9
+ * Licensed under the MIT license:
10
10
  * http://www.opensource.org/licenses/mit-license.php
11
11
  *
12
12
  */
@@ -23,9 +23,12 @@
23
23
  var formOptionsBeforeSend = this.options.formOptions.beforeSend;
24
24
  var formOptionsBeforeSubmit = this.options.formOptions.beforeSubmit;
25
25
  var formOptionsBeforeSerialize = this.options.formOptions.beforeSerialize;
26
- this.options.formOptions = $.extend(this.options.formOptions,{
27
- success : function(responseText, textStatus, xhr){
28
- if(formOptionsSuccess){
26
+ var $firstStep;
27
+ var stateData = {};
28
+
29
+ this.options.formOptions = $.extend(this.options.formOptions, {
30
+ success : function(responseText, textStatus, xhr) {
31
+ if (formOptionsSuccess) {
29
32
  formOptionsSuccess(responseText, textStatus, xhr);
30
33
  }
31
34
  if(wizard.options.formOptions && wizard.options.formOptions.resetForm || !wizard.options.formOptions){
@@ -67,52 +70,55 @@
67
70
  this.steps = this.element.find(".step").hide();
68
71
 
69
72
  this.firstStep = this.options.firstStep || this.steps.eq(0).attr("id");
70
- this.activatedSteps = [];
73
+
74
+ $firstStep = this._stepElement(this.firstStep);
75
+ stateData["step"] = this.firstStep;
76
+ History.replaceState(stateData, $firstStep.data("page-title"), location.pathname);
77
+
71
78
  this.isLastStep = false;
72
79
  this.previousStep = undefined;
73
80
  this.currentStep = this.firstStep;
74
81
 
75
82
  this._updateButtons();
76
83
 
77
- if(this.options.validationEnabled && jQuery().validate == undefined){
84
+ if (this.options.validationEnabled && jQuery().validate === undefined) {
78
85
  this.options.validationEnabled = false;
79
- if( (window['console'] !== undefined) ){
86
+ if ( (window['console'] !== undefined) ) {
80
87
  console.log("%s", "validationEnabled option set, but the validation plugin is not included");
81
88
  }
82
- }else if(this.options.validationEnabled){
89
+ } else if(this.options.validationEnabled) {
83
90
  this.element.validate(this.options.validationOptions);
84
91
  }
85
- if(this.options.formPluginEnabled && jQuery().ajaxSubmit == undefined){
92
+ if (this.options.formPluginEnabled && jQuery().ajaxSubmit === undefined) {
86
93
  this.options.formPluginEnabled = false;
87
- if( (window['console'] !== undefined) ){
94
+ if ( (window['console'] !== undefined) ) {
88
95
  console.log("%s", "formPluginEnabled option set but the form plugin is not included");
89
96
  }
90
97
  }
91
98
 
92
- if(this.options.disableInputFields == true){
99
+ if (this.options.disableInputFields === true) {
93
100
  $(this.steps).find(":input:not('.wizard-ignore')").attr("disabled","disabled");
94
101
  }
95
102
 
96
- if(this.options.historyEnabled){
97
- History.Adapter.bind(window, 'statechange', function() {
98
- var state;
99
- var step;
100
- state = History.getState();
101
- step = state.data.step;
102
- if(step !== wizard.currentStep){
103
- if(wizard.options.validationEnabled && step === wizard._navigate(wizard.currentStep)){
104
- if(!wizard.element.valid()){
105
- wizard._updateHistory(wizard.currentStep);
106
- wizard.element.validate().focusInvalid();
107
-
108
- return false;
109
- }
103
+ History.Adapter.bind(window, 'statechange', function() {
104
+ var state;
105
+ var step;
106
+ state = History.getState();
107
+ step = state.data.step;
108
+ if (step !== wizard.currentStep) {
109
+ if (wizard.options.validationEnabled && step === wizard._navigate(wizard.currentStep)) {
110
+ if (!wizard.element.valid()) {
111
+ wizard._show(wizard.currentStep);
112
+ wizard.element.validate().focusInvalid();
113
+
114
+ return false;
110
115
  }
111
- if(step !== wizard.currentStep)
112
- wizard._show(step);
113
116
  }
114
- });
115
- }
117
+ if (step !== wizard.currentStep) {
118
+ wizard._show(step);
119
+ }
120
+ }
121
+ });
116
122
 
117
123
  this.element.addClass("ui-formwizard");
118
124
  this.element.find(":input").addClass("ui-wizard-content");
@@ -131,7 +137,11 @@
131
137
  return $(this);
132
138
  },
133
139
 
134
- _updateButtons : function(){
140
+ _stepElement : function(stepId) {
141
+ return $(this.steps.filter("#" + stepId)[0]);
142
+ },
143
+
144
+ _updateButtons : function() {
135
145
  var wizard = this;
136
146
 
137
147
  this.nextButton = this.element.find(this.options.next);
@@ -141,19 +151,11 @@
141
151
  typeof events['click'] === "undefined" ||
142
152
  events['click'].length === 0) {
143
153
  $(this).click(function() {
144
- var nextClickCallbackData = {
145
- "currentStep": wizard.currentStep,
146
- "button": $(this).attr("id")
147
- };
148
- $(wizard.element).trigger('next_click', nextClickCallbackData);
149
- return wizard._next();
154
+ return wizard._next(this);
150
155
  });
151
156
  }
152
157
  });
153
158
 
154
- this.nextButtonInitinalValue = this.nextButton.val();
155
- this.nextButton.val(this.options.textNext);
156
-
157
159
  this.backButton = this.element.find(this.options.back);
158
160
  this.backButton.each(function() {
159
161
  var events = $(this).data('events');
@@ -171,28 +173,48 @@
171
173
  });
172
174
  }
173
175
  });
174
-
175
- this.backButtonInitinalValue = this.backButton.val();
176
- this.backButton.val(this.options.textBack);
177
176
  },
178
177
 
179
- _next : function(){
180
- if(this.options.validationEnabled){
181
- if(!this.element.valid()){
178
+ _next : function(button) {
179
+ var nextClickCallbackData = {
180
+ "currentStep": this.currentStep,
181
+ "button": $(button).attr("id")
182
+ };
183
+ $(this.element).trigger('next_click', nextClickCallbackData);
184
+
185
+ if (this.options.validationEnabled) {
186
+ if (!this.element.valid()) {
182
187
  this.element.validate().focusInvalid();
183
188
  return false;
184
189
  }
185
190
  }
186
191
 
187
- if(this.options.remoteAjax != undefined){
192
+ if (this.options.remoteAjax !== undefined) {
188
193
  var options = this.options.remoteAjax[this.currentStep];
189
194
  var wizard = this;
190
- if(options !== undefined){
195
+ if (options !== undefined) {
191
196
  var success = options.success;
192
197
  var beforeSend = options.beforeSend;
193
198
  var complete = options.complete;
194
199
 
195
- options = $.extend({},options,{
200
+ options = $.extend({}, options, {
201
+ beforeSerialize : function(form, options) {
202
+ var $button;
203
+ var buttonName;
204
+ var buttonValue;
205
+ var buttonData = {};
206
+
207
+ // serialize the button that was clicked into the ajax submission
208
+ $button = $(button);
209
+ buttonName = $button.attr("name");
210
+ buttonValue = $button.val();
211
+ if (buttonName !== undefined && buttonName !== "" && buttonValue !== undefined && buttonValue !== "") {
212
+ buttonData[buttonName] = buttonValue;
213
+ options.data = $.extend({}, options.data, buttonData);
214
+ }
215
+ return true;
216
+ },
217
+
196
218
  beforeSend : function(xhr){
197
219
  wizard._disableNavigation();
198
220
  if(beforeSend !== undefined)
@@ -226,51 +248,74 @@
226
248
  return this._continueToNextStep();
227
249
  },
228
250
 
229
- _back : function(){
230
- if(this.activatedSteps.length > 0){
231
- if(this.options.historyEnabled){
232
- this._updateHistory(this.activatedSteps[this.activatedSteps.length - 2]);
233
- }else{
234
- this._show(this.activatedSteps[this.activatedSteps.length - 2], true);
235
- }
236
- }
251
+ _back : function() {
252
+ History.back();
237
253
  return false;
238
254
  },
239
255
 
240
256
  _continueToNextStep : function(){
241
- if(this.isLastStep){
242
- for(var i = 0; i < this.activatedSteps.length; i++){
243
- this.steps.filter("#" + this.activatedSteps[i]).find(":input").not(".wizard-ignore").removeAttr("disabled");
244
- }
245
- if(!this.options.formPluginEnabled){
246
- return true;
247
- }else{
248
- this._disableNavigation();
249
- this.element.ajaxSubmit(this.options.formOptions);
250
- return false;
251
- }
252
- }
253
-
254
257
  var step = this._navigate(this.currentStep);
255
- if(step == this.currentStep){
258
+ if (step == this.currentStep) {
256
259
  return false;
257
260
  }
258
- if(this.options.historyEnabled){
259
- this._updateHistory(step);
260
- }else{
261
- this._show(step, true);
262
- }
261
+ this._updateHistory(step);
263
262
  return false;
264
263
  },
265
264
 
265
+ _pageTitleForStep : function(step) {
266
+ var $step = this._stepElement(step);
267
+ var title = $step.data("page-title");
268
+ return title;
269
+ },
270
+
266
271
  _updateHistory : function(step) {
267
- var state = {};
268
- var title = $("title").text();
269
- state["step"] = step;
270
- History.pushState(state, title, step);
272
+ var stateData = {};
273
+ var newUrlPath = this._urlPathForStep(step);
274
+ var title = this._pageTitleForStep(step);
275
+
276
+ stateData["step"] = step;
277
+ History.pushState(stateData, title, newUrlPath);
278
+ },
279
+
280
+ _urlPathForStep : function(step) {
281
+ var currentState = History.getState();
282
+ var currentStep = this.currentStep;
283
+ var urlPathComponents;
284
+ var newUrlPathComponents = [];
285
+ var newUrl;
286
+ var i;
287
+ var lastIndex;
288
+
289
+ urlPathComponents = currentState.url.split("/").filter(function(c) {
290
+ return (c !== "");
291
+ });
292
+ urlPathComponents.shift(); // drop first element; the "http(s):"
293
+ urlPathComponents.shift(); // next element is host:port section; drop it
294
+ lastIndex = urlPathComponents.length - 1;
295
+
296
+ for (i=0; i<lastIndex; i++) {
297
+ newUrlPathComponents.push(urlPathComponents[i]);
298
+ }
299
+
300
+ // remove any query params from the end of the URL
301
+ lastPathComponent = urlPathComponents[lastIndex].split("?")[0];
302
+
303
+ if (lastPathComponent !== currentStep) {
304
+ newUrlPathComponents.push(lastPathComponent);
305
+ }
306
+
307
+ newUrlPathComponents.push(step);
308
+ newUrl = "/" + newUrlPathComponents.join("/");
309
+
310
+ return newUrl;
271
311
  },
272
312
 
273
- _disableNavigation : function(){
313
+ _redirect : function(step) {
314
+ var stepUrlPath = this._urlPathForStep(step);
315
+ location.pathname = stepUrlPath;
316
+ },
317
+
318
+ _disableNavigation : function() {
274
319
  this.nextButton.attr("disabled","disabled");
275
320
  this.backButton.attr("disabled","disabled");
276
321
  if(!this.options.disableUIStyles){
@@ -279,19 +324,7 @@
279
324
  }
280
325
  },
281
326
 
282
- _setNavButtonValues : function(){
283
- if(this.isLastStep){
284
- this.nextButton.val(this.options.textSubmit);
285
- }else{
286
- this.nextButton.val(this.options.textNext);
287
- }
288
- },
289
-
290
327
  _enableNavigation : function(){
291
- if(this.nextButton.val() === ""){
292
- this._setNavButtonValues();
293
- }
294
-
295
328
  if($.trim(this.currentStep) !== this.steps.eq(0).attr("id")){
296
329
  this.backButton.removeAttr("disabled");
297
330
  if(!this.options.disableUIStyles){
@@ -314,8 +347,9 @@
314
347
  var wizard = this;
315
348
  old.animate(wizard.options.outAnimation, wizard.options.outDuration, wizard.options.easing, function(){
316
349
  current.animate(wizard.options.inAnimation, wizard.options.inDuration, wizard.options.easing, function(){
317
- if(wizard.options.focusFirstInput)
318
- current.find(":input:first").focus();
350
+ if (wizard.options.focusFirstInput) {
351
+ current.filter("fieldset:not(.no-focus)").find(":input:not(input[type=hidden]):first").focus();
352
+ }
319
353
  wizard._enableNavigation();
320
354
 
321
355
  stepShownCallback.apply(wizard);
@@ -331,28 +365,28 @@
331
365
  }
332
366
  },
333
367
 
334
- _getLink : function(step){
335
- var link = undefined;
368
+ _getLink : function(step) {
369
+ var link;
336
370
  var links = this.steps.filter("#" + step).find(this.options.linkClass);
337
371
 
338
- if(links != undefined){
339
- if(links.filter(":radio,:checkbox").size() > 0){
372
+ if (links !== undefined) {
373
+ if (links.filter(":radio,:checkbox").size() > 0) {
340
374
  link = links.filter(this.options.linkClass + ":checked").val();
341
- }else{
375
+ } else {
342
376
  link = $(links).val();
343
377
  }
344
378
  }
345
379
  return link;
346
380
  },
347
381
 
348
- _navigate : function(step){
382
+ _navigate : function(step) {
349
383
  var link = this._getLink(step);
350
- if(link != undefined){
351
- if((link != "" && link != null && link != undefined) && this.steps.filter("#" + link).attr("id") != undefined){
384
+ if (link !== undefined) {
385
+ if ((link !== "" && link !== null && link !== undefined) && this.steps.filter("#" + link).attr("id") !== undefined) {
352
386
  return link;
353
387
  }
354
388
  return this.currentStep;
355
- }else if(link == undefined && !this.isLastStep){
389
+ } else if (link === undefined && !this.isLastStep) {
356
390
  var step1 = this.steps.filter("#" + step).next().attr("id");
357
391
  return step1;
358
392
  }
@@ -368,54 +402,34 @@
368
402
  }
369
403
  },
370
404
 
371
- _show : function(step){
372
- var backwards = false;
373
- var triggerStepShown = step !== undefined;
405
+ _show : function(step) {
374
406
  var fragment;
375
- if(step == undefined || step == ""){
407
+ if (step === undefined || step === "") {
376
408
  step = this._stepFromPath() || this.firstStep;
377
- this.activatedSteps.pop();
378
- this.activatedSteps.push(step);
379
- }else{
380
- if($.inArray(step, this.activatedSteps) > -1){
381
- backwards = true;
382
- this.activatedSteps.pop();
383
- }else {
384
- this.activatedSteps.push(step);
385
- }
386
409
  }
387
410
 
388
- if(this.currentStep !== step || step === this.firstStep){
411
+ if (this.currentStep !== step || step === this.firstStep) {
389
412
  this.previousStep = this.currentStep;
390
413
  this._checkIflastStep(step);
391
414
  this.currentStep = step;
392
- var stepShownCallback = function(){if(triggerStepShown)$(this.element).trigger('step_shown', $.extend({"isBackNavigation" : backwards},this._state()));};
415
+ var stepShownCallback = function() {
416
+ $(this.element).trigger('step_shown', this._state());
417
+ };
393
418
  this._animate(this.previousStep, step, stepShownCallback);
394
- };
395
-
419
+ }
396
420
 
397
421
  },
398
422
 
399
423
  _reset : function(){
400
- this.element.resetForm()
424
+ this.element.resetForm();
401
425
  $("label,:input,textarea",this).removeClass("error");
402
- for(var i = 0; i < this.activatedSteps.length; i++){
403
- this.steps.filter("#" + this.activatedSteps[i]).hide().find(":input").attr("disabled","disabled");
404
- }
405
- this.activatedSteps = new Array();
406
426
  this.previousStep = undefined;
407
427
  this.isLastStep = false;
408
- if(this.options.historyEnabled){
409
- this._updateHistory(this.firstStep);
410
- }else{
411
- this._show(this.firstStep);
412
- }
413
-
428
+ this._updateHistory(this.firstStep);
414
429
  },
415
430
 
416
- _state : function(state){
431
+ _state : function(state) {
417
432
  var currentState = { "settings" : this.options,
418
- "activatedSteps" : this.activatedSteps,
419
433
  "isLastStep" : this.isLastStep,
420
434
  "isFirstStep" : this.currentStep === this.firstStep,
421
435
  "previousStep" : this.previousStep,
@@ -424,22 +438,23 @@
424
438
  "nextButton" : this.nextButton,
425
439
  "steps" : this.steps,
426
440
  "firstStep" : this.firstStep
427
- }
441
+ };
428
442
 
429
- if(state !== undefined)
443
+ if (state !== undefined) {
430
444
  return currentState[state];
445
+ }
431
446
 
432
447
  return currentState;
433
448
  },
434
449
 
435
450
  /*Methods*/
436
451
 
437
- show : function(step){
438
- if(this.options.historyEnabled){
439
- this._updateHistory(step);
440
- }else{
441
- this._show(step);
442
- }
452
+ show : function(step) {
453
+ this._updateHistory(step);
454
+ },
455
+
456
+ redirect : function(step) {
457
+ this._redirect(step);
443
458
  },
444
459
 
445
460
  state : function(state){
@@ -464,7 +479,6 @@
464
479
  this.backButton.unbind("click").val(this.backButtonInitinalValue).removeClass("ui-state-disabled").addClass("ui-state-active");
465
480
  this.backButtonInitinalValue = undefined;
466
481
  this.nextButtonInitinalValue = undefined;
467
- this.activatedSteps = undefined;
468
482
  this.previousStep = undefined;
469
483
  this.currentStep = undefined;
470
484
  this.isLastStep = undefined;
@@ -489,15 +503,18 @@
489
503
  }
490
504
  },
491
505
 
506
+ update_buttons : function() {
507
+ this._updateButtons();
508
+ },
509
+
492
510
  options: {
493
- historyEnabled : false,
494
511
  validationEnabled : false,
495
512
  validationOptions : undefined,
496
513
  formPluginEnabled : false,
497
514
  linkClass : ".link",
498
515
  submitStepClass : "submit_step",
499
- back : ":reset",
500
- next : ":submit",
516
+ back : "input:reset",
517
+ next : "input:submit",
501
518
  textSubmit : 'Submit',
502
519
  textNext : 'Next',
503
520
  textBack : 'Back',
@@ -1 +1,77 @@
1
- window.JSON||(window.JSON={}),function(){function f(a){return a<10?"0"+a:a}function quote(a){return escapable.lastIndex=0,escapable.test(a)?'"'+a.replace(escapable,function(a){var b=meta[a];return typeof b=="string"?b:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function str(a,b){var c,d,e,f,g=gap,h,i=b[a];i&&typeof i=="object"&&typeof i.toJSON=="function"&&(i=i.toJSON(a)),typeof rep=="function"&&(i=rep.call(b,a,i));switch(typeof i){case"string":return quote(i);case"number":return isFinite(i)?String(i):"null";case"boolean":case"null":return String(i);case"object":if(!i)return"null";gap+=indent,h=[];if(Object.prototype.toString.apply(i)==="[object Array]"){f=i.length;for(c=0;c<f;c+=1)h[c]=str(c,i)||"null";return e=h.length===0?"[]":gap?"[\n"+gap+h.join(",\n"+gap)+"\n"+g+"]":"["+h.join(",")+"]",gap=g,e}if(rep&&typeof rep=="object"){f=rep.length;for(c=0;c<f;c+=1)d=rep[c],typeof d=="string"&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e))}else for(d in i)Object.hasOwnProperty.call(i,d)&&(e=str(d,i),e&&h.push(quote(d)+(gap?": ":":")+e));return e=h.length===0?"{}":gap?"{\n"+gap+h.join(",\n"+gap)+"\n"+g+"}":"{"+h.join(",")+"}",gap=g,e}}"use strict",typeof Date.prototype.toJSON!="function"&&(Date.prototype.toJSON=function(a){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(a){return this.valueOf()});var JSON=window.JSON,cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;typeof JSON.stringify!="function"&&(JSON.stringify=function(a,b,c){var d;gap="",indent="";if(typeof c=="number")for(d=0;d<c;d+=1)indent+=" ";else typeof c=="string"&&(indent=c);rep=b;if(!b||typeof b=="function"||typeof b=="object"&&typeof b.length=="number")return str("",{"":a});throw new Error("JSON.stringify")}),typeof JSON.parse!="function"&&(JSON.parse=function(text,reviver){function walk(a,b){var c,d,e=a[b];if(e&&typeof e=="object")for(c in e)Object.hasOwnProperty.call(e,c)&&(d=walk(e,c),d!==undefined?e[c]=d:delete e[c]);return reviver.call(a,b,e)}var j;text=String(text),cx.lastIndex=0,cx.test(text)&&(text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),typeof reviver=="function"?walk({"":j},""):j;throw new SyntaxError("JSON.parse")})}(),function(a,b){"use strict";var c=a.History=a.History||{},d=a.jQuery;if(typeof c.Adapter!="undefined")throw new Error("History.js Adapter has already been loaded...");c.Adapter={bind:function(a,b,c){d(a).bind(b,c)},trigger:function(a,b,c){d(a).trigger(b,c)},extractEventData:function(a,c,d){var e=c&&c.originalEvent&&c.originalEvent[a]||d&&d[a]||b;return e},onDomLoad:function(a){d(a)}},typeof c.init!="undefined"&&c.init()}(window),function(a,b){"use strict";var c=a.document,d=a.setTimeout||d,e=a.clearTimeout||e,f=a.setInterval||f,g=a.History=a.History||{};if(typeof g.initHtml4!="undefined")throw new Error("History.js HTML4 Support has already been loaded...");g.initHtml4=function(){if(typeof g.initHtml4.initialized!="undefined")return!1;g.initHtml4.initialized=!0,g.enabled=!0,g.savedHashes=[],g.isLastHash=function(a){var b=g.getHashByIndex(),c;return c=a===b,c},g.saveHash=function(a){return g.isLastHash(a)?!1:(g.savedHashes.push(a),!0)},g.getHashByIndex=function(a){var b=null;return typeof a=="undefined"?b=g.savedHashes[g.savedHashes.length-1]:a<0?b=g.savedHashes[g.savedHashes.length+a]:b=g.savedHashes[a],b},g.discardedHashes={},g.discardedStates={},g.discardState=function(a,b,c){var d=g.getHashByState(a),e;return e={discardedState:a,backState:c,forwardState:b},g.discardedStates[d]=e,!0},g.discardHash=function(a,b,c){var d={discardedHash:a,backState:c,forwardState:b};return g.discardedHashes[a]=d,!0},g.discardedState=function(a){var b=g.getHashByState(a),c;return c=g.discardedStates[b]||!1,c},g.discardedHash=function(a){var b=g.discardedHashes[a]||!1;return b},g.recycleState=function(a){var b=g.getHashByState(a);return g.discardedState(a)&&delete g.discardedStates[b],!0},g.emulated.hashChange&&(g.hashChangeInit=function(){g.checkerFunction=null;var b="",d,e,h,i;return g.isInternetExplorer()?(d="historyjs-iframe",e=c.createElement("iframe"),e.setAttribute("id",d),e.style.display="none",c.body.appendChild(e),e.contentWindow.document.open(),e.contentWindow.document.close(),h="",i=!1,g.checkerFunction=function(){if(i)return!1;i=!0;var c=g.getHash()||"",d=g.unescapeHash(e.contentWindow.document.location.hash)||"";return c!==b?(b=c,d!==c&&(h=d=c,e.contentWindow.document.open(),e.contentWindow.document.close(),e.contentWindow.document.location.hash=g.escapeHash(c)),g.Adapter.trigger(a,"hashchange")):d!==h&&(h=d,g.setHash(d,!1)),i=!1,!0}):g.checkerFunction=function(){var c=g.getHash();return c!==b&&(b=c,g.Adapter.trigger(a,"hashchange")),!0},g.intervalList.push(f(g.checkerFunction,g.options.hashChangeInterval)),!0},g.Adapter.onDomLoad(g.hashChangeInit)),g.emulated.pushState&&(g.onHashChange=function(b){var d=b&&b.newURL||c.location.href,e=g.getHashByUrl(d),f=null,h=null,i=null,j;return g.isLastHash(e)?(g.busy(!1),!1):(g.doubleCheckComplete(),g.saveHash(e),e&&g.isTraditionalAnchor(e)?(g.Adapter.trigger(a,"anchorchange"),g.busy(!1),!1):(f=g.extractState(g.getFullUrl(e||c.location.href,!1),!0),g.isLastSavedState(f)?(g.busy(!1),!1):(h=g.getHashByState(f),j=g.discardedState(f),j?(g.getHashByIndex(-2)===g.getHashByState(j.forwardState)?g.back(!1):g.forward(!1),!1):(g.pushState(f.data,f.title,f.url,!1),!0))))},g.Adapter.bind(a,"hashchange",g.onHashChange),g.pushState=function(b,d,e,f){if(g.getHashByUrl(e))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(f!==!1&&g.busy())return g.pushQueue({scope:g,callback:g.pushState,args:arguments,queue:f}),!1;g.busy(!0);var h=g.createStateObject(b,d,e),i=g.getHashByState(h),j=g.getState(!1),k=g.getHashByState(j),l=g.getHash();return g.storeState(h),g.expectedStateId=h.id,g.recycleState(h),g.setTitle(h),i===k?(g.busy(!1),!1):i!==l&&i!==g.getShortUrl(c.location.href)?(g.setHash(i,!1),!1):(g.saveState(h),g.Adapter.trigger(a,"statechange"),g.busy(!1),!0)},g.replaceState=function(a,b,c,d){if(g.getHashByUrl(c))throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(d!==!1&&g.busy())return g.pushQueue({scope:g,callback:g.replaceState,args:arguments,queue:d}),!1;g.busy(!0);var e=g.createStateObject(a,b,c),f=g.getState(!1),h=g.getStateByIndex(-2);return g.discardState(f,e,h),g.pushState(e.data,e.title,e.url,!1),!0}),g.emulated.pushState&&g.getHash()&&!g.emulated.hashChange&&g.Adapter.onDomLoad(function(){g.Adapter.trigger(a,"hashchange")})},typeof g.init!="undefined"&&g.init()}(window),function(a,b){"use strict";var c=a.console||b,d=a.document,e=a.navigator,f=a.sessionStorage||!1,g=a.setTimeout,h=a.clearTimeout,i=a.setInterval,j=a.clearInterval,k=a.JSON,l=a.alert,m=a.History=a.History||{},n=a.history;k.stringify=k.stringify||k.encode,k.parse=k.parse||k.decode;if(typeof m.init!="undefined")throw new Error("History.js Core has already been loaded...");m.init=function(){return typeof m.Adapter=="undefined"?!1:(typeof m.initCore!="undefined"&&m.initCore(),typeof m.initHtml4!="undefined"&&m.initHtml4(),!0)},m.initCore=function(){if(typeof m.initCore.initialized!="undefined")return!1;m.initCore.initialized=!0,m.options=m.options||{},m.options.hashChangeInterval=m.options.hashChangeInterval||100,m.options.safariPollInterval=m.options.safariPollInterval||500,m.options.doubleCheckInterval=m.options.doubleCheckInterval||500,m.options.storeInterval=m.options.storeInterval||1e3,m.options.busyDelay=m.options.busyDelay||250,m.options.debug=m.options.debug||!1,m.options.initialTitle=m.options.initialTitle||d.title,m.intervalList=[],m.clearAllIntervals=function(){var a,b=m.intervalList;if(typeof b!="undefined"&&b!==null){for(a=0;a<b.length;a++)j(b[a]);m.intervalList=null}},m.debug=function(){(m.options.debug||!1)&&m.log.apply(m,arguments)},m.log=function(){var a=typeof c!="undefined"&&typeof c.log!="undefined"&&typeof c.log.apply!="undefined",b=d.getElementById("log"),e,f,g,h,i;a?(h=Array.prototype.slice.call(arguments),e=h.shift(),typeof c.debug!="undefined"?c.debug.apply(c,[e,h]):c.log.apply(c,[e,h])):e="\n"+arguments[0]+"\n";for(f=1,g=arguments.length;f<g;++f){i=arguments[f];if(typeof i=="object"&&typeof k!="undefined")try{i=k.stringify(i)}catch(j){}e+="\n"+i+"\n"}return b?(b.value+=e+"\n-----\n",b.scrollTop=b.scrollHeight-b.clientHeight):a||l(e),!0},m.getInternetExplorerMajorVersion=function(){var a=m.getInternetExplorerMajorVersion.cached=typeof m.getInternetExplorerMajorVersion.cached!="undefined"?m.getInternetExplorerMajorVersion.cached:function(){var a=3,b=d.createElement("div"),c=b.getElementsByTagName("i");while((b.innerHTML="<!--[if gt IE "+ ++a+"]><i></i><![endif]-->")&&c[0]);return a>4?a:!1}();return a},m.isInternetExplorer=function(){var a=m.isInternetExplorer.cached=typeof m.isInternetExplorer.cached!="undefined"?m.isInternetExplorer.cached:Boolean(m.getInternetExplorerMajorVersion());return a},m.emulated={pushState:!Boolean(a.history&&a.history.pushState&&a.history.replaceState&&!/ Mobile\/([1-7][a-z]|(8([abcde]|f(1[0-8]))))/i.test(e.userAgent)&&!/AppleWebKit\/5([0-2]|3[0-2])/i.test(e.userAgent)),hashChange:Boolean(!("onhashchange"in a||"onhashchange"in d)||m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8)},m.enabled=!m.emulated.pushState,m.bugs={setHash:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),safariPoll:Boolean(!m.emulated.pushState&&e.vendor==="Apple Computer, Inc."&&/AppleWebKit\/5([0-2]|3[0-3])/.test(e.userAgent)),ieDoubleCheck:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<8),hashEscape:Boolean(m.isInternetExplorer()&&m.getInternetExplorerMajorVersion()<7)},m.isEmptyObject=function(a){for(var b in a)return!1;return!0},m.cloneObject=function(a){var b,c;return a?(b=k.stringify(a),c=k.parse(b)):c={},c},m.getRootUrl=function(){var a=d.location.protocol+"//"+(d.location.hostname||d.location.host);if(d.location.port||!1)a+=":"+d.location.port;return a+="/",a},m.getBaseHref=function(){var a=d.getElementsByTagName("base"),b=null,c="";return a.length===1&&(b=a[0],c=b.href.replace(/[^\/]+$/,"")),c=c.replace(/\/+$/,""),c&&(c+="/"),c},m.getBaseUrl=function(){var a=m.getBaseHref()||m.getBasePageUrl()||m.getRootUrl();return a},m.getPageUrl=function(){var a=m.getState(!1,!1),b=(a||{}).url||d.location.href,c;return c=b.replace(/\/+$/,"").replace(/[^\/]+$/,function(a,b,c){return/\./.test(a)?a:a+"/"}),c},m.getBasePageUrl=function(){var a=d.location.href.replace(/[#\?].*/,"").replace(/[^\/]+$/,function(a,b,c){return/[^\/]$/.test(a)?"":a}).replace(/\/+$/,"")+"/";return a},m.getFullUrl=function(a,b){var c=a,d=a.substring(0,1);return b=typeof b=="undefined"?!0:b,/[a-z]+\:\/\//.test(a)||(d==="/"?c=m.getRootUrl()+a.replace(/^\/+/,""):d==="#"?c=m.getPageUrl().replace(/#.*/,"")+a:d==="?"?c=m.getPageUrl().replace(/[\?#].*/,"")+a:b?c=m.getBaseUrl()+a.replace(/^(\.\/)+/,""):c=m.getBasePageUrl()+a.replace(/^(\.\/)+/,"")),c.replace(/\#$/,"")},m.getShortUrl=function(a){var b=a,c=m.getBaseUrl(),d=m.getRootUrl();return m.emulated.pushState&&(b=b.replace(c,"")),b=b.replace(d,"/"),m.isTraditionalAnchor(b)&&(b="./"+b),b=b.replace(/^(\.\/)+/g,"./").replace(/\#$/,""),b},m.store={},m.idToState=m.idToState||{},m.stateToId=m.stateToId||{},m.urlToId=m.urlToId||{},m.storedStates=m.storedStates||[],m.savedStates=m.savedStates||[],m.normalizeStore=function(){m.store.idToState=m.store.idToState||{},m.store.urlToId=m.store.urlToId||{},m.store.stateToId=m.store.stateToId||{}},m.getState=function(a,b){typeof a=="undefined"&&(a=!0),typeof b=="undefined"&&(b=!0);var c=m.getLastSavedState();return!c&&b&&(c=m.createStateObject()),a&&(c=m.cloneObject(c),c.url=c.cleanUrl||c.url),c},m.getIdByState=function(a){var b=m.extractId(a.url),c;if(!b){c=m.getStateString(a);if(typeof m.stateToId[c]!="undefined")b=m.stateToId[c];else if(typeof m.store.stateToId[c]!="undefined")b=m.store.stateToId[c];else{for(;;){b=(new Date).getTime()+String(Math.random()).replace(/\D/g,"");if(typeof m.idToState[b]=="undefined"&&typeof m.store.idToState[b]=="undefined")break}m.stateToId[c]=b,m.idToState[b]=a}}return b},m.normalizeState=function(a){var b,c;if(!a||typeof a!="object")a={};if(typeof a.normalized!="undefined")return a;if(!a.data||typeof a.data!="object")a.data={};b={},b.normalized=!0,b.title=a.title||"",b.url=m.getFullUrl(m.unescapeString(a.url||d.location.href)),b.hash=m.getShortUrl(b.url),b.data=m.cloneObject(a.data),b.id=m.getIdByState(b),b.cleanUrl=b.url.replace(/\??\&_suid.*/,""),b.url=b.cleanUrl,c=!m.isEmptyObject(b.data);if(b.title||c)b.hash=m.getShortUrl(b.url).replace(/\??\&_suid.*/,""),/\?/.test(b.hash)||(b.hash+="?"),b.hash+="&_suid="+b.id;return b.hashedUrl=m.getFullUrl(b.hash),(m.emulated.pushState||m.bugs.safariPoll)&&m.hasUrlDuplicate(b)&&(b.url=b.hashedUrl),b},m.createStateObject=function(a,b,c){var d={data:a,title:b,url:c};return d=m.normalizeState(d),d},m.getStateById=function(a){a=String(a);var c=m.idToState[a]||m.store.idToState[a]||b;return c},m.getStateString=function(a){var b,c,d;return b=m.normalizeState(a),c={data:b.data,title:a.title,url:a.url},d=k.stringify(c),d},m.getStateId=function(a){var b,c;return b=m.normalizeState(a),c=b.id,c},m.getHashByState=function(a){var b,c;return b=m.normalizeState(a),c=b.hash,c},m.extractId=function(a){var b,c,d;return c=/(.*)\&_suid=([0-9]+)$/.exec(a),d=c?c[1]||a:a,b=c?String(c[2]||""):"",b||!1},m.isTraditionalAnchor=function(a){var b=!/[\/\?\.]/.test(a);return b},m.extractState=function(a,b){var c=null,d,e;return b=b||!1,d=m.extractId(a),d&&(c=m.getStateById(d)),c||(e=m.getFullUrl(a),d=m.getIdByUrl(e)||!1,d&&(c=m.getStateById(d)),!c&&b&&!m.isTraditionalAnchor(a)&&(c=m.createStateObject(null,null,e))),c},m.getIdByUrl=function(a){var c=m.urlToId[a]||m.store.urlToId[a]||b;return c},m.getLastSavedState=function(){return m.savedStates[m.savedStates.length-1]||b},m.getLastStoredState=function(){return m.storedStates[m.storedStates.length-1]||b},m.hasUrlDuplicate=function(a){var b=!1,c;return c=m.extractState(a.url),b=c&&c.id!==a.id,b},m.storeState=function(a){return m.urlToId[a.url]=a.id,m.storedStates.push(m.cloneObject(a)),a},m.isLastSavedState=function(a){var b=!1,c,d,e;return m.savedStates.length&&(c=a.id,d=m.getLastSavedState(),e=d.id,b=c===e),b},m.saveState=function(a){return m.isLastSavedState(a)?!1:(m.savedStates.push(m.cloneObject(a)),!0)},m.getStateByIndex=function(a){var b=null;return typeof a=="undefined"?b=m.savedStates[m.savedStates.length-1]:a<0?b=m.savedStates[m.savedStates.length+a]:b=m.savedStates[a],b},m.getHash=function(){var a=m.unescapeHash(d.location.hash);return a},m.unescapeString=function(b){var c=b,d;for(;;){d=a.unescape(c);if(d===c)break;c=d}return c},m.unescapeHash=function(a){var b=m.normalizeHash(a);return b=m.unescapeString(b),b},m.normalizeHash=function(a){var b=a.replace(/[^#]*#/,"").replace(/#.*/,"");return b},m.setHash=function(a,b){var c,e,f;return b!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.setHash,args:arguments,queue:b}),!1):(c=m.escapeHash(a),m.busy(!0),e=m.extractState(a,!0),e&&!m.emulated.pushState?m.pushState(e.data,e.title,e.url,!1):d.location.hash!==c&&(m.bugs.setHash?(f=m.getPageUrl(),m.pushState(null,null,f+"#"+c,!1)):d.location.hash=c),m)},m.escapeHash=function(b){var c=m.normalizeHash(b);return c=a.escape(c),m.bugs.hashEscape||(c=c.replace(/\%21/g,"!").replace(/\%26/g,"&").replace(/\%3D/g,"=").replace(/\%3F/g,"?")),c},m.getHashByUrl=function(a){var b=String(a).replace(/([^#]*)#?([^#]*)#?(.*)/,"$2");return b=m.unescapeHash(b),b},m.setTitle=function(a){var b=a.title,c;b||(c=m.getStateByIndex(0),c&&c.url===a.url&&(b=c.title||m.options.initialTitle));try{d.getElementsByTagName("title")[0].innerHTML=b.replace("<","&lt;").replace(">","&gt;").replace(" & "," &amp; ")}catch(e){}return d.title=b,m},m.queues=[],m.busy=function(a){typeof a!="undefined"?m.busy.flag=a:typeof m.busy.flag=="undefined"&&(m.busy.flag=!1);if(!m.busy.flag){h(m.busy.timeout);var b=function(){var a,c,d;if(m.busy.flag)return;for(a=m.queues.length-1;a>=0;--a){c=m.queues[a];if(c.length===0)continue;d=c.shift(),m.fireQueueItem(d),m.busy.timeout=g(b,m.options.busyDelay)}};m.busy.timeout=g(b,m.options.busyDelay)}return m.busy.flag},m.busy.flag=!1,m.fireQueueItem=function(a){return a.callback.apply(a.scope||m,a.args||[])},m.pushQueue=function(a){return m.queues[a.queue||0]=m.queues[a.queue||0]||[],m.queues[a.queue||0].push(a),m},m.queue=function(a,b){return typeof a=="function"&&(a={callback:a}),typeof b!="undefined"&&(a.queue=b),m.busy()?m.pushQueue(a):m.fireQueueItem(a),m},m.clearQueue=function(){return m.busy.flag=!1,m.queues=[],m},m.stateChanged=!1,m.doubleChecker=!1,m.doubleCheckComplete=function(){return m.stateChanged=!0,m.doubleCheckClear(),m},m.doubleCheckClear=function(){return m.doubleChecker&&(h(m.doubleChecker),m.doubleChecker=!1),m},m.doubleCheck=function(a){return m.stateChanged=!1,m.doubleCheckClear(),m.bugs.ieDoubleCheck&&(m.doubleChecker=g(function(){return m.doubleCheckClear(),m.stateChanged||a(),!0},m.options.doubleCheckInterval)),m},m.safariStatePoll=function(){var b=m.extractState(d.location.href),c;if(!m.isLastSavedState(b))c=b;else return;return c||(c=m.createStateObject()),m.Adapter.trigger(a,"popstate"),m},m.back=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.back,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.back(!1)}),n.go(-1),!0)},m.forward=function(a){return a!==!1&&m.busy()?(m.pushQueue({scope:m,callback:m.forward,args:arguments,queue:a}),!1):(m.busy(!0),m.doubleCheck(function(){m.forward(!1)}),n.go(1),!0)},m.go=function(a,b){var c;if(a>0)for(c=1;c<=a;++c)m.forward(b);else{if(!(a<0))throw new Error("History.go: History.go requires a positive or negative integer passed.");for(c=-1;c>=a;--c)m.back(b)}return m};if(m.emulated.pushState){var o=function(){};m.pushState=m.pushState||o,m.replaceState=m.replaceState||o}else m.onPopState=function(b,c){var e=!1,f=!1,g,h;return m.doubleCheckComplete(),g=m.getHash(),g?(h=m.extractState(g||d.location.href,!0),h?m.replaceState(h.data,h.title,h.url,!1):(m.Adapter.trigger(a,"anchorchange"),m.busy(!1)),m.expectedStateId=!1,!1):(e=m.Adapter.extractEventData("state",b,c)||!1,e?f=m.getStateById(e):m.expectedStateId?f=m.getStateById(m.expectedStateId):f=m.extractState(d.location.href),f||(f=m.createStateObject(null,null,d.location.href)),m.expectedStateId=!1,m.isLastSavedState(f)?(m.busy(!1),!1):(m.storeState(f),m.saveState(f),m.setTitle(f),m.Adapter.trigger(a,"statechange"),m.busy(!1),!0))},m.Adapter.bind(a,"popstate",m.onPopState),m.pushState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.pushState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.pushState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0},m.replaceState=function(b,c,d,e){if(m.getHashByUrl(d)&&m.emulated.pushState)throw new Error("History.js does not support states with fragement-identifiers (hashes/anchors).");if(e!==!1&&m.busy())return m.pushQueue({scope:m,callback:m.replaceState,args:arguments,queue:e}),!1;m.busy(!0);var f=m.createStateObject(b,c,d);return m.isLastSavedState(f)?m.busy(!1):(m.storeState(f),m.expectedStateId=f.id,n.replaceState(f.id,f.title,f.url),m.Adapter.trigger(a,"popstate")),!0};if(f){try{m.store=k.parse(f.getItem("History.store"))||{}}catch(p){m.store={}}m.normalizeStore()}else m.store={},m.normalizeStore();m.Adapter.bind(a,"beforeunload",m.clearAllIntervals),m.Adapter.bind(a,"unload",m.clearAllIntervals),m.saveState(m.storeState(m.extractState(d.location.href,!0))),f&&(m.onUnload=function(){var a,b;try{a=k.parse(f.getItem("History.store"))||{}}catch(c){a={}}a.idToState=a.idToState||{},a.urlToId=a.urlToId||{},a.stateToId=a.stateToId||{};for(b in m.idToState){if(!m.idToState.hasOwnProperty(b))continue;a.idToState[b]=m.idToState[b]}for(b in m.urlToId){if(!m.urlToId.hasOwnProperty(b))continue;a.urlToId[b]=m.urlToId[b]}for(b in m.stateToId){if(!m.stateToId.hasOwnProperty(b))continue;a.stateToId[b]=m.stateToId[b]}m.store=a,m.normalizeStore(),f.setItem("History.store",k.stringify(a))},m.intervalList.push(i(m.onUnload,m.options.storeInterval)),m.Adapter.bind(a,"beforeunload",m.onUnload),m.Adapter.bind(a,"unload",m.onUnload));if(!m.emulated.pushState){m.bugs.safariPoll&&m.intervalList.push(i(m.safariStatePoll,m.options.safariPollInterval));if(e.vendor==="Apple Computer, Inc."||(e.appCodeName||"")==="Mozilla")m.Adapter.bind(a,"hashchange",function(){m.Adapter.trigger(a,"popstate")}),m.getHash()&&m.Adapter.onDomLoad(function(){m.Adapter.trigger(a,"hashchange")})}},m.init()}(window)
1
+ /**
2
+ * History.js jQuery Adapter
3
+ * @author Benjamin Arthur Lupton <contact@balupton.com>
4
+ * @copyright 2010-2011 Benjamin Arthur Lupton <contact@balupton.com>
5
+ * @license New BSD License <http://creativecommons.org/licenses/BSD/>
6
+ */
7
+
8
+ // Closure
9
+ (function(window,undefined){
10
+ "use strict";
11
+
12
+ // Localise Globals
13
+ var
14
+ History = window.History = window.History||{},
15
+ jQuery = window.jQuery;
16
+
17
+ // Check Existence
18
+ if ( typeof History.Adapter !== 'undefined' ) {
19
+ throw new Error('History.js Adapter has already been loaded...');
20
+ }
21
+
22
+ // Add the Adapter
23
+ History.Adapter = {
24
+ /**
25
+ * History.Adapter.bind(el,event,callback)
26
+ * @param {Element|string} el
27
+ * @param {string} event - custom and standard events
28
+ * @param {function} callback
29
+ * @return {void}
30
+ */
31
+ bind: function(el,event,callback){
32
+ jQuery(el).bind(event,callback);
33
+ },
34
+
35
+ /**
36
+ * History.Adapter.trigger(el,event)
37
+ * @param {Element|string} el
38
+ * @param {string} event - custom and standard events
39
+ * @param {Object=} extra - a object of extra event data (optional)
40
+ * @return {void}
41
+ */
42
+ trigger: function(el,event,extra){
43
+ jQuery(el).trigger(event,extra);
44
+ },
45
+
46
+ /**
47
+ * History.Adapter.extractEventData(key,event,extra)
48
+ * @param {string} key - key for the event data to extract
49
+ * @param {string} event - custom and standard events
50
+ * @param {Object=} extra - a object of extra event data (optional)
51
+ * @return {mixed}
52
+ */
53
+ extractEventData: function(key,event,extra){
54
+ // jQuery Native then jQuery Custom
55
+ var result = (event && event.originalEvent && event.originalEvent[key]) || (extra && extra[key]) || undefined;
56
+
57
+ // Return
58
+ return result;
59
+ },
60
+
61
+ /**
62
+ * History.Adapter.onDomLoad(callback)
63
+ * @param {function} callback
64
+ * @return {void}
65
+ */
66
+ onDomLoad: function(callback) {
67
+ jQuery(callback);
68
+ }
69
+ };
70
+
71
+ // Try and Initialise History
72
+ if ( typeof History.init !== 'undefined' ) {
73
+ History.init();
74
+ }
75
+
76
+ })(window);
77
+