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