github.com/shohhei1126/hugo@v0.42.2-0.20180623210752-3d5928889ad7/examples/blog/static/js/bootstrap.js (about)

     1  /*!
     2   * Bootstrap v3.3.6 (http://getbootstrap.com)
     3   * Copyright 2011-2015 Twitter, Inc.
     4   * Licensed under the MIT license
     5   */
     6  
     7  if (typeof jQuery === 'undefined') {
     8    throw new Error('Bootstrap\'s JavaScript requires jQuery')
     9  }
    10  
    11  +function ($) {
    12    'use strict';
    13    var version = $.fn.jquery.split(' ')[0].split('.')
    14    if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {
    15      throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')
    16    }
    17  }(jQuery);
    18  
    19  /* ========================================================================
    20   * Bootstrap: transition.js v3.3.6
    21   * http://getbootstrap.com/javascript/#transitions
    22   * ========================================================================
    23   * Copyright 2011-2015 Twitter, Inc.
    24   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
    25   * ======================================================================== */
    26  
    27  
    28  +function ($) {
    29    'use strict';
    30  
    31    // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
    32    // ============================================================
    33  
    34    function transitionEnd() {
    35      var el = document.createElement('bootstrap')
    36  
    37      var transEndEventNames = {
    38        WebkitTransition : 'webkitTransitionEnd',
    39        MozTransition    : 'transitionend',
    40        OTransition      : 'oTransitionEnd otransitionend',
    41        transition       : 'transitionend'
    42      }
    43  
    44      for (var name in transEndEventNames) {
    45        if (el.style[name] !== undefined) {
    46          return { end: transEndEventNames[name] }
    47        }
    48      }
    49  
    50      return false // explicit for ie8 (  ._.)
    51    }
    52  
    53    // http://blog.alexmaccaw.com/css-transitions
    54    $.fn.emulateTransitionEnd = function (duration) {
    55      var called = false
    56      var $el = this
    57      $(this).one('bsTransitionEnd', function () { called = true })
    58      var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    59      setTimeout(callback, duration)
    60      return this
    61    }
    62  
    63    $(function () {
    64      $.support.transition = transitionEnd()
    65  
    66      if (!$.support.transition) return
    67  
    68      $.event.special.bsTransitionEnd = {
    69        bindType: $.support.transition.end,
    70        delegateType: $.support.transition.end,
    71        handle: function (e) {
    72          if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
    73        }
    74      }
    75    })
    76  
    77  }(jQuery);
    78  
    79  /* ========================================================================
    80   * Bootstrap: alert.js v3.3.6
    81   * http://getbootstrap.com/javascript/#alerts
    82   * ========================================================================
    83   * Copyright 2011-2015 Twitter, Inc.
    84   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
    85   * ======================================================================== */
    86  
    87  
    88  +function ($) {
    89    'use strict';
    90  
    91    // ALERT CLASS DEFINITION
    92    // ======================
    93  
    94    var dismiss = '[data-dismiss="alert"]'
    95    var Alert   = function (el) {
    96      $(el).on('click', dismiss, this.close)
    97    }
    98  
    99    Alert.VERSION = '3.3.6'
   100  
   101    Alert.TRANSITION_DURATION = 150
   102  
   103    Alert.prototype.close = function (e) {
   104      var $this    = $(this)
   105      var selector = $this.attr('data-target')
   106  
   107      if (!selector) {
   108        selector = $this.attr('href')
   109        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
   110      }
   111  
   112      var $parent = $(selector)
   113  
   114      if (e) e.preventDefault()
   115  
   116      if (!$parent.length) {
   117        $parent = $this.closest('.alert')
   118      }
   119  
   120      $parent.trigger(e = $.Event('close.bs.alert'))
   121  
   122      if (e.isDefaultPrevented()) return
   123  
   124      $parent.removeClass('in')
   125  
   126      function removeElement() {
   127        // detach from parent, fire event then clean up data
   128        $parent.detach().trigger('closed.bs.alert').remove()
   129      }
   130  
   131      $.support.transition && $parent.hasClass('fade') ?
   132        $parent
   133          .one('bsTransitionEnd', removeElement)
   134          .emulateTransitionEnd(Alert.TRANSITION_DURATION) :
   135        removeElement()
   136    }
   137  
   138  
   139    // ALERT PLUGIN DEFINITION
   140    // =======================
   141  
   142    function Plugin(option) {
   143      return this.each(function () {
   144        var $this = $(this)
   145        var data  = $this.data('bs.alert')
   146  
   147        if (!data) $this.data('bs.alert', (data = new Alert(this)))
   148        if (typeof option == 'string') data[option].call($this)
   149      })
   150    }
   151  
   152    var old = $.fn.alert
   153  
   154    $.fn.alert             = Plugin
   155    $.fn.alert.Constructor = Alert
   156  
   157  
   158    // ALERT NO CONFLICT
   159    // =================
   160  
   161    $.fn.alert.noConflict = function () {
   162      $.fn.alert = old
   163      return this
   164    }
   165  
   166  
   167    // ALERT DATA-API
   168    // ==============
   169  
   170    $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
   171  
   172  }(jQuery);
   173  
   174  /* ========================================================================
   175   * Bootstrap: button.js v3.3.6
   176   * http://getbootstrap.com/javascript/#buttons
   177   * ========================================================================
   178   * Copyright 2011-2015 Twitter, Inc.
   179   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
   180   * ======================================================================== */
   181  
   182  
   183  +function ($) {
   184    'use strict';
   185  
   186    // BUTTON PUBLIC CLASS DEFINITION
   187    // ==============================
   188  
   189    var Button = function (element, options) {
   190      this.$element  = $(element)
   191      this.options   = $.extend({}, Button.DEFAULTS, options)
   192      this.isLoading = false
   193    }
   194  
   195    Button.VERSION  = '3.3.6'
   196  
   197    Button.DEFAULTS = {
   198      loadingText: 'loading...'
   199    }
   200  
   201    Button.prototype.setState = function (state) {
   202      var d    = 'disabled'
   203      var $el  = this.$element
   204      var val  = $el.is('input') ? 'val' : 'html'
   205      var data = $el.data()
   206  
   207      state += 'Text'
   208  
   209      if (data.resetText == null) $el.data('resetText', $el[val]())
   210  
   211      // push to event loop to allow forms to submit
   212      setTimeout($.proxy(function () {
   213        $el[val](data[state] == null ? this.options[state] : data[state])
   214  
   215        if (state == 'loadingText') {
   216          this.isLoading = true
   217          $el.addClass(d).attr(d, d)
   218        } else if (this.isLoading) {
   219          this.isLoading = false
   220          $el.removeClass(d).removeAttr(d)
   221        }
   222      }, this), 0)
   223    }
   224  
   225    Button.prototype.toggle = function () {
   226      var changed = true
   227      var $parent = this.$element.closest('[data-toggle="buttons"]')
   228  
   229      if ($parent.length) {
   230        var $input = this.$element.find('input')
   231        if ($input.prop('type') == 'radio') {
   232          if ($input.prop('checked')) changed = false
   233          $parent.find('.active').removeClass('active')
   234          this.$element.addClass('active')
   235        } else if ($input.prop('type') == 'checkbox') {
   236          if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
   237          this.$element.toggleClass('active')
   238        }
   239        $input.prop('checked', this.$element.hasClass('active'))
   240        if (changed) $input.trigger('change')
   241      } else {
   242        this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
   243        this.$element.toggleClass('active')
   244      }
   245    }
   246  
   247  
   248    // BUTTON PLUGIN DEFINITION
   249    // ========================
   250  
   251    function Plugin(option) {
   252      return this.each(function () {
   253        var $this   = $(this)
   254        var data    = $this.data('bs.button')
   255        var options = typeof option == 'object' && option
   256  
   257        if (!data) $this.data('bs.button', (data = new Button(this, options)))
   258  
   259        if (option == 'toggle') data.toggle()
   260        else if (option) data.setState(option)
   261      })
   262    }
   263  
   264    var old = $.fn.button
   265  
   266    $.fn.button             = Plugin
   267    $.fn.button.Constructor = Button
   268  
   269  
   270    // BUTTON NO CONFLICT
   271    // ==================
   272  
   273    $.fn.button.noConflict = function () {
   274      $.fn.button = old
   275      return this
   276    }
   277  
   278  
   279    // BUTTON DATA-API
   280    // ===============
   281  
   282    $(document)
   283      .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
   284        var $btn = $(e.target)
   285        if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
   286        Plugin.call($btn, 'toggle')
   287        if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault()
   288      })
   289      .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
   290        $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
   291      })
   292  
   293  }(jQuery);
   294  
   295  /* ========================================================================
   296   * Bootstrap: carousel.js v3.3.6
   297   * http://getbootstrap.com/javascript/#carousel
   298   * ========================================================================
   299   * Copyright 2011-2015 Twitter, Inc.
   300   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
   301   * ======================================================================== */
   302  
   303  
   304  +function ($) {
   305    'use strict';
   306  
   307    // CAROUSEL CLASS DEFINITION
   308    // =========================
   309  
   310    var Carousel = function (element, options) {
   311      this.$element    = $(element)
   312      this.$indicators = this.$element.find('.carousel-indicators')
   313      this.options     = options
   314      this.paused      = null
   315      this.sliding     = null
   316      this.interval    = null
   317      this.$active     = null
   318      this.$items      = null
   319  
   320      this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
   321  
   322      this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
   323        .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
   324        .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
   325    }
   326  
   327    Carousel.VERSION  = '3.3.6'
   328  
   329    Carousel.TRANSITION_DURATION = 600
   330  
   331    Carousel.DEFAULTS = {
   332      interval: 5000,
   333      pause: 'hover',
   334      wrap: true,
   335      keyboard: true
   336    }
   337  
   338    Carousel.prototype.keydown = function (e) {
   339      if (/input|textarea/i.test(e.target.tagName)) return
   340      switch (e.which) {
   341        case 37: this.prev(); break
   342        case 39: this.next(); break
   343        default: return
   344      }
   345  
   346      e.preventDefault()
   347    }
   348  
   349    Carousel.prototype.cycle = function (e) {
   350      e || (this.paused = false)
   351  
   352      this.interval && clearInterval(this.interval)
   353  
   354      this.options.interval
   355        && !this.paused
   356        && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
   357  
   358      return this
   359    }
   360  
   361    Carousel.prototype.getItemIndex = function (item) {
   362      this.$items = item.parent().children('.item')
   363      return this.$items.index(item || this.$active)
   364    }
   365  
   366    Carousel.prototype.getItemForDirection = function (direction, active) {
   367      var activeIndex = this.getItemIndex(active)
   368      var willWrap = (direction == 'prev' && activeIndex === 0)
   369                  || (direction == 'next' && activeIndex == (this.$items.length - 1))
   370      if (willWrap && !this.options.wrap) return active
   371      var delta = direction == 'prev' ? -1 : 1
   372      var itemIndex = (activeIndex + delta) % this.$items.length
   373      return this.$items.eq(itemIndex)
   374    }
   375  
   376    Carousel.prototype.to = function (pos) {
   377      var that        = this
   378      var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
   379  
   380      if (pos > (this.$items.length - 1) || pos < 0) return
   381  
   382      if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
   383      if (activeIndex == pos) return this.pause().cycle()
   384  
   385      return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
   386    }
   387  
   388    Carousel.prototype.pause = function (e) {
   389      e || (this.paused = true)
   390  
   391      if (this.$element.find('.next, .prev').length && $.support.transition) {
   392        this.$element.trigger($.support.transition.end)
   393        this.cycle(true)
   394      }
   395  
   396      this.interval = clearInterval(this.interval)
   397  
   398      return this
   399    }
   400  
   401    Carousel.prototype.next = function () {
   402      if (this.sliding) return
   403      return this.slide('next')
   404    }
   405  
   406    Carousel.prototype.prev = function () {
   407      if (this.sliding) return
   408      return this.slide('prev')
   409    }
   410  
   411    Carousel.prototype.slide = function (type, next) {
   412      var $active   = this.$element.find('.item.active')
   413      var $next     = next || this.getItemForDirection(type, $active)
   414      var isCycling = this.interval
   415      var direction = type == 'next' ? 'left' : 'right'
   416      var that      = this
   417  
   418      if ($next.hasClass('active')) return (this.sliding = false)
   419  
   420      var relatedTarget = $next[0]
   421      var slideEvent = $.Event('slide.bs.carousel', {
   422        relatedTarget: relatedTarget,
   423        direction: direction
   424      })
   425      this.$element.trigger(slideEvent)
   426      if (slideEvent.isDefaultPrevented()) return
   427  
   428      this.sliding = true
   429  
   430      isCycling && this.pause()
   431  
   432      if (this.$indicators.length) {
   433        this.$indicators.find('.active').removeClass('active')
   434        var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
   435        $nextIndicator && $nextIndicator.addClass('active')
   436      }
   437  
   438      var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
   439      if ($.support.transition && this.$element.hasClass('slide')) {
   440        $next.addClass(type)
   441        $next[0].offsetWidth // force reflow
   442        $active.addClass(direction)
   443        $next.addClass(direction)
   444        $active
   445          .one('bsTransitionEnd', function () {
   446            $next.removeClass([type, direction].join(' ')).addClass('active')
   447            $active.removeClass(['active', direction].join(' '))
   448            that.sliding = false
   449            setTimeout(function () {
   450              that.$element.trigger(slidEvent)
   451            }, 0)
   452          })
   453          .emulateTransitionEnd(Carousel.TRANSITION_DURATION)
   454      } else {
   455        $active.removeClass('active')
   456        $next.addClass('active')
   457        this.sliding = false
   458        this.$element.trigger(slidEvent)
   459      }
   460  
   461      isCycling && this.cycle()
   462  
   463      return this
   464    }
   465  
   466  
   467    // CAROUSEL PLUGIN DEFINITION
   468    // ==========================
   469  
   470    function Plugin(option) {
   471      return this.each(function () {
   472        var $this   = $(this)
   473        var data    = $this.data('bs.carousel')
   474        var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
   475        var action  = typeof option == 'string' ? option : options.slide
   476  
   477        if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
   478        if (typeof option == 'number') data.to(option)
   479        else if (action) data[action]()
   480        else if (options.interval) data.pause().cycle()
   481      })
   482    }
   483  
   484    var old = $.fn.carousel
   485  
   486    $.fn.carousel             = Plugin
   487    $.fn.carousel.Constructor = Carousel
   488  
   489  
   490    // CAROUSEL NO CONFLICT
   491    // ====================
   492  
   493    $.fn.carousel.noConflict = function () {
   494      $.fn.carousel = old
   495      return this
   496    }
   497  
   498  
   499    // CAROUSEL DATA-API
   500    // =================
   501  
   502    var clickHandler = function (e) {
   503      var href
   504      var $this   = $(this)
   505      var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
   506      if (!$target.hasClass('carousel')) return
   507      var options = $.extend({}, $target.data(), $this.data())
   508      var slideIndex = $this.attr('data-slide-to')
   509      if (slideIndex) options.interval = false
   510  
   511      Plugin.call($target, options)
   512  
   513      if (slideIndex) {
   514        $target.data('bs.carousel').to(slideIndex)
   515      }
   516  
   517      e.preventDefault()
   518    }
   519  
   520    $(document)
   521      .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
   522      .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
   523  
   524    $(window).on('load', function () {
   525      $('[data-ride="carousel"]').each(function () {
   526        var $carousel = $(this)
   527        Plugin.call($carousel, $carousel.data())
   528      })
   529    })
   530  
   531  }(jQuery);
   532  
   533  /* ========================================================================
   534   * Bootstrap: collapse.js v3.3.6
   535   * http://getbootstrap.com/javascript/#collapse
   536   * ========================================================================
   537   * Copyright 2011-2015 Twitter, Inc.
   538   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
   539   * ======================================================================== */
   540  
   541  
   542  +function ($) {
   543    'use strict';
   544  
   545    // COLLAPSE PUBLIC CLASS DEFINITION
   546    // ================================
   547  
   548    var Collapse = function (element, options) {
   549      this.$element      = $(element)
   550      this.options       = $.extend({}, Collapse.DEFAULTS, options)
   551      this.$trigger      = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
   552                             '[data-toggle="collapse"][data-target="#' + element.id + '"]')
   553      this.transitioning = null
   554  
   555      if (this.options.parent) {
   556        this.$parent = this.getParent()
   557      } else {
   558        this.addAriaAndCollapsedClass(this.$element, this.$trigger)
   559      }
   560  
   561      if (this.options.toggle) this.toggle()
   562    }
   563  
   564    Collapse.VERSION  = '3.3.6'
   565  
   566    Collapse.TRANSITION_DURATION = 350
   567  
   568    Collapse.DEFAULTS = {
   569      toggle: true
   570    }
   571  
   572    Collapse.prototype.dimension = function () {
   573      var hasWidth = this.$element.hasClass('width')
   574      return hasWidth ? 'width' : 'height'
   575    }
   576  
   577    Collapse.prototype.show = function () {
   578      if (this.transitioning || this.$element.hasClass('in')) return
   579  
   580      var activesData
   581      var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
   582  
   583      if (actives && actives.length) {
   584        activesData = actives.data('bs.collapse')
   585        if (activesData && activesData.transitioning) return
   586      }
   587  
   588      var startEvent = $.Event('show.bs.collapse')
   589      this.$element.trigger(startEvent)
   590      if (startEvent.isDefaultPrevented()) return
   591  
   592      if (actives && actives.length) {
   593        Plugin.call(actives, 'hide')
   594        activesData || actives.data('bs.collapse', null)
   595      }
   596  
   597      var dimension = this.dimension()
   598  
   599      this.$element
   600        .removeClass('collapse')
   601        .addClass('collapsing')[dimension](0)
   602        .attr('aria-expanded', true)
   603  
   604      this.$trigger
   605        .removeClass('collapsed')
   606        .attr('aria-expanded', true)
   607  
   608      this.transitioning = 1
   609  
   610      var complete = function () {
   611        this.$element
   612          .removeClass('collapsing')
   613          .addClass('collapse in')[dimension]('')
   614        this.transitioning = 0
   615        this.$element
   616          .trigger('shown.bs.collapse')
   617      }
   618  
   619      if (!$.support.transition) return complete.call(this)
   620  
   621      var scrollSize = $.camelCase(['scroll', dimension].join('-'))
   622  
   623      this.$element
   624        .one('bsTransitionEnd', $.proxy(complete, this))
   625        .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
   626    }
   627  
   628    Collapse.prototype.hide = function () {
   629      if (this.transitioning || !this.$element.hasClass('in')) return
   630  
   631      var startEvent = $.Event('hide.bs.collapse')
   632      this.$element.trigger(startEvent)
   633      if (startEvent.isDefaultPrevented()) return
   634  
   635      var dimension = this.dimension()
   636  
   637      this.$element[dimension](this.$element[dimension]())[0].offsetHeight
   638  
   639      this.$element
   640        .addClass('collapsing')
   641        .removeClass('collapse in')
   642        .attr('aria-expanded', false)
   643  
   644      this.$trigger
   645        .addClass('collapsed')
   646        .attr('aria-expanded', false)
   647  
   648      this.transitioning = 1
   649  
   650      var complete = function () {
   651        this.transitioning = 0
   652        this.$element
   653          .removeClass('collapsing')
   654          .addClass('collapse')
   655          .trigger('hidden.bs.collapse')
   656      }
   657  
   658      if (!$.support.transition) return complete.call(this)
   659  
   660      this.$element
   661        [dimension](0)
   662        .one('bsTransitionEnd', $.proxy(complete, this))
   663        .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
   664    }
   665  
   666    Collapse.prototype.toggle = function () {
   667      this[this.$element.hasClass('in') ? 'hide' : 'show']()
   668    }
   669  
   670    Collapse.prototype.getParent = function () {
   671      return $(this.options.parent)
   672        .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
   673        .each($.proxy(function (i, element) {
   674          var $element = $(element)
   675          this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
   676        }, this))
   677        .end()
   678    }
   679  
   680    Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
   681      var isOpen = $element.hasClass('in')
   682  
   683      $element.attr('aria-expanded', isOpen)
   684      $trigger
   685        .toggleClass('collapsed', !isOpen)
   686        .attr('aria-expanded', isOpen)
   687    }
   688  
   689    function getTargetFromTrigger($trigger) {
   690      var href
   691      var target = $trigger.attr('data-target')
   692        || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
   693  
   694      return $(target)
   695    }
   696  
   697  
   698    // COLLAPSE PLUGIN DEFINITION
   699    // ==========================
   700  
   701    function Plugin(option) {
   702      return this.each(function () {
   703        var $this   = $(this)
   704        var data    = $this.data('bs.collapse')
   705        var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
   706  
   707        if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
   708        if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
   709        if (typeof option == 'string') data[option]()
   710      })
   711    }
   712  
   713    var old = $.fn.collapse
   714  
   715    $.fn.collapse             = Plugin
   716    $.fn.collapse.Constructor = Collapse
   717  
   718  
   719    // COLLAPSE NO CONFLICT
   720    // ====================
   721  
   722    $.fn.collapse.noConflict = function () {
   723      $.fn.collapse = old
   724      return this
   725    }
   726  
   727  
   728    // COLLAPSE DATA-API
   729    // =================
   730  
   731    $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
   732      var $this   = $(this)
   733  
   734      if (!$this.attr('data-target')) e.preventDefault()
   735  
   736      var $target = getTargetFromTrigger($this)
   737      var data    = $target.data('bs.collapse')
   738      var option  = data ? 'toggle' : $this.data()
   739  
   740      Plugin.call($target, option)
   741    })
   742  
   743  }(jQuery);
   744  
   745  /* ========================================================================
   746   * Bootstrap: dropdown.js v3.3.6
   747   * http://getbootstrap.com/javascript/#dropdowns
   748   * ========================================================================
   749   * Copyright 2011-2015 Twitter, Inc.
   750   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
   751   * ======================================================================== */
   752  
   753  
   754  +function ($) {
   755    'use strict';
   756  
   757    // DROPDOWN CLASS DEFINITION
   758    // =========================
   759  
   760    var backdrop = '.dropdown-backdrop'
   761    var toggle   = '[data-toggle="dropdown"]'
   762    var Dropdown = function (element) {
   763      $(element).on('click.bs.dropdown', this.toggle)
   764    }
   765  
   766    Dropdown.VERSION = '3.3.6'
   767  
   768    function getParent($this) {
   769      var selector = $this.attr('data-target')
   770  
   771      if (!selector) {
   772        selector = $this.attr('href')
   773        selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
   774      }
   775  
   776      var $parent = selector && $(selector)
   777  
   778      return $parent && $parent.length ? $parent : $this.parent()
   779    }
   780  
   781    function clearMenus(e) {
   782      if (e && e.which === 3) return
   783      $(backdrop).remove()
   784      $(toggle).each(function () {
   785        var $this         = $(this)
   786        var $parent       = getParent($this)
   787        var relatedTarget = { relatedTarget: this }
   788  
   789        if (!$parent.hasClass('open')) return
   790  
   791        if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
   792  
   793        $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
   794  
   795        if (e.isDefaultPrevented()) return
   796  
   797        $this.attr('aria-expanded', 'false')
   798        $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
   799      })
   800    }
   801  
   802    Dropdown.prototype.toggle = function (e) {
   803      var $this = $(this)
   804  
   805      if ($this.is('.disabled, :disabled')) return
   806  
   807      var $parent  = getParent($this)
   808      var isActive = $parent.hasClass('open')
   809  
   810      clearMenus()
   811  
   812      if (!isActive) {
   813        if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
   814          // if mobile we use a backdrop because click events don't delegate
   815          $(document.createElement('div'))
   816            .addClass('dropdown-backdrop')
   817            .insertAfter($(this))
   818            .on('click', clearMenus)
   819        }
   820  
   821        var relatedTarget = { relatedTarget: this }
   822        $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
   823  
   824        if (e.isDefaultPrevented()) return
   825  
   826        $this
   827          .trigger('focus')
   828          .attr('aria-expanded', 'true')
   829  
   830        $parent
   831          .toggleClass('open')
   832          .trigger($.Event('shown.bs.dropdown', relatedTarget))
   833      }
   834  
   835      return false
   836    }
   837  
   838    Dropdown.prototype.keydown = function (e) {
   839      if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
   840  
   841      var $this = $(this)
   842  
   843      e.preventDefault()
   844      e.stopPropagation()
   845  
   846      if ($this.is('.disabled, :disabled')) return
   847  
   848      var $parent  = getParent($this)
   849      var isActive = $parent.hasClass('open')
   850  
   851      if (!isActive && e.which != 27 || isActive && e.which == 27) {
   852        if (e.which == 27) $parent.find(toggle).trigger('focus')
   853        return $this.trigger('click')
   854      }
   855  
   856      var desc = ' li:not(.disabled):visible a'
   857      var $items = $parent.find('.dropdown-menu' + desc)
   858  
   859      if (!$items.length) return
   860  
   861      var index = $items.index(e.target)
   862  
   863      if (e.which == 38 && index > 0)                 index--         // up
   864      if (e.which == 40 && index < $items.length - 1) index++         // down
   865      if (!~index)                                    index = 0
   866  
   867      $items.eq(index).trigger('focus')
   868    }
   869  
   870  
   871    // DROPDOWN PLUGIN DEFINITION
   872    // ==========================
   873  
   874    function Plugin(option) {
   875      return this.each(function () {
   876        var $this = $(this)
   877        var data  = $this.data('bs.dropdown')
   878  
   879        if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
   880        if (typeof option == 'string') data[option].call($this)
   881      })
   882    }
   883  
   884    var old = $.fn.dropdown
   885  
   886    $.fn.dropdown             = Plugin
   887    $.fn.dropdown.Constructor = Dropdown
   888  
   889  
   890    // DROPDOWN NO CONFLICT
   891    // ====================
   892  
   893    $.fn.dropdown.noConflict = function () {
   894      $.fn.dropdown = old
   895      return this
   896    }
   897  
   898  
   899    // APPLY TO STANDARD DROPDOWN ELEMENTS
   900    // ===================================
   901  
   902    $(document)
   903      .on('click.bs.dropdown.data-api', clearMenus)
   904      .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
   905      .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
   906      .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
   907      .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
   908  
   909  }(jQuery);
   910  
   911  /* ========================================================================
   912   * Bootstrap: modal.js v3.3.6
   913   * http://getbootstrap.com/javascript/#modals
   914   * ========================================================================
   915   * Copyright 2011-2015 Twitter, Inc.
   916   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
   917   * ======================================================================== */
   918  
   919  
   920  +function ($) {
   921    'use strict';
   922  
   923    // MODAL CLASS DEFINITION
   924    // ======================
   925  
   926    var Modal = function (element, options) {
   927      this.options             = options
   928      this.$body               = $(document.body)
   929      this.$element            = $(element)
   930      this.$dialog             = this.$element.find('.modal-dialog')
   931      this.$backdrop           = null
   932      this.isShown             = null
   933      this.originalBodyPad     = null
   934      this.scrollbarWidth      = 0
   935      this.ignoreBackdropClick = false
   936  
   937      if (this.options.remote) {
   938        this.$element
   939          .find('.modal-content')
   940          .load(this.options.remote, $.proxy(function () {
   941            this.$element.trigger('loaded.bs.modal')
   942          }, this))
   943      }
   944    }
   945  
   946    Modal.VERSION  = '3.3.6'
   947  
   948    Modal.TRANSITION_DURATION = 300
   949    Modal.BACKDROP_TRANSITION_DURATION = 150
   950  
   951    Modal.DEFAULTS = {
   952      backdrop: true,
   953      keyboard: true,
   954      show: true
   955    }
   956  
   957    Modal.prototype.toggle = function (_relatedTarget) {
   958      return this.isShown ? this.hide() : this.show(_relatedTarget)
   959    }
   960  
   961    Modal.prototype.show = function (_relatedTarget) {
   962      var that = this
   963      var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
   964  
   965      this.$element.trigger(e)
   966  
   967      if (this.isShown || e.isDefaultPrevented()) return
   968  
   969      this.isShown = true
   970  
   971      this.checkScrollbar()
   972      this.setScrollbar()
   973      this.$body.addClass('modal-open')
   974  
   975      this.escape()
   976      this.resize()
   977  
   978      this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
   979  
   980      this.$dialog.on('mousedown.dismiss.bs.modal', function () {
   981        that.$element.one('mouseup.dismiss.bs.modal', function (e) {
   982          if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
   983        })
   984      })
   985  
   986      this.backdrop(function () {
   987        var transition = $.support.transition && that.$element.hasClass('fade')
   988  
   989        if (!that.$element.parent().length) {
   990          that.$element.appendTo(that.$body) // don't move modals dom position
   991        }
   992  
   993        that.$element
   994          .show()
   995          .scrollTop(0)
   996  
   997        that.adjustDialog()
   998  
   999        if (transition) {
  1000          that.$element[0].offsetWidth // force reflow
  1001        }
  1002  
  1003        that.$element.addClass('in')
  1004  
  1005        that.enforceFocus()
  1006  
  1007        var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
  1008  
  1009        transition ?
  1010          that.$dialog // wait for modal to slide in
  1011            .one('bsTransitionEnd', function () {
  1012              that.$element.trigger('focus').trigger(e)
  1013            })
  1014            .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
  1015          that.$element.trigger('focus').trigger(e)
  1016      })
  1017    }
  1018  
  1019    Modal.prototype.hide = function (e) {
  1020      if (e) e.preventDefault()
  1021  
  1022      e = $.Event('hide.bs.modal')
  1023  
  1024      this.$element.trigger(e)
  1025  
  1026      if (!this.isShown || e.isDefaultPrevented()) return
  1027  
  1028      this.isShown = false
  1029  
  1030      this.escape()
  1031      this.resize()
  1032  
  1033      $(document).off('focusin.bs.modal')
  1034  
  1035      this.$element
  1036        .removeClass('in')
  1037        .off('click.dismiss.bs.modal')
  1038        .off('mouseup.dismiss.bs.modal')
  1039  
  1040      this.$dialog.off('mousedown.dismiss.bs.modal')
  1041  
  1042      $.support.transition && this.$element.hasClass('fade') ?
  1043        this.$element
  1044          .one('bsTransitionEnd', $.proxy(this.hideModal, this))
  1045          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :
  1046        this.hideModal()
  1047    }
  1048  
  1049    Modal.prototype.enforceFocus = function () {
  1050      $(document)
  1051        .off('focusin.bs.modal') // guard against infinite focus loop
  1052        .on('focusin.bs.modal', $.proxy(function (e) {
  1053          if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
  1054            this.$element.trigger('focus')
  1055          }
  1056        }, this))
  1057    }
  1058  
  1059    Modal.prototype.escape = function () {
  1060      if (this.isShown && this.options.keyboard) {
  1061        this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
  1062          e.which == 27 && this.hide()
  1063        }, this))
  1064      } else if (!this.isShown) {
  1065        this.$element.off('keydown.dismiss.bs.modal')
  1066      }
  1067    }
  1068  
  1069    Modal.prototype.resize = function () {
  1070      if (this.isShown) {
  1071        $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
  1072      } else {
  1073        $(window).off('resize.bs.modal')
  1074      }
  1075    }
  1076  
  1077    Modal.prototype.hideModal = function () {
  1078      var that = this
  1079      this.$element.hide()
  1080      this.backdrop(function () {
  1081        that.$body.removeClass('modal-open')
  1082        that.resetAdjustments()
  1083        that.resetScrollbar()
  1084        that.$element.trigger('hidden.bs.modal')
  1085      })
  1086    }
  1087  
  1088    Modal.prototype.removeBackdrop = function () {
  1089      this.$backdrop && this.$backdrop.remove()
  1090      this.$backdrop = null
  1091    }
  1092  
  1093    Modal.prototype.backdrop = function (callback) {
  1094      var that = this
  1095      var animate = this.$element.hasClass('fade') ? 'fade' : ''
  1096  
  1097      if (this.isShown && this.options.backdrop) {
  1098        var doAnimate = $.support.transition && animate
  1099  
  1100        this.$backdrop = $(document.createElement('div'))
  1101          .addClass('modal-backdrop ' + animate)
  1102          .appendTo(this.$body)
  1103  
  1104        this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
  1105          if (this.ignoreBackdropClick) {
  1106            this.ignoreBackdropClick = false
  1107            return
  1108          }
  1109          if (e.target !== e.currentTarget) return
  1110          this.options.backdrop == 'static'
  1111            ? this.$element[0].focus()
  1112            : this.hide()
  1113        }, this))
  1114  
  1115        if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
  1116  
  1117        this.$backdrop.addClass('in')
  1118  
  1119        if (!callback) return
  1120  
  1121        doAnimate ?
  1122          this.$backdrop
  1123            .one('bsTransitionEnd', callback)
  1124            .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
  1125          callback()
  1126  
  1127      } else if (!this.isShown && this.$backdrop) {
  1128        this.$backdrop.removeClass('in')
  1129  
  1130        var callbackRemove = function () {
  1131          that.removeBackdrop()
  1132          callback && callback()
  1133        }
  1134        $.support.transition && this.$element.hasClass('fade') ?
  1135          this.$backdrop
  1136            .one('bsTransitionEnd', callbackRemove)
  1137            .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
  1138          callbackRemove()
  1139  
  1140      } else if (callback) {
  1141        callback()
  1142      }
  1143    }
  1144  
  1145    // these following methods are used to handle overflowing modals
  1146  
  1147    Modal.prototype.handleUpdate = function () {
  1148      this.adjustDialog()
  1149    }
  1150  
  1151    Modal.prototype.adjustDialog = function () {
  1152      var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
  1153  
  1154      this.$element.css({
  1155        paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
  1156        paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
  1157      })
  1158    }
  1159  
  1160    Modal.prototype.resetAdjustments = function () {
  1161      this.$element.css({
  1162        paddingLeft: '',
  1163        paddingRight: ''
  1164      })
  1165    }
  1166  
  1167    Modal.prototype.checkScrollbar = function () {
  1168      var fullWindowWidth = window.innerWidth
  1169      if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
  1170        var documentElementRect = document.documentElement.getBoundingClientRect()
  1171        fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
  1172      }
  1173      this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
  1174      this.scrollbarWidth = this.measureScrollbar()
  1175    }
  1176  
  1177    Modal.prototype.setScrollbar = function () {
  1178      var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
  1179      this.originalBodyPad = document.body.style.paddingRight || ''
  1180      if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
  1181    }
  1182  
  1183    Modal.prototype.resetScrollbar = function () {
  1184      this.$body.css('padding-right', this.originalBodyPad)
  1185    }
  1186  
  1187    Modal.prototype.measureScrollbar = function () { // thx walsh
  1188      var scrollDiv = document.createElement('div')
  1189      scrollDiv.className = 'modal-scrollbar-measure'
  1190      this.$body.append(scrollDiv)
  1191      var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
  1192      this.$body[0].removeChild(scrollDiv)
  1193      return scrollbarWidth
  1194    }
  1195  
  1196  
  1197    // MODAL PLUGIN DEFINITION
  1198    // =======================
  1199  
  1200    function Plugin(option, _relatedTarget) {
  1201      return this.each(function () {
  1202        var $this   = $(this)
  1203        var data    = $this.data('bs.modal')
  1204        var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
  1205  
  1206        if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
  1207        if (typeof option == 'string') data[option](_relatedTarget)
  1208        else if (options.show) data.show(_relatedTarget)
  1209      })
  1210    }
  1211  
  1212    var old = $.fn.modal
  1213  
  1214    $.fn.modal             = Plugin
  1215    $.fn.modal.Constructor = Modal
  1216  
  1217  
  1218    // MODAL NO CONFLICT
  1219    // =================
  1220  
  1221    $.fn.modal.noConflict = function () {
  1222      $.fn.modal = old
  1223      return this
  1224    }
  1225  
  1226  
  1227    // MODAL DATA-API
  1228    // ==============
  1229  
  1230    $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
  1231      var $this   = $(this)
  1232      var href    = $this.attr('href')
  1233      var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
  1234      var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
  1235  
  1236      if ($this.is('a')) e.preventDefault()
  1237  
  1238      $target.one('show.bs.modal', function (showEvent) {
  1239        if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
  1240        $target.one('hidden.bs.modal', function () {
  1241          $this.is(':visible') && $this.trigger('focus')
  1242        })
  1243      })
  1244      Plugin.call($target, option, this)
  1245    })
  1246  
  1247  }(jQuery);
  1248  
  1249  /* ========================================================================
  1250   * Bootstrap: tooltip.js v3.3.6
  1251   * http://getbootstrap.com/javascript/#tooltip
  1252   * Inspired by the original jQuery.tipsy by Jason Frame
  1253   * ========================================================================
  1254   * Copyright 2011-2015 Twitter, Inc.
  1255   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  1256   * ======================================================================== */
  1257  
  1258  
  1259  +function ($) {
  1260    'use strict';
  1261  
  1262    // TOOLTIP PUBLIC CLASS DEFINITION
  1263    // ===============================
  1264  
  1265    var Tooltip = function (element, options) {
  1266      this.type       = null
  1267      this.options    = null
  1268      this.enabled    = null
  1269      this.timeout    = null
  1270      this.hoverState = null
  1271      this.$element   = null
  1272      this.inState    = null
  1273  
  1274      this.init('tooltip', element, options)
  1275    }
  1276  
  1277    Tooltip.VERSION  = '3.3.6'
  1278  
  1279    Tooltip.TRANSITION_DURATION = 150
  1280  
  1281    Tooltip.DEFAULTS = {
  1282      animation: true,
  1283      placement: 'top',
  1284      selector: false,
  1285      template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
  1286      trigger: 'hover focus',
  1287      title: '',
  1288      delay: 0,
  1289      html: false,
  1290      container: false,
  1291      viewport: {
  1292        selector: 'body',
  1293        padding: 0
  1294      }
  1295    }
  1296  
  1297    Tooltip.prototype.init = function (type, element, options) {
  1298      this.enabled   = true
  1299      this.type      = type
  1300      this.$element  = $(element)
  1301      this.options   = this.getOptions(options)
  1302      this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))
  1303      this.inState   = { click: false, hover: false, focus: false }
  1304  
  1305      if (this.$element[0] instanceof document.constructor && !this.options.selector) {
  1306        throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')
  1307      }
  1308  
  1309      var triggers = this.options.trigger.split(' ')
  1310  
  1311      for (var i = triggers.length; i--;) {
  1312        var trigger = triggers[i]
  1313  
  1314        if (trigger == 'click') {
  1315          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
  1316        } else if (trigger != 'manual') {
  1317          var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
  1318          var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
  1319  
  1320          this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
  1321          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
  1322        }
  1323      }
  1324  
  1325      this.options.selector ?
  1326        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
  1327        this.fixTitle()
  1328    }
  1329  
  1330    Tooltip.prototype.getDefaults = function () {
  1331      return Tooltip.DEFAULTS
  1332    }
  1333  
  1334    Tooltip.prototype.getOptions = function (options) {
  1335      options = $.extend({}, this.getDefaults(), this.$element.data(), options)
  1336  
  1337      if (options.delay && typeof options.delay == 'number') {
  1338        options.delay = {
  1339          show: options.delay,
  1340          hide: options.delay
  1341        }
  1342      }
  1343  
  1344      return options
  1345    }
  1346  
  1347    Tooltip.prototype.getDelegateOptions = function () {
  1348      var options  = {}
  1349      var defaults = this.getDefaults()
  1350  
  1351      this._options && $.each(this._options, function (key, value) {
  1352        if (defaults[key] != value) options[key] = value
  1353      })
  1354  
  1355      return options
  1356    }
  1357  
  1358    Tooltip.prototype.enter = function (obj) {
  1359      var self = obj instanceof this.constructor ?
  1360        obj : $(obj.currentTarget).data('bs.' + this.type)
  1361  
  1362      if (!self) {
  1363        self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
  1364        $(obj.currentTarget).data('bs.' + this.type, self)
  1365      }
  1366  
  1367      if (obj instanceof $.Event) {
  1368        self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true
  1369      }
  1370  
  1371      if (self.tip().hasClass('in') || self.hoverState == 'in') {
  1372        self.hoverState = 'in'
  1373        return
  1374      }
  1375  
  1376      clearTimeout(self.timeout)
  1377  
  1378      self.hoverState = 'in'
  1379  
  1380      if (!self.options.delay || !self.options.delay.show) return self.show()
  1381  
  1382      self.timeout = setTimeout(function () {
  1383        if (self.hoverState == 'in') self.show()
  1384      }, self.options.delay.show)
  1385    }
  1386  
  1387    Tooltip.prototype.isInStateTrue = function () {
  1388      for (var key in this.inState) {
  1389        if (this.inState[key]) return true
  1390      }
  1391  
  1392      return false
  1393    }
  1394  
  1395    Tooltip.prototype.leave = function (obj) {
  1396      var self = obj instanceof this.constructor ?
  1397        obj : $(obj.currentTarget).data('bs.' + this.type)
  1398  
  1399      if (!self) {
  1400        self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
  1401        $(obj.currentTarget).data('bs.' + this.type, self)
  1402      }
  1403  
  1404      if (obj instanceof $.Event) {
  1405        self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false
  1406      }
  1407  
  1408      if (self.isInStateTrue()) return
  1409  
  1410      clearTimeout(self.timeout)
  1411  
  1412      self.hoverState = 'out'
  1413  
  1414      if (!self.options.delay || !self.options.delay.hide) return self.hide()
  1415  
  1416      self.timeout = setTimeout(function () {
  1417        if (self.hoverState == 'out') self.hide()
  1418      }, self.options.delay.hide)
  1419    }
  1420  
  1421    Tooltip.prototype.show = function () {
  1422      var e = $.Event('show.bs.' + this.type)
  1423  
  1424      if (this.hasContent() && this.enabled) {
  1425        this.$element.trigger(e)
  1426  
  1427        var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])
  1428        if (e.isDefaultPrevented() || !inDom) return
  1429        var that = this
  1430  
  1431        var $tip = this.tip()
  1432  
  1433        var tipId = this.getUID(this.type)
  1434  
  1435        this.setContent()
  1436        $tip.attr('id', tipId)
  1437        this.$element.attr('aria-describedby', tipId)
  1438  
  1439        if (this.options.animation) $tip.addClass('fade')
  1440  
  1441        var placement = typeof this.options.placement == 'function' ?
  1442          this.options.placement.call(this, $tip[0], this.$element[0]) :
  1443          this.options.placement
  1444  
  1445        var autoToken = /\s?auto?\s?/i
  1446        var autoPlace = autoToken.test(placement)
  1447        if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
  1448  
  1449        $tip
  1450          .detach()
  1451          .css({ top: 0, left: 0, display: 'block' })
  1452          .addClass(placement)
  1453          .data('bs.' + this.type, this)
  1454  
  1455        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
  1456        this.$element.trigger('inserted.bs.' + this.type)
  1457  
  1458        var pos          = this.getPosition()
  1459        var actualWidth  = $tip[0].offsetWidth
  1460        var actualHeight = $tip[0].offsetHeight
  1461  
  1462        if (autoPlace) {
  1463          var orgPlacement = placement
  1464          var viewportDim = this.getPosition(this.$viewport)
  1465  
  1466          placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :
  1467                      placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :
  1468                      placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :
  1469                      placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :
  1470                      placement
  1471  
  1472          $tip
  1473            .removeClass(orgPlacement)
  1474            .addClass(placement)
  1475        }
  1476  
  1477        var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
  1478  
  1479        this.applyPlacement(calculatedOffset, placement)
  1480  
  1481        var complete = function () {
  1482          var prevHoverState = that.hoverState
  1483          that.$element.trigger('shown.bs.' + that.type)
  1484          that.hoverState = null
  1485  
  1486          if (prevHoverState == 'out') that.leave(that)
  1487        }
  1488  
  1489        $.support.transition && this.$tip.hasClass('fade') ?
  1490          $tip
  1491            .one('bsTransitionEnd', complete)
  1492            .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
  1493          complete()
  1494      }
  1495    }
  1496  
  1497    Tooltip.prototype.applyPlacement = function (offset, placement) {
  1498      var $tip   = this.tip()
  1499      var width  = $tip[0].offsetWidth
  1500      var height = $tip[0].offsetHeight
  1501  
  1502      // manually read margins because getBoundingClientRect includes difference
  1503      var marginTop = parseInt($tip.css('margin-top'), 10)
  1504      var marginLeft = parseInt($tip.css('margin-left'), 10)
  1505  
  1506      // we must check for NaN for ie 8/9
  1507      if (isNaN(marginTop))  marginTop  = 0
  1508      if (isNaN(marginLeft)) marginLeft = 0
  1509  
  1510      offset.top  += marginTop
  1511      offset.left += marginLeft
  1512  
  1513      // $.fn.offset doesn't round pixel values
  1514      // so we use setOffset directly with our own function B-0
  1515      $.offset.setOffset($tip[0], $.extend({
  1516        using: function (props) {
  1517          $tip.css({
  1518            top: Math.round(props.top),
  1519            left: Math.round(props.left)
  1520          })
  1521        }
  1522      }, offset), 0)
  1523  
  1524      $tip.addClass('in')
  1525  
  1526      // check to see if placing tip in new offset caused the tip to resize itself
  1527      var actualWidth  = $tip[0].offsetWidth
  1528      var actualHeight = $tip[0].offsetHeight
  1529  
  1530      if (placement == 'top' && actualHeight != height) {
  1531        offset.top = offset.top + height - actualHeight
  1532      }
  1533  
  1534      var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
  1535  
  1536      if (delta.left) offset.left += delta.left
  1537      else offset.top += delta.top
  1538  
  1539      var isVertical          = /top|bottom/.test(placement)
  1540      var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
  1541      var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
  1542  
  1543      $tip.offset(offset)
  1544      this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
  1545    }
  1546  
  1547    Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
  1548      this.arrow()
  1549        .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
  1550        .css(isVertical ? 'top' : 'left', '')
  1551    }
  1552  
  1553    Tooltip.prototype.setContent = function () {
  1554      var $tip  = this.tip()
  1555      var title = this.getTitle()
  1556  
  1557      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
  1558      $tip.removeClass('fade in top bottom left right')
  1559    }
  1560  
  1561    Tooltip.prototype.hide = function (callback) {
  1562      var that = this
  1563      var $tip = $(this.$tip)
  1564      var e    = $.Event('hide.bs.' + this.type)
  1565  
  1566      function complete() {
  1567        if (that.hoverState != 'in') $tip.detach()
  1568        that.$element
  1569          .removeAttr('aria-describedby')
  1570          .trigger('hidden.bs.' + that.type)
  1571        callback && callback()
  1572      }
  1573  
  1574      this.$element.trigger(e)
  1575  
  1576      if (e.isDefaultPrevented()) return
  1577  
  1578      $tip.removeClass('in')
  1579  
  1580      $.support.transition && $tip.hasClass('fade') ?
  1581        $tip
  1582          .one('bsTransitionEnd', complete)
  1583          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
  1584        complete()
  1585  
  1586      this.hoverState = null
  1587  
  1588      return this
  1589    }
  1590  
  1591    Tooltip.prototype.fixTitle = function () {
  1592      var $e = this.$element
  1593      if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {
  1594        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
  1595      }
  1596    }
  1597  
  1598    Tooltip.prototype.hasContent = function () {
  1599      return this.getTitle()
  1600    }
  1601  
  1602    Tooltip.prototype.getPosition = function ($element) {
  1603      $element   = $element || this.$element
  1604  
  1605      var el     = $element[0]
  1606      var isBody = el.tagName == 'BODY'
  1607  
  1608      var elRect    = el.getBoundingClientRect()
  1609      if (elRect.width == null) {
  1610        // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
  1611        elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
  1612      }
  1613      var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
  1614      var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
  1615      var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
  1616  
  1617      return $.extend({}, elRect, scroll, outerDims, elOffset)
  1618    }
  1619  
  1620    Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
  1621      return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :
  1622             placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
  1623             placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
  1624          /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
  1625  
  1626    }
  1627  
  1628    Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
  1629      var delta = { top: 0, left: 0 }
  1630      if (!this.$viewport) return delta
  1631  
  1632      var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
  1633      var viewportDimensions = this.getPosition(this.$viewport)
  1634  
  1635      if (/right|left/.test(placement)) {
  1636        var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
  1637        var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
  1638        if (topEdgeOffset < viewportDimensions.top) { // top overflow
  1639          delta.top = viewportDimensions.top - topEdgeOffset
  1640        } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
  1641          delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
  1642        }
  1643      } else {
  1644        var leftEdgeOffset  = pos.left - viewportPadding
  1645        var rightEdgeOffset = pos.left + viewportPadding + actualWidth
  1646        if (leftEdgeOffset < viewportDimensions.left) { // left overflow
  1647          delta.left = viewportDimensions.left - leftEdgeOffset
  1648        } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow
  1649          delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
  1650        }
  1651      }
  1652  
  1653      return delta
  1654    }
  1655  
  1656    Tooltip.prototype.getTitle = function () {
  1657      var title
  1658      var $e = this.$element
  1659      var o  = this.options
  1660  
  1661      title = $e.attr('data-original-title')
  1662        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
  1663  
  1664      return title
  1665    }
  1666  
  1667    Tooltip.prototype.getUID = function (prefix) {
  1668      do prefix += ~~(Math.random() * 1000000)
  1669      while (document.getElementById(prefix))
  1670      return prefix
  1671    }
  1672  
  1673    Tooltip.prototype.tip = function () {
  1674      if (!this.$tip) {
  1675        this.$tip = $(this.options.template)
  1676        if (this.$tip.length != 1) {
  1677          throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')
  1678        }
  1679      }
  1680      return this.$tip
  1681    }
  1682  
  1683    Tooltip.prototype.arrow = function () {
  1684      return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
  1685    }
  1686  
  1687    Tooltip.prototype.enable = function () {
  1688      this.enabled = true
  1689    }
  1690  
  1691    Tooltip.prototype.disable = function () {
  1692      this.enabled = false
  1693    }
  1694  
  1695    Tooltip.prototype.toggleEnabled = function () {
  1696      this.enabled = !this.enabled
  1697    }
  1698  
  1699    Tooltip.prototype.toggle = function (e) {
  1700      var self = this
  1701      if (e) {
  1702        self = $(e.currentTarget).data('bs.' + this.type)
  1703        if (!self) {
  1704          self = new this.constructor(e.currentTarget, this.getDelegateOptions())
  1705          $(e.currentTarget).data('bs.' + this.type, self)
  1706        }
  1707      }
  1708  
  1709      if (e) {
  1710        self.inState.click = !self.inState.click
  1711        if (self.isInStateTrue()) self.enter(self)
  1712        else self.leave(self)
  1713      } else {
  1714        self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
  1715      }
  1716    }
  1717  
  1718    Tooltip.prototype.destroy = function () {
  1719      var that = this
  1720      clearTimeout(this.timeout)
  1721      this.hide(function () {
  1722        that.$element.off('.' + that.type).removeData('bs.' + that.type)
  1723        if (that.$tip) {
  1724          that.$tip.detach()
  1725        }
  1726        that.$tip = null
  1727        that.$arrow = null
  1728        that.$viewport = null
  1729      })
  1730    }
  1731  
  1732  
  1733    // TOOLTIP PLUGIN DEFINITION
  1734    // =========================
  1735  
  1736    function Plugin(option) {
  1737      return this.each(function () {
  1738        var $this   = $(this)
  1739        var data    = $this.data('bs.tooltip')
  1740        var options = typeof option == 'object' && option
  1741  
  1742        if (!data && /destroy|hide/.test(option)) return
  1743        if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
  1744        if (typeof option == 'string') data[option]()
  1745      })
  1746    }
  1747  
  1748    var old = $.fn.tooltip
  1749  
  1750    $.fn.tooltip             = Plugin
  1751    $.fn.tooltip.Constructor = Tooltip
  1752  
  1753  
  1754    // TOOLTIP NO CONFLICT
  1755    // ===================
  1756  
  1757    $.fn.tooltip.noConflict = function () {
  1758      $.fn.tooltip = old
  1759      return this
  1760    }
  1761  
  1762  }(jQuery);
  1763  
  1764  /* ========================================================================
  1765   * Bootstrap: popover.js v3.3.6
  1766   * http://getbootstrap.com/javascript/#popovers
  1767   * ========================================================================
  1768   * Copyright 2011-2015 Twitter, Inc.
  1769   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  1770   * ======================================================================== */
  1771  
  1772  
  1773  +function ($) {
  1774    'use strict';
  1775  
  1776    // POPOVER PUBLIC CLASS DEFINITION
  1777    // ===============================
  1778  
  1779    var Popover = function (element, options) {
  1780      this.init('popover', element, options)
  1781    }
  1782  
  1783    if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
  1784  
  1785    Popover.VERSION  = '3.3.6'
  1786  
  1787    Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
  1788      placement: 'right',
  1789      trigger: 'click',
  1790      content: '',
  1791      template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
  1792    })
  1793  
  1794  
  1795    // NOTE: POPOVER EXTENDS tooltip.js
  1796    // ================================
  1797  
  1798    Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
  1799  
  1800    Popover.prototype.constructor = Popover
  1801  
  1802    Popover.prototype.getDefaults = function () {
  1803      return Popover.DEFAULTS
  1804    }
  1805  
  1806    Popover.prototype.setContent = function () {
  1807      var $tip    = this.tip()
  1808      var title   = this.getTitle()
  1809      var content = this.getContent()
  1810  
  1811      $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
  1812      $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
  1813        this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
  1814      ](content)
  1815  
  1816      $tip.removeClass('fade top bottom left right in')
  1817  
  1818      // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
  1819      // this manually by checking the contents.
  1820      if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
  1821    }
  1822  
  1823    Popover.prototype.hasContent = function () {
  1824      return this.getTitle() || this.getContent()
  1825    }
  1826  
  1827    Popover.prototype.getContent = function () {
  1828      var $e = this.$element
  1829      var o  = this.options
  1830  
  1831      return $e.attr('data-content')
  1832        || (typeof o.content == 'function' ?
  1833              o.content.call($e[0]) :
  1834              o.content)
  1835    }
  1836  
  1837    Popover.prototype.arrow = function () {
  1838      return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
  1839    }
  1840  
  1841  
  1842    // POPOVER PLUGIN DEFINITION
  1843    // =========================
  1844  
  1845    function Plugin(option) {
  1846      return this.each(function () {
  1847        var $this   = $(this)
  1848        var data    = $this.data('bs.popover')
  1849        var options = typeof option == 'object' && option
  1850  
  1851        if (!data && /destroy|hide/.test(option)) return
  1852        if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
  1853        if (typeof option == 'string') data[option]()
  1854      })
  1855    }
  1856  
  1857    var old = $.fn.popover
  1858  
  1859    $.fn.popover             = Plugin
  1860    $.fn.popover.Constructor = Popover
  1861  
  1862  
  1863    // POPOVER NO CONFLICT
  1864    // ===================
  1865  
  1866    $.fn.popover.noConflict = function () {
  1867      $.fn.popover = old
  1868      return this
  1869    }
  1870  
  1871  }(jQuery);
  1872  
  1873  /* ========================================================================
  1874   * Bootstrap: scrollspy.js v3.3.6
  1875   * http://getbootstrap.com/javascript/#scrollspy
  1876   * ========================================================================
  1877   * Copyright 2011-2015 Twitter, Inc.
  1878   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  1879   * ======================================================================== */
  1880  
  1881  
  1882  +function ($) {
  1883    'use strict';
  1884  
  1885    // SCROLLSPY CLASS DEFINITION
  1886    // ==========================
  1887  
  1888    function ScrollSpy(element, options) {
  1889      this.$body          = $(document.body)
  1890      this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
  1891      this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)
  1892      this.selector       = (this.options.target || '') + ' .nav li > a'
  1893      this.offsets        = []
  1894      this.targets        = []
  1895      this.activeTarget   = null
  1896      this.scrollHeight   = 0
  1897  
  1898      this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
  1899      this.refresh()
  1900      this.process()
  1901    }
  1902  
  1903    ScrollSpy.VERSION  = '3.3.6'
  1904  
  1905    ScrollSpy.DEFAULTS = {
  1906      offset: 10
  1907    }
  1908  
  1909    ScrollSpy.prototype.getScrollHeight = function () {
  1910      return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
  1911    }
  1912  
  1913    ScrollSpy.prototype.refresh = function () {
  1914      var that          = this
  1915      var offsetMethod  = 'offset'
  1916      var offsetBase    = 0
  1917  
  1918      this.offsets      = []
  1919      this.targets      = []
  1920      this.scrollHeight = this.getScrollHeight()
  1921  
  1922      if (!$.isWindow(this.$scrollElement[0])) {
  1923        offsetMethod = 'position'
  1924        offsetBase   = this.$scrollElement.scrollTop()
  1925      }
  1926  
  1927      this.$body
  1928        .find(this.selector)
  1929        .map(function () {
  1930          var $el   = $(this)
  1931          var href  = $el.data('target') || $el.attr('href')
  1932          var $href = /^#./.test(href) && $(href)
  1933  
  1934          return ($href
  1935            && $href.length
  1936            && $href.is(':visible')
  1937            && [[$href[offsetMethod]().top + offsetBase, href]]) || null
  1938        })
  1939        .sort(function (a, b) { return a[0] - b[0] })
  1940        .each(function () {
  1941          that.offsets.push(this[0])
  1942          that.targets.push(this[1])
  1943        })
  1944    }
  1945  
  1946    ScrollSpy.prototype.process = function () {
  1947      var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset
  1948      var scrollHeight = this.getScrollHeight()
  1949      var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()
  1950      var offsets      = this.offsets
  1951      var targets      = this.targets
  1952      var activeTarget = this.activeTarget
  1953      var i
  1954  
  1955      if (this.scrollHeight != scrollHeight) {
  1956        this.refresh()
  1957      }
  1958  
  1959      if (scrollTop >= maxScroll) {
  1960        return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
  1961      }
  1962  
  1963      if (activeTarget && scrollTop < offsets[0]) {
  1964        this.activeTarget = null
  1965        return this.clear()
  1966      }
  1967  
  1968      for (i = offsets.length; i--;) {
  1969        activeTarget != targets[i]
  1970          && scrollTop >= offsets[i]
  1971          && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
  1972          && this.activate(targets[i])
  1973      }
  1974    }
  1975  
  1976    ScrollSpy.prototype.activate = function (target) {
  1977      this.activeTarget = target
  1978  
  1979      this.clear()
  1980  
  1981      var selector = this.selector +
  1982        '[data-target="' + target + '"],' +
  1983        this.selector + '[href="' + target + '"]'
  1984  
  1985      var active = $(selector)
  1986        .parents('li')
  1987        .addClass('active')
  1988  
  1989      if (active.parent('.dropdown-menu').length) {
  1990        active = active
  1991          .closest('li.dropdown')
  1992          .addClass('active')
  1993      }
  1994  
  1995      active.trigger('activate.bs.scrollspy')
  1996    }
  1997  
  1998    ScrollSpy.prototype.clear = function () {
  1999      $(this.selector)
  2000        .parentsUntil(this.options.target, '.active')
  2001        .removeClass('active')
  2002    }
  2003  
  2004  
  2005    // SCROLLSPY PLUGIN DEFINITION
  2006    // ===========================
  2007  
  2008    function Plugin(option) {
  2009      return this.each(function () {
  2010        var $this   = $(this)
  2011        var data    = $this.data('bs.scrollspy')
  2012        var options = typeof option == 'object' && option
  2013  
  2014        if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
  2015        if (typeof option == 'string') data[option]()
  2016      })
  2017    }
  2018  
  2019    var old = $.fn.scrollspy
  2020  
  2021    $.fn.scrollspy             = Plugin
  2022    $.fn.scrollspy.Constructor = ScrollSpy
  2023  
  2024  
  2025    // SCROLLSPY NO CONFLICT
  2026    // =====================
  2027  
  2028    $.fn.scrollspy.noConflict = function () {
  2029      $.fn.scrollspy = old
  2030      return this
  2031    }
  2032  
  2033  
  2034    // SCROLLSPY DATA-API
  2035    // ==================
  2036  
  2037    $(window).on('load.bs.scrollspy.data-api', function () {
  2038      $('[data-spy="scroll"]').each(function () {
  2039        var $spy = $(this)
  2040        Plugin.call($spy, $spy.data())
  2041      })
  2042    })
  2043  
  2044  }(jQuery);
  2045  
  2046  /* ========================================================================
  2047   * Bootstrap: tab.js v3.3.6
  2048   * http://getbootstrap.com/javascript/#tabs
  2049   * ========================================================================
  2050   * Copyright 2011-2015 Twitter, Inc.
  2051   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  2052   * ======================================================================== */
  2053  
  2054  
  2055  +function ($) {
  2056    'use strict';
  2057  
  2058    // TAB CLASS DEFINITION
  2059    // ====================
  2060  
  2061    var Tab = function (element) {
  2062      // jscs:disable requireDollarBeforejQueryAssignment
  2063      this.element = $(element)
  2064      // jscs:enable requireDollarBeforejQueryAssignment
  2065    }
  2066  
  2067    Tab.VERSION = '3.3.6'
  2068  
  2069    Tab.TRANSITION_DURATION = 150
  2070  
  2071    Tab.prototype.show = function () {
  2072      var $this    = this.element
  2073      var $ul      = $this.closest('ul:not(.dropdown-menu)')
  2074      var selector = $this.data('target')
  2075  
  2076      if (!selector) {
  2077        selector = $this.attr('href')
  2078        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
  2079      }
  2080  
  2081      if ($this.parent('li').hasClass('active')) return
  2082  
  2083      var $previous = $ul.find('.active:last a')
  2084      var hideEvent = $.Event('hide.bs.tab', {
  2085        relatedTarget: $this[0]
  2086      })
  2087      var showEvent = $.Event('show.bs.tab', {
  2088        relatedTarget: $previous[0]
  2089      })
  2090  
  2091      $previous.trigger(hideEvent)
  2092      $this.trigger(showEvent)
  2093  
  2094      if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
  2095  
  2096      var $target = $(selector)
  2097  
  2098      this.activate($this.closest('li'), $ul)
  2099      this.activate($target, $target.parent(), function () {
  2100        $previous.trigger({
  2101          type: 'hidden.bs.tab',
  2102          relatedTarget: $this[0]
  2103        })
  2104        $this.trigger({
  2105          type: 'shown.bs.tab',
  2106          relatedTarget: $previous[0]
  2107        })
  2108      })
  2109    }
  2110  
  2111    Tab.prototype.activate = function (element, container, callback) {
  2112      var $active    = container.find('> .active')
  2113      var transition = callback
  2114        && $.support.transition
  2115        && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)
  2116  
  2117      function next() {
  2118        $active
  2119          .removeClass('active')
  2120          .find('> .dropdown-menu > .active')
  2121            .removeClass('active')
  2122          .end()
  2123          .find('[data-toggle="tab"]')
  2124            .attr('aria-expanded', false)
  2125  
  2126        element
  2127          .addClass('active')
  2128          .find('[data-toggle="tab"]')
  2129            .attr('aria-expanded', true)
  2130  
  2131        if (transition) {
  2132          element[0].offsetWidth // reflow for transition
  2133          element.addClass('in')
  2134        } else {
  2135          element.removeClass('fade')
  2136        }
  2137  
  2138        if (element.parent('.dropdown-menu').length) {
  2139          element
  2140            .closest('li.dropdown')
  2141              .addClass('active')
  2142            .end()
  2143            .find('[data-toggle="tab"]')
  2144              .attr('aria-expanded', true)
  2145        }
  2146  
  2147        callback && callback()
  2148      }
  2149  
  2150      $active.length && transition ?
  2151        $active
  2152          .one('bsTransitionEnd', next)
  2153          .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
  2154        next()
  2155  
  2156      $active.removeClass('in')
  2157    }
  2158  
  2159  
  2160    // TAB PLUGIN DEFINITION
  2161    // =====================
  2162  
  2163    function Plugin(option) {
  2164      return this.each(function () {
  2165        var $this = $(this)
  2166        var data  = $this.data('bs.tab')
  2167  
  2168        if (!data) $this.data('bs.tab', (data = new Tab(this)))
  2169        if (typeof option == 'string') data[option]()
  2170      })
  2171    }
  2172  
  2173    var old = $.fn.tab
  2174  
  2175    $.fn.tab             = Plugin
  2176    $.fn.tab.Constructor = Tab
  2177  
  2178  
  2179    // TAB NO CONFLICT
  2180    // ===============
  2181  
  2182    $.fn.tab.noConflict = function () {
  2183      $.fn.tab = old
  2184      return this
  2185    }
  2186  
  2187  
  2188    // TAB DATA-API
  2189    // ============
  2190  
  2191    var clickHandler = function (e) {
  2192      e.preventDefault()
  2193      Plugin.call($(this), 'show')
  2194    }
  2195  
  2196    $(document)
  2197      .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
  2198      .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
  2199  
  2200  }(jQuery);
  2201  
  2202  /* ========================================================================
  2203   * Bootstrap: affix.js v3.3.6
  2204   * http://getbootstrap.com/javascript/#affix
  2205   * ========================================================================
  2206   * Copyright 2011-2015 Twitter, Inc.
  2207   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
  2208   * ======================================================================== */
  2209  
  2210  
  2211  +function ($) {
  2212    'use strict';
  2213  
  2214    // AFFIX CLASS DEFINITION
  2215    // ======================
  2216  
  2217    var Affix = function (element, options) {
  2218      this.options = $.extend({}, Affix.DEFAULTS, options)
  2219  
  2220      this.$target = $(this.options.target)
  2221        .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
  2222        .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))
  2223  
  2224      this.$element     = $(element)
  2225      this.affixed      = null
  2226      this.unpin        = null
  2227      this.pinnedOffset = null
  2228  
  2229      this.checkPosition()
  2230    }
  2231  
  2232    Affix.VERSION  = '3.3.6'
  2233  
  2234    Affix.RESET    = 'affix affix-top affix-bottom'
  2235  
  2236    Affix.DEFAULTS = {
  2237      offset: 0,
  2238      target: window
  2239    }
  2240  
  2241    Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
  2242      var scrollTop    = this.$target.scrollTop()
  2243      var position     = this.$element.offset()
  2244      var targetHeight = this.$target.height()
  2245  
  2246      if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
  2247  
  2248      if (this.affixed == 'bottom') {
  2249        if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
  2250        return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
  2251      }
  2252  
  2253      var initializing   = this.affixed == null
  2254      var colliderTop    = initializing ? scrollTop : position.top
  2255      var colliderHeight = initializing ? targetHeight : height
  2256  
  2257      if (offsetTop != null && scrollTop <= offsetTop) return 'top'
  2258      if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
  2259  
  2260      return false
  2261    }
  2262  
  2263    Affix.prototype.getPinnedOffset = function () {
  2264      if (this.pinnedOffset) return this.pinnedOffset
  2265      this.$element.removeClass(Affix.RESET).addClass('affix')
  2266      var scrollTop = this.$target.scrollTop()
  2267      var position  = this.$element.offset()
  2268      return (this.pinnedOffset = position.top - scrollTop)
  2269    }
  2270  
  2271    Affix.prototype.checkPositionWithEventLoop = function () {
  2272      setTimeout($.proxy(this.checkPosition, this), 1)
  2273    }
  2274  
  2275    Affix.prototype.checkPosition = function () {
  2276      if (!this.$element.is(':visible')) return
  2277  
  2278      var height       = this.$element.height()
  2279      var offset       = this.options.offset
  2280      var offsetTop    = offset.top
  2281      var offsetBottom = offset.bottom
  2282      var scrollHeight = Math.max($(document).height(), $(document.body).height())
  2283  
  2284      if (typeof offset != 'object')         offsetBottom = offsetTop = offset
  2285      if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)
  2286      if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
  2287  
  2288      var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
  2289  
  2290      if (this.affixed != affix) {
  2291        if (this.unpin != null) this.$element.css('top', '')
  2292  
  2293        var affixType = 'affix' + (affix ? '-' + affix : '')
  2294        var e         = $.Event(affixType + '.bs.affix')
  2295  
  2296        this.$element.trigger(e)
  2297  
  2298        if (e.isDefaultPrevented()) return
  2299  
  2300        this.affixed = affix
  2301        this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
  2302  
  2303        this.$element
  2304          .removeClass(Affix.RESET)
  2305          .addClass(affixType)
  2306          .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
  2307      }
  2308  
  2309      if (affix == 'bottom') {
  2310        this.$element.offset({
  2311          top: scrollHeight - height - offsetBottom
  2312        })
  2313      }
  2314    }
  2315  
  2316  
  2317    // AFFIX PLUGIN DEFINITION
  2318    // =======================
  2319  
  2320    function Plugin(option) {
  2321      return this.each(function () {
  2322        var $this   = $(this)
  2323        var data    = $this.data('bs.affix')
  2324        var options = typeof option == 'object' && option
  2325  
  2326        if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
  2327        if (typeof option == 'string') data[option]()
  2328      })
  2329    }
  2330  
  2331    var old = $.fn.affix
  2332  
  2333    $.fn.affix             = Plugin
  2334    $.fn.affix.Constructor = Affix
  2335  
  2336  
  2337    // AFFIX NO CONFLICT
  2338    // =================
  2339  
  2340    $.fn.affix.noConflict = function () {
  2341      $.fn.affix = old
  2342      return this
  2343    }
  2344  
  2345  
  2346    // AFFIX DATA-API
  2347    // ==============
  2348  
  2349    $(window).on('load', function () {
  2350      $('[data-spy="affix"]').each(function () {
  2351        var $spy = $(this)
  2352        var data = $spy.data()
  2353  
  2354        data.offset = data.offset || {}
  2355  
  2356        if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
  2357        if (data.offsetTop    != null) data.offset.top    = data.offsetTop
  2358  
  2359        Plugin.call($spy, data)
  2360      })
  2361    })
  2362  
  2363  }(jQuery);