PageSourceSearch

https://lavida.jp/assets_lvd/menu/js/menu.js

js lavida.jp collected 2026-10-08 04:20:03 UTC 167,591 bytes, 6,168 lines download raw bytes

1(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
2// Easing Vraiety
3// http://gsgd.co.uk/sandbox/jquery/easing/
4
5var Accordion = function(opts){
6  var defaults = {
7    root: document,
8    accordion: '[data-lvdheader-accordion="container"]',
9    item: '[data-lvdheader-accordion="item"]',
10    trigger: '[data-lvdheader-accordion="item"] > a',
11    target: '[data-lvdheader-accordion="content"]',
12    statusClass: 'is-active',
13    duration: 350,
14    easing: 'jswing'
15  };
16  var listenEvents = [
17    'webkitTransitionEnd',
18    'transitionend'
19  ];
20  this.listenEvents = listenEvents.join(' ');
21  this.conf = $.extend({}, defaults, opts);
22}
23
24Accordion.prototype.toggle = function($elem) {
25  var _this = this;
26  var $item = $elem.parents(_this.conf.item);
27  var $target = $item.find(_this.conf.target);
28  if($elem.hasClass(this.conf.statusClass)){
29    $elem.removeClass(this.conf.statusClass);
30    $target.slideUp(this.conf.duration, this.conf.easing, function(){
31      $target.removeClass(_this.conf.statusClass);
32    })
33  } else {
34    $elem.addClass(this.conf.statusClass);
35    $target.slideDown(this.conf.duration, this.conf.easing, function(){
36      $target.addClass(_this.conf.statusClass);
37    })
38  }
39};
40
41Accordion.prototype.init = function() {
42  var _this = this;
43  $(this.conf.root).on('click', this.conf.trigger, function(event) {
44    event.preventDefault();
45    _this.toggle($(this));
46  });
47};
48
49module.exports = Accordion;
50},{}],2:[function(require,module,exports){
51var Ajax = function(api,$appendTarget,query){
52  this.api = api;
53  this.appendTarget = $appendTarget;
54  this.type = 'GET';
55  this.query = query;
56}
57
58// $.Ajax ラッパー関数
59Ajax.prototype.jqXHR = function(){
60  var defer = $.Deferred();
61  $.ajax({
62    url: this.api,
63    type: this.type,
64    dataType: 'json',
65    data: this.query,
66    cache : false,
67    timeout: 8000,
68    success: defer.resolve,
69    error: defer.reject,
70    statusCode: {
71      404: function(){
72        alert('API is not found');
73      }
74    }
75  });
76  return defer.promise();
77}
78
79// Ajax append
80Ajax.prototype.appendCallback = function(callbackFunc) {
81  this.dfdAppend().done(callbackFunc);
82};
83
84Ajax.prototype.appendData = function($elem,returnData){
85  var html = returnData.html;
86  $elem.append(html);
87};
88Ajax.prototype.appendError = function($elem){
89  $elem.append('<p>読み込めませんでした。</p>');
90};
91Ajax.prototype.historyReplace = function(page){
92  // onload 実行時 page: 1 は処理しない
93  var state = new LVD.state();
94  state.replace('page',page);
95};
96
97Ajax.prototype.appendLast = false;
98
99Ajax.prototype.getNum = 0;
100
101Ajax.prototype.appendDone = function(data,dfd){
102  var _this = this;
103  // API status check
104  if(!data.status){
105    console.log(data.errors);
106    dfd.resolve();
107    return;
108  } else {
109
110    // Paginate Last check
111    if( 'meta.last' in data ) {
112      if(data.meta.last) {
113        this.appendLast = true;
114      }
115    }
116
117    // num_item check
118    if( 'meta.num_item' in data ) {
119      if(data.meta.num_item !== undefined){
120        this.getNum = data.meta.num_item;
121      }
122    }
123
124    // img ロード処理後 promiseを返却 TODO:モジュール化するか
125    var html = data.html;
126    var $images = $(html).find('img');
127    var imgLength = $images.length;
128    var completeImageCount = 0;
129    if(!imgLength){
130      this.appendData(this.appendTarget,data);
131      dfd.resolve();
132    } else {
133      var loaded = function(){
134        completeImageCount ++;
135        if (imgLength == completeImageCount){
136          _this.appendData(_this.appendTarget,data);
137          dfd.resolve();
138        }
139      }
140      for(var i = 0; i < imgLength; i++){
141        $($images[i]).on('error load', function() {
142          loaded();
143        });
144      }
145    }
146  }
147}
148Ajax.prototype.dfdAppend = function() {
149  return (function(_this){
150    var dfd = $.Deferred();
151    _this.jqXHR()
152    .then(
153      function(returnData) {
154        _this.appendDone(returnData,dfd);
155      },
156      function() {
157        _this.appendError(_this.appendTarget);
158        console.log('error');
159        dfd.resolve();
160      }
161    );
162    return dfd.promise();
163  })(this);
164};
165
166// Ajax status check
167Ajax.prototype.successBool = false;
168
169Ajax.prototype.dfdStatusCheck = function() {
170  return (function(_this){
171    var dfd = $.Deferred();
172    _this.successBool = false
173    _this.jqXHR()
174    .then(
175      function(returnData) {
176        if(returnData.status){
177          setTimeout(function(){
178            _this.successBool = true;
179            dfd.resolve();
180          }, 500);
181        } else {
182          console.log(returnData.message);
183          _this.successBool = false;
184          dfd.resolve();
185        }
186      },
187      function() {
188        _this.sucess = false;
189        console.log('api error');
190        dfd.resolve();
191      }
192    );
193    return dfd.promise();
194  })(this);
195};
196
197module.exports = Ajax;
198
199},{}],3:[function(require,module,exports){
200var anchorScroll = function(opts){
201  var defaults = {
202    headerFixedClass: 'is-lvd-header-fixed',
203    headerClass: '.lvd-header',
204    commnityHeaderClass: '.lvc-mheader-titlebar',
205    duration: 100
206  }
207  var listenEvents = [
208    'webkitTransitionEnd',
209    'transitionend'
210  ]
211  this.listenEvents = listenEvents.join(' ')
212  this.conf = $.extend({}, defaults, opts)
213
214  var $scrollElement = Modernizr.safari && Modernizr.desktop && $('html').hasClass(this.conf.headerFixedClass) ? $('.lvd-root') : $('body,html')
215  this.scrollElement = $scrollElement
216}
217
218anchorScroll.prototype.headerHeight = function(){
219  var h = 0
220  if ($('html').hasClass(this.conf.headerFixedClass)) {
221    h = $(this.conf.headerClass).height()
222  }
223  if ($(this.conf.commnityHeaderClass).length > 0) {
224    h = $(this.conf.commnityHeaderClass).height()
225  }
226  return h
227}
228
229anchorScroll.prototype.detectPos = function(id){
230  var obj = $('#' + id)
231  if (obj.length > 0){
232    this.scrollElement.animate({
233        scrollTop: $(obj).offset().top - this.headerHeight()
234    }, 500);
235    return false
236  } else {
237    return false
238  }
239}
240
241anchorScroll.prototype.scroll = function(id){
242  this.detectPos(id)
243}
244
245module.exports = anchorScroll
246
247},{}],4:[function(require,module,exports){
248var ClipButton = function(opts){
249  var defaults = {
250    root: document,
251    trigger: '[data-lvdaction="clip"]',
252    propAddApi: 'data-api-add',
253    propDeleteApi: 'data-api-delete',
254    propState: 'data-state',
255    disableClass: 'is-disabled'
256  };
257  this.conf = $.extend({}, defaults, opts);
258  this.init();
259}
260
261// data-state を見て Add かどうかチェックする Add = true, Delete = false
262ClipButton.prototype.checkAdd = function($trigger) {
263  if($trigger.attr(this.conf.propState) == 'active'){
264    return false;
265  } else {
266    return true;
267  }
268};
269
270// 通信ダミー
271ClipButton.prototype.delay = function() {
272  var dfd = $.Deferred();
273  setTimeout(function(){
274    dfd.resolve();
275  }, 500);
276  return dfd.promise();
277};
278
279// remove disableClass
280ClipButton.prototype.removeDisable = function($trigger) {
281  $trigger.removeClass(this.conf.disableClass);
282};
283
284// Request
285ClipButton.prototype.request = function($trigger) {
286  var _this = this;
287  if(this.checkAdd($trigger)){
288    var api = $trigger.attr(this.conf.propAddApi);
289  } else {
290    var api = $trigger.attr(this.conf.propDeleteApi);
291  }
292  var request = new LVD.Ajax(api, null);
293  request.jqXHR().then(
294    function(data){
295      // status check
296      if(data.status) {
297        if(_this.checkAdd($trigger)){
298          $trigger.attr(_this.conf.propState, 'active');
299          _this.removeDisable($trigger);
300        } else {
301          $trigger.attr(_this.conf.propState, '');
302          _this.removeDisable($trigger);
303        }
304      } else {
305        _this.removeDisable($trigger);
306        console.log('clip button status error');
307      }
308    }, function(){
309      _this.removeDisable($trigger);
310      console.log('api error');
311    }
312  );
313};
314
315ClipButton.prototype.init = function() {
316  var _this = this;
317  $(this.conf.root).on('click', this.conf.trigger, function(event) {
318    event.preventDefault();
319    var $this = $(this);
320    if(!$(this).hasClass(_this.conf.disableClass)){
321      $(this).addClass(_this.conf.disableClass);
322      _this.delay().done(function(){
323        _this.request($this);
324      })
325    }
326  });
327};
328
329var clipButton = new ClipButton();
330module.exports = clipButton;
331},{}],5:[function(require,module,exports){
332var Dialog = require('../libs/modal-ajax.coffee');
333var DialogIframe = require('../libs/modal-iframe.coffee');
334
335window.LVD.dialog = {};
336
337// SSO 画像ローディング後遷移
338$('[data-lvdloadimg="target"]').on('load', function() {
339  var href = $(this).attr('data-href');
340  window.parent.location.href = href;
341});
342
343// 汎用Ajaxモーダル
344function setDialog(options){
345  if(!options || !options.target || !options.api){
346    console.log('LVD.dialog: arguments error');
347    return
348  }
349  var dialog = new Dialog(options);
350  dialog.show();
351}
352window.LVD.dialog.set = setDialog;
353
354// H01 ダイアログ
355var login = new Dialog({
356  target: '#lvd-login',
357  trigger: '[data-lvddialog="login"]',
358  ns: 'dialoglogin',
359  api: '/modal/login-form'
360  // api: '/_api/H01-login.json' // テスト用
361});
362window.LVD.dialog.login = function(query){
363  login.conf.query = query ? query : null;
364  login.show();
365}
366
367// H02 ダイアログ
368var createAccount = new Dialog({
369  target: '#lvd-create-account',
370  trigger: '[data-lvddialog="create-account"]',
371  ns: 'dialogcreateAccount',
372  api: '/modal/create-form'
373  // api: '/_api/H02-create-account.json' // テスト用
374});
375window.LVD.dialog.createAccount = function(query){
376  createAccount.conf.query = query ? query : null;
377  createAccount.show();
378}
379
380// H03 ダイアログ
381var addAccountData = new Dialog({
382  target: '#lvd-add-account-data',
383  trigger: '[data-lvddialog="add-accound-data"]',
384  ns: 'dialogAddAccountData',
385  // TODO:APIは差替える必要
386  api: '/_api/H03-add-account-data.json'
387});
388window.LVD.dialog.addAccountData = function(query){
389  addAccountData.conf.query = query ? query : null;
390  addAccountData.show();
391}
392
393// H04 ダイアログ
394var addProfileData = new Dialog({
395  target: '#lvd-add-profile-data',
396  trigger: '[data-lvddialog="add-profile-data"]',
397  ns: 'dialogaddProfileData',
398  // TODO:APIは差替える必要
399  api: '/_api/H04-add-profile-data.json'
400});
401window.LVD.dialog.addProfileData = function(query){
402  addProfileData.conf.query = query ? query : null;
403  addProfileData.show();
404}
405
406// H/B-35 ダイアログ(バッジ)
407var badge = new Dialog({
408  target: '#lvd-badge',
409  trigger: '[data-lvddialog="badge"]',
410  ns: 'dialogaddProfileData',
411  api: '/modal/flash-badge'
412  // api: '/_api/B35-badge.json' // テスト用
413});
414window.LVD.dialog.badge = function(query){
415  badge.conf.query = query ? query : null;
416  badge.show();
417}
418
419// H01 aタグを洗って実行
420var dialogLogin = function(){
421  $("a[href*='/auth/login/']").on('click', function(event){
422    event.preventDefault();
423    var linkArray = $(this).attr('href').split('redir')
424    if (linkArray.length > 1){
425      alert(linkArray[1].substr(1))
426      LVD.dialog.login({redir: linkArray[1].substr(1)})
427      //alert(linkArray[1].substr(1))
428    }
429  })
430}
431//dialogLogin()
432
433
434var dialogIframe = new DialogIframe({
435  trigger: '[data-lvddialogiframe="trigger"]',
436  iframe: '[data-lvddialogiframe="iframe"]',
437  ns: 'lvddialogiframe'
438});
439window.LVD.dialog.iframe = function(selector){
440  dialogIframe.show(selector);
441}
442
443},{"../libs/modal-ajax.coffee":15,"../libs/modal-iframe.coffee":16}],6:[function(require,module,exports){
444var Cookie = require('tiny-cookie');
445
446var FirstLogin = function(opts){
447  var defaults = {
448    cookie: 'firstlogin',
449    target: '[data-lvdheader-modal-channel="recommend"]',
450    excludeClass: '.lvd-func-loading',
451    iconClass: '.lvd-header-icon--h-star',
452    statusClass: 'is-first',
453    reverbClass: 'lvd-firstlogin-animation-reverb',
454    attentionHTMLClass: '.lvd-header-firstlogin__balloon',
455    attentionHTML: '<div class="lvd-header-firstlogin__balloon"><div class="lvd-header-firstlogin__balloon-inner">新しいおすすめがあります。</div></div>',
456    showTimer: 'timerShow',
457    hideTimer: 'timerHide',
458    clickFlag: false
459  };
460  var listenEvents = [
461    'webkitAnimationEnd',
462    'AnimationEnd'
463  ];
464  this.wlHostName = [
465    'lavida.jp',
466    'buzzlife.jp'
467  ];
468  this.wlPathName = [
469    '^/$',
470    '^/sp/my$',
471    '^/sp/my/$',
472    '^/project',
473    '^/sp/project',
474    '^/buzz-it-flow/(.*)/isAdd/1$',
475    '^/sp/buzz-it-flow/(.*)/isAdd/1$'
476  ];
477  this.blPathName = [
478    '^/auth'
479  ];
480  this.listenEvents = listenEvents.join(' ');
481  this.conf = $.extend({}, defaults, opts);
482  // ui.jsから左右のメニューのターゲットを持ってくる
483  // var ui = new LVD.UI();
484  // $.extend(this.conf, ui.conf);
485};
486
487FirstLogin.prototype.init = function() {
488  var _this = this,
489      loginCheck = this.loginCheck(),
490      uriCheck = this.uriCheck();
491  if (uriCheck && loginCheck) {
492    // おすすめをクリックしたらCookie発行
493    $(this.conf.target).on('click', function() {
494      Cookie.set(_this.conf.cookie, true, { expires: '14D' });
495    });
496    if (!Cookie(this.conf.cookie)) {
497      // Cookie.set(this.conf.cookie, true, { expires: '1m' });
498      // レスポンシブのブレイクポイントで処理を変えられるようにしておく
499      if (window.matchMedia('screen and (min-width: 701px)').matches) {
500        this.execute('desktop', 2000, 5750, 2000);
501      } else {
502        this.execute('mobile', 2000, 5750, 2000);
503      };
504      // 途中で「おすすめ」をクリックされたらクリアする
505      $(this.conf.target).on('click', function() {
506        _this.clear();
507      });
508    } else {
509      // Cookieの有効期限更新
510      // Cookie.set(this.conf.cookie, true, { expires: '1m' });
511    };
512  } else {
513    // console.log('NO');
514  };
515};
516
517// ホワイトリストによるチェック
518// FirstLogin.prototype.uriCheck = function() {
519//   var _this = this,
520//       flag = false,
521//       host = location.hostname,
522//       path = location.pathname;
523//   $(this.wlHostName).each(function(i, hostname) {
524//     var regHost = new RegExp(hostname, 'g');
525//     if (regHost.test(host)) {
526//       $(_this.wlPathName).each(function(j, pathname) {
527//         var regPath = new RegExp(pathname, 'g');
528//         if (regPath.test(path)) {
529//           flag = true;
530//           return false;
531//         }
532//       });
533//       return false;
534//     };
535//   });
536//   return flag;
537// };
538
539// ブラックリストによるチェック(パスのみ)
540FirstLogin.prototype.uriCheck = function() {
541  var _this = this,
542      flag = true,
543      path = location.pathname;
544  $(_this.blPathName).each(function(j, pathname) {
545    var regPath = new RegExp(pathname, 'g');
546    if (regPath.test(path)) {
547      flag = false;
548      return false;
549    }
550  });
551  return flag;
552};
553
554FirstLogin.prototype.loginCheck = function() {
555  if ($(this.conf.target).length > 0 && $(this.conf.excludeClass).length === 0) {
556    return true;
557  } else {
558    return false;
559  };
560};
561
562FirstLogin.prototype.execute = function(env, start, end, reverb) {
563  var _this = this,
564      currentQs = LVD.qs.parse(window.location.search.slice(1));
565  this.currentNav = currentQs.nav;
566  if (this.currentNav !== 'recommend') {
567    this.conf.showTimer = setTimeout(function() {
568      // if (env === 'desktop') {
569      //   _this.targetTriggerClick();
570      // };
571      _this.show();
572    }, start);
573    this.conf.hideTimer = setTimeout(function() {
574      // if (env === 'desktop') {
575      //   _this.restoreMenu();
576      // };
577      _this.hide(reverb);
578    }, end);
579  };
580};
581
582FirstLogin.prototype.show = function() {
583  $(this.conf.target).append(this.conf.attentionHTML);
584  // $(this.conf.attentionHTMLClass).fadeIn('ease-in');
585  //$(this.conf.attentionHTMLClass).show();
586  $(this.conf.iconClass).addClass(this.conf.statusClass);
587};
588
589FirstLogin.prototype.hide = function(reverb) {
590  var _this = this;
591  var timer = setTimeout(function() {
592    $(_this.conf.attentionHTMLClass).addClass(_this.conf.reverbClass);
593    $('.' + _this.conf.reverbClass).on(_this.listenEvents, function() {
594      $('.' + _this.conf.reverbClass).remove();
595    });
596  }, reverb);
597  $(this.conf.iconClass).removeClass(this.conf.statusClass);
598};
599
600// おすすめメニューを出す
601FirstLogin.prototype.targetTriggerClick = function() {
602  this.conf.clickFlag = true;
603  $(this.conf.target).trigger('click').append(this.conf.attentionHTML);
604};
605
606// メニューを元に戻す
607FirstLogin.prototype.restoreMenu = function() {
608  this.conf.clickFlag = false;
609  if (this.currentNav) {
610    if (this.currentNav === 'user') {
611      $(this.conf.userTrigger).trigger('click');
612    } else
613    if (this.currentNav === 'main') {
614      $(this.conf.mainTrigger).trigger('click');
615    } else {
616      $('[data-lvdheader-modal-channel="' + this.currentNav + '"]').trigger('click');
617    };
618  } else {
619    $(this.conf.target).trigger('click');
620  };
621};
622
623FirstLogin.prototype.clear = function() {
624  clearTimeout(this.conf.showTimer);
625  if (!this.conf.clickFlag) {
626    clearTimeout(this.conf.hideTimer);
627  };
628  this.hide();
629};
630
631var firstLogin = new FirstLogin();
632firstLogin.init();
633module.exports = firstLogin;
634
635},{"tiny-cookie":32}],7:[function(require,module,exports){
636var NavModal = function(opts){
637  var defaults = {
638    root: document,
639    trigger: null,
640    commonTrigger: '[data-lvdheader-modal="trigger"]',
641    statusClass: 'is-active',
642    header: '.lvd-header',
643    statusHeaderClass: 'is-active--nav',
644    loadedAttr: 'data-load',
645    notifyBadgeClass: null,
646    uiFiClass: 'ui-fade-in',
647    uiFoClass: 'ui-fade-out',
648    duration: 100,
649    routePath: null
650  };
651  var listenEvents = [
652    'webkitTransitionEnd',
653    'transitionend'
654  ];
655  this.listenEvents = listenEvents.join(' ');
656  this.conf = $.extend({}, defaults, opts);
657  this.target = $(this.conf.trigger).data('target');
658  this.api = $(this.conf.trigger).data('api');
659  this.loading = false; // APIレスポンス待ちフラグ
660};
661
662NavModal.prototype.hide = function($trigger,$target) {
663  var _this = this;
664  // スタティックヘッダのためのスクロールロック
665  if(!$('html').hasClass('is-lvd-header-fixed')){
666    $('html').removeClass('is-lvd-header-active--nav');
667  }
668  $(this.conf.header).removeClass(this.conf.statusHeaderClass);
669  $trigger.removeClass(this.conf.statusClass);
670  $target
671  .removeClass(this.conf.uiFiClass)
672  .on(this.listenEvents, function() {
673    $target.removeClass(_this.conf.statusClass)
674  });
675};
676
677NavModal.prototype.addClass = function() {
678  var _this = this;
679  $(this.conf.header).addClass(this.conf.statusHeaderClass);
680  $(this.conf.trigger).addClass(this.conf.statusClass);
681  $(this.target).addClass(this.conf.statusClass);
682  setTimeout(function(){
683    $(_this.target).addClass(_this.conf.uiFiClass);
684  }, this.conf.duration);
685};
686
687NavModal.prototype.show = function() {
688  var _this = this;
689  if(!$(this.conf.trigger).hasClass(this.conf.statusClass)){
690    this.activeHide();
691    // スタティックヘッダのためのスクロールロック
692    if(!$('html').hasClass('is-lvd-header-fixed')){
693      $('html').addClass('is-lvd-header-active--nav');
694    }
695    $(this.target).off(this.listenEvents);
696    var loadedStatus = $(this.target).attr(this.conf.loadedAttr);
697    if( loadedStatus == 'false' ){
698      // レスポンス待ちならなにもせず
699      if(_this.loading){
700        return
701      }
702      _this.loading = true;
703      new LVD.Ajax(
704        _this.api,
705        $(_this.target)
706      ).appendCallback(function(){
707        _this.addClass();
708        $(_this.target).attr(_this.conf.loadedAttr, true);
709        _this.loading = false;
710        // お気に入りのみスクロールロードbindを実行
711        if($(_this.target).attr('data-lvdload-scroll') == 'trigger') {
712          var $activeTab = $(_this.target).find('[data-lvdheader-tab="item"].is-active');
713          LVD.htab.tabloadBind($activeTab);
714        }
715      });
716    } else {
717      this.addClass()
718    }
719  }
720};
721
722NavModal.prototype.activeHide = function() {
723  if($(this.conf.commonTrigger).hasClass(this.conf.statusClass)){
724    // スタティックヘッダのためのスクロールロック
725    if(!$('html').hasClass('is-lvd-header-fixed')){
726      $('html').removeClass('is-lvd-header-active--nav');
727    }
728    var $target = $($(this.conf.commonTrigger+'.'+this.conf.statusClass).data('target'));
729    $(this.conf.header).removeClass(this.conf.statusHeaderClass);
730    this.hide($(this.conf.commonTrigger),$target);
731  }
732};
733
734NavModal.prototype.toggle = function($elem) {
735  var $target = $($elem.data('target'));
736  var state = new LVD.state();
737  if(
738    $elem.hasClass(this.conf.statusClass)
739  ) {
740    this.hide($elem,$target);
741    state.remove('nav');
742    state.replace(state.query);
743  } else {
744    LVD.Header.navHidden();
745    this.show();
746    state.replace('nav',this.conf.routePath);
747  }
748};
749
750NavModal.prototype.init = function(){
751  var _this = this;
752  $(this.conf.root).on('click', this.conf.trigger, function(){
753    _this.toggle($(this));
754  });
755};
756
757module.exports = NavModal;
758
759},{}],8:[function(require,module,exports){
760var $scrollWrapper, $scrollElem;
761
762if($('html').hasClass('is-lvd-header-fixed')){
763  $scrollWrapper = $('.lvd-root');
764  $scrollElement = $('.lvd-root');
765  if($('#planet').length > 0) {
766    $scrollWrapper = $(window);
767    $scrollElement = $('body,html');
768  }
769} else {
770  $scrollWrapper = $(window);
771  $scrollElement = $('body,html');
772}
773
774//pagetop
775function scrollDisplay($elem,pos){
776  var winHeight = $scrollWrapper.outerHeight();
777  if(pos > winHeight*2){
778    $elem.addClass('ui-fade-in');
779  } else {
780    $elem.removeClass('ui-fade-in');
781  }
782}
783// scrolltop bind
784$(document).on('click', '.lvd-footer-pagetop', function(event) {
785  event.preventDefault();
786  $scrollElement.animate({
787      scrollTop: 0
788  }, 500);
789  return false;
790});
791
792// addEvent
793$scrollWrapper.on({
794  // onScroll
795  scroll: function(){
796    var scrollpos = $scrollWrapper.scrollTop();
797    // pagetop Fade
798    scrollDisplay($('.lvd-footer-pagetop'),scrollpos);
799  }
800});
801
802},{}],9:[function(require,module,exports){
803var location = window.location.pathname;
804
805LVD.router.base(location);
806LVD.router('*', parse);
807LVD.router('/', show);
808LVD.router();
809
810// UI Wrapper Function
811function headerNavReset(){
812  LVD.Header.resetMainNav();
813  LVD.Header.resetUserNav();
814}
815function tabReset(ctx){
816  // global
817  if(!ctx.query.tab && LVD.main){
818    LVD.tab.showFirstTab();
819  }
820  // menu
821  if(!ctx.query.htab){
822    setTimeout(function(){
823      LVD.htab.showFirstTab();
824    }, 300);
825  }
826}
827
828function modalHide(){
829  if(LVD.modal && LVD.main){
830    LVD.modal.hide();
831    LVD.alert.hide();
832  }
833}
834
835// Routing Query Parse
836function parse(ctx, next) {
837  ctx.query = LVD.qs.parse(ctx.querystring);
838  next();
839}
840
841// Routing UI Function
842function show(ctx, next) {
843  if (Object.keys(ctx.query).length > 0) {
844
845    // タブ routing
846    // global
847    if(ctx.query.tab && LVD.main){
848      LVD.tab.show('#'+ctx.query.tab);
849    }
850    // menu
851    if(ctx.query.htab && LVD.main){
852      setTimeout(function(){
853        LVD.htab.show('#'+ctx.query.htab);
854      }, 50);
855    }
856
857    // ヘッダナビゲーション routing
858    if(ctx.query.nav){
859      if(ctx.query.nav == 'main'){
860        modalHide();
861        LVD.Header.showMainNav();
862      }
863      if(ctx.query.nav == 'user'){
864        modalHide();
865        LVD.Header.showUserNav();
866      }
867      if(ctx.query.nav == 'recommend'){
868        modalHide();
869        headerNavReset();
870        LVD.Header.Recommend.show();
871      }
872      if(ctx.query.nav == 'favorite'){
873        modalHide();
874        headerNavReset();
875        LVD.Header.Favorite.show();
876      }
877      if(ctx.query.nav == 'notify'){
878        modalHide();
879        headerNavReset();
880        LVD.Header.Notify.show();
881      }
882      // ヘッダナビゲーションとタブの共存
883      tabReset(ctx);
884    }
885
886    // モーダル routing
887    else if(ctx.query.modal && LVD.main){
888      LVD.modal.show('#'+ctx.query.modal);
889    }
890
891    else {
892      headerNavReset();
893      LVD.Header.Modal.activeHide();
894      tabReset(ctx);
895      modalHide();
896    }
897
898    // ページ内アンカー routing
899    if(ctx.query.anc_id && ctx.query.id){
900      LVD.anchor.scroll(ctx.query.anc_id)
901    } else {
902      if(ctx.query.anc_id){
903        LVD.anchor.scroll(ctx.query.anc_id)
904      }
905      if(ctx.query.id){
906        LVD.anchor.scroll(ctx.query.id)
907      }
908    }
909
910  } else {
911    headerNavReset();
912    LVD.Header.Modal.activeHide();
913    // global
914    if(LVD.main){
915      LVD.tab.showFirstTab();
916    }
917    // menu
918    LVD.htab.showFirstTab();
919    modalHide();
920  }
921  next();
922}
923
924},{}],10:[function(require,module,exports){
925var ScrollLoad = function (opts){
926  var defaults = {
927    root: document,
928    trigger: '[data-lvdload-scroll="trigger"]',
929    target: '[data-lvdload-scroll="target"]',
930    loadingContainerId: 'lvd-page-load-container',
931    loadingAnimationId: 'lvd-page-load-animation',
932    loadedStatus: 'is-loaded',
933    loadingStatus: 'is-loading',
934    uiFiClass: 'fx-in',
935    uiClass: 'fx-fade',
936    api: 'data-api',
937    page: 'data-page',
938    duration: 100
939  };
940  var listenEvents = [
941    'webkitTransitionEnd',
942    'transitionend'
943  ];
944  this.listenEvents = listenEvents.join(' ');
945  this.conf = $.extend({}, defaults, opts);
946  this.elemLoadContainer = '<div class="'+this.conf.uiClass+'" id="'+this.conf.loadingContainerId+'"/>';
947  this.loadingAnimation = '<div title="読込中" class="lvd-func-loading--scroll" id="'+this.conf.loadingAnimationId+'"><div class="lvd-func-loading__spinner"></div></div>';
948  this.init();
949}
950
951ScrollLoad.prototype.paginate = function($elem) {
952  return (function(_this){
953    var target = $elem.data('target');
954    var dfd = $.Deferred();
955    var page = $elem.attr(_this.conf.page) ? 'page='+$elem.attr(_this.conf.page) : '';
956    var pageNum = $elem.attr(_this.conf.page);
957    var api = $elem.attr(_this.conf.api);
958    var pipe = $elem.attr(_this.conf.api).indexOf('?') > 0 ? '&':'?';
959    var request = api + pipe + page;
960
961    $(target).append(_this.loadingAnimation);
962    $(target).append(_this.elemLoadContainer);
963    var ajax = new LVD.Ajax(
964      request,
965      $('#'+_this.conf.loadingContainerId)
966    )
967    // 擬似ローディング遅延
968    setTimeout(function(){
969      ajax.appendCallback(function(){
970        $('#'+_this.conf.loadingAnimationId).remove();
971        $('#'+_this.conf.loadingContainerId)
972          .addClass(_this.conf.uiFiClass)
973          .on(_this.listenEvents, function() {
974            $('#'+_this.conf.loadingContainerId).replaceWith(function(){
975              if(!ajax.appendLast){
976                $elem.attr(_this.conf.page, +pageNum+1);
977                _this.bind($elem);
978              } else {
979                $elem.attr(_this.conf.page, 0);
980              }
981              dfd.resolve();
982              return this.childNodes;
983            })
984          });
985      });
986    }, 750);
987    return dfd.promise();
988  })(this);
989};
990
991ScrollLoad.prototype.paginateInTab = function($elem) {
992  return (function(_this){
993    var dfd = $.Deferred();
994    var $activeTab = $elem.find('[data-lvdheader-tab="item"].is-active');
995    var target = $activeTab.data('target');
996    var page = $activeTab.attr(_this.conf.page) ? 'page='+$activeTab.attr(_this.conf.page) : '';
997    var pageNum = $activeTab.attr(_this.conf.page);
998    var api = $activeTab.attr(_this.conf.api);
999    var pipe = $activeTab.attr(_this.conf.api).indexOf('?') > 0 ? '&':'?';
1000    var request = api + pipe + page;
1001
1002    $(target).append(_this.loadingAnimation);
1003    $(target).append(_this.elemLoadContainer);
1004    var ajax = new LVD.Ajax(
1005      request,
1006      $('#'+_this.conf.loadingContainerId)
1007    )
1008    // 擬似ローディング遅延
1009    setTimeout(function(){
1010      ajax.appendCallback(function(){
1011        $('#'+_this.conf.loadingAnimationId).remove();
1012        $('#'+_this.conf.loadingContainerId)
1013          .addClass(_this.conf.uiFiClass)
1014          .on(_this.listenEvents, function() {
1015            $('#'+_this.conf.loadingContainerId).replaceWith(function(){
1016              if(!ajax.appendLast){
1017                $activeTab.attr(_this.conf.page, +pageNum+1);
1018                _this.bind($elem);
1019              } else {
1020                $activeTab.attr(_this.conf.page, 0);
1021              }
1022              dfd.resolve();
1023              return this.childNodes;
1024            })
1025          });
1026      });
1027    }, 750);
1028    return dfd.promise();
1029  })(this);
1030};
1031
1032ScrollLoad.prototype.checkStatus = function($elem){
1033  if($elem.attr(this.conf.page) != undefined){
1034    if($elem.attr(this.conf.page) != '0' ){
1035      return true;
1036    } else {
1037      return false;
1038    }
1039  } else {
1040    var $activeTab = $elem.find('[data-lvdheader-tab="item"].is-active');
1041    if($activeTab.attr(this.conf.page) != '0' ){
1042      return true;
1043    } else {
1044      return false;
1045    }
1046  }
1047}
1048
1049ScrollLoad.prototype.done = function($elem){
1050  var _this = this;
1051  if($elem.attr(this.conf.api) != undefined) {
1052    this.paginate($elem);
1053  } else {
1054    this.paginateInTab($elem);
1055  }
1056
1057  //.done(function(){}) callback 担保
1058}
1059
1060ScrollLoad.prototype.bind = function($elem) {
1061  var _this = this;
1062  if( _this.checkStatus($elem) ) {
1063    $elem.on('scroll', function(event) {
1064      var elem = $(this).get(0);
1065      var height = elem.offsetHeight;
1066      // 要素のスクロール分を含めた高さを取得
1067      var scrollHeight = elem.scrollHeight - 1;
1068      // 要素のスクロール位置を取得
1069      var scrollTop = elem.scrollTop;
1070      // 現在の表示位置の高さ
1071      var scrollPosition = height + scrollTop;
1072      // どれだけ近づいたかを判断する値
1073      // 0に近いほど、スクロールの最終が近い
1074      var proximity = 0;
1075
1076      // console.log('-----------');
1077      // console.log('height : '+height);
1078      // console.log('scrollHeight : '+scrollHeight);
1079      // console.log('scrollTop : '+scrollTop);
1080      // console.log('scrollPosition : '+scrollPosition);
1081
1082      if ((scrollHeight - scrollPosition) / scrollHeight <= proximity) {
1083        // console.log(scrollPosition);
1084        // console.log('end!');
1085        // 一度イベントを破棄
1086        $elem.off('scroll');
1087        _this.done($(elem));
1088      }
1089    });
1090  }
1091};
1092ScrollLoad.prototype.unbind = function($elem) {
1093  $elem.off('scroll');
1094}
1095
1096ScrollLoad.prototype.init = function() {
1097  var _this = this;
1098  $(this.conf.trigger).each(function(index, elem) {
1099    _this.bind($(elem));
1100  });
1101};
1102
1103var scrollLoad = new ScrollLoad();
1104window.LVD.ScrollLoad = scrollLoad;
1105
1106},{}],11:[function(require,module,exports){
1107// Init
1108$('[data-lvdautocomplete="remove"]').addClass('fx-fade');
1109$('.lvd-top-main__search-note').addClass('fx-fade');
1110
1111// 検索コンポーネント スクリプト
1112var searchFields = [
1113  $('.lvd-search-form__field > input'),
1114  $('.lvd-header-main__search-field'),
1115  $('.lvd-top-main__input')
1116];
1117
1118searchFields.map(addClassSearchField);
1119searchFields.map(function(elem) {
1120  $(elem).on('blur', function() {
1121    addClassSearchField($(this));
1122  });
1123  $(elem).on('focus keyup', function() {
1124    addRemoveElement($(this))
1125  });
1126});
1127
1128$('[data-lvdautocomplete="remove"]').on('click', function() {
1129  var $field = $(this).prev('input');
1130  $field.val('');
1131  $field.focus();
1132  $(this).removeClass('fx-in');
1133  $('.lvd-top-main__search-note').removeClass('fx-in')
1134});
1135
1136function addClassSearchField($field){
1137  if($field.val()){
1138    $field.addClass('is-inputin')
1139  } else {
1140    $field.removeClass('is-inputin')
1141  }
1142}
1143
1144function addRemoveElement($field){
1145  if($field.val()){
1146    $field.next('[data-lvdautocomplete="remove"]').addClass('fx-in')
1147    $('.lvd-top-main__search-note').addClass('fx-in')
1148  } else {
1149    $field.next('[data-lvdautocomplete="remove"]').removeClass('fx-in')
1150    $('.lvd-top-main__search-note').removeClass('fx-in')
1151  }
1152}
1153
1154
1155},{}],12:[function(require,module,exports){
1156var Tab = function(opts){
1157  var defaults = {
1158    root: document,
1159    tab: '[data-lvdheader-tab="container"]',
1160    nav: '[data-lvdheader-tab="nav"]',
1161    trigger: '[data-lvdheader-tab="link"]',
1162    contents: '[data-lvdheader-tab="contents"]',
1163    item: '[data-lvdheader-tab="item"]',
1164    statusClass: 'is-active',
1165    // commonTrigger: null,
1166    // loadedAttr: 'data-load',
1167    // notifyBadgeClass: null,
1168    uiFiClass: 'ui-fade-in',
1169    uiFoClass: 'ui-fade-out',
1170    duration: 100
1171  };
1172  var listenEvents = [
1173    'webkitTransitionEnd',
1174    'transitionend'
1175  ];
1176  this.listenEvents = listenEvents.join(' ');
1177  this.conf = $.extend({}, defaults, opts);
1178};
1179
1180Tab.prototype.tabloadBind = function($target) {
1181  if( $target.attr('data-page') != '0' ){
1182    LVD.ScrollLoad.bind($('#lvd-header-favorite'));
1183  } else {
1184    LVD.ScrollLoad.unbind($('#lvd-header-favorite'));
1185  }
1186};
1187
1188Tab.prototype.addClass = function($trigger) {
1189  var $target = $($trigger.attr('href'));
1190  var addQuery = $trigger.attr('href').split('#')[1];
1191  var query = LVD.qs.parse( window.location.search.slice(1) );
1192  var _this = this;
1193  $trigger.addClass(this.conf.statusClass);
1194  $target.addClass(this.conf.statusClass);
1195  setTimeout(function(){
1196    $target.addClass(_this.conf.uiFiClass);
1197    // state control
1198    var state = new LVD.state()
1199    if(query.htab != addQuery){
1200      state.replace('htab',addQuery)
1201    }
1202    // scroll load bind
1203    _this.tabloadBind($target);
1204  }, this.conf.duration);
1205};
1206
1207Tab.prototype.removeClass = function($trigger) {
1208  var _this = this;
1209  var $target = $($trigger.attr('href'));
1210  var $triggers = $trigger.closest(this.conf.nav).find(this.conf.trigger);
1211  $triggers.removeClass(this.conf.statusClass);
1212  $(this.conf.item).removeClass(this.conf.uiFiClass+' '+this.conf.statusClass);
1213};
1214
1215Tab.prototype.show = function(id) {
1216  var $trigger = $(this.conf.trigger);
1217  var $targetTrigger = $(this.conf.trigger+'[href="'+id+'"]');
1218  var $target = $( id );
1219  var _this = this;
1220  this.removeClass($trigger);
1221  $targetTrigger.addClass(this.conf.statusClass);
1222  $target.addClass(this.conf.statusClass);
1223  setTimeout(function(){
1224    $target.addClass(_this.conf.uiFiClass);
1225    // scroll load bind
1226    _this.tabloadBind($target);
1227  }, this.conf.duration);
1228};
1229
1230Tab.prototype.showFirstTab = function(){
1231  var $firstTrigger = $(this.conf.trigger+':nth-of-type(1)').eq(0);
1232  var $target = $( $firstTrigger.attr('href') );
1233  var _this = this;
1234  this.removeClass($firstTrigger);
1235  $firstTrigger.addClass(this.conf.statusClass);
1236  $target.addClass(this.conf.statusClass);
1237  setTimeout(function(){
1238    $target.addClass(_this.conf.uiFiClass);
1239    // scroll load bind
1240    _this.tabloadBind($target);
1241  }, this.conf.duration);
1242}
1243
1244Tab.prototype.init = function() {
1245  var _this = this;
1246  $(this.conf.root).on('click', this.conf.trigger, function(event) {
1247    event.preventDefault();
1248    _this.removeClass($(this));
1249    _this.addClass($(this));
1250  });
1251};
1252
1253module.exports = Tab;
1254
1255},{}],13:[function(require,module,exports){
1256/**
1257 * @namespace -
1258 * @class LvdHeaderUi
1259 */
1260function LvdHeaderUi(){
1261  this.conf = {
1262    html: 'html',
1263    header: '.LVD .lvd-header',
1264    mainTrigger: '.lvd-header-toggle',
1265    userTrigger: '.lvd-header-nav__item:last-child',
1266    mainBlock: '.lvd-header-main',
1267    userBlock: '.lvd-header-user',
1268    overlay: '.lvd-root__overlay',
1269    content: '.lvd-root'
1270  };
1271  this.listenEvents = 'webkitTransitionEnd transitionend';
1272}
1273
1274LvdHeaderUi.prototype.isOpenMainNav = false;
1275LvdHeaderUi.prototype.isOpenUserNav = false;
1276
1277LvdHeaderUi.prototype.animationEnd = function($animation, $target) {
1278  $animation.one(this.listenEvents, function() {
1279    $target.removeClass('is-active');
1280  });
1281};
1282
1283LvdHeaderUi.prototype.navHidden = function(){
1284  $(this.conf.content).removeClass('lvd-is-active--user lvd-is-active--main');
1285  $(this.conf.html).removeClass('is-lvd-active--user is-lvd-active--main');
1286  $(this.conf.mainTrigger).removeClass('is-active');
1287  $(this.conf.userTrigger).removeClass('is-active');
1288  $(this.conf.header).removeClass('is-active--user is-active--main');
1289  this.animationEnd($(this.conf.content), $(this.conf.mainBlock));
1290  this.animationEnd($(this.conf.content), $(this.conf.userBlock));
1291  this.isOpenMainNav = false;
1292  this.isOpenUserNav = false;
1293};
1294
1295/**
1296 * @method resetUserNav
1297 */
1298LvdHeaderUi.prototype.resetUserNav = function(){
1299  $(this.conf.content).removeClass('lvd-is-active--user');
1300  $(this.conf.html).removeClass('is-lvd-active--user');
1301  $(this.conf.userTrigger).removeClass('is-active');
1302  $(this.conf.header).removeClass('is-active--user');
1303  if(this.isOpenUserNav){
1304    this.animationEnd($(this.conf.content), $(this.conf.userBlock));
1305    this.isOpenUserNav = false;
1306  }
1307}
1308
1309/**
1310 * @method resetMainNav
1311 */
1312LvdHeaderUi.prototype.resetMainNav = function(){
1313  $(this.conf.content).removeClass('lvd-is-active--main');
1314  $(this.conf.html).removeClass('is-lvd-active--main');
1315  $(this.conf.mainTrigger).removeClass('is-active');
1316  $(this.conf.header).removeClass('is-active--main');
1317  if(this.isOpenMainNav){
1318    this.animationEnd($(this.conf.content), $(this.conf.mainBlock));
1319    this.isOpenMainNav = false;
1320  }
1321}
1322
1323
1324/**
1325 * @method toggleMainNav
1326 */
1327LvdHeaderUi.prototype.showMainNav = function(){
1328  $(this.conf.content).off(this.listenEvents);
1329  this.isOpenMainNav = true;
1330  // ヘッダ内モーダル hide
1331  LVD.Header.Modal.activeHide();
1332  // Trigger-self
1333  $(this.conf.mainTrigger).addClass('is-active');
1334  $(this.conf.mainBlock).addClass('is-active');
1335  // Reset UserNav
1336  this.resetUserNav();
1337  // Trigger-header,another
1338  $(this.conf.header).addClass('is-active--main');
1339  $(this.conf.content).addClass('lvd-is-active--main');
1340  $(this.conf.html).addClass('is-lvd-active--main');
1341}
1342
1343/**
1344 * @method toggleUserNav
1345 */
1346LvdHeaderUi.prototype.showUserNav = function(){
1347  $(this.conf.content).off(this.listenEvents);
1348  this.isOpenUserNav = true;
1349  // ヘッダ内モーダル hide
1350  LVD.Header.Modal.activeHide();
1351  // Trigger-self
1352  $(this.conf.userTrigger).addClass('is-active');
1353  $(this.conf.userBlock).addClass('is-active');
1354  // Reset MainNav
1355  this.resetMainNav();
1356  // Trigger-header,another
1357  $(this.conf.header).addClass('is-active--user');
1358  $(this.conf.content).addClass('lvd-is-active--user');
1359  $(this.conf.html).addClass('is-lvd-active--user');
1360}
1361
1362/**
1363 * @method init
1364 */
1365LvdHeaderUi.prototype.init = function(){
1366  var _this = this;
1367  $(document).on('click', this.conf.mainTrigger, function(event) {
1368    event.preventDefault();
1369    var state = new LVD.state();
1370    if(!_this.isOpenMainNav){
1371      _this.showMainNav();
1372      state.replace('nav','main');
1373    } else {
1374      _this.resetMainNav();
1375      state.remove('nav');
1376      state.replace(state.query);
1377    }
1378  });
1379  $(document).on('click', this.conf.userTrigger, function(event) {
1380    event.preventDefault();
1381    var state = new LVD.state();
1382    if(!_this.isOpenUserNav){
1383      _this.showUserNav();
1384      state.replace('nav','user');
1385    } else {
1386      _this.resetUserNav();
1387      state.remove('nav');
1388      state.replace(state.query);
1389    }
1390  });
1391  $(document).on('click touchstart', this.conf.overlay, function(event) {
1392    event.preventDefault();
1393    var state = new LVD.state();
1394    _this.navHidden();
1395    state.remove('nav');
1396    state.replace(state.query);
1397  });
1398};
1399
1400module.exports = LvdHeaderUi;
1401window.LVD.UI = LvdHeaderUi;
1402
1403},{}],14:[function(require,module,exports){
1404// Window 高さと lvd-root 高さを比較して
1405// フッター要素に高さをふかす
1406
1407var $footer = $('.lvd-root .lvd-page .LVD');
1408
1409function windowAdjust($window,$root) {
1410  var $footer = $('.lvd-root .lvd-page .LVD');
1411  $footer.removeAttr('style');
1412  var wh, rh, fh, add;
1413  wh = $window.outerHeight();
1414  rh = $root.outerHeight()+45;
1415  fh = $footer.outerHeight();
1416  if( wh > rh+fh ){
1417    add = wh - rh - fh;
1418    $footer.css('margin-top', add);
1419  }
1420}
1421
1422function destroyWindowAdjust(){
1423  var $footer = $('.lvd-root .lvd-page .LVD');
1424  $footer.removeAttr('style');
1425
1426  $(window).off('load.adjust').off('resize.adjust');
1427}
1428
1429$(window).on({
1430
1431  'load.adjust': function(){
1432    windowAdjust($(window),$('.lvd-page__wrapper'));
1433  },
1434
1435  'resize.adjust': function(){
1436    windowAdjust($(window),$('.lvd-page__wrapper'));
1437  }
1438
1439});
1440
1441window.LVD.windowAdjust = windowAdjust;
1442window.LVD.destroyWindowAdjust = destroyWindowAdjust;
1443
1444},{}],15:[function(require,module,exports){
1445'use strict';
1446var Modal, ModalDialog, iframeResizer;
1447
1448iframeResizer = require('iframe-resizer');
1449
1450ModalDialog = (function() {
1451  function ModalDialog(conf, $el1) {
1452    this.conf = conf;
1453    this.$el = $el1;
1454    this.setOverlay();
1455    this.setModal();
1456    return;
1457  }
1458
1459  ModalDialog.prototype.setOverlay = function() {
1460    this.$overlay = !($("body > ." + this.conf.overlay).length < 1) ? $("body > ." + this.conf.overlay) : $("<div class=\"" + this.conf.overlay + "\"></div>");
1461    this.$overlay.addClass('fx-fade').appendTo('body');
1462    if (this.conf.overlayClose) {
1463      this.$overlay.on("click." + this.conf.ns, this.hide.bind(this));
1464    }
1465  };
1466
1467  ModalDialog.prototype.setModal = function() {
1468    this.$el.addClass('fx-fade').on("click." + this.conf.ns, this.conf.hide, (function(_this) {
1469      return function(e) {
1470        _this.hide();
1471        return e.preventDefault();
1472      };
1473    })(this));
1474  };
1475
1476  ModalDialog.prototype.request = function() {
1477    var $target, ajax, dfd, selector;
1478    $target = $(this.conf.target);
1479    dfd = $.Deferred();
1480    if ($target.html() === '') {
1481      selector = this.conf.target + ' iframe';
1482      ajax = new LVD.Ajax(this.conf.api, $target, this.conf.query);
1483      ajax.jqXHR().then((function(_this) {
1484        return function(data) {
1485          if (data.render) {
1486            if (!data.status) {
1487              console.log(data.errors);
1488              return;
1489            }
1490            $target.append(data.html);
1491            if (Modernizr.firefox) {
1492              iframeResizer.iframeResizer({}, selector);
1493              dfd.resolve();
1494            } else {
1495              $(selector).on('load', function() {
1496                iframeResizer.iframeResizer({}, selector);
1497                return setTimeout(function() {
1498                  return dfd.resolve();
1499                }, 300);
1500              });
1501            }
1502            return;
1503          } else {
1504            console.log('api.rander:' + data.render);
1505            return;
1506          }
1507        };
1508      })(this), (function(_this) {
1509        return function(data) {
1510          console.log('error');
1511        };
1512      })(this));
1513    } else {
1514      dfd.resolve();
1515    }
1516    return dfd.promise();
1517  };
1518
1519  ModalDialog.prototype.show = function() {
1520    if (this.conf.modalStatusClass) {
1521      $('html').addClass(this.conf.modalStatusClass);
1522    }
1523    return this.request().done((function(_this) {
1524      return function() {
1525        _this.showElement(_this.$el).done(function() {});
1526        _this.showElement(_this.$overlay);
1527      };
1528    })(this));
1529  };
1530
1531  ModalDialog.prototype.hide = function() {
1532    if (this.conf.modalStatusClass) {
1533      $('html').removeClass(this.conf.modalStatusClass);
1534    }
1535    if (this.conf.disableWindowScroll && Modernizr.ios) {
1536      this.restoreScrollPos();
1537    }
1538    this.hideElement(this.$el);
1539    this.hideElement(this.$overlay);
1540  };
1541
1542  ModalDialog.prototype.showElement = function($el) {
1543    var dfd;
1544    dfd = $.Deferred();
1545    $el.addClass('is-active').trigger("show." + this.conf.ns);
1546    setTimeout((function(_this) {
1547      return function() {
1548        $el.addClass('fx-in');
1549        dfd.resolve();
1550      };
1551    })(this), 10);
1552    dfd.done((function(_this) {
1553      return function() {
1554        return _this.addAnimateClass($el);
1555      };
1556    })(this));
1557    return dfd.promise();
1558  };
1559
1560  ModalDialog.prototype.hideElement = function($el) {
1561    var callback;
1562    $el.removeClass('fx-in').trigger("hide." + this.conf.ns);
1563    callback = (function(_this) {
1564      return function() {
1565        $el.removeClass('is-active');
1566        $el.trigger("hidden." + _this.conf.ns);
1567      };
1568    })(this);
1569    if (!$.support.transition) {
1570      return callback.call(this);
1571    }
1572    $el.one($.support.transition.end, callback.bind(this)).emulateTransitionEnd(this.conf.duration + 50);
1573    this.removeAnimateClass($el);
1574  };
1575
1576  ModalDialog.prototype.setScrollPos = function() {
1577    $(window).data('scrollTop', $(window).scrollTop());
1578  };
1579
1580  ModalDialog.prototype.fixScrollPos = function() {
1581    $('body').css({
1582      top: "-" + ($(window).data('scrollTop')) + "px"
1583    });
1584  };
1585
1586  ModalDialog.prototype.restoreScrollPos = function() {
1587    $('body').css({
1588      top: "0px"
1589    });
1590    $(window).scrollTop($(window).data('scrollTop'));
1591  };
1592
1593  ModalDialog.prototype.addAnimateClass = function($el) {
1594    var $iframe, $target, iframeDoc;
1595    $iframe = $el.find('iframe');
1596    if ($iframe.length > 0) {
1597      if (Modernizr.firefox) {
1598        $iframe.on('load', (function(_this) {
1599          return function() {
1600            var $target, iframeDoc;
1601            iframeDoc = $iframe[0].contentWindow.document;
1602            $target = $(_this.conf.animateElem, iframeDoc);
1603            return $target.addClass('fx-in');
1604          };
1605        })(this));
1606      } else {
1607        iframeDoc = $iframe[0].contentWindow.document;
1608        $target = $(this.conf.animateElem, iframeDoc);
1609        $target.addClass('fx-in');
1610      }
1611    }
1612  };
1613
1614  ModalDialog.prototype.removeAnimateClass = function($el) {
1615    var $target;
1616    $target = $el.find($('[data-lvdmodal-animate="target"]'));
1617    if ($target.length > 0) {
1618      $target.removeClass('fx-in');
1619    }
1620  };
1621
1622  return ModalDialog;
1623
1624})();
1625
1626Modal = (function() {
1627  var defaults;
1628
1629  defaults = {
1630    root: document,
1631    trigger: null,
1632    target: null,
1633    hide: '[data-lvddialog="hide"]',
1634    hideParent: '[data-lvddialog="hide.parent"]',
1635    overlay: 'lvd-dialog-overlay',
1636    animateElem: '[data-lvdmodal-animate="target"]',
1637    overlayClose: true,
1638    modalStatusClass: 'is-lvdmodal-active',
1639    disableWindowScroll: true,
1640    duration: 300,
1641    ns: 'modal',
1642    api: null,
1643    query: null
1644  };
1645
1646  function Modal(options) {
1647    this.conf = $.extend({}, defaults, options);
1648    this.setup();
1649    return;
1650  }
1651
1652  Modal.prototype.setup = function() {
1653    $(this.conf.animateElem).addClass('fx-fade');
1654    if (this.conf.trigger) {
1655      $(this.conf.root).on("click." + this.conf.ns, this.conf.trigger, (function(_this) {
1656        return function(e) {
1657          var $this;
1658          $this = $(e.currentTarget);
1659          if ($this.is('a')) {
1660            e.preventDefault();
1661          }
1662          return _this.show();
1663        };
1664      })(this));
1665    }
1666    $(this.conf.root).on("click." + this.conf.ns, this.conf.hideParent, (function(_this) {
1667      return function(e) {
1668        var $this;
1669        $this = $(e.currentTarget);
1670        if ($this.is('a')) {
1671          e.preventDefault();
1672        }
1673        return $('.' + _this.conf.overlay, parent.document).trigger('click');
1674      };
1675    })(this));
1676  };
1677
1678  Modal.prototype.show = function() {
1679    this.setScrollPos();
1680    if (this.conf.disableWindowScroll && Modernizr.ios) {
1681      this.fixScrollPos();
1682    }
1683    this.activate();
1684  };
1685
1686  Modal.prototype.activate = function() {
1687    var $el, $modal, $modalRoot, modal;
1688    $modal = $(this.conf.target);
1689    if ($modal.length === 0) {
1690      $modalRoot = $('<div class="lvd-dialog" id="' + this.conf.target.split('#')[1] + '" />');
1691      $('body').append($modalRoot);
1692    }
1693    LVD.Header.navHidden();
1694    LVD.Header.Modal.activeHide();
1695    $el = $(this.conf.target);
1696    modal = new ModalDialog(this.conf, $el);
1697    modal.show();
1698  };
1699
1700  Modal.prototype.setScrollPos = function() {
1701    $(window).data('scrollTop', $(window).scrollTop());
1702  };
1703
1704  Modal.prototype.fixScrollPos = function() {
1705    $('body').css({
1706      top: "-" + ($(window).data('scrollTop')) + "px"
1707    });
1708  };
1709
1710  Modal.prototype.restoreScrollPos = function() {
1711    $('body').css({
1712      top: "0px"
1713    });
1714    $(window).scrollTop($(window).data('scrollTop'));
1715  };
1716
1717  return Modal;
1718
1719})();
1720
1721module.exports = Modal;
1722
1723
1724},{"iframe-resizer":19}],16:[function(require,module,exports){
1725'use strict';
1726var Modal, ModalDialog, iframeResizer;
1727
1728iframeResizer = require('iframe-resizer');
1729
1730ModalDialog = (function() {
1731  function ModalDialog(conf, $el1) {
1732    this.conf = conf;
1733    this.$el = $el1;
1734    this.iframeLoaded = false;
1735    this.setOverlay();
1736    this.setModal();
1737    return;
1738  }
1739
1740  ModalDialog.prototype.setOverlay = function() {
1741    this.$overlay = !($("body > ." + this.conf.overlay).length < 1) ? $("body > ." + this.conf.overlay) : $("<div class=\"" + this.conf.overlay + "\"></div>");
1742    this.$overlay.addClass('fx-fade').appendTo('body');
1743    if (this.conf.overlayClose) {
1744      this.$overlay.on("click." + this.conf.ns, this.hide.bind(this));
1745    }
1746  };
1747
1748  ModalDialog.prototype.setModal = function() {
1749    if (Modernizr.ios && Modernizr.safari) {
1750      $('body').append(this.$el);
1751    }
1752    this.$el.addClass('fx-fade').on("click." + this.conf.ns, this.conf.hide, (function(_this) {
1753      return function(e) {
1754        _this.hide();
1755        return e.preventDefault();
1756      };
1757    })(this));
1758    this.loadIframe();
1759  };
1760
1761  ModalDialog.prototype.loadIframe = function() {
1762    var $iframe, $spinner;
1763    $iframe = this.$el.find(this.conf.iframe);
1764    if (!($iframe.length > 0)) {
1765      return;
1766    }
1767    if (!!this.iframeLoaded) {
1768      return;
1769    }
1770    $spinner = this.$el.find(this.conf.loadingSpinner);
1771    $iframe.attr('src', $iframe.attr('data-src')).on('load', (function(_this) {
1772      return function() {
1773        iframeResizer.iframeResizer({}, $iframe.get(0));
1774        $spinner.hide();
1775        return _this.iframeLoaded = true;
1776      };
1777    })(this));
1778  };
1779
1780  ModalDialog.prototype.show = function() {
1781    if (this.conf.modalStatusClass) {
1782      $('html').addClass(this.conf.modalStatusClass);
1783    }
1784    this.showElement(this.$el);
1785    this.showElement(this.$overlay);
1786  };
1787
1788  ModalDialog.prototype.hide = function() {
1789    if (this.conf.modalStatusClass) {
1790      $('html').removeClass(this.conf.modalStatusClass);
1791    }
1792    this.hideElement(this.$el);
1793    this.hideElement(this.$overlay);
1794  };
1795
1796  ModalDialog.prototype.showElement = function($el) {
1797    var dfd;
1798    dfd = $.Deferred();
1799    $el.addClass('is-active').trigger("show." + this.conf.ns);
1800    setTimeout((function(_this) {
1801      return function() {
1802        $el.addClass('fx-in');
1803        dfd.resolve();
1804      };
1805    })(this), 10);
1806    return dfd.promise();
1807  };
1808
1809  ModalDialog.prototype.hideElement = function($el) {
1810    var callback;
1811    $el.removeClass('fx-in').trigger("hide." + this.conf.ns);
1812    callback = (function(_this) {
1813      return function() {
1814        $el.removeClass('is-active');
1815        $el.trigger("hidden." + _this.conf.ns);
1816      };
1817    })(this);
1818    if (!$.support.transition) {
1819      return callback.call(this);
1820    }
1821    $el.one($.support.transition.end, callback.bind(this)).emulateTransitionEnd(this.conf.duration + 50);
1822  };
1823
1824  return ModalDialog;
1825
1826})();
1827
1828Modal = (function() {
1829  var defaults;
1830
1831  defaults = {
1832    root: document,
1833    trigger: '[data-lvddialogiframe="trigger"]',
1834    iframe: '[data-lvddialogiframe="iframe"]',
1835    hide: '[data-lvddialog="hide"]',
1836    hideParent: '[data-lvddialog="hide.parent"]',
1837    loadingSpinner: '.js-loading-spinner',
1838    overlay: 'lvd-dialog-overlay',
1839    overlayClose: true,
1840    modalStatusClass: 'is-lvdmodal-active',
1841    duration: 300,
1842    ns: 'modal'
1843  };
1844
1845  function Modal(options) {
1846    this.conf = $.extend({}, defaults, options);
1847    this.setup();
1848    return;
1849  }
1850
1851  Modal.prototype.setup = function() {
1852    if (this.conf.trigger) {
1853      $(this.conf.root).on("click." + this.conf.ns, this.conf.trigger, (function(_this) {
1854        return function(e) {
1855          var $this;
1856          $this = $(e.currentTarget);
1857          if ($this.is('a')) {
1858            e.preventDefault();
1859          }
1860          return _this.activate(_this.getTargetFromTrigger($this));
1861        };
1862      })(this));
1863    }
1864    $(this.conf.root).on("click." + this.conf.ns, this.conf.hideParent, (function(_this) {
1865      return function(e) {
1866        var $this;
1867        $this = $(e.currentTarget);
1868        if ($this.is('a')) {
1869          e.preventDefault();
1870        }
1871        return $('.' + _this.conf.overlay, parent.document).trigger('click');
1872      };
1873    })(this));
1874  };
1875
1876  Modal.prototype.show = function(id) {
1877    this.activate(id);
1878  };
1879
1880  Modal.prototype.activate = function(selector) {
1881    var $el, data;
1882    $el = $(selector);
1883    if (!($el.length > 0)) {
1884      console.log('modal error: target not found');
1885      return;
1886    }
1887    LVD.Header.navHidden();
1888    LVD.Header.Modal.activeHide();
1889    data = $el.data('modalDialog');
1890    if (!data) {
1891      data = new ModalDialog(this.conf, $el);
1892      $el.data('modalDialog', data);
1893    }
1894    data.show();
1895  };
1896
1897  Modal.prototype.getTargetFromTrigger = function($trigger) {
1898    return $trigger.attr('data-target');
1899  };
1900
1901  return Modal;
1902
1903})();
1904
1905module.exports = Modal;
1906
1907
1908},{"iframe-resizer":19}],17:[function(require,module,exports){
1909var StateControll = function(){
1910  this.domain = window.location.host;
1911  this.location = window.location.pathname;
1912  this.query = LVD.qs.parse(window.location.search.slice(1));
1913};
1914
1915StateControll.prototype.update = function() {
1916  if(!Object.keys(this.query).length){
1917    var state = {path:this.location};
1918    window.history.pushState(state,null, this.location);
1919  } else {
1920    var string = LVD.qs.stringify(this.query);
1921    var url = '?'+string;
1922    var state = {path:this.location+url};
1923    window.history.pushState(state,null,url);
1924  }
1925};
1926
1927StateControll.prototype.add = function(key,val){
1928  this.query[key] = val;
1929};
1930
1931StateControll.prototype.remove = function(key){
1932  delete this.query[key];
1933};
1934
1935StateControll.prototype.replace = function() {
1936  var url, state;
1937  if( arguments[1] ){
1938    var key = arguments[0];
1939    var val = arguments[1];
1940    this.query[key] = val;
1941  } else {
1942    this.query = arguments[0];
1943  }
1944  if(this.query == undefined || Object.keys(this.query).length == 0){
1945    var state = {path:this.location};
1946    url = this.location;
1947  } else {
1948    url = '?'+LVD.qs.stringify(this.query, { encode: false});
1949    state = {path:this.location+url};
1950  }
1951  window.history.replaceState(state,null,url);
1952};
1953
1954module.exports = StateControll;
1955window.LVD.state = StateControll;
1956
1957},{}],18:[function(require,module,exports){
1958if(!window.LVD){
1959  window.LVD = {};
1960}
1961
1962require('jquery.easing');
1963
1964var UI = require('./components/ui');
1965var NavModal = require('./components/navmodal');
1966var Tab = require('./components/tab');
1967var Accordion = require('./components/accordion');
1968var AnchorScroll = require('./components/anchorScroll');
1969
1970// Global Exports
1971window.LVD.Accordion = Accordion;
1972window.LVD.Ajax = require('./components/ajax');
1973window.LVD.router = require('page');
1974window.LVD.qs = require('qs');
1975window.LVD.iframeResizer = require('iframe-resizer');
1976
1977require('./libs/state-controller');
1978
1979(function($){
1980  $(function(){
1981
1982    // Footer の位置調整
1983    require('./components/window-adjust');
1984
1985    // UI init
1986    var headerUI = new UI();
1987    headerUI.init();
1988    // Global Exports
1989    window.LVD.Header = headerUI;
1990
1991    // Modal Init - recommend
1992    var modalRecommend = new NavModal({
1993      trigger: '[data-lvdheader-modal-channel="recommend"]',
1994      routePath: 'recommend'
1995    });
1996    modalRecommend.init();
1997    // Global Exports
1998    window.LVD.Header.Recommend = modalRecommend;
1999
2000    // Modal Init - favorite
2001    var modalFavorite = new NavModal({
2002      trigger: '[data-lvdheader-modal-channel="favorite"]',
2003      routePath: 'favorite'
2004    });
2005    modalFavorite.init();
2006    // Global Exports
2007    window.LVD.Header.Favorite = modalFavorite;
2008
2009    // Modal Init - notify
2010    var modalNotify = new NavModal({
2011      trigger: '[data-lvdheader-modal-channel="notify"]',
2012      routePath: 'notify'
2013      // notifyBadgeClass: '.lvd-header-nav__count',
2014    })
2015    modalNotify.init();
2016    // Global Exports
2017    window.LVD.Header.Notify = modalNotify;
2018
2019    var headerModal = new NavModal();
2020    // Global Exports
2021    window.LVD.Header.Modal = headerModal;
2022
2023    // Tab Init
2024    var headerTab = new Tab();
2025    headerTab.init();
2026    window.LVD.htab = headerTab;
2027
2028    // Scroll Anchor
2029    var anchor = new AnchorScroll()
2030    window.LVD.anchor = anchor
2031
2032    // Accordion Init
2033    var headerAccordion = new Accordion().init();
2034
2035    // Scroll Load
2036    require('./components/scroll-load');
2037
2038    // clip
2039    require('./components/clip');
2040
2041    // Ajax Modal
2042    require('./components/dialog');
2043
2044    // Pagetop Animation
2045    require('./components/pagetop');
2046
2047    // SearchField Component
2048    require('./components/search');
2049
2050    // Router
2051    require('./components/router');
2052
2053    // First Login
2054    require('./components/firstlogin.js');
2055
2056  });
2057})(jQuery);
2058
2059}
2059,{"./components/accordion":1,"./components/ajax":2,"./components/anchorScroll":3,"./components/clip":4,"./components/dialog":5,"./components/firstlogin.js":6,"./components/navmodal":7,"./components/pagetop":8,"./components/router":9,"./components/scroll-load":10,"./components/search":11,"./components/tab":12,"./components/ui":13,"./components/window-adjust":14,"./libs/state-controller":17,"iframe-resizer":19,"jquery.easing":24,"page":25,"qs":28}],19:[function(require,module,exports){
2060
2061'use strict';
2062
2063module.exports = require('./js');
2064
2065},{"./js":22}],20:[function(require,module,exports){
2066/*
2067 * File: iframeResizer.contentWindow.js
2068 * Desc: Include this file in any page being loaded into an iframe
2069 *       to force the iframe to resize to the content size.
2070 * Requires: iframeResizer.js on host page.
2071 * Doc: https://github.com/davidjbradshaw/iframe-resizer
2072 * Author: David J. Bradshaw - [email protected]
2073 * Contributor: Jure Mav - [email protected]
2074 * Contributor: Ian Caunce - [email protected]
2075 */
2076
2077
2078;(function(window, undefined) {
2079	'use strict';
2080
2081	var
2082		autoResize            = true,
2083		base                  = 10,
2084		bodyBackground        = '',
2085		bodyMargin            = 0,
2086		bodyMarginStr         = '',
2087		bodyObserver          = null,
2088		bodyPadding           = '',
2089		calculateWidth        = false,
2090		doubleEventList       = {'resize':1,'click':1},
2091		eventCancelTimer      = 128,
2092		firstRun              = true,
2093		height                = 1,
2094		heightCalcModeDefault = 'bodyOffset',
2095		heightCalcMode        = heightCalcModeDefault,
2096		initLock              = true,
2097		initMsg               = '',
2098		inPageLinks           = {},
2099		interval              = 32,
2100		intervalTimer         = null,
2101		logging               = false,
2102		msgID                 = '[iFrameSizer]',  //Must match host page msg ID
2103		msgIdLen              = msgID.length,
2104		myID                  = '',
2105		observer              = null,
2106		resetRequiredMethods  = {max:1,min:1,bodyScroll:1,documentElementScroll:1},
2107		resizeFrom            = 'child',
2108		sendPermit            = true,
2109		target                = window.parent,
2110		targetOriginDefault   = '*',
2111		tolerance             = 0,
2112		triggerLocked         = false,
2113		triggerLockedTimer    = null,
2114		throttledTimer        = 16,
2115		width                 = 1,
2116		widthCalcModeDefault  = 'scroll',
2117		widthCalcMode         = widthCalcModeDefault,
2118		win                   = window,
2119		messageCallback       = function(){ warn('MessageCallback function not defined'); },
2120		readyCallback         = function(){},
2121		pageInfoCallback      = function(){},
2122		customCalcMethods     = {
2123			height: function(){
2124				warn('Custom height calculation function not defined');
2125				return document.documentElement.offsetHeight;
2126			}, 
2127			width: function(){
2128				warn('Custom width calculation function not defined');
2129				return document.body.scrollWidth;
2130			}
2131		};
2132
2133
2134	function addEventListener(el,evt,func){
2135		/* istanbul ignore else */ // Not testable in phantonJS
2136		if ('addEventListener' in window){
2137			el.addEventListener(evt,func, false);
2138		} else if ('attachEvent' in window){ //IE
2139			el.attachEvent('on'+evt,func);
2140		}
2141	}
2142
2143	function removeEventListener(el,evt,func){
2144		/* istanbul ignore else */ // Not testable in phantonJS
2145		if ('removeEventListener' in window){
2146			el.removeEventListener(evt,func, false);
2147		} else if ('detachEvent' in window){ //IE
2148			el.detachEvent('on'+evt,func);
2149		}
2150	}
2151
2152	function capitalizeFirstLetter(string) {
2153		return string.charAt(0).toUpperCase() + string.slice(1);
2154	}
2155
2156	//Based on underscore.js
2157	function throttle(func) {
2158		var
2159			context, args, result,
2160			timeout = null,
2161			previous = 0,
2162			later = function() {
2163				previous = getNow();
2164				timeout = null;
2165				result = func.apply(context, args);
2166				if (!timeout) {
2167					context = args = null;
2168				}
2169			};
2170
2171		return function() {
2172			var now = getNow();
2173
2174			if (!previous) {
2175				previous = now;
2176			}
2177
2178			var remaining = throttledTimer - (now - previous);
2179
2180			context = this;
2181			args = arguments;
2182
2183			if (remaining <= 0 || remaining > throttledTimer) {
2184				if (timeout) {
2185					clearTimeout(timeout);
2186					timeout = null;
2187				}
2188
2189				previous = now;
2190				result = func.apply(context, args);
2191
2192				if (!timeout) {
2193					context = args = null;
2194				}
2195
2196			} else if (!timeout) {
2197				timeout = setTimeout(later, remaining);
2198			}
2199
2200			return result;
2201		};
2202	}
2203
2204	var getNow = Date.now || function() {
2205		/* istanbul ignore next */ // Not testable in PhantonJS
2206		return new Date().getTime();
2207	};
2208
2209	function formatLogMsg(msg){
2210		return msgID + '[' + myID + ']' + ' ' + msg;
2211	}
2212
2213	function log(msg){
2214		if (logging && ('object' === typeof window.console)){
2215			console.log(formatLogMsg(msg));
2216		}
2217	}
2218
2219	function warn(msg){
2220		if ('object' === typeof window.console){
2221			console.warn(formatLogMsg(msg));
2222		}
2223	}
2224
2225
2226	function init(){
2227		readDataFromParent();
2228		log('Initialising iFrame ('+location.href+')');
2229		readDataFromPage();
2230		setMargin();
2231		setBodyStyle('background',bodyBackground);
2232		setBodyStyle('padding',bodyPadding);
2233		injectClearFixIntoBodyElement();
2234		checkHeightMode();
2235		checkWidthMode();
2236		stopInfiniteResizingOfIFrame();
2237		setupPublicMethods();
2238		startEventListeners();
2239		inPageLinks = setupInPageLinks();
2240		sendSize('init','Init message from host page');
2241		readyCallback();
2242	}
2243
2244	function readDataFromParent(){
2245
2246		function strBool(str){
2247			return 'true' === str ? true : false;
2248		}
2249
2250		var data = initMsg.substr(msgIdLen).split(':');
2251
2252		myID               = data[0];
2253		bodyMargin         = (undefined !== data[1]) ? Number(data[1])   : bodyMargin; //For V1 compatibility
2254		calculateWidth     = (undefined !== data[2]) ? strBool(data[2])  : calculateWidth;
2255		logging            = (undefined !== data[3]) ? strBool(data[3])  : logging;
2256		interval           = (undefined !== data[4]) ? Number(data[4])   : interval;
2257		autoResize         = (undefined !== data[6]) ? strBool(data[6])  : autoResize;
2258		bodyMarginStr      = data[7];
2259		heightCalcMode     = (undefined !== data[8]) ? data[8]           : heightCalcMode;
2260		bodyBackground     = data[9];
2261		bodyPadding        = data[10];
2262		tolerance          = (undefined !== data[11]) ? Number(data[11]) : tolerance;
2263		inPageLinks.enable = (undefined !== data[12]) ? strBool(data[12]): false;
2264		resizeFrom         = (undefined !== data[13]) ? data[13]         : resizeFrom;
2265		widthCalcMode      = (undefined !== data[14]) ? data[14]         : widthCalcMode;
2266	}
2267
2268	function readDataFromPage(){
2269		function readData(){
2270			var data = window.iFrameResizer;
2271
2272			log('Reading data from page: ' + JSON.stringify(data));
2273
2274			messageCallback     = ('messageCallback'         in data) ? data.messageCallback         : messageCallback;
2275			readyCallback       = ('readyCallback'           in data) ? data.readyCallback           : readyCallback;
2276			targetOriginDefault = ('targetOrigin'            in data) ? data.targetOrigin            : targetOriginDefault;
2277			heightCalcMode      = ('heightCalculationMethod' in data) ? data.heightCalculationMethod : heightCalcMode;
2278			widthCalcMode       = ('widthCalculationMethod'  in data) ? data.widthCalculationMethod  : widthCalcMode;
2279		}
2280
2281		function setupCustomCalcMethods(calcMode, calcFunc){
2282			if ('function' === typeof calcMode) {
2283				log('Setup custom ' + calcFunc + 'CalcMethod');
2284				customCalcMethods[calcFunc] = calcMode;
2285				calcMode = 'custom';
2286			}
2287
2288			return calcMode;
2289		}
2290
2291		if(('iFrameResizer' in window) && (Object === window.iFrameResizer.constructor)) {
2292			readData();
2293			heightCalcMode = setupCustomCalcMethods(heightCalcMode, 'height');
2294			widthCalcMode  = setupCustomCalcMethods(widthCalcMode,  'width');
2295		}
2296
2297		log('TargetOrigin for parent set to: ' + targetOriginDefault);
2298	}
2299
2300
2301	function chkCSS(attr,value){
2302		if (-1 !== value.indexOf('-')){
2303			warn('Negative CSS value ignored for '+attr);
2304			value='';
2305		}
2306		return value;
2307	}
2308
2309	function setBodyStyle(attr,value){
2310		if ((undefined !== value) && ('' !== value) && ('null' !== value)){
2311			document.body.style[attr] = value;
2312			log('Body '+attr+' set to "'+value+'"');
2313		}
2314	}
2315
2316	function setMargin(){
2317		//If called via V1 script, convert bodyMargin from int to str
2318		if (undefined === bodyMarginStr){
2319			bodyMarginStr = bodyMargin+'px';
2320		}
2321
2322		setBodyStyle('margin',chkCSS('margin',bodyMarginStr));
2323	}
2324
2325	function stopInfiniteResizingOfIFrame(){
2326		document.documentElement.style.height = '';
2327		document.body.style.height = '';
2328		log('HTML & body height set to "auto"');
2329	}
2330
2331
2332	function manageTriggerEvent(options){
2333		function handleEvent(){
2334			sendSize(options.eventName,options.eventType);
2335		}
2336
2337		var listener = {
2338			add:    function(eventName){
2339				addEventListener(window,eventName,handleEvent);
2340			},
2341			remove: function(eventName){
2342				removeEventListener(window,eventName,handleEvent);
2343			}
2344		};
2345
2346		if(options.eventNames && Array.prototype.map){
2347			options.eventName = options.eventNames[0];
2348			options.eventNames.map(listener[options.method]);
2349		} else {
2350			listener[options.method](options.eventName);
2351		}
2352
2353		log(capitalizeFirstLetter(options.method) + ' event listener: ' + options.eventType);
2354	}
2355
2356	function manageEventListeners(method){
2357		manageTriggerEvent({method:method, eventType: 'Animation Start',           eventNames: ['animationstart','webkitAnimationStart'] });
2358		manageTriggerEvent({method:method, eventType: 'Animation Iteration',       eventNames: ['animationiteration','webkitAnimationIteration'] });
2359		manageTriggerEvent({method:method, eventType: 'Animation End',             eventNames: ['animationend','webkitAnimationEnd'] });
2360		manageTriggerEvent({method:method, eventType: 'Input',                     eventName:  'input' });
2361		manageTriggerEvent({method:method, eventType: 'Mouse Up',                  eventName:  'mouseup' });
2362		manageTriggerEvent({method:method, eventType: 'Mouse Down',                eventName:  'mousedown' });
2363		manageTriggerEvent({method:method, eventType: 'Orientation Change',        eventName:  'orientationchange' });
2364		manageTriggerEvent({method:method, eventType: 'Print',                     eventName:  ['afterprint', 'beforeprint'] });
2365		manageTriggerEvent({method:method, eventType: 'Ready State Change',        eventName:  'readystatechange' });
2366		manageTriggerEvent({method:method, eventType: 'Touch Start',               eventName:  'touchstart' });
2367		manageTriggerEvent({method:method, eventType: 'Touch End',                 eventName:  'touchend' });
2368		manageTriggerEvent({method:method, eventType: 'Touch Cancel',              eventName:  'touchcancel' });
2369		manageTriggerEvent({method:method, eventType: 'Transition Start',          eventNames: ['transitionstart','webkitTransitionStart','MSTransitionStart','oTransitionStart','otransitionstart'] });
2370		manageTriggerEvent({method:method, eventType: 'Transition Iteration',      eventNames: ['transitioniteration','webkitTransitionIteration','MSTransitionIteration','oTransitionIteration','otransitioniteration'] });
2371		manageTriggerEvent({method:method, eventType: 'Transition End',            eventNames: ['transitionend','webkitTransitionEnd','MSTransitionEnd','oTransitionEnd','otransitionend'] });
2372		if('child' === resizeFrom){
2373			manageTriggerEvent({method:method, eventType: 'IFrame Resized',        eventName:  'resize' });
2374		}
2375	}
2376
2377	function checkCalcMode(calcMode,calcModeDefault,modes,type){
2378		if (calcModeDefault !== calcMode){
2379			if (!(calcMode in modes)){
2380				warn(calcMode + ' is not a valid option for '+type+'CalculationMethod.');
2381				calcMode=calcModeDefault;
2382			}
2383			log(type+' calculation method set to "'+calcMode+'"');
2384		}
2385
2386		return calcMode;
2387	}
2388
2389	function checkHeightMode(){
2390		heightCalcMode = checkCalcMode(heightCalcMode,heightCalcModeDefault,getHeight,'height');
2391	}
2392
2393	function checkWidthMode(){
2394		widthCalcMode = checkCalcMode(widthCalcMode,widthCalcModeDefault,getWidth,'width');
2395	}
2396
2397	function startEventListeners(){
2398		if ( true === autoResize ) {
2399			manageEventListeners('add');
2400			setupMutationObserver();
2401		}
2402		else {
2403			log('Auto Resize disabled');
2404		}
2405	}
2406
2407	function stopMsgsToParent(){
2408		log('Disable outgoing messages');
2409		sendPermit = false;
2410	}
2411
2412	function removeMsgListener(){
2413		log('Remove event listener: Message');
2414		removeEventListener(window, 'message', receiver);
2415	}
2416
2417	function disconnectMutationObserver(){
2418		if (null !== bodyObserver){
2419			/* istanbul ignore next */ // Not testable in PhantonJS
2420			bodyObserver.disconnect();
2421		}
2422	}
2423
2424	function stopEventListeners(){
2425		manageEventListeners('remove');
2426		disconnectMutationObserver();
2427		clearInterval(intervalTimer);
2428	}
2429
2430	function teardown(){
2431		stopMsgsToParent();
2432		removeMsgListener();
2433		if (true === autoResize) stopEventListeners();
2434	}
2435
2436	function injectClearFixIntoBodyElement(){
2437		var clearFix = document.createElement('div');
2438		clearFix.style.clear   = 'both';
2439		clearFix.style.display = 'block'; //Guard against this having been globally redefined in CSS.
2440		document.body.appendChild(clearFix);
2441	}
2442
2443	function setupInPageLinks(){
2444
2445		function getPagePosition (){
2446			return {
2447				x: (window.pageXOffset !== undefined) ? window.pageXOffset : document.documentElement.scrollLeft,
2448				y: (window.pageYOffset !== undefined) ? window.pageYOffset : document.documentElement.scrollTop
2449			};
2450		}
2451
2452		function getElementPosition(el){
2453			var
2454				elPosition   = el.getBoundingClientRect(),
2455				pagePosition = getPagePosition();
2456
2457			return {
2458				x: parseInt(elPosition.left,10) + parseInt(pagePosition.x,10),
2459				y: parseInt(elPosition.top,10)  + parseInt(pagePosition.y,10)
2460			};
2461		}
2462
2463		function findTarget(location){
2464			function jumpToTarget(target){
2465				var jumpPosition = getElementPosition(target);
2466
2467				log('Moving to in page link (#'+hash+') at x: '+jumpPosition.x+' y: '+jumpPosition.y);
2468				sendMsg(jumpPosition.y, jumpPosition.x, 'scrollToOffset'); // X&Y reversed at sendMsg uses height/width
2469			}
2470
2471			var
2472				hash     = location.split('#')[1] || location, //Remove # if present
2473				hashData = decodeURIComponent(hash),
2474				target   = document.getElementById(hashData) || document.getElementsByName(hashData)[0];
2475
2476			if (undefined !== target){
2477				jumpToTarget(target);
2478			} else {
2479				log('In page link (#' + hash + ') not found in iFrame, so sending to parent');
2480				sendMsg(0,0,'inPageLink','#'+hash);
2481			}
2482		}
2483
2484		function checkLocationHash(){
2485			if ('' !== location.hash && '#' !== location.hash){
2486				findTarget(location.href);
2487			}
2488		}
2489
2490		function bindAnchors(){
2491			function setupLink(el){
2492				function linkClicked(e){
2493					e.preventDefault();
2494
2495					/*jshint validthis:true */
2496					findTarget(this.getAttribute('href'));
2497				}
2498
2499				if ('#' !== el.getAttribute('href')){
2500					addEventListener(el,'click',linkClicked);
2501				}
2502			}
2503
2504			Array.prototype.forEach.call( document.querySelectorAll( 'a[href^="#"]' ), setupLink );
2505		}
2506
2507		function bindLocationHash(){
2508			addEventListener(window,'hashchange',checkLocationHash);
2509		}
2510
2511		function initCheck(){ //check if page loaded with location hash after init resize
2512			setTimeout(checkLocationHash,eventCancelTimer);
2513		}
2514
2515		function enableInPageLinks(){
2516			/* istanbul ignore else */ // Not testable in phantonJS
2517			if(Array.prototype.forEach && document.querySelectorAll){
2518				log('Setting up location.hash handlers');
2519				bindAnchors();
2520				bindLocationHash();
2521				initCheck();
2522			} else {
2523				warn('In page linking not fully supported in this browser! (See README.md for IE8 workaround)');
2524			}
2525		}
2526
2527		if(inPageLinks.enable){
2528			enableInPageLinks();
2529		} else {
2530			log('In page linking not enabled');
2531		}
2532
2533		return {
2534			findTarget:findTarget
2535		};
2536	}
2537
2538	function setupPublicMethods(){
2539		log('Enable public methods');
2540
2541		win.parentIFrame = {
2542
2543			autoResize: function autoResizeF(resize){
2544				if (true === resize && false === autoResize) {
2545					autoResize=true;
2546					startEventListeners();
2547					//sendSize('autoResize','Auto Resize enabled');
2548				} else if (false === resize && true === autoResize) {
2549					autoResize=false;
2550					stopEventListeners();
2551				}
2552
2553				return autoResize;
2554			},
2555
2556			close: function closeF(){
2557				sendMsg(0,0,'close');
2558				teardown();
2559			},
2560
2561			getId: function getIdF(){
2562				return myID;
2563			},
2564
2565			getPageInfo: function getPageInfoF(callback){
2566				if ('function' === typeof callback){
2567					pageInfoCallback = callback;
2568					sendMsg(0,0,'pageInfo');
2569				} else {
2570					pageInfoCallback = function(){};
2571					sendMsg(0,0,'pageInfoStop');
2572				}
2573			},
2574
2575			moveToAnchor: function moveToAnchorF(hash){
2576				inPageLinks.findTarget(hash);
2577			},
2578
2579			reset: function resetF(){
2580				resetIFrame('parentIFrame.reset');
2581			},
2582
2583			scrollTo: function scrollToF(x,y){
2584				sendMsg(y,x,'scrollTo'); // X&Y reversed at sendMsg uses height/width
2585			},
2586
2587			scrollToOffset: function scrollToF(x,y){
2588				sendMsg(y,x,'scrollToOffset'); // X&Y reversed at sendMsg uses height/width
2589			},
2590
2591			sendMessage: function sendMessageF(msg,targetOrigin){
2592				sendMsg(0,0,'message',JSON.stringify(msg),targetOrigin);
2593			},
2594
2595			setHeightCalculationMethod: function setHeightCalculationMethodF(heightCalculationMethod){
2596				heightCalcMode = heightCalculationMethod;
2597				checkHeightMode();
2598			},
2599
2600			setWidthCalculationMethod: function setWidthCalculationMethodF(widthCalculationMethod){
2601				widthCalcMode = widthCalculationMethod;
2602				checkWidthMode();
2603			},
2604
2605			setTargetOrigin: function setTargetOriginF(targetOrigin){
2606				log('Set targetOrigin: '+targetOrigin);
2607				targetOriginDefault = targetOrigin;
2608			},
2609
2610			size: function sizeF(customHeight, customWidth){
2611				var valString = ''+(customHeight?customHeight:'')+(customWidth?','+customWidth:'');
2612				//lockTrigger();
2613				sendSize('size','parentIFrame.size('+valString+')', customHeight, customWidth);
2614			}
2615		};
2616	}
2617
2618	function initInterval(){
2619		if ( 0 !== interval ){
2620			log('setInterval: '+interval+'ms');
2621			intervalTimer = setInterval(function(){
2622				sendSize('interval','setInterval: '+interval);
2623			},Math.abs(interval));
2624		}
2625	}
2626
2627	/* istanbul ignore next */  //Not testable in PhantomJS
2628	function setupBodyMutationObserver(){
2629		function addImageLoadListners(mutation) {
2630			function addImageLoadListener(element){
2631				if (false === element.complete) {
2632					log('Attach listeners to ' + element.src);
2633					element.addEventListener('load', imageLoaded, false);
2634					element.addEventListener('error', imageError, false);
2635					elements.push(element);
2636				}
2637			}
2638
2639			if (mutation.type === 'attributes' && mutation.attributeName === 'src'){
2640				addImageLoadListener(mutation.target);
2641			} else if (mutation.type === 'childList'){
2642				Array.prototype.forEach.call(
2643					mutation.target.querySelectorAll('img'),
2644					addImageLoadListener
2645				);
2646			}
2647		}
2648
2649		function removeFromArray(element){
2650			elements.splice(elements.indexOf(element),1);
2651		}
2652
2653		function removeImageLoadListener(element){
2654			log('Remove listeners from ' + element.src);
2655			element.removeEventListener('load', imageLoaded, false);
2656			element.removeEventListener('error', imageError, false);
2657			removeFromArray(element);
2658		}
2659
2660		function imageEventTriggered(event,type,typeDesc){
2661			removeImageLoadListener(event.target);
2662			sendSize(type, typeDesc + ': ' + event.target.src, undefined, undefined);
2663		}
2664
2665		function imageLoaded(event) {
2666			imageEventTriggered(event,'imageLoad','Image loaded');
2667		}
2668
2669		function imageError(event) {
2670			imageEventTriggered(event,'imageLoadFailed','Image load failed');
2671		}
2672
2673		function mutationObserved(mutations) {
2674			sendSize('mutationObserver','mutationObserver: ' + mutations[0].target + ' ' + mutations[0].type);
2675
2676			//Deal with WebKit asyncing image loading when tags are injected into the page
2677			mutations.forEach(addImageLoadListners);
2678		}
2679
2680		function createMutationObserver(){
2681			var
2682				target = document.querySelector('body'),
2683
2684				config = {
2685					attributes            : true,
2686					attributeOldValue     : false,
2687					characterData         : true,
2688					characterDataOldValue : false,
2689					childList             : true,
2690					subtree               : true
2691				};
2692
2693			observer = new MutationObserver(mutationObserved);
2694
2695			log('Create body MutationObserver');
2696			observer.observe(target, config);
2697
2698			return observer;
2699		}
2700
2701		var
2702			elements         = [],
2703			MutationObserver = window.MutationObserver || window.WebKitMutationObserver,
2704			observer         = createMutationObserver();
2705
2706		return {
2707			disconnect: function (){
2708				if ('disconnect' in observer){
2709					log('Disconnect body MutationObserver');
2710					observer.disconnect();
2711					elements.forEach(removeImageLoadListener);
2712				}
2713			}
2714		};
2715	}
2716
2717	function setupMutationObserver(){
2718		var	forceIntervalTimer = 0 > interval;
2719
2720		/* istanbul ignore if */ // Not testable in PhantomJS
2721		if (window.MutationObserver || window.WebKitMutationObserver){
2722			if (forceIntervalTimer) {
2723				initInterval();
2724			} else {
2725				bodyObserver = setupBodyMutationObserver();
2726			}
2727		} else {
2728			log('MutationObserver not supported in this browser!');
2729			initInterval();
2730		}
2731	}
2732
2733
2734	// document.documentElement.offsetHeight is not reliable, so
2735	// we have to jump through hoops to get a better value.
2736	function getComputedStyle(prop,el) {
2737		/* istanbul ignore next */  //Not testable in PhantomJS
2738		function convertUnitsToPxForIE8(value) {
2739			var PIXEL = /^\d+(px)?$/i;
2740
2741			if (PIXEL.test(value)) {
2742				return parseInt(value,base);
2743			}
2744
2745			var
2746				style = el.style.left,
2747				runtimeStyle = el.runtimeStyle.left;
2748
2749			el.runtimeStyle.left = el.currentStyle.left;
2750			el.style.left = value || 0;
2751			value = el.style.pixelLeft;
2752			el.style.left = style;
2753			el.runtimeStyle.left = runtimeStyle;
2754
2755			return value;
2756		}
2757
2758		var retVal = 0;
2759		el =  el || document.body;
2760
2761		/* istanbul ignore else */ // Not testable in phantonJS
2762		if (('defaultView' in document) && ('getComputedStyle' in document.defaultView)) {
2763			retVal = document.defaultView.getComputedStyle(el, null);
2764			retVal = (null !== retVal) ? retVal[prop] : 0;
2765		} else {//IE8
2766			retVal =  convertUnitsToPxForIE8(el.currentStyle[prop]);
2767		}
2768
2769		return parseInt(retVal,base);
2770	}
2771
2772	function chkEventThottle(timer){
2773		if(timer > throttledTimer/2){
2774			throttledTimer = 2*timer;
2775			log('Event throttle increased to ' + throttledTimer + 'ms');
2776		}
2777	}
2778
2779	//Idea from https://github.com/guardian/iframe-messenger
2780	function getMaxElement(side,elements) {
2781		var
2782			elementsLength = elements.length,
2783			elVal          = 0,
2784			maxVal         = 0,
2785			Side           = capitalizeFirstLetter(side),
2786			timer          = getNow();
2787
2788		for (var i = 0; i < elementsLength; i++) {
2789			elVal = elements[i].getBoundingClientRect()[side] + getComputedStyle('margin'+Side,elements[i]);
2790			if (elVal > maxVal) {
2791				maxVal = elVal;
2792			}
2793		}
2794
2795		timer = getNow() - timer;
2796
2797		log('Parsed '+elementsLength+' HTML elements');
2798		log('Element position calculated in ' + timer + 'ms');
2799
2800		chkEventThottle(timer);
2801
2802		return maxVal;
2803	}
2804
2805	function getAllMeasurements(dimention){
2806		return [
2807			dimention.bodyOffset(),
2808			dimention.bodyScroll(),
2809			dimention.documentElementOffset(),
2810			dimention.documentElementScroll()
2811		];
2812	}
2813
2814	function getTaggedElements(side,tag){
2815		function noTaggedElementsFound(){
2816			warn('No tagged elements ('+tag+') found on page');
2817			return height; //current height
2818		}
2819
2820		var elements = document.querySelectorAll('['+tag+']');
2821
2822		return 0 === elements.length ?  noTaggedElementsFound() : getMaxElement(side,elements);
2823	}
2824
2825	function getAllElements(){
2826		return document.querySelectorAll('body *');
2827	}
2828
2829	var
2830		getHeight = {
2831			bodyOffset: function getBodyOffsetHeight(){
2832				return  document.body.offsetHeight + getComputedStyle('marginTop') + getComputedStyle('marginBottom');
2833			},
2834
2835			offset: function(){
2836				return getHeight.bodyOffset(); //Backwards compatability
2837			},
2838
2839			bodyScroll: function getBodyScrollHeight(){
2840				return document.body.scrollHeight;
2841			},
2842
2843			custom: function getCustomWidth(){
2844				return customCalcMethods.height();
2845			},
2846
2847			documentElementOffset: function getDEOffsetHeight(){
2848				return document.documentElement.offsetHeight;
2849			},
2850
2851			documentElementScroll: function getDEScrollHeight(){
2852				return document.documentElement.scrollHeight;
2853			},
2854
2855			max: function getMaxHeight(){
2856				return Math.max.apply(null,getAllMeasurements(getHeight));
2857			},
2858
2859			min: function getMinHeight(){
2860				return Math.min.apply(null,getAllMeasurements(getHeight));
2861			},
2862
2863			grow: function growHeight(){
2864				return getHeight.max(); //Run max without the forced downsizing
2865			},
2866
2867			lowestElement: function getBestHeight(){
2868				return Math.max(getHeight.bodyOffset(), getMaxElement('bottom',getAllElements()));
2869			},
2870
2871			taggedElement: function getTaggedElementsHeight(){
2872				return getTaggedElements('bottom','data-iframe-height');
2873			}
2874		},
2875
2876		getWidth = {
2877			bodyScroll: function getBodyScrollWidth(){
2878				return document.body.scrollWidth;
2879			},
2880
2881			bodyOffset: function getBodyOffsetWidth(){
2882				return document.body.offsetWidth;
2883			},
2884
2885			custom: function getCustomWidth(){
2886				return customCalcMethods.width();
2887			},
2888
2889			documentElementScroll: function getDEScrollWidth(){
2890				return document.documentElement.scrollWidth;
2891			},
2892
2893			documentElementOffset: function getDEOffsetWidth(){
2894				return document.documentElement.offsetWidth;
2895			},
2896
2897			scroll: function getMaxWidth(){
2898				return Math.max(getWidth.bodyScroll(), getWidth.documentElementScroll());
2899			},
2900
2901			max: function getMaxWidth(){
2902				return Math.max.apply(null,getAllMeasurements(getWidth));
2903			},
2904
2905			min: function getMinWidth(){
2906				return Math.min.apply(null,getAllMeasurements(getWidth));
2907			},
2908
2909			rightMostElement: function rightMostElement(){
2910				return getMaxElement('right', getAllElements());
2911			},
2912
2913			taggedElement: function getTaggedElementsWidth(){
2914				return getTaggedElements('right', 'data-iframe-width');
2915			}
2916		};
2917
2918
2919	function sizeIFrame(triggerEvent, triggerEventDesc, customHeight, customWidth){
2920
2921		function resizeIFrame(){
2922			height = currentHeight;
2923			width  = currentWidth;
2924
2925			sendMsg(height,width,triggerEvent);
2926		}
2927
2928		function isSizeChangeDetected(){
2929			function checkTolarance(a,b){
2930				var retVal = Math.abs(a-b) <= tolerance;
2931				return !retVal;
2932			}
2933
2934			currentHeight = (undefined !== customHeight)  ? customHeight : getHeight[height
2934CalcMode]();
2935			currentWidth  = (undefined !== customWidth )  ? customWidth  : getWidth[widthCalcMode]();
2936
2937			return	checkTolarance(height,currentHeight) || (calculateWidth && checkTolarance(width,currentWidth));
2938		}
2939
2940		function isForceResizableEvent(){
2941			return !(triggerEvent in {'init':1,'interval':1,'size':1});
2942		}
2943
2944		function isForceResizableCalcMode(){
2945			return (heightCalcMode in resetRequiredMethods) || (calculateWidth && widthCalcMode in resetRequiredMethods);
2946		}
2947
2948		function logIgnored(){
2949			log('No change in size detected');
2950		}
2951
2952		function checkDownSizing(){
2953			if (isForceResizableEvent() && isForceResizableCalcMode()){
2954				resetIFrame(triggerEventDesc);
2955			} else if (!(triggerEvent in {'interval':1})){
2956				logIgnored();
2957			}
2958		}
2959
2960		var	currentHeight,currentWidth;
2961
2962		if (isSizeChangeDetected() || 'init' === triggerEvent){
2963			lockTrigger();
2964			resizeIFrame();
2965		} else {
2966			checkDownSizing();
2967		}
2968	}
2969
2970	var sizeIFrameThrottled = throttle(sizeIFrame);
2971
2972	function sendSize(triggerEvent, triggerEventDesc, customHeight, customWidth){
2973		function recordTrigger(){
2974			if (!(triggerEvent in {'reset':1,'resetPage':1,'init':1})){
2975				log( 'Trigger event: ' + triggerEventDesc );
2976			}
2977		}
2978
2979		function isDoubleFiredEvent(){
2980			return  triggerLocked && (triggerEvent in doubleEventList);
2981		}
2982
2983		if (!isDoubleFiredEvent()){
2984			recordTrigger();
2985			sizeIFrameThrottled(triggerEvent, triggerEventDesc, customHeight, customWidth);
2986		} else {
2987			log('Trigger event cancelled: '+triggerEvent);
2988		}
2989	}
2990
2991	function lockTrigger(){
2992		if (!triggerLocked){
2993			triggerLocked = true;
2994			log('Trigger event lock on');
2995		}
2996		clearTimeout(triggerLockedTimer);
2997		triggerLockedTimer = setTimeout(function(){
2998			triggerLocked = false;
2999			log('Trigger event lock off');
3000			log('--');
3001		},eventCancelTimer);
3002	}
3003
3004	function triggerReset(triggerEvent){
3005		height = getHeight[heightCalcMode]();
3006		width  = getWidth[widthCalcMode]();
3007
3008		sendMsg(height,width,triggerEvent);
3009	}
3010
3011	function resetIFrame(triggerEventDesc){
3012		var hcm = heightCalcMode;
3013		heightCalcMode = heightCalcModeDefault;
3014
3015		log('Reset trigger event: ' + triggerEventDesc);
3016		lockTrigger();
3017		triggerReset('reset');
3018
3019		heightCalcMode = hcm;
3020	}
3021
3022	function sendMsg(height,width,triggerEvent,msg,targetOrigin){
3023		function setTargetOrigin(){
3024			if (undefined === targetOrigin){
3025				targetOrigin = targetOriginDefault;
3026			} else {
3027				log('Message targetOrigin: '+targetOrigin);
3028			}
3029		}
3030
3031		function sendToParent(){
3032			var
3033				size  = height + ':' + width,
3034				message = myID + ':' +  size + ':' + triggerEvent + (undefined !== msg ? ':' + msg : '');
3035
3036			log('Sending message to host page (' + message + ')');
3037			target.postMessage( msgID + message, targetOrigin);
3038		}
3039
3040		if(true === sendPermit){
3041			setTargetOrigin();
3042			sendToParent();
3043		}
3044	}
3045
3046	function receiver(event) {
3047		function isMessageForUs(){
3048			return msgID === (''+event.data).substr(0,msgIdLen); //''+ Protects against non-string messages
3049		}
3050
3051		function initFromParent(){
3052			function fireInit(){
3053				initMsg = event.data;
3054				target  = event.source;
3055
3056				init();
3057				firstRun = false;
3058				setTimeout(function(){ initLock = false;},eventCancelTimer);
3059			}
3060
3061			if (document.body){
3062				fireInit();
3063			} else {
3064				log('Waiting for page ready');
3065				addEventListener(window,'readystatechange',initFromParent);
3066			}
3067		}
3068
3069		function resetFromParent(){
3070			if (!initLock){
3071				log('Page size reset by host page');
3072				triggerReset('resetPage');
3073			} else {
3074				log('Page reset ignored by init');
3075			}
3076		}
3077
3078		function resizeFromParent(){
3079			sendSize('resizeParent','Parent window requested size check');
3080		}
3081
3082		function moveToAnchor(){
3083			var anchor = getData();
3084			inPageLinks.findTarget(anchor);
3085		}
3086
3087		function getMessageType(){
3088			return event.data.split(']')[1].split(':')[0];
3089		}
3090
3091		function getData(){
3092			return event.data.substr(event.data.indexOf(':')+1);
3093		}
3094
3095		function isMiddleTier(){
3096			return ('iFrameResize' in window);
3097		}
3098
3099		function messageFromParent(){
3100			var msgBody = getData();
3101
3102			log('MessageCallback called from parent: ' + msgBody );
3103			messageCallback(JSON.parse(msgBody));
3104			log(' --');
3105		}
3106
3107		function pageInfoFromParent(){
3108			var msgBody = getData();
3109			log('PageInfoFromParent called from parent: ' + msgBody );
3110			pageInfoCallback(JSON.parse(msgBody));
3111			log(' --');
3112		}
3113
3114		function isInitMsg(){
3115			//Test if this message is from a child below us. This is an ugly test, however, updating
3116			//the message format would break backwards compatibity.
3117			return event.data.split(':')[2] in {'true':1,'false':1};
3118		}
3119
3120		function callFromParent(){
3121			switch (getMessageType()){
3122			case 'reset':
3123				resetFromParent();
3124				break;
3125			case 'resize':
3126				resizeFromParent();
3127				break;
3128			case 'inPageLink':
3129			case 'moveToAnchor':
3130				moveToAnchor();
3131				break;
3132			case 'message':
3133				messageFromParent();
3134				break;
3135			case 'pageInfo':
3136				pageInfoFromParent();
3137				break;
3138			default:
3139				if (!isMiddleTier() && !isInitMsg()){
3140					warn('Unexpected message ('+event.data+')');
3141				}
3142			}
3143		}
3144
3145		function processMessage(){
3146			if (false === firstRun) {
3147				callFromParent();
3148			} else if (isInitMsg()) {
3149				initFromParent();
3150			} else {
3151				log('Ignored message of type "' + getMessageType() + '". Received before initialization.');
3152			}
3153		}
3154
3155		if (isMessageForUs()){
3156			processMessage();
3157		}
3158	}
3159
3160	//Normally the parent kicks things off when it detects the iFrame has loaded.
3161	//If this script is async-loaded, then tell parent page to retry init.
3162	function chkLateLoaded(){
3163		if('loading' !== document.readyState){
3164			window.parent.postMessage('[iFrameResizerChild]Ready','*');
3165		}
3166	}
3167
3168	addEventListener(window, 'message', receiver);
3169	chkLateLoaded();
3170
3171	
3172
3173})(window || {});
3174
3175},{}],21:[function(require,module,exports){
3176/*
3177 * File: iframeResizer.js
3178 * Desc: Force iframes to size to content.
3179 * Requires: iframeResizer.contentWindow.js to be loaded into the target frame.
3180 * Doc: https://github.com/davidjbradshaw/iframe-resizer
3181 * Author: David J. Bradshaw - [email protected]
3182 * Contributor: Jure Mav - [email protected]
3183 * Contributor: Reed Dadoune - [email protected]
3184 */
3185
3186
3187;(function(window) {
3188	'use strict';
3189
3190	var
3191		count                 = 0,
3192		logEnabled            = false,
3193		hiddenCheckEnabled    = false,
3194		msgHeader             = 'message',
3195		msgHeaderLen          = msgHeader.length,
3196		msgId                 = '[iFrameSizer]', //Must match iframe msg ID
3197		msgIdLen              = msgId.length,
3198		pagePosition          = null,
3199		requestAnimationFrame = window.requestAnimationFrame,
3200		resetRequiredMethods  = {max:1,scroll:1,bodyScroll:1,documentElementScroll:1},
3201		settings              = {},
3202		timer                 = null,
3203		logId                 = 'Host Page',
3204
3205		defaults              = {
3206			autoResize                : true,
3207			bodyBackground            : null,
3208			bodyMargin                : null,
3209			bodyMarginV1              : 8,
3210			bodyPadding               : null,
3211			checkOrigin               : true,
3212			inPageLinks               : false,
3213			enablePublicMethods       : true,
3214			heightCalculationMethod   : 'bodyOffset',
3215			id                        : 'iFrameResizer',
3216			interval                  : 32,
3217			log                       : false,
3218			maxHeight                 : Infinity,
3219			maxWidth                  : Infinity,
3220			minHeight                 : 0,
3221			minWidth                  : 0,
3222			resizeFrom                : 'parent',
3223			scrolling                 : false,
3224			sizeHeight                : true,
3225			sizeWidth                 : false,
3226			tolerance                 : 0,
3227			widthCalculationMethod    : 'scroll',
3228			closedCallback            : function(){},
3229			initCallback              : function(){},
3230			messageCallback           : function(){warn('MessageCallback function not defined');},
3231			resizedCallback           : function(){},
3232			scrollCallback            : function(){return true;}
3233		};
3234
3235	function addEventListener(obj,evt,func){
3236		/* istanbul ignore else */ // Not testable in PhantonJS
3237		if ('addEventListener' in window){
3238			obj.addEventListener(evt,func, false);
3239		} else if ('attachEvent' in window){//IE
3240			obj.attachEvent('on'+evt,func);
3241		}
3242	}
3243
3244	function removeEventListener(el,evt,func){
3245		/* istanbul ignore else */ // Not testable in phantonJS
3246		if ('removeEventListener' in window){
3247			el.removeEventListener(evt,func, false);
3248		} else if ('detachEvent' in window){ //IE
3249			el.detachEvent('on'+evt,func);
3250		}
3251	}
3252
3253	function setupRequestAnimationFrame(){
3254		var
3255			vendors = ['moz', 'webkit', 'o', 'ms'],
3256			x;
3257
3258		// Remove vendor prefixing if prefixed and break early if not
3259		for (x = 0; x < vendors.length && !requestAnimationFrame; x += 1) {
3260			requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
3261		}
3262
3263		if (!(requestAnimationFrame)){
3264			log('setup','RequestAnimationFrame not supported');
3265		}
3266	}
3267
3268	function getMyID(iframeId){
3269		var retStr = 'Host page: '+iframeId;
3270
3271		if (window.top!==window.self){
3272			if (window.parentIFrame && window.parentIFrame.getId){
3273				retStr = window.parentIFrame.getId()+': '+iframeId;
3274			} else {
3275				retStr = 'Nested host page: '+iframeId;
3276			}
3277		}
3278
3279		return retStr;
3280	}
3281
3282	function formatLogHeader(iframeId){
3283		return msgId + '[' + getMyID(iframeId) + ']';
3284	}
3285
3286	function isLogEnabled(iframeId){
3287		return settings[iframeId] ? settings[iframeId].log : logEnabled;
3288	}
3289
3290	function log(iframeId,msg){
3291		output('log',iframeId,msg,isLogEnabled(iframeId));
3292	}
3293
3294	function info(iframeId,msg){
3295		output('info',iframeId,msg,isLogEnabled(iframeId));
3296	}
3297
3298	function warn(iframeId,msg){
3299		output('warn',iframeId,msg,true);
3300	}
3301
3302	function output(type,iframeId,msg,enabled){
3303		if (true === enabled && 'object' === typeof window.console){
3304			console[type](formatLogHeader(iframeId),msg);
3305		}
3306	}
3307
3308	function iFrameListener(event){
3309		function resizeIFrame(){
3310			function resize(){
3311				setSize(messageData);
3312				setPagePosition(iframeId);
3313			}
3314
3315			ensureInRange('Height');
3316			ensureInRange('Width');
3317
3318			syncResize(resize,messageData,'init');
3319		}
3320
3321		function processMsg(){
3322			var data = msg.substr(msgIdLen).split(':');
3323
3324			return {
3325				iframe: settings[data[0]].iframe,
3326				id:     data[0],
3327				height: data[1],
3328				width:  data[2],
3329				type:   data[3]
3330			};
3331		}
3332
3333		function ensureInRange(Dimension){
3334			var
3335				max  = Number(settings[iframeId]['max' + Dimension]),
3336				min  = Number(settings[iframeId]['min' + Dimension]),
3337				dimension = Dimension.toLowerCase(),
3338				size = Number(messageData[dimension]);
3339
3340			log(iframeId,'Checking ' + dimension + ' is in range ' + min + '-' + max);
3341
3342			if (size<min) {
3343				size=min;
3344				log(iframeId,'Set ' + dimension + ' to min value');
3345			}
3346
3347			if (size>max) {
3348				size=max;
3349				log(iframeId,'Set ' + dimension + ' to max value');
3350			}
3351
3352			messageData[dimension] = '' + size;
3353		}
3354
3355
3356		function isMessageFromIFrame(){
3357			function checkAllowedOrigin(){
3358				function checkList(){
3359					var
3360						i = 0,
3361						retCode = false;
3362
3363					log(iframeId,'Checking connection is from allowed list of origins: ' + checkOrigin);
3364
3365					for (; i < checkOrigin.length; i++) {
3366						if (checkOrigin[i] === origin) {
3367							retCode = true;
3368							break;
3369						}
3370					}
3371					return retCode;
3372				}
3373
3374				function checkSingle(){
3375					var remoteHost  = settings[iframeId].remoteHost;
3376					log(iframeId,'Checking connection is from: '+remoteHost);
3377					return origin === remoteHost;
3378				}
3379
3380				return checkOrigin.constructor === Array ? checkList() : checkSingle();
3381			}
3382
3383			var
3384				origin      = event.origin,
3385				checkOrigin = settings[iframeId].checkOrigin;
3386
3387			if (checkOrigin && (''+origin !== 'null') && !checkAllowedOrigin()) {
3388				throw new Error(
3389					'Unexpected message received from: ' + origin +
3390					' for ' + messageData.iframe.id +
3391					'. Message was: ' + event.data +
3392					'. This error can be disabled by setting the checkOrigin: false option or by providing of array of trusted domains.'
3393				);
3394			}
3395
3396			return true;
3397		}
3398
3399		function isMessageForUs(){
3400			return msgId === (('' + msg).substr(0,msgIdLen)) && (msg.substr(msgIdLen).split(':')[0] in settings); //''+Protects against non-string msg
3401		}
3402
3403		function isMessageFromMetaParent(){
3404			//Test if this message is from a parent above us. This is an ugly test, however, updating
3405			//the message format would break backwards compatibity.
3406			var retCode = messageData.type in {'true':1,'false':1,'undefined':1};
3407
3408			if (retCode){
3409				log(iframeId,'Ignoring init message from meta parent page');
3410			}
3411
3412			return retCode;
3413		}
3414
3415		function getMsgBody(offset){
3416			return msg.substr(msg.indexOf(':')+msgHeaderLen+offset);
3417		}
3418
3419		function forwardMsgFromIFrame(msgBody){
3420			log(iframeId,'MessageCallback passed: {iframe: '+ messageData.iframe.id + ', message: ' + msgBody + '}');
3421			callback('messageCallback',{
3422				iframe: messageData.iframe,
3423				message: JSON.parse(msgBody)
3424			});
3425			log(iframeId,'--');
3426		}
3427
3428		function getPageInfo(){
3429			var
3430				bodyPosition   = document.body.getBoundingClientRect(),
3431				iFramePosition = messageData.iframe.getBoundingClientRect();
3432
3433			return JSON.stringify({
3434				iframeHeight: iFramePosition.height,
3435				iframeWidth:  iFramePosition.width,
3436				clientHeight: Math.max(document.documentElement.clientHeight, window.innerHeight || 0),
3437				clientWidth:  Math.max(document.documentElement.clientWidth,  window.innerWidth  || 0),
3438				offsetTop:    parseInt(iFramePosition.top  - bodyPosition.top,  10),
3439				offsetLeft:   parseInt(iFramePosition.left - bodyPosition.left, 10),
3440				scrollTop:    window.pageYOffset,
3441				scrollLeft:   window.pageXOffset
3442			});
3443		}
3444
3445		function sendPageInfoToIframe(iframe,iframeId){
3446			function debouncedTrigger(){
3447				trigger(
3448					'Send Page Info',
3449					'pageInfo:' + getPageInfo(), 
3450					iframe, 
3451					iframeId
3452				);
3453			}
3454
3455			debouce(debouncedTrigger,32);
3456		}
3457
3458
3459		function startPageInfoMonitor(){
3460			function setListener(type,func){
3461				function sendPageInfo(){
3462					if (settings[id]){
3463						sendPageInfoToIframe(settings[id].iframe,id);
3464					} else {
3465						stop();
3466					}
3467				}
3468
3469				['scroll','resize'].forEach(function(evt){
3470					log(id, type +  evt + ' listener for sendPageInfo');
3471					func(window,evt,sendPageInfo);
3472				});
3473			}
3474
3475			function stop(){
3476				setListener('Remove ', removeEventListener);
3477			}
3478
3479			function start(){
3480				setListener('Add ', addEventListener);
3481			}
3482			
3483			var id = iframeId; //Create locally scoped copy of iFrame ID
3484
3485			start();
3486
3487			settings[id].stopPageInfo = stop;
3488		}
3489
3490		function stopPageInfoMonitor(){
3491			if (settings[iframeId] && settings[iframeId].stopPageInfo){
3492				settings[iframeId].stopPageInfo();
3493				delete settings[iframeId].stopPageInfo;
3494			}
3495		}
3496
3497		function checkIFrameExists(){
3498			var retBool = true;
3499
3500			if (null === messageData.iframe) {
3501				warn(iframeId,'IFrame ('+messageData.id+') not found');
3502				retBool = false;
3503			}
3504			return retBool;
3505		}
3506
3507		function getElementPosition(target){
3508			var iFramePosition = target.getBoundingClientRect();
3509
3510			getPagePosition(iframeId);
3511
3512			return {
3513				x: Math.floor( Number(iFramePosition.left) + Number(pagePosition.x) ),
3514				y: Math.floor( Number(iFramePosition.top)  + Number(pagePosition.y) )
3515			};
3516		}
3517
3518		function scrollRequestFromChild(addOffset){
3519			/* istanbul ignore next */  //Not testable in Karma
3520			function reposition(){
3521				pagePosition = newPosition;
3522				scrollTo();
3523				log(iframeId,'--');
3524			}
3525
3526			function calcOffset(){
3527				return {
3528					x: Number(messageData.width) + offset.x,
3529					y: Number(messageData.height) + offset.y
3530				};
3531			}
3532
3533			function scrollParent(){
3534				if (window.parentIFrame){
3535					window.parentIFrame['scrollTo'+(addOffset?'Offset':'')](newPosition.x,newPosition.y);
3536				} else {
3537					warn(iframeId,'Unable to scroll to requested position, window.parentIFrame not found');
3538				}
3539			}
3540
3541			var
3542				offset = addOffset ? getElementPosition(messageData.iframe) : {x:0,y:0},
3543				newPosition = calcOffset();
3544
3545			log(iframeId,'Reposition requested from iFrame (offset x:'+offset.x+' y:'+offset.y+')');
3546
3547			if(window.top!==window.self){
3548				scrollParent();
3549			} else {
3550				reposition();
3551			}
3552		}
3553
3554		function scrollTo(){
3555			if (false !== callback('scrollCallback',pagePosition)){
3556				setPagePosition(iframeId);
3557			} else {
3558				unsetPagePosition();
3559			}
3560		}
3561
3562		function findTarget(location){
3563			function jumpToTarget(){
3564				var jumpPosition = getElementPosition(target);
3565
3566				log(iframeId,'Moving to in page link (#'+hash+') at x: '+jumpPosition.x+' y: '+jumpPosition.y);
3567				pagePosition = {
3568					x: jumpPosition.x,
3569					y: jumpPosition.y
3570				};
3571
3572				scrollTo();
3573				log(iframeId,'--');
3574			}
3575
3576			function jumpToParent(){
3577				if (window.parentIFrame){
3578					window.parentIFrame.moveToAnchor(hash);
3579				} else {
3580					log(iframeId,'In page link #'+hash+' not found and window.parentIFrame not found');
3581				}
3582			}
3583
3584			var
3585				hash     = location.split('#')[1] || '',
3586				hashData = decodeURIComponent(hash),
3587				target   = document.getElementById(hashData) || document.getElementsByName(hashData)[0];
3588
3589			if (target){
3590				jumpToTarget();
3591			} else if(window.top!==window.self){
3592				jumpToParent();
3593			} else {
3594				log(iframeId,'In page link #'+hash+' not found');
3595			}
3596		}
3597
3598		function callback(funcName,val){
3599			return chkCallback(iframeId,funcName,val);
3600		}
3601
3602		function actionMsg(){
3603
3604			if(settings[iframeId].firstRun) firstRun();
3605
3606			switch(messageData.type){
3607			case 'close':
3608				closeIFrame(messageData.iframe);
3609				break;
3610			case 'message':
3611				forwardMsgFromIFrame(getMsgBody(6));
3612				break;
3613			case 'scrollTo':
3614				scrollRequestFromChild(false);
3615				break;
3616			case 'scrollToOffset':
3617				scrollRequestFromChild(true);
3618				break;
3619			case 'pageInfo':
3620				sendPageInfoToIframe(settings[iframeId].iframe,iframeId);
3621				startPageInfoMonitor();
3622				break;
3623			case 'pageInfoStop':
3624				stopPageInfoMonitor();
3625				break;
3626			case 'inPageLink':
3627				findTarget(getMsgBody(9));
3628				break;
3629			case 'reset':
3630				resetIFrame(messageData);
3631				break;
3632			case 'init':
3633				resizeIFrame();
3634				callback('initCallback',messageData.iframe);
3635				callback('resizedCallback',messageData);
3636				break;
3637			default:
3638				resizeIFrame();
3639				callback('resizedCallback',messageData);
3640			}
3641		}
3642
3643		function hasSettings(iframeId){
3644			var retBool = true;
3645
3646			if (!settings[iframeId]){
3647				retBool = false;
3648				warn(messageData.type + ' No settings for ' + iframeId + '. Message was: ' + msg);
3649			}
3650
3651			return retBool;
3652		}
3653
3654		function iFrameReadyMsgReceived(){
3655			for (var iframeId in settings){
3656				trigger('iFrame requested init',createOutgoingMsg(iframeId),document.getElementById(iframeId),iframeId);
3657			}
3658		}
3659
3660		function firstRun() {
3661			settings[iframeId].firstRun = false;
3662		}
3663
3664		var
3665			msg = event.data,
3666			messageData = {},
3667			iframeId = null;
3668
3669		if('[iFrameResizerChild]Ready' === msg){
3670			iFrameReadyMsgReceived();
3671		} else if (isMessageForUs()){
3672			messageData = processMsg();
3673			iframeId    = logId = messageData.id;
3674
3675			if (!isMessageFromMetaParent() && hasSettings(iframeId)){
3676				log(iframeId,'Received: '+msg);
3677
3678				if ( checkIFrameExists() && isMessageFromIFrame() ){
3679					actionMsg();
3680				}
3681			}
3682		} else {
3683			info(iframeId,'Ignored: '+msg);
3684		}
3685
3686	}
3687
3688
3689	function chkCallback(iframeId,funcName,val){
3690		var
3691			func = null,
3692			retVal = null;
3693
3694		if(settings[iframeId]){
3695			func = settings[iframeId][funcName];
3696
3697			if( 'function' === typeof func){
3698				retVal = func(val);
3699			} else {
3700				throw new TypeError(funcName+' on iFrame['+iframeId+'] is not a function');
3701			}
3702		}
3703
3704		return retVal;
3705	}
3706
3707	function closeIFrame(iframe){
3708		var iframeId = iframe.id;
3709
3710		log(iframeId,'Removing iFrame: '+iframeId);
3711		iframe.parentNode.removeChild(iframe);
3712		chkCallback(iframeId,'closedCallback',iframeId);
3713		log(iframeId,'--');
3714		delete settings[iframeId];
3715	}
3716
3717	function getPagePosition(iframeId){
3718		if(null === pagePosition){
3719			pagePosition = {
3720				x: (window.pageXOffset !== undefined) ? window.pageXOffset : document.documentElement.scrollLeft,
3721				y: (window.pageYOffset !== undefined) ? window.pageYOffset : document.documentElement.scrollTop
3722			};
3723			log(iframeId,'Get page position: '+pagePosition.x+','+pagePosition.y);
3724		}
3725	}
3726
3727	function setPagePosition(iframeId){
3728		if(null !== pagePosition){
3729			window.scrollTo(pagePosition.x,pagePosition.y);
3730			log(iframeId,'Set page position: '+pagePosition.x+','+pagePosition.y);
3731			unsetPagePosition();
3732		}
3733	}
3734
3735	function unsetPagePosition(){
3736		pagePosition = null;
3737	}
3738
3739	function resetIFrame(messageData){
3740		function reset(){
3741			setSize(messageData);
3742			trigger('reset','reset',messageData.iframe,messageData.id);
3743		}
3744
3745		log(messageData.id,'Size reset requested by '+('init'===messageData.type?'host page':'iFrame'));
3746		getPagePosition(messageData.id);
3747		syncResize(reset,messageData,'reset');
3748	}
3749
3750	function setSize(messageData){
3751		function setDimension(dimension){
3752			messageData.iframe.style[dimension] = messageData[dimension] + 'px';
3753			log(
3754				messageData.id,
3755				'IFrame (' + iframeId +
3756				') ' + dimension +
3757				' set to ' + messageData[dimension] + 'px'
3758			);
3759		}
3760
3761		function chkZero(dimension){
3762			//FireFox sets dimension of hidden iFrames to zero.
3763			//So if we detect that set up an event to check for
3764			//when iFrame becomes visible.
3765
3766			/* istanbul ignore next */  //Not testable in PhantomJS
3767			if (!hiddenCheckEnabled && '0' === messageData[dimension]){
3768				hiddenCheckEnabled = true;
3769				log(iframeId,'Hidden iFrame detected, creating visibility listener');
3770				fixHiddenIFrames();
3771			}
3772		}
3773
3774		function processDimension(dimension){
3775			setDimension(dimension);
3776			chkZero(dimension);
3777		}
3778
3779		var iframeId = messageData.iframe.id;
3780
3781		if(settings[iframeId]){
3782			if( settings[iframeId].sizeHeight) { processDimension('height'); }
3783			if( settings[iframeId].sizeWidth ) { processDimension('width'); }
3784		}
3785	}
3786
3787	function syncResize(func,messageData,doNotSync){
3788		/* istanbul ignore if */  //Not testable in PhantomJS
3789		if(doNotSync!==messageData.type && requestAnimationFrame){
3790			log(messageData.id,'Requesting animation frame');
3791			requestAnimationFrame(func);
3792		} else {
3793			func();
3794		}
3795	}
3796
3797	function trigger(calleeMsg,msg,iframe,id){
3798		function postMessageToIFrame(){
3799			var target = settings[id].targetOrigin;
3800			log(id,'[' + calleeMsg + '] Sending msg to iframe['+id+'] ('+msg+') targetOrigin: '+target);
3801			iframe.contentWindow.postMessage( msgId + msg, target );
3802		}
3803
3804		function iFrameNotFound(){
3805			info(id,'[' + calleeMsg + '] IFrame('+id+') not found');
3806			if(settings[id]) {
3807				delete settings[id];
3808			}
3809		}
3810
3811		function chkAndSend(){
3812			if(iframe && 'contentWindow' in iframe && (null !== iframe.contentWindow)){ //Null test for PhantomJS
3813				postMessageToIFrame();
3814			} else {
3815				iFrameNotFound();
3816			}
3817		}
3818
3819		id = id || iframe.id;
3820
3821		if(settings[id]) {
3822			chkAndSend();
3823		}
3824
3825	}
3826
3827	function createOutgoingMsg(iframeId){
3828		return iframeId +
3829			':' + settings[iframeId].bodyMarginV1 +
3830			':' + settings[iframeId].sizeWidth +
3831			':' + settings[iframeId].log +
3832			':' + settings[iframeId].interval +
3833			':' + settings[iframeId].enablePublicMethods +
3834			':' + settings[iframeId].autoResize +
3835			':' + settings[iframeId].bodyMargin +
3836			':' + settings[iframeId].heightCalculationMethod +
3837			':' + settings[iframeId].bodyBackground +
3838			':' + settings[iframeId].bodyPadding +
3839			':' + settings[iframeId].tolerance +
3840			':' + settings[iframeId].inPageLinks +
3841			':' + settings[iframeId].resizeFrom +
3842			':' + settings[iframeId].widthCalculationMethod;
3843	}
3844
3845	function setupIFrame(iframe,options){
3846		function setLimits(){
3847			function addStyle(style){
3848				if ((Infinity !== settings[iframeId][style]) && (0 !== settings[iframeId][style])){
3849					iframe.style[style] = settings[iframeId][style] + 'px';
3850					log(iframeId,'Set '+style+' = '+settings[iframeId][style]+'px');
3851				}
3852			}
3853
3854			function chkMinMax(dimension){
3855				if (settings[iframeId]['min'+dimension]>settings[iframeId]['max'+dimension]){
3856					throw new Error('Value for min'+dimension+' can not be greater than max'+dimension);
3857				}
3858			}
3859
3860			chkMinMax('Height');
3861			chkMinMax('Width');
3862
3863			addStyle('maxHeight');
3864			addStyle('minHeight');
3865			addStyle('maxWidth');
3866			addStyle('minWidth');
3867		}
3868
3869		function newId(){
3870			var id = ((options && options.id) || defaults.id + count++);
3871			if  (null!==document.getElementById(id)){
3872				id = id + count++;
3873			}
3874			return id;
3875		}
3876
3877		function ensureHasId(iframeId){
3878			logId=iframeId;
3879			if (''===iframeId){
3880				iframe.id = iframeId =  newId();
3881				logEnabled = (options || {}).log;
3882				logId=iframeId;
3883				log(iframeId,'Added missing iframe ID: '+ iframeId +' (' + iframe.
3883src + ')');
3884			}
3885
3886
3887			return iframeId;
3888		}
3889
3890		function setScrolling(){
3891			log(iframeId,'IFrame scrolling ' + (settings[iframeId].scrolling ? 'enabled' : 'disabled') + ' for ' + iframeId);
3892			iframe.style.overflow = false === settings[iframeId].scrolling ? 'hidden' : 'auto';
3893			iframe.scrolling      = false === settings[iframeId].scrolling ? 'no' : 'yes';
3894		}
3895
3896		//The V1 iFrame script expects an int, where as in V2 expects a CSS
3897		//string value such as '1px 3em', so if we have an int for V2, set V1=V2
3898		//and then convert V2 to a string PX value.
3899		function setupBodyMarginValues(){
3900			if (('number'===typeof(settings[iframeId].bodyMargin)) || ('0'===settings[iframeId].bodyMargin)){
3901				settings[iframeId].bodyMarginV1 = settings[iframeId].bodyMargin;
3902				settings[iframeId].bodyMargin   = '' + settings[iframeId].bodyMargin + 'px';
3903			}
3904		}
3905
3906		function checkReset(){
3907			// Reduce scope of firstRun to function, because IE8's JS execution
3908			// context stack is borked and this value gets externally
3909			// changed midway through running this function!!!
3910			var
3911				firstRun           = settings[iframeId].firstRun,
3912				resetRequertMethod = settings[iframeId].heightCalculationMethod in resetRequiredMethods;
3913
3914			if (!firstRun && resetRequertMethod){
3915				resetIFrame({iframe:iframe, height:0, width:0, type:'init'});
3916			}
3917		}
3918
3919		function setupIFrameObject(){
3920			if(Function.prototype.bind){ //Ignore unpolyfilled IE8.
3921				settings[iframeId].iframe.iFrameResizer = {
3922
3923					close        : closeIFrame.bind(null,settings[iframeId].iframe),
3924
3925					resize       : trigger.bind(null,'Window resize', 'resize', settings[iframeId].iframe),
3926
3927					moveToAnchor : function(anchor){
3928						trigger('Move to anchor','moveToAnchor:'+anchor, settings[iframeId].iframe,iframeId);
3929					},
3930
3931					sendMessage  : function(message){
3932						message = JSON.stringify(message);
3933						trigger('Send Message','message:'+message, settings[iframeId].iframe,iframeId);
3934					}
3935				};
3936			}
3937		}
3938
3939		//We have to call trigger twice, as we can not be sure if all
3940		//iframes have completed loading when this code runs. The
3941		//event listener also catches the page changing in the iFrame.
3942		function init(msg){
3943			function iFrameLoaded(){
3944				trigger('iFrame.onload',msg,iframe);
3945				checkReset();
3946			}
3947
3948			addEventListener(iframe,'load',iFrameLoaded);
3949			trigger('init',msg,iframe);
3950		}
3951
3952		function checkOptions(options){
3953			if ('object' !== typeof options){
3954				throw new TypeError('Options is not an object');
3955			}
3956		}
3957
3958		function copyOptions(options){
3959			for (var option in defaults) {
3960				if (defaults.hasOwnProperty(option)){
3961					settings[iframeId][option] = options.hasOwnProperty(option) ? options[option] : defaults[option];
3962				}
3963			}
3964		}
3965
3966		function getTargetOrigin (remoteHost){
3967			return ('' === remoteHost || 'file://' === remoteHost) ? '*' : remoteHost;
3968		}
3969
3970		function processOptions(options){
3971			options = options || {};
3972			settings[iframeId] = {
3973				firstRun	: true,
3974				iframe		: iframe,
3975				remoteHost	: iframe.src.split('/').slice(0,3).join('/')
3976			};
3977
3978			checkOptions(options);
3979			copyOptions(options);
3980
3981			settings[iframeId].targetOrigin = true === settings[iframeId].checkOrigin ? getTargetOrigin(settings[iframeId].remoteHost) : '*';
3982		}
3983
3984		function beenHere(){
3985			return (iframeId in settings && 'iFrameResizer' in iframe);
3986		}
3987
3988		var iframeId = ensureHasId(iframe.id);
3989
3990		if (!beenHere()){
3991			processOptions(options);
3992			setScrolling();
3993			setLimits();
3994			setupBodyMarginValues();
3995			init(createOutgoingMsg(iframeId));
3996			setupIFrameObject();
3997		} else {
3998			warn(iframeId,'Ignored iFrame, already setup.');
3999		}
4000	}
4001
4002	function debouce(fn,time){
4003		if (null === timer){
4004			timer = setTimeout(function(){
4005				timer = null;
4006				fn();
4007			}, time);
4008		}
4009	}
4010
4011	/* istanbul ignore next */  //Not testable in PhantomJS
4012	function fixHiddenIFrames(){
4013		function checkIFrames(){
4014			function checkIFrame(settingId){
4015				function chkDimension(dimension){
4016					return '0px' === settings[settingId].iframe.style[dimension];
4017				}
4018
4019				function isVisible(el) {
4020					return (null !== el.offsetParent);
4021				}
4022
4023				if (isVisible(settings[settingId].iframe) && (chkDimension('height') || chkDimension('width'))){
4024					trigger('Visibility change', 'resize', settings[settingId].iframe,settingId);
4025				}
4026			}
4027
4028			for (var settingId in settings){
4029				checkIFrame(settingId);
4030			}
4031		}
4032
4033		function mutationObserved(mutations){
4034			log('window','Mutation observed: ' + mutations[0].target + ' ' + mutations[0].type);
4035			debouce(checkIFrames,16);
4036		}
4037
4038		function createMutationObserver(){
4039			var
4040				target = document.querySelector('body'),
4041
4042				config = {
4043					attributes            : true,
4044					attributeOldValue     : false,
4045					characterData         : true,
4046					characterDataOldValue : false,
4047					childList             : true,
4048					subtree               : true
4049				},
4050
4051				observer = new MutationObserver(mutationObserved);
4052
4053			observer.observe(target, config);
4054		}
4055
4056		var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
4057
4058		if (MutationObserver) createMutationObserver();
4059	}
4060
4061
4062	function resizeIFrames(event){
4063		function resize(){
4064			sendTriggerMsg('Window '+event,'resize');
4065		}
4066
4067		log('window','Trigger event: '+event);
4068		debouce(resize,16);
4069	}
4070
4071	/* istanbul ignore next */  //Not testable in PhantomJS
4072	function tabVisible() {
4073		function resize(){
4074			sendTriggerMsg('Tab Visable','resize');
4075		}
4076
4077		if('hidden' !== document.visibilityState) {
4078			log('document','Trigger event: Visiblity change');
4079			debouce(resize,16);
4080		}
4081	}
4082
4083	function sendTriggerMsg(eventName,event){
4084		function isIFrameResizeEnabled(iframeId) {
4085			return	'parent' === settings[iframeId].resizeFrom &&
4086					settings[iframeId].autoResize &&
4087					!settings[iframeId].firstRun;
4088		}
4089
4090		for (var iframeId in settings){
4091			if(isIFrameResizeEnabled(iframeId)){
4092				trigger(eventName,event,document.getElementById(iframeId),iframeId);
4093			}
4094		}
4095	}
4096
4097	function setupEventListeners(){
4098		addEventListener(window,'message',iFrameListener);
4099
4100		addEventListener(window,'resize', function(){resizeIFrames('resize');});
4101
4102		addEventListener(document,'visibilitychange',tabVisible);
4103		addEventListener(document,'-webkit-visibilitychange',tabVisible); //Andriod 4.4
4104		addEventListener(window,'focusin',function(){resizeIFrames('focus');}); //IE8-9
4105		addEventListener(window,'focus',function(){resizeIFrames('focus');});
4106	}
4107
4108
4109	function factory(){
4110		function init(options,element){
4111			function chkType(){
4112				if(!element.tagName) {
4113					throw new TypeError('Object is not a valid DOM element');
4114				} else if ('IFRAME' !== element.tagName.toUpperCase()) {
4115					throw new TypeError('Expected <IFRAME> tag, found <'+element.tagName+'>');
4116				}
4117			}
4118
4119			if(element) {
4120				chkType();
4121				setupIFrame(element, options);
4122				iFrames.push(element);
4123			}
4124		}
4125
4126		var iFrames;
4127
4128		setupRequestAnimationFrame();
4129		setupEventListeners();
4130
4131		return function iFrameResizeF(options,target){
4132			iFrames = []; //Only return iFrames past in on this call
4133
4134			switch (typeof(target)){
4135			case 'undefined':
4136			case 'string':
4137				Array.prototype.forEach.call(
4138					document.querySelectorAll( target || 'iframe' ),
4139					init.bind(undefined, options)
4140				);
4141				break;
4142			case 'object':
4143				init(options,target);
4144				break;
4145			default:
4146				throw new TypeError('Unexpected data type ('+typeof(target)+')');
4147			}
4148
4149			return iFrames;
4150		};
4151	}
4152
4153	function createJQueryPublicMethod($){
4154		if (!$.fn) {
4155			info('','Unable to bind to jQuery, it is not fully loaded.');
4156		} else {
4157			$.fn.iFrameResize = function $iFrameResizeF(options) {
4158				function init(index, element) {
4159					setupIFrame(element, options);
4160				}
4161
4162				return this.filter('iframe').each(init).end();
4163			};
4164		}
4165	}
4166
4167	if (window.jQuery) { createJQueryPublicMethod(jQuery); }
4168
4169	if (typeof define === 'function' && define.amd) {
4170		define([],factory);
4171	} else if (typeof module === 'object' && typeof module.exports === 'object') { //Node for browserfy
4172		module.exports = factory();
4173	} else {
4174		window.iFrameResize = window.iFrameResize || factory();
4175	}
4176
4177})(window || {});
4178
4179},{}],22:[function(require,module,exports){
4180exports.iframeResizer = require('./iframeResizer');
4181exports.iframeResizerContentWindow = require('./iframeResizer.contentWindow');
4182
4183},{"./iframeResizer":21,"./iframeResizer.contentWindow":20}],23:[function(require,module,exports){
4184module.exports = Array.isArray || function (arr) {
4185  return Object.prototype.toString.call(arr) == '[object Array]';
4186};
4187
4188},{}],24:[function(require,module,exports){
4189/*
4190 * jQuery Easing v1.3.2 - http://gsgd.co.uk/sandbox/jquery/easing/
4191 * Open source under the BSD License.
4192 * Copyright © 2008 George McGinley Smith
4193 * All rights reserved.
4194 * https://raw.github.com/gdsmith/jquery-easing/master/LICENSE
4195*/
4196
4197// t: current time, b: begInnIng value, c: change In value, d: duration
4198(function($){$.easing['jswing'] = $.easing['swing'];
4199
4200$.extend( $.easing,
4201{
4202	def: 'easeOutQuad',
4203	swing: function (x, t, b, c, d) {
4204		//alert($.easing.default);
4205		return $.easing[$.easing.def](x, t, b, c, d);
4206	},
4207	easeInQuad: function (x, t, b, c, d) {
4208		return c*(t/=d)*t + b;
4209	},
4210	easeOutQuad: function (x, t, b, c, d) {
4211		return -c *(t/=d)*(t-2) + b;
4212	},
4213	easeInOutQuad: function (x, t, b, c, d) {
4214		if ((t/=d/2) < 1) return c/2*t*t + b;
4215		return -c/2 * ((--t)*(t-2) - 1) + b;
4216	},
4217	easeInCubic: function (x, t, b, c, d) {
vendor: 4,949 bytes, lines 4218-4377
4218		return c*(t/=d)*t*t + b;
4219	},
4220	easeOutCubic: function (x, t, b, c, d) {
4221		return c*((t=t/d-1)*t*t + 1) + b;
4222	},
4223	easeInOutCubic: function (x, t, b, c, d) {
4224		if ((t/=d/2) < 1) return c/2*t*t*t + b;
4225		return c/2*((t-=2)*t*t + 2) + b;
4226	},
4227	easeInQuart: function (x, t, b, c, d) {
4228		return c*(t/=d)*t*t*t + b;
4229	},
4230	easeOutQuart: function (x, t, b, c, d) {
4231		return -c * ((t=t/d-1)*t*t*t - 1) + b;
4232	},
4233	easeInOutQuart: function (x, t, b, c, d) {
4234		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
4235		return -c/2 * ((t-=2)*t*t*t - 2) + b;
4236	},
4237	easeInQuint: function (x, t, b, c, d) {
4238		return c*(t/=d)*t*t*t*t + b;
4239	},
4240	easeOutQuint: function (x, t, b, c, d) {
4241		return c*((t=t/d-1)*t*t*t*t + 1) + b;
4242	},
4243	easeInOutQuint: function (x, t, b, c, d) {
4244		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
4245		return c/2*((t-=2)*t*t*t*t + 2) + b;
4246	},
4247	easeInSine: function (x, t, b, c, d) {
4248		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
4249	},
4250	easeOutSine: function (x, t, b, c, d) {
4251		return c * Math.sin(t/d * (Math.PI/2)) + b;
4252	},
4253	easeInOutSine: function (x, t, b, c, d) {
4254		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
4255	},
4256	easeInExpo: function (x, t, b, c, d) {
4257		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
4258	},
4259	easeOutExpo: function (x, t, b, c, d) {
4260		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
4261	},
4262	easeInOutExpo: function (x, t, b, c, d) {
4263		if (t==0) return b;
4264		if (t==d) return b+c;
4265		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
4266		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
4267	},
4268	easeInCirc: function (x, t, b, c, d) {
4269		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
4270	},
4271	easeOutCirc: function (x, t, b, c, d) {
4272		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
4273	},
4274	easeInOutCirc: function (x, t, b, c, d) {
4275		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
4276		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
4277	},
4278	easeInElastic: function (x, t, b, c, d) {
4279		var s=1.70158;var p=0;var a=c;
4280		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4281		if (a < Math.abs(c)) { a=c; var s=p/4; }
4282		else var s = p/(2*Math.PI) * Math.asin (c/a);
4283		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4284	},
4285	easeOutElastic: function (x, t, b, c, d) {
4286		var s=1.70158;var p=0;var a=c;
4287		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
4288		if (a < Math.abs(c)) { a=c; var s=p/4; }
4289		else var s = p/(2*Math.PI) * Math.asin (c/a);
4290		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
4291	},
4292	easeInOutElastic: function (x, t, b, c, d) {
4293		var s=1.70158;var p=0;var a=c;
4294		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
4295		if (a < Math.abs(c)) { a=c; var s=p/4; }
4296		else var s = p/(2*Math.PI) * Math.asin (c/a);
4297		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
4298		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
4299	},
4300	easeInBack: function (x, t, b, c, d, s) {
4301		if (s == undefined) s = 1.70158;
4302		return c*(t/=d)*t*((s+1)*t - s) + b;
4303	},
4304	easeOutBack: function (x, t, b, c, d, s) {
4305		if (s == undefined) s = 1.70158;
4306		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
4307	},
4308	easeInOutBack: function (x, t, b, c, d, s) {
4309		if (s == undefined) s = 1.70158; 
4310		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
4311		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
4312	},
4313	easeInBounce: function (x, t, b, c, d) {
4314		return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
4315	},
4316	easeOutBounce: function (x, t, b, c, d) {
4317		if ((t/=d) < (1/2.75)) {
4318			return c*(7.5625*t*t) + b;
4319		} else if (t < (2/2.75)) {
4320			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
4321		} else if (t < (2.5/2.75)) {
4322			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
4323		} else {
4324			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
4325		}
4326	},
4327	easeInOutBounce: function (x, t, b, c, d) {
4328		if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
4329		return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
4330	}
4331});})(jQuery);
4332
4333},{}],25:[function(require,module,exports){
4334(function (process){
4335  /* globals require, module */
4336
4337  'use strict';
4338
4339  /**
4340   * Module dependencies.
4341   */
4342
4343  var pathtoRegexp = require('path-to-regexp');
4344
4345  /**
4346   * Module exports.
4347   */
4348
4349  module.exports = page;
4350
4351  /**
4352   * Detect click event
4353   */
4354  var clickEvent = ('undefined' !== typeof document) && document.ontouchstart ? 'touchstart' : 'click';
4355
4356  /**
4357   * To work properly with the URL
4358   * history.location generated polyfill in https://github.com/devote/HTML5-History-API
4359   */
4360
4361  var location = ('undefined' !== typeof window) && (window.history.location || window.location);
4362
4363  /**
4364   * Perform initial dispatch.
4365   */
4366
4367  var dispatch = true;
4368
4369
4370  /**
4371   * Decode URL components (query string, pathname, hash).
4372   * Accommodates both regular percent encoding and x-www-form-urlencoded format.
4373   */
4374  var decodeURLComponents = true;
4375
4376  /**
4377   * Base path.
4378   */
4379
4380  var base = '';
4381
4382  /**
4383   * Running flag.
4384   */
4385
4386  var running;
4387
4388  /**
4389   * HashBang option
4390   */
4391
4392  var hashbang = false;
4393
4394  /**
4395   * Previous context, for capturing
4396   * page exit events.
4397   */
4398
4399  var prevContext;
4400
4401  /**
4402   * Register `path` with callback `fn()`,
4403   * or route `path`, or redirection,
4404   * or `page.start()`.
4405   *
4406   *   page(fn);
4407   *   page('*', fn);
4408   *   page('/user/:id', load, user);
4409   *   page('/user/' + user.id, { some: 'thing' });
4410   *   page('/user/' + user.id);
4411   *   page('/from', '/to')
4412   *   page();
4413   *
4414   * @param {string|!Function|!Object} path
4415   * @param {Function=} fn
4416   * @api public
4417   */
4418
4419  function page(path, fn) {
4420    // <callback>
4421    if ('function' === typeof path) {
4422      return page('*', path);
4423    }
4424
4425    // route <path> to <callback ...>
4426    if ('function' === typeof fn) {
4427      var route = new Route(/** @type {string} */ (path));
4428      for (var i = 1; i < arguments.length; ++i) {
4429        page.callbacks.push(route.middleware(arguments[i]));
4430      }
4431      // show <path> with [state]
4432    } else if ('string' === typeof path) {
4433      page['string' === typeof fn ? 'redirect' : 'show'](path, fn);
4434      // start [options]
4435    } else {
4436      page.start(path);
4437    }
4438  }
4439
4440  /**
4441   * Callback functions.
4442   */
4443
4444  page.callbacks = [];
4445  page.exits = [];
4446
4447  /**
4448   * Current path being processed
4449   * @type {string}
4450   */
4451  page.current = '';
4452
4453  /**
4454   * Number of pages navigated to.
4455   * @type {number}
4456   *
4457   *     page.len == 0;
4458   *     page('/login');
4459   *     page.len == 1;
4460   */
4461
4462  page.len = 0;
4463
4464  /**
4465   * Get or set basepath to `path`.
4466   *
4467   * @param {string} path
4468   * @api public
4469   */
4470
4471  page.base = function(path) {
4472    if (0 === arguments.length) return base;
4473    base = path;
4474  };
4475
4476  /**
4477   * Bind with the given `options`.
4478   *
4479   * Options:
4480   *
4481   *    - `click` bind to click events [true]
4482   *    - `popstate` bind to popstate [true]
4483   *    - `dispatch` perform initial dispatch [true]
4484   *
4485   * @param {Object} options
4486   * @api public
4487   */
4488
4489  page.start = function(options) {
4490    options = options || {};
4491    if (running) return;
4492    running = true;
4493    if (false === options.dispatch) dispatch = false;
4494    if (false === options.decodeURLComponents) decodeURLComponents = false;
4495    if (false !== options.popstate) window.addEventListener('popstate', onpopstate, false);
4496    if (false !== options.click) {
4497      document.addEventListener(clickEvent, onclick, false);
4498    }
4499    if (true === options.hashbang) hashbang = true;
4500    if (!dispatch) return;
4501    var url = (hashbang && ~location.hash.indexOf('#!')) ? location.hash.substr(2) + location.search : location.pathname + location.search + location.hash;
4502    page.replace(url, null, true, dispatch);
4503  };
4504
4505  /**
4506   * Unbind click and popstate event handlers.
4507   *
4508   * @api public
4509   */
4510
4511  page.stop = function() {
4512    if (!running) return;
4513    page.current = '';
4514    page.len = 0;
4515    running = false;
4516    document.removeEventListener(clickEvent, onclick, false);
4517    window.removeEventListener('popstate', onpopstate, false);
4518  };
4519
4520  /**
4521   * Show `path` with optional `state` object.
4522   *
4523   * @param {string} path
4524   * @param {Object=} state
4525   * @param {boolean=} dispatch
4526   * @param {boolean=} push
4527   * @return {!Context}
4528   * @api public
4529   */
4530
4531  page.show = function(path, state, dispatch, push) {
4532    var ctx = new Context(path, state);
4533    page.current = ctx.path;
4534    if (false !== dispatch) page.dispatch(ctx);
4535    if (false !== ctx.handled && false !== push) ctx.pushState();
4536    return ctx;
4537  };
4538
4539  /**
4540   * Goes back in the history
4541   * Back should always let the current route push state and then go back.
4542   *
4543   * @param {string} path - fallback path to go back if no more history exists, if undefined defaults to page.base
4544   * @param {Object=} state
4545   * @api public
4546   */
4547
4548  page.back = function(path, state) {
4549    if (page.len > 0) {
4550      // this may need more testing to see if all browsers
4551      // wait for the next tick to go back in history
4552      history.back();
4553      page.len--;
4554    } else if (path) {
4555      setTimeout(function() {
4556        page.show(path, state);
4557      });
4558    }else{
4559      setTimeout(function() {
4560        page.show(base, state);
4561      });
4562    }
4563  };
4564
4565
4566  /**
4567   * Register route to redirect from one path to other
4568   * or just redirect to another route
4569   *
4570   * @param {string} from - if param 'to' is undefined redirects to 'from'
4571   * @param {string=} to
4572   * @api public
4573   */
4574  page.redirect = function(from, to) {
4575    // Define route from a path to another
4576    if ('string' === typeof from && 'string' === typeof to) {
4577      page(from, function(e) {
4578        setTimeout(function() {
4579          page.replace(/** @type {!string} */ (to));
4580        }, 0);
4581      });
4582    }
4583
4584    // Wait for the push state and replace it with another
4585    if ('string' === typeof from && 'undefined' === typeof to) {
4586      setTimeout(function() {
4587        page.replace(from);
4588      }, 0);
4589    }
4590  };
4591
4592  /**
4593   * Replace `path` with optional `state` object.
4594   *
4595   * @param {string} path
4596   * @param {Object=} state
4597   * @param {boolean=} init
4598   * @param {boolean=} dispatch
4599   * @return {!Context}
4600   * @api public
4601   */
4602
4603
4604  page.replace = function(path, state, init, dispatch) {
4605    var ctx = new Context(path, state);
4606    page.current = ctx.path;
4607    ctx.init = init;
4608    ctx.save(); // save before dispatching, which may redirect
4609    if (false !== dispatch) page.dispatch(ctx);
4610    return ctx;
4611  };
4612
4613  /**
4614   * Dispatch the given `ctx`.
4615   *
4616   * @param {Context} ctx
4617   * @api private
4618   */
4619  page.dispatch = function(ctx) {
4620    var prev = prevContext,
4621      i = 0,
4622      j = 0;
4623
4624    prevContext = ctx;
4625
4626    function nextExit() {
4627      var fn = page.exits[j++];
4628      if (!fn) return nextEnter();
4629      fn(prev, nextExit);
4630    }
4631
4632    function nextEnter() {
4633      var fn = page.callbacks[i++];
4634
4635      if (ctx.path !== page.current) {
4636        ctx.handled = false;
4637        return;
4638      }
4639      if (!fn) return unhandled(ctx);
4640      fn(ctx, nextEnter);
4641    }
4642
4643    if (prev) {
4644      nextExit();
4645    } else {
4646      nextEnter();
4647    }
4648  };
4649
4650  /**
4651   * Unhandled `ctx`. When it's not the initial
4652   * popstate then redirect. If you wish to handle
4653   * 404s on your own use `page('*', callback)`.
4654   *
4655   * @param {Context} ctx
4656   * @api private
4657   */
4658  function unhandled(ctx) {
4659    if (ctx.handled) return;
4660    var current;
4661
4662    if (hashbang) {
4663      current = base + location.hash.replace('#!', '');
4664    } else {
4665      current = location.pathname + location.search;
4666    }
4667
4668    if (current === ctx.canonicalPath) return;
4669    page.stop();
4670    ctx.handled = false;
4671    location.href = ctx.canonicalPath;
4672  }
4673
4674  /**
4675   * Register an exit route on `path` with
4676   * callback `fn()`, which will be called
4677   * on the previous context when a new
4678   * page is visited.
4679   */
4680  page.exit = function(path, fn) {
4681    if (typeof path === 'function') {
4682      return page.exit('*', path);
4683    }
4684
4685    var route = new Route(path);
4686    for (var i = 1; i < arguments.length; ++i) {
4687      page.exits.push(route.middleware(arguments[i]));
4688    }
4689  };
4690
4691  /**
4692   * Remove URL encoding from the given `str`.
4693   * Accommodates whitespace in both x-www-form-urlencoded
4694   * and regular percent-encoded form.
4695   *
4696   * @param {string} val - URL component to decode
4697   */
4698  function decodeURLEncodedURIComponent(val) {
4699    if (typeof val !== 'string') { return val; }
4700    return decodeURLComponents ? decodeURIComponent(val.replace(/\+/g, ' ')) : val;
4701  }
4702
4703  /**
4704   * Initialize a new "request" `Context`
4705   * with the given `path` and optional initial `state`.
4706   *
4707   * @constructor
4708   * @param {string} path
4709   * @param {Object=} state
4710   * @api public
4711   */
4712
4713  function Context(path, state) {
4714    if ('/' === path[0] && 0 !== path.indexOf(base)) path = base + (hashbang ? '#!' : '') + path;
4715    var i = path.indexOf('?');
4716
4717    this.canonicalPath = path;
4718    this.path = path.replace(base, '') || '/';
4719    if (hashbang) this.path = this.path.replace('#!', '') || '/';
4720
4721    this.title = document.title;
4722    this.state = state || {};
4723    this.state.path = path;
4724    this.querystring = ~i ? decodeURLEncodedURIComponent(path.slice(i + 1)) : '';
4725    this.pathname = decodeURLEncodedURIComponent(~i ? path.slice(0, i) : path);
4726    this.params = {};
4727
4728    // fragment
4729    this.hash = '';
4730    if (!hashbang) {
4731      if (!~this.path.indexOf('#')) return;
4732      var parts = this.path.split('#');
4733      this.path = parts[0];
4734      this.hash = decodeURLEncodedURIComponent(parts[1]) || '';
4735      this.querystring = this.querystring.split('#')[0];
4736    }
4737  }
4738
4739  /**
4740   * Expose `Context`.
4741   */
4742
4743  page.Context = Context;
4744
4745  /**
4746   * Push state.
4747   *
4748   * @api private
4749   */
4750
4751  Context.prototype.pushState = function() {
4752    page.len++;
4753    history.pushState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
4754  };
4755
4756  /**
4757   * Save the context state.
4758   *
4759   * @api public
4760   */
4761
4762  Context.prototype.save = function() {
4763    history.replaceState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
4764  };
4765
4766  /**
4767   * Initialize `Route` with the given HTTP `path`,
4768   * and an array of `callbacks` and `options`.
4769   *
4770   * Options:
4771   *
4772   *   - `sensitive`    enable case-sensitive routes
4773   *   - `strict`       enable strict matching for trailing slashes
4774   *
4775   * @constructor
4776   * @param {string} path
4777   * @param {Object=} options
4778   * @api private
4779   */
4780
4781  function Route(path, options) {
4782    options = options || {};
4783    this.path = (path === '*') ? '(.*)' : path;
4784    this.method = 'GET';
4785    this.regexp = pathtoRegexp(this.path,
4786      this.keys = [],
4787      options);
4788  }
4789
4790  /**
4791   * Expose `Route`.
4792   */
4793
4794  page.Route = Route;
4795
4796  /**
4797   * Return route middleware with
4798   * the given callback `fn()`.
4799   *
4800   * @param {Function} fn
4801   * @return {Function}
4802   * @api public
4803   */
4804
4805  Route.prototype.middleware = function(fn) {
4806    var self = this;
4807    return function(ctx, next) {
4808      if (self.match(ctx.path, ctx.params)) return fn(ctx, next);
4809      next();
4810    };
4811  };
4812
4813  /**
4814   * Check if this route matches `path`, if so
4815   * populate `params`.
4816   *
4817   * @param {string} path
4818   * @param {Object} params
4819   * @return {boolean}
4820   * @api private
4821   */
4822
4823  Route.prototype.match = function(path, params) {
4824    var keys = this.keys,
4825      qsIndex = path.indexOf('?'),
4826      pathname = ~qsIndex ? path.slice(0, qsIndex) : path,
4827      m = this.regexp.exec(decodeURIComponent(pathname));
4828
4829    if (!m) return false;
4830
4831    for (var i = 1, len = m.length; i < len; ++i) {
4832      var key = keys[i - 1];
4833      var val = decodeURLEncodedURIComponent(m[i]);
4834      if (val !== undefined || !(hasOwnProperty.call(params, key.name))) {
4835        params[key.name] = val;
4836      }
4837    }
4838
4839    return true;
4840  };
4841
4842
4843  /**
4844   * Handle "populate" events.
4845   */
4846
4847  var onpopstate = (function () {
4848    var loaded = false;
4849    if ('undefined' === typeof window) {
4850      return;
4851    }
4852    if (document.readyState === 'complete') {
4853      loaded = true;
4854    } else {
4855      window.addEventListener('load', function() {
4856        setTimeout(function() {
4857          loaded = true;
4858        }, 0);
4859      });
4860    }
4861    return function onpopstate(e) {
4862      if (!loaded) return;
4863      if (e.state) {
4864        var path = e.state.path;
4865        page.replace(path, e.state);
4866      } else {
4867        page.show(location.pathname + location.hash, undefined, undefined, false);
4868      }
4869    };
4870  })();
4871  /**
4872   * Handle "click" events.
4873   */
4874
4875  function onclick(e) {
4876
4877    if (1 !== which(e)) return;
4878
4879    if (e.metaKey || e.ctrlKey || e.shiftKey) return;
4880    if (e.defaultPrevented) return;
4881
4882
4883
4884    // ensure link
4885    // use shadow dom when available
4886    var el = e.path ? e.path[0] : e.target;
4887    while (el && 'A' !== el.nodeName) el = el.parentNode;
4888    if (!el || 'A' !== el.nodeName) return;
4889
4890
4891
4892    // Ignore if tag has
4893    // 1. "download" attribute
4894    // 2. rel="external" attribute
4895    if (el.hasAttribute('download') || el.getAttribute('rel') === 'external') return;
4896
4897    // ensure non-hash for the same path
4898    var link = el.getAttribute('href');
4899    if (!hashbang && el.pathname === location.pathname && (el.hash || '#' === link)) return;
4900
4901
4902
4903    // Check for mailto: in the href
4904    if (link && link.indexOf('mailto:') > -1) return;
4905
4906    // check target
4907    if (el.target) return;
4908
4909    // x-origin
4910    if (!sameOrigin(el.href)) return;
4911
4912
4913
4914    // rebuild path
4915    var path = el.pathname + el.search + (el.hash || '');
4916
4917    // strip leading "/[drive letter]:" on NW.js on Windows
4918    if (typeof process !== 'undefined' && path.match(/^\/[a-zA-Z]:\//)) {
4919      path = path.replace(/^\/[a-zA-Z]:\//, '/');
4920    }
4921
4922    // same page
4923    var orig = path;
4924
4925    if (path.indexOf(base) === 0) {
4926      path = path.substr(base.length);
4927    }
4928
4929    if (hashbang) path = path.replace('#!', '');
4930
4931    if (base && orig === path) return;
4932
4933    e.preventDefault();
4934    page.show(orig);
4935  }
4936
4937  /**
4938   * Event button.
4939   */
4940
4941  function which(e) {
4942    e = e || window.event;
4943    return null === e.which ? e.button : e.which;
4944  }
4945
4946  /**
4947   * Check if `href` is the same origin.
4948   */
4949
4950  function sameOrigin(href) {
4951    var origin = location.protocol + '//' + location.hostname;
4952    if (location.port) origin += ':' + location.port;
4953    return (href && (0 === href.indexOf(origin)));
4954  }
4955
4956  page.sameOrigin = sameOrigin;
4957
4958}).call(this,require('_process'))
4959},{"_process":27,"path-to-regexp":26}],26:[function(require,module,exports){
4960var isarray = require('isarray')
4961
4962/**
4963 * Expose `pathToRegexp`.
4964 */
4965module.exports = pathToRegexp
4966module.exports.parse = parse
4967module.exports.compile = compile
4968module.exports.tokensToFunction = tokensToFunction
4969module.exports.tokensToRegExp = tokensToRegExp
4970
4971/**
4972 * The main path matching regexp utility.
4973 *
4974 * @type {RegExp}
4975 */
4976var PATH_REGEXP = new RegExp([
4977  // Match escaped characters that would otherwise appear in future matches.
4978  // This allows the user to escape special characters that won't transform.
4979  '(\\\\.)',
4980  // Match Express-style parameters and un-named parameters with a prefix
4981  // and optional suffixes. Matches appear as:
4982  //
4983  // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
4984  // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined, undefined]
4985  // "/*"            => ["/", undefined, undefined, undefined, undefined, "*"]
4986  '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))'
4987].join('|'), 'g')
4988
4989/**
4990 * Parse a string for the raw tokens.
4991 *
4992 * @param  {String} str
4993 * @return {Array}
4994 */
4995function parse (str) {
4996  var tokens = []
4997  var key = 0
4998  var index = 0
4999  var path = ''
5000  var res
5001
5002  while ((res = PATH_REGEXP.exec(str)) != null) {
5003    var m = res[0]
5004    var escaped = res[1]
5005    var offset = res.index
5006    path += str.slice(index, offset)
5007    index = offset + m.length
5008
5009    // Ignore already escaped sequences.
5010    if (escaped) {
5011      path += escaped[1]
5012      continue
5013    }
5014
5015    // Push the current path onto the tokens.
5016    if (path) {
5017      tokens.push(path)
5018      path = ''
5019    }
5020
5021    var prefix = res[2]
5022    var name = res[3]
5023    var capture = res[4]
5024    var group = res[5]
5025    var suffix = res[6]
5026    var asterisk = res[7]
5027
5028    var repeat = suffix === '+' || suffix === '*'
5029    var optional = suffix === '?' || suffix === '*'
5030    var delimiter = prefix || '/'
5031    var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')
5032
5033    tokens.push({
5034      name: name || key++,
5035      prefix: prefix || '',
5036      delimiter: delimiter,
5037      optional: optional,
5038      repeat: repeat,
5039      pattern: escapeGroup(pattern)
5040    })
5041  }
5042
5043  // Match any characters still remaining.
5044  if (index < str.length) {
5045    path += str.substr(index)
5046  }
5047
5048  // If the path exists, push it onto the end.
5049  if (path) {
5050    tokens.push(path)
5051  }
5052
5053  return tokens
5054}
5055
5056/**
5057 * Compile a string to a template function for the path.
5058 *
5059 * @param  {String}   str
5060 * @return {Function}
5061 */
5062function compile (str) {
5063  return tokensToFunction(parse(str))
5064}
5065
5066/**
5067 * Expose a method for transforming tokens into the path function.
5068 */
5069function tokensToFunction (tokens) {
5070  // Compile all the tokens into regexps.
5071  var matches = new Array(tokens.length)
5072
5073  // Compile all the patterns before compilation.
5074  for (var i = 0; i < tokens.length; i++) {
5075    if (typeof tokens[i] === 'object') {
5076      matches[i] = new RegExp('^' + tokens[i].pattern + '$')
5077    }
5078  }
5079
5080  return function (obj) {
5081    var path = ''
5082    var data = obj || {}
5083
5084    for (var i = 0; i < tokens.length; i++) {
5085      var token = tokens[i]
5086
5087      if (typeof token === 'string') {
5088        path += token
5089
5090        continue
5091      }
5092
5093      var value = data[token.name]
5094      var segment
5095
5096      if (value == null) {
5097        if (token.optional) {
5098          continue
5099        } else {
5100          throw new TypeError('Expected "' + token.name + '" to be defined')
5101        }
5102      }
5103
5104      if (isarray(value)) {
5105        if (!token.repeat) {
5106          throw new TypeError('Expected "' + token.name + '" to not repeat, but received "' + value + '"')
5107        }
5108
5109        if (value.length === 0) {
5110          if (token.optional) {
5111            continue
5112          } else {
5113            throw new TypeError('Expected "' + token.name + '" to not be empty')
5114          }
5115        }
5116
5117        for (var j = 0; j < value.length; j++) {
5118          segment = encodeURIComponent(value[j])
5119
5120          if (!matches[i].test(segment)) {
5121            throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
5122          }
5123
5124          path += (j === 0 ? token.prefix : token.delimiter) + segment
5125        }
5126
5127        continue
5128      }
5129
5130      segment = encodeURIComponent(value)
5131
5132      if (!matches[i].test(segment)) {
5133        throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
5134      }
5135
5136      path += token.prefix + segment
5137    }
5138
5139    return path
5140  }
5141}
5142
5143/**
5144 * Escape a regular expression string.
5145 *
5146 * @param  {String} str
5147 * @return {String}
5148 */
5149function escapeString (str) {
5150  return str.replace(/([.+*?=^!:${}()[\]|\/])/g, '\\$1')
5151}
5152
5153/**
5154 * Escape the capturing group by escaping special characters and meaning.
5155 *
5156 * @param  {String} group
5157 * @return {String}
5158 */
5159function escapeGroup (group) {
5160  return group.replace(/([=!:$\/()])/g, '\\$1')
5161}
5162
5163/**
5164 * Attach the keys as a property of the regexp.
5165 *
5166 * @param  {RegExp} re
5167 * @param  {Array}  keys
5168 * @return {RegExp}
5169 */
5170function attachKeys (re, keys) {
5171  re.keys = keys
5172  return re
5173}
5174
5175/**
5176 * Get the flags for a regexp from the options.
5177 *
5178 * @param  {Object} options
5179 * @return {String}
5180 */
5181function flags (options) {
5182  return options.sensitive ? '' : 'i'
5183}
5184
5185/**
5186 * Pull out keys from a regexp.
5187 *
5188 * @param  {RegExp} path
5189 * @param  {Array}  keys
5190 * @return {RegExp}
5191 */
5192function regexpToRegexp (path, keys) {
5193  // Use a negative lookahead to match only capturing groups.
5194  var groups = path.source.match(/\((?!\?)/g)
5195
5196  if (groups) {
5197    for (var i = 0; i < groups.length; i++) {
5198      keys.push({
5199        name: i,
5200        prefix: null,
5201        delimiter: null,
5202        optional: false,
5203        repeat: false,
5204        pattern: null
5205      })
5206    }
5207  }
5208
5209  return attachKeys(path, keys)
5210}
5211
5212/**
5213 * Transform an array into a regexp.
5214 *
5215 * @param  {Array}  path
5216 * @param  {Array}  keys
5217 * @param  {Object} options
5218 * @return {RegExp}
5219 */
5220function arrayToRegexp (path, keys, options) {
5221  var parts = []
5222
5223  for (var i = 0; i < path.length; i++) {
5224    parts.push(pathToRegexp(path[i], keys, options).source)
5225  }
5226
5227  var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
5228
5229  return attachKeys(regexp, keys)
5230}
5231
5232/**
5233 * Create a path regexp from string input.
5234 *
5235 * @param  {String} path
5236 * @param  {Array}  keys
5237 * @param  {Object} options
5238 * @return {RegExp}
5239 */
5240function stringToRegexp (path, keys, options) {
5241  var tokens = parse(path)
5242  var re = tokensToRegExp(tokens, options)
5243
5244  // Attach keys back to the regexp.
5245  for (var i = 0; i < tokens.length; i++) {
5246    if (typeof tokens[i] !== 'string') {
5247      keys.push(tokens[i])
5248    }
5249  }
5250
5251  return attachKeys(re, keys)
5252}
5253
5254/**
5255 * Expose a function for taking tokens and returning a RegExp.
5256 *
5257 * @param  {Array}  tokens
5258 * @param  {Array}  keys
5259 * @param  {Object} options
5260 * @return {RegExp}
5261 */
5262function tokensToRegExp (tokens, options) {
5263  options = options || {}
5264
5265  var strict = options.strict
5266  var end = options.end !== false
5267  var route = ''
5268  var lastToken = tokens[tokens.length - 1]
5269  var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)
5270
5271  // Iterate over the tokens and create our regexp string.
5272  for (var i = 0; i < tokens.length; i++) {
5273    var token = tokens[i]
5274
5275    if (typeof token === 'string') {
5276      route += escapeString(token)
5277    } else {
5278      var prefix = escapeString(token.prefix)
5279      var capture = token.pattern
5280
5281      if (token.repeat) {
5282        capture += '(?:' + prefix + capture + ')*'
5283      }
5284
5285      if (token.optional) {
5286        if (prefix) {
5287          capture = '(?:' + prefix + '(' + capture + '))?'
5288        } else {
5289          capture = '(' + capture + ')?'
5290        }
5291      } else {
5292        capture = prefix + '(' + capture + ')'
5293      }
5294
5295      route += capture
5296    }
5297  }
5298
5299  // In non-strict mode we allow a slash at the end of match. If the path to
5300  // match already ends with a slash, we remove it for consistency. The slash
5301  // is valid at the end of a path match, not in the middle. This is important
5302  // in non-ending mode, where "/test/" shouldn't match "/test//route".
5303  if (!strict) {
5304    route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'
5305  }
5306
5307  if (end) {
5308    route += '$'
5309  } else {
5310    // In non-ending mode, we need the capturing groups to match as much as
5311    // possible by using a positive lookahead to the end or next path segment.
5312    route += strict && endsWithSlash ? '' : '(?=\\/|$)'
5313  }
5314
5315  return new RegExp('^' + route, flags(options))
5316}
5317
5318/**
5319 * Normalize the given path string, returning a regular expression.
5320 *
5321 * An empty array can be passed in for the keys, which will hold the
5322 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
5323 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
5324 *
5325 * @param  {(String|RegExp|Array)} path
5326 * @param  {Array}                 [keys]
5327 * @param  {Object}                [options]
5328 * @return {RegExp}
5329 */
5330function pathToRegexp (path, keys, options) {
5331  keys = keys || []
5332
5333  if (!isarray(keys)) {
5334    options = keys
5335    keys = []
5336  } else if (!options) {
5337    options = {}
5338  }
5339
5340  if (path instanceof RegExp) {
5341    return regexpToRegexp(path, keys, options)
5342  }
5343
5344  if (isarray(path)) {
5345    return arrayToRegexp(path, keys, options)
5346  }
5347
5348  return stringToRegexp(path, keys, options)
5349}
5350
5351},{"isarray":23}],27
vendor: 5,461 bytes, lines 5351-5537
5351:[function(require,module,exports){
5352// shim for using process in browser
5353var process = module.exports = {};
5354
5355// cached from whatever global is present so that test runners that stub it
5356// don't break things.  But we need to wrap it in a try catch in case it is
5357// wrapped in strict mode code which doesn't define any globals.  It's inside a
5358// function because try/catches deoptimize in certain engines.
5359
5360var cachedSetTimeout;
5361var cachedClearTimeout;
5362
5363function defaultSetTimout() {
5364    throw new Error('setTimeout has not been defined');
5365}
5366function defaultClearTimeout () {
5367    throw new Error('clearTimeout has not been defined');
5368}
5369(function () {
5370    try {
5371        if (typeof setTimeout === 'function') {
5372            cachedSetTimeout = setTimeout;
5373        } else {
5374            cachedSetTimeout = defaultSetTimout;
5375        }
5376    } catch (e) {
5377        cachedSetTimeout = defaultSetTimout;
5378    }
5379    try {
5380        if (typeof clearTimeout === 'function') {
5381            cachedClearTimeout = clearTimeout;
5382        } else {
5383            cachedClearTimeout = defaultClearTimeout;
5384        }
5385    } catch (e) {
5386        cachedClearTimeout = defaultClearTimeout;
5387    }
5388} ())
5389function runTimeout(fun) {
5390    if (cachedSetTimeout === setTimeout) {
5391        //normal enviroments in sane situations
5392        return setTimeout(fun, 0);
5393    }
5394    // if setTimeout wasn't available but was latter defined
5395    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
5396        cachedSetTimeout = setTimeout;
5397        return setTimeout(fun, 0);
5398    }
5399    try {
5400        // when when somebody has screwed with setTimeout but no I.E. maddness
5401        return cachedSetTimeout(fun, 0);
5402    } catch(e){
5403        try {
5404            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
5405            return cachedSetTimeout.call(null, fun, 0);
5406        } catch(e){
5407            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
5408            return cachedSetTimeout.call(this, fun, 0);
5409        }
5410    }
5411
5412
5413}
5414function runClearTimeout(marker) {
5415    if (cachedClearTimeout === clearTimeout) {
5416        //normal enviroments in sane situations
5417        return clearTimeout(marker);
5418    }
5419    // if clearTimeout wasn't available but was latter defined
5420    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
5421        cachedClearTimeout = clearTimeout;
5422        return clearTimeout(marker);
5423    }
5424    try {
5425        // when when somebody has screwed with setTimeout but no I.E. maddness
5426        return cachedClearTimeout(marker);
5427    } catch (e){
5428        try {
5429            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
5430            return cachedClearTimeout.call(null, marker);
5431        } catch (e){
5432            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
5433            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
5434            return cachedClearTimeout.call(this, marker);
5435        }
5436    }
5437
5438
5439
5440}
5441var queue = [];
5442var draining = false;
5443var currentQueue;
5444var queueIndex = -1;
5445
5446function cleanUpNextTick() {
5447    if (!draining || !currentQueue) {
5448        return;
5449    }
5450    draining = false;
5451    if (currentQueue.length) {
5452        queue = currentQueue.concat(queue);
5453    } else {
5454        queueIndex = -1;
5455    }
5456    if (queue.length) {
5457        drainQueue();
5458    }
5459}
5460
5461function drainQueue() {
5462    if (draining) {
5463        return;
5464    }
5465    var timeout = runTimeout(cleanUpNextTick);
5466    draining = true;
5467
5468    var len = queue.length;
5469    while(len) {
5470        currentQueue = queue;
5471        queue = [];
5472        while (++queueIndex < len) {
5473            if (currentQueue) {
5474                currentQueue[queueIndex].run();
5475            }
5476        }
5477        queueIndex = -1;
5478        len = queue.length;
5479    }
5480    currentQueue = null;
5481    draining = false;
5482    runClearTimeout(timeout);
5483}
5484
5485process.nextTick = function (fun) {
5486    var args = new Array(arguments.length - 1);
5487    if (arguments.length > 1) {
5488        for (var i = 1; i < arguments.length; i++) {
5489            args[i - 1] = arguments[i];
5490        }
5491    }
5492    queue.push(new Item(fun, args));
5493    if (queue.length === 1 && !draining) {
5494        runTimeout(drainQueue);
5495    }
5496};
5497
5498// v8 likes predictible objects
5499function Item(fun, array) {
5500    this.fun = fun;
5501    this.array = array;
5502}
5503Item.prototype.run = function () {
5504    this.fun.apply(null, this.array);
5505};
5506process.title = 'browser';
5507process.browser = true;
5508process.env = {};
5509process.argv = [];
5510process.version = ''; // empty string to avoid regexp issues
5511process.versions = {};
5512
5513function noop() {}
5514
5515process.on = noop;
5516process.addListener = noop;
5517process.once = noop;
5518process.off = noop;
5519process.removeListener = noop;
5520process.removeAllListeners = noop;
5521process.emit = noop;
5522process.prependListener = noop;
5523process.prependOnceListener = noop;
5524
5525process.listeners = function (name) { return [] }
5526
5527process.binding = function (name) {
5528    throw new Error('process.binding is not supported');
5529};
5530
5531process.cwd = function () { return '/' };
5532process.chdir = function (dir) {
5533    throw new Error('process.chdir is not supported');
5534};
5535process.umask = function() { return 0; };
5536
5537},{}],
553728:[function(require,module,exports){
5538'use strict';
5539
5540var Stringify = require('./stringify');
5541var Parse = require('./parse');
5542
5543module.exports = {
5544    stringify: Stringify,
5545    parse: Parse
5546};
5547
5548},{"./parse":29,"./stringify":30}],29:[function(require,module,exports){
5549'use strict';
5550
5551var Utils = require('./utils');
5552
5553var defaults = {
5554    delimiter: '&',
5555    depth: 5,
5556    arrayLimit: 20,
5557    parameterLimit: 1000,
5558    strictNullHandling: false,
5559    plainObjects: false,
5560    allowPrototypes: false,
5561    allowDots: false,
5562    decoder: Utils.decode
5563};
5564
5565var parseValues = function parseValues(str, options) {
5566    var obj = {};
5567    var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
5568
5569    for (var i = 0; i < parts.length; ++i) {
5570        var part = parts[i];
5571        var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
5572
5573        if (pos === -1) {
5574            obj[options.decoder(part)] = '';
5575
5576            if (options.strictNullHandling) {
5577                obj[options.decoder(part)] = null;
5578            }
5579        } else {
5580            var key = options.decoder(part.slice(0, pos));
5581            var val = options.decoder(part.slice(pos + 1));
5582
5583            if (Object.prototype.hasOwnProperty.call(obj, key)) {
5584                obj[key] = [].concat(obj[key]).concat(val);
5585            } else {
5586                obj[key] = val;
5587            }
5588        }
5589    }
5590
5591    return obj;
5592};
5593
5594var parseObject = function parseObject(chain, val, options) {
5595    if (!chain.length) {
5596        return val;
5597    }
5598
5599    var root = chain.shift();
5600
5601    var obj;
5602    if (root === '[]') {
5603        obj = [];
5604        obj = obj.concat(parseObject(chain, val, options));
5605    } else {
5606        obj = options.plainObjects ? Object.create(null) : {};
5607        var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
5608        var index = parseInt(cleanRoot, 10);
5609        if (
5610            !isNaN(index) &&
5611            root !== cleanRoot &&
5612            String(index) === cleanRoot &&
5613            index >= 0 &&
5614            (options.parseArrays && index <= options.arrayLimit)
5615        ) {
5616            obj = [];
5617            obj[index] = parseObject(chain, val, options);
5618        } else {
5619            obj[cleanRoot] = parseObject(chain, val, options);
5620        }
5621    }
5622
5623    return obj;
5624};
5625
5626var parseKeys = function parseKeys(givenKey, val, options) {
5627    if (!givenKey) {
5628        return;
5629    }
5630
5631    // Transform dot notation to bracket notation
5632    var key = options.allowDots ? givenKey.replace(/\.([^\.\[]+)/g, '[$1]') : givenKey;
5633
5634    // The regex chunks
5635
5636    var parent = /^([^\[\]]*)/;
5637    var child = /(\[[^\[\]]*\])/g;
5638
5639    // Get the parent
5640
5641    var segment = parent.exec(key);
5642
5643    // Stash the parent if it exists
5644
5645    var keys = [];
5646    if (segment[1]) {
5647        // If we aren't using plain objects, optionally prefix keys
5648        // that would overwrite object prototype properties
5649        if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1])) {
5650            if (!options.allowPrototypes) {
5651                return;
5652            }
5653        }
5654
5655        keys.push(segment[1]);
5656    }
5657
5658    // Loop through children appending to the array until we hit depth
5659
5660    var i = 0;
5661    while ((segment = child.exec(key)) !== null && i < options.depth) {
5662        i += 1;
5663        if (!options.plainObjects && Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
5664            if (!options.allowPrototypes) {
5665                continue;
5666            }
5667        }
5668        keys.push(segment[1]);
5669    }
5670
5671    // If there's a remainder, just add whatever is left
5672
5673    if (segment) {
5674        keys.push('[' + key.slice(segment.index) + ']');
5675    }
5676
5677    return parseObject(keys, val, options);
5678};
5679
5680module.exports = function (str, opts) {
5681    var options = opts || {};
5682
5683    if (options.decoder !== null && options.decoder !== undefined && typeof options.decoder !== 'function') {
5684        throw new TypeError('Decoder has to be a function.');
5685    }
5686
5687    options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : defaults.delimiter;
5688    options.depth = typeof options.depth === 'number' ? options.depth : defaults.depth;
5689    options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : defaults.arrayLimit;
5690    options.parseArrays = options.parseArrays !== false;
5691    options.decoder = typeof options.decoder === 'function' ? options.decoder : defaults.decoder;
5692    options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : defaults.allowDots;
5693    options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : defaults.plainObjects;
5694    options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : defaults.allowPrototypes;
5695    options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : defaults.parameterLimit;
5696    options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
5697
5698    if (str === '' || str === null || typeof str === 'undefined') {
5699        return options.plainObjects ? Object.create(null) : {};
5700    }
5701
5702    var tempObj = typeof str === 'string' ? parseValues(str, options) : str;
5703    var obj = options.plainObjects ? Object.create(null) : {};
5704
5705    // Iterate over the keys and setup the new object
5706
5707    var keys = Object.keys(tempObj);
5708    for (var i = 0; i < keys.length; ++i) {
5709        var key = keys[i];
5710        var newObj = parseKeys(key, tempObj[key], options);
5711        obj = Utils.merge(obj, newObj, options);
5712    }
5713
5714    return Utils.compact(obj);
5715};
5716
5717},{"./utils":31}],30:[function(require,module,exports){
5718'use strict';
5719
5720var Utils = require('./utils');
5721
5722var arrayPrefixGenerators = {
5723    brackets: function brackets(prefix) {
5724        return prefix + '[]';
5725    },
5726    indices: function indices(prefix, key) {
5727        return prefix + '[' + key + ']';
5728    },
5729    repeat: function repeat(prefix) {
5730        return prefix;
5731    }
5732};
5733
5734var defaults = {
5735    delimiter: '&',
5736    strictNullHandling: false,
5737    skipNulls: false,
5738    encode: true,
5739    encoder: Utils.encode
5740};
5741
5742var stringify = function stringify(object, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots) {
5743    var obj = object;
5744    if (typeof filter === 'function') {
5745        obj = filter(prefix, obj);
5746    } else if (obj instanceof Date) {
5747        obj = obj.toISOString();
5748    } else if (obj === null) {
5749        if (strictNullHandling) {
5750            return encoder ? encoder(prefix) : prefix;
5751        }
5752
5753        obj = '';
5754    }
5755
5756    if (typeof obj === 'string' || typeof obj === 'number' || typeof obj === 'boolean' || Utils.isBuffer(obj)) {
5757        if (encoder) {
5758            return [encoder(prefix) + '=' + encoder(obj)];
5759        }
5760        return [prefix + '=' + String(obj)];
5761    }
5762
5763    var values = [];
5764
5765    if (typeof obj === 'undefined') {
5766        return values;
5767    }
5768
5769    var objKeys;
5770    if (Array.isArray(filter)) {
5771        objKeys = filter;
5772    } else {
5773        var keys = Object.keys(obj);
5774        objKeys = sort ? keys.sort(sort) : keys;
5775    }
5776
5777    for (var i = 0; i < objKeys.length; ++i) {
5778        var key = objKeys[i];
5779
5780        if (skipNulls && obj[key] === null) {
5781            continue;
5782        }
5783
5784        if (Array.isArray(obj)) {
5785            values = values.concat(stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
5786        } else {
5787            values = values.concat(stringify(obj[key], prefix + (allowDots ? '.' + key : '[' + key + ']'), generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
5788        }
5789    }
5790
5791    return values;
5792};
5793
5794module.exports = function (object, opts) {
5795    var obj = object;
5796    var options = opts || {};
5797    var delimiter = typeof options.delimiter === 'undefined' ? defaults.delimiter : options.delimiter;
5798    var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : defaults.strictNullHandling;
5799    var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : defaults.skipNulls;
5800    var encode = typeof options.encode === 'boolean' ? options.encode : defaults.encode;
5801    var encoder = encode ? (typeof options.encoder === 'function' ? options.encoder : defaults.encoder) : null;
5802    var sort = typeof options.sort === 'function' ? options.sort : null;
5803    var allowDots = typeof options.allowDots === 'undefined' ? false : options.allowDots;
5804    var objKeys;
5805    var filter;
5806
5807    if (options.encoder !== null && options.encoder !== undefined && typeof options.encoder !== 'function') {
5808        throw new TypeError('Encoder has to be a function.');
5809    }
5810
5811    if (typeof options.filter === 'function') {
5812        filter = options.filter;
5813        obj = filter('', obj);
5814    } else if (Array.isArray(options.filter)) {
5815        objKeys = filter = options.filter;
5816    }
5817
5818    var keys = [];
5819
5820    if (typeof obj !== 'object' || obj === null) {
5821        return '';
5822    }
5823
5824    var arrayFormat;
5825    if (options.arrayFormat in arrayPrefixGenerators) {
5826        arrayFormat = options.arrayFormat;
5827    } else if ('indices' in options) {
5828        arrayFormat = options.indices ? 'indices' : 'repeat';
5829    } else {
5830        arrayFormat = 'indices';
5831    }
5832
5833    var generateArrayPrefix = arrayPrefixGenerators[arrayFormat];
5834
5835    if (!objKeys) {
5836        objKeys = Object.keys(obj);
5837    }
5838
5839    if (sort) {
5840        objKeys.sort(sort);
5841    }
5842
5843    for (var i = 0; i < objKeys.length; ++i) {
5844        var key = objKeys[i];
5845
5846        if (skipNulls && obj[key] === null) {
5847            continue;
5848        }
5849
5850        keys = keys.concat(stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encoder, filter, sort, allowDots));
5851    }
5852
5853    return keys.join(delimiter);
5854};
5855
5856},{"./utils":31}],31:[function(require,module,exports){
5857'use strict';
5858
5859var hexTable = (function () {
5860    var array = new Array(256);
5861    for (var i = 0; i < 256; ++i) {
5862        array[i] = '%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase();
5863    }
5864
5865    return array;
5866}());
5867
5868exports.arrayToObject = function (source, options) {
5869    var obj = options.plainObjects ? Object.create(null) : {};
5870    for (var i = 0; i < source.length; ++i) {
5871        if (typeof source[i] !== 'undefined') {
5872            obj[i] = source[i];
5873        }
5874    }
5875
5876    return obj;
5877};
5878
5879exports.merge = function (target, source, options) {
5880    if (!source) {
5881        return target;
5882    }
5883
5884    if (typeof source !== 'object') {
5885        if (Array.isArray(target)) {
5886            target.push(source);
5887        } else if (typeof target === 'object') {
5888            target[source] = true;
5889        } else {
5890            return [target, source];
5891        }
5892
5893        return target;
5894    }
5895
5896    if (typeof target !== 'object') {
5897        return [target].concat(source);
5898    }
5899
5900    var mergeTarget = target;
5901    if (Array.isArray(target) && !Array.isArray(source)) {
5902        mergeTarget = exports.arrayToObject(target, options);
5903    }
5904
5905    return Object.keys(source).reduce(function (acc, key) {
5906        var value = source[key];
5907
5908        if (Object.prototype.hasOwnProperty.call(acc, key)) {
5909            acc[key] = exports.merge(acc[key], value, options);
5910        } else {
5911            acc[key] = value;
5912        }
5913        return acc;
5914    }, mergeTarget);
5915};
5916
5917exports.decode = function (str) {
5918    try {
5919        return decodeURIComponent(str.replace(/\+/g, ' '));
5920    } catch (e) {
5921        return str;
5922    }
5923};
5924
5925exports.encode = function (str) {
5926    // This code was originally written by Brian White (mscdex) for the io.js core querystring library.
5927    // It has been adapted here for stricter adherence to RFC 3986
5928    if (str.length === 0) {
5929        return str;
5930    }
5931
5932    var string = typeof str === 'string' ? str : String(str);
5933
5934    var out = '';
5935    for (var i = 0; i < string.length; ++i) {
5936        var c = string.charCodeAt(i);
5937
5938        if (
5939            c === 0x2D || // -
5940            c === 0x2E || // .
5941            c === 0x5F || // _
5942            c === 0x7E || // ~
5943            (c >= 0x30 && c <= 0x39) || // 0-9
5944            (c >= 0x41 && c <= 0x5A) || // a-z
5945            (c >= 0x61 && c <= 0x7A) // A-Z
5946        ) {
5947            out += string.charAt(i);
5948            continue;
5949        }
5950
5951        if (c < 0x80) {
5952            out = out + hexTable[c];
5953            continue;
5954        }
5955
5956        if (c < 0x800) {
5957            out = out + (hexTable[0xC0 | (c >> 6)] + hexTable[0x80 | (c & 0x3F)]);
5958            continue;
5959        }
5960
5961        if (c < 0xD800 || c >= 0xE000) {
5962            out = out + (hexTable[0xE0 | (c >> 12)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)]);
5963            continue;
5964        }
5965
5966        i += 1;
5967        c = 0x10000 + (((c & 0x3FF) << 10) | (string.charCodeAt(i) & 0x3FF));
5968        out += hexTable[0xF0 | (c >> 18)] + hexTable[0x80 | ((c >> 12) & 0x3F)] + hexTable[0x80 | ((c >> 6) & 0x3F)] + hexTable[0x80 | (c & 0x3F)];
5969    }
5970
5971    return out;
5972};
5973
5974exports.compact = function (obj, references) {
5975    if (typeof obj !== 'object' || obj === null) {
5976        return obj;
5977    }
5978
5979    var refs = references || [];
5980    var lookup = refs.indexOf(obj);
5981    if (lookup !== -1) {
5982        return refs[lookup];
5983    }
5984
5985    refs.push(obj);
5986
5987    if (Array.isArray(obj)) {
5988        var compacted = [];
5989
5990        for (var i = 0; i < obj.length; ++i) {
5991            if (obj[i] && typeof obj[i] === 'object') {
5992                compacted.push(exports.compact(obj[i], refs));
5993            } else if (typeof obj[i] !== 'undefined') {
5994                compacted.push(obj[i]);
5995            }
5996        }
5997
5998        return compacted;
5999    }
6000
6001    var keys = Object.keys(obj);
6002    for (var j = 0; j < keys.length; ++j) {
6003        var key = keys[j];
6004        obj[key] = exports.compact(obj[key], refs);
6005    }
6006
6007    return obj;
6008};
6009
6010exports.isRegExp = function (obj) {
6011    return Object.prototype.toString.call(obj) === '[object RegExp]';
6012};
6013
6014exports.isBuffer = function (obj) {
6015    if (obj === null || typeof obj === 'undefined') {
6016        return false;
6017    }
6018
6019    return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
6020};
6021
6022},{}],32:[function(require,module,exports){
6023/*!
6024 * tiny-cookie - A tiny cookie manipulation plugin
6025 * https://github.com/Alex1990/tiny-cookie
6026 * Under the MIT license | (c) Alex Chao
6027 */
6028
6029!(function(root, factory) {
6030
6031  // Uses CommonJS, AMD or browser global to create a jQuery plugin.
6032  // See: https://github.com/umdjs/umd
6033  if (typeof define === 'function' && define.amd) {
6034    // Expose this plugin as an AMD module. Register an anonymous module.
6035    define(factory);
6036  } else if (typeof exports === 'object') {
6037    // Node/CommonJS module
6038    module.exports = factory();
6039  } else {
6040    // Browser globals 
6041    root.Cookie = factory();
6042  }
6043
6044}(this, function() {
6045
6046  'use strict';
6047
6048  // The public function which can get/set/remove cookie.
6049  function Cookie(key, value, opts) {
6050    if (value === void 0) {
6051      return Cookie.get(key);
6052    } else if (value === null) {
6053      Cookie.remove(key);
6054    } else {
6055      Cookie.set(key, value, opts);
6056    }
6057  }
6058
6059  // Check if the cookie is enabled.
6060  Cookie.enabled = function() {
6061    var key = '__test_key';
6062    var enabled;
6063
6064    document.cookie = key + '=1';
6065    enabled = !!document.cookie;
6066
6067    if (enabled) Cookie.remove(key);
6068
6069    return enabled;
6070  };
6071
6072  // Get the cookie value by the key.
6073  Cookie.get = function(key, raw) {
6074    if (typeof key !== 'string' || !key) return null;
6075
6076    key = '(?:^|; )' + escapeRe(key) + '(?:=([^;]*?))?(?:;|$)';
6077
6078    var reKey = new RegExp(key);
6079    var res = reKey.exec(document.cookie);
6080
6081    return res !== null ? (raw ? res[1] : decodeURIComponent(res[1])) : null;
6082  };
6083
6084  // Get the cookie's value without decoding.
6085  Cookie.getRaw = function(key) {
6086    return Cookie.get(key, true);
6087  };
6088
6089  // Set a cookie.
6090  Cookie.set = function(key, value, raw, opts) {
6091    if (raw !== true) {
6092      opts = raw;
6093      raw = false;
6094    }
6095    opts = opts ? convert(opts) : convert({});
6096    var cookie = key + '=' + (raw ? value : encodeURIComponent(value)) + opts;
6097    document.cookie = cookie;
6098  };
6099
6100  // Set a cookie without encoding the value.
6101  Cookie.setRaw = function(key, value, opts) {
6102    Cookie.set(key, value, true, opts);
6103  };
6104
6105  // Remove a cookie by the specified key.
6106  Cookie.remove = function(key) {
6107    Cookie.set(key, 'a', { expires: new Date() });
6108  };
6109
6110  // Helper function
6111  // ---------------
6112
6113  // Escape special characters.
6114  function escapeRe(str) {
6115    return str.replace(/[.*+?^$|[\](){}\\-]/g, '\\$&');
6116  }
6117
6118  // Convert an object to a cookie option string.
6119  function convert(opts) {
6120    var res = '';
6121
6122    for (var p in opts) {
6123      if (opts.hasOwnProperty(p)) {
6124
6125        if (p === 'expires') {
6126          var expires = opts[p];
6127          if (typeof expires !== 'object') {
6128            expires += typeof expires === 'number' ? 'D' : '';
6129            expires = computeExpires(expires);
6130          }
6131          opts[p] = expires.toUTCString();
6132        }
6133
6134        res += ';' + p + '=' + opts[p];
6135      }
6136    }
6137
6138    if (!opts.hasOwnProperty('path')) {
6139      res += ';path=/';
6140    }
6141
6142    return res;
6143  }
6144
6145  // Return a future date by the given string.
6146  function computeExpires(str) {
6147    var expires = new Date();
6148    var lastCh = str.charAt(str.length - 1);
6149    var value = parseInt(str, 10);
6150
6151    switch (lastCh) {
6152      case 'Y': expires.setFullYear(expires.getFullYear() + value); break;
6153      case 'M': expires.setMonth(expires.getMonth() + value); break;
6154      case 'D': expires.setDate(expires.getDate() + value); break;
6155      case 'h': expires.setHours(expires.getHours() + value); break;
6156      case 'm': expires.setMinutes(expires.getMinutes() + value); break;
6157      case 's': expires.setSeconds(expires.getSeconds() + value); break;
6158      default: expires = new Date(str);
6159    }
6160
6161    return expires;
6162  }
6163
6164  return Cookie;
6165
6166}));
6167
6168},{}]},{},[18]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.