2 * Bootstrap v3.1.1 (http://getbootstrap.com)
3 * Copyright 2011-2014 Twitter, Inc.
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
7 if (typeof jQuery
=== 'undefined') { throw new Error('Bootstrap\'s JavaScript requires jQuery') }
9 /* ========================================================================
10 * Bootstrap: transition.js v3.1.1
11 * http://getbootstrap.com/javascript/#transitions
12 * ========================================================================
13 * Copyright 2011-2014 Twitter, Inc.
14 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15 * ======================================================================== */
21 // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
22 // ============================================================
24 function transitionEnd() {
25 var el
= document
.createElement('bootstrap')
27 var transEndEventNames
= {
28 'WebkitTransition' : 'webkitTransitionEnd',
29 'MozTransition' : 'transitionend',
30 'OTransition' : 'oTransitionEnd otransitionend',
31 'transition' : 'transitionend'
34 for (var name
in transEndEventNames
) {
35 if (el
.style
[name
] !== undefined) {
36 return { end
: transEndEventNames
[name
] }
40 return false // explicit for ie8 ( ._.)
43 // http://blog.alexmaccaw.com/css-transitions
44 $.fn
.emulateTransitionEnd = function (duration
) {
45 var called
= false, $el
= this
46 $(this).one($.support
.transition
.end
, function () { called
= true })
47 var callback = function () { if (!called
) $($el
).trigger($.support
.transition
.end
) }
48 setTimeout(callback
, duration
)
53 $.support
.transition
= transitionEnd()
58 /* ========================================================================
59 * Bootstrap: alert.js v3.1.1
60 * http://getbootstrap.com/javascript/#alerts
61 * ========================================================================
62 * Copyright 2011-2014 Twitter, Inc.
63 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
64 * ======================================================================== */
70 // ALERT CLASS DEFINITION
71 // ======================
73 var dismiss
= '[data-dismiss="alert"]'
74 var Alert = function (el
) {
75 $(el
).on('click', dismiss
, this.close
)
78 Alert
.prototype.close = function (e
) {
80 var selector
= $this.attr('data-target')
83 selector
= $this.attr('href')
84 selector
= selector
&& selector
.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
87 var $parent
= $(selector
)
89 if (e
) e
.preventDefault()
91 if (!$parent
.length
) {
92 $parent
= $this.hasClass('alert') ? $this : $this.parent()
95 $parent
.trigger(e
= $.Event('close.bs.alert'))
97 if (e
.isDefaultPrevented()) return
99 $parent
.removeClass('in')
101 function removeElement() {
102 $parent
.trigger('closed.bs.alert').remove()
105 $.support
.transition
&& $parent
.hasClass('fade') ?
107 .one($.support
.transition
.end
, removeElement
)
108 .emulateTransitionEnd(150) :
113 // ALERT PLUGIN DEFINITION
114 // =======================
118 $.fn
.alert = function (option
) {
119 return this.each(function () {
121 var data
= $this.data('bs.alert')
123 if (!data
) $this.data('bs.alert', (data
= new Alert(this)))
124 if (typeof option
== 'string') data
[option
].call($this)
128 $.fn
.alert
.Constructor
= Alert
134 $.fn
.alert
.noConflict = function () {
143 $(document
).on('click.bs.alert.data-api', dismiss
, Alert
.prototype.close
)
147 /* ========================================================================
148 * Bootstrap: button.js v3.1.1
149 * http://getbootstrap.com/javascript/#buttons
150 * ========================================================================
151 * Copyright 2011-2014 Twitter, Inc.
152 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
153 * ======================================================================== */
159 // BUTTON PUBLIC CLASS DEFINITION
160 // ==============================
162 var Button = function (element
, options
) {
163 this.$element
= $(element
)
164 this.options
= $.extend({}, Button
.DEFAULTS
, options
)
165 this.isLoading
= false
169 loadingText
: 'loading...'
172 Button
.prototype.setState = function (state
) {
174 var $el
= this.$element
175 var val
= $el
.is('input') ? 'val' : 'html'
176 var data
= $el
.data()
178 state
= state
+ 'Text'
180 if (!data
.resetText
) $el
.data('resetText', $el
[val
]())
182 $el
[val
](data
[state
] || this.options
[state
])
184 // push to event loop to allow forms to submit
185 setTimeout($.proxy(function () {
186 if (state
== 'loadingText') {
187 this.isLoading
= true
188 $el
.addClass(d
).attr(d
, d
)
189 } else if (this.isLoading
) {
190 this.isLoading
= false
191 $el
.removeClass(d
).removeAttr(d
)
196 Button
.prototype.toggle = function () {
198 var $parent
= this.$element
.closest('[data-toggle="buttons"]')
200 if ($parent
.length
) {
201 var $input
= this.$element
.find('input')
202 if ($input
.prop('type') == 'radio') {
203 if ($input
.prop('checked') && this.$element
.hasClass('active')) changed
= false
204 else $parent
.find('.active').removeClass('active')
206 if (changed
) $input
.prop('checked', !this.$element
.hasClass('active')).trigger('change')
209 if (changed
) this.$element
.toggleClass('active')
213 // BUTTON PLUGIN DEFINITION
214 // ========================
216 var old
= $.fn
.button
218 $.fn
.button = function (option
) {
219 return this.each(function () {
221 var data
= $this.data('bs.button')
222 var options
= typeof option
== 'object' && option
224 if (!data
) $this.data('bs.button', (data
= new Button(this, options
)))
226 if (option
== 'toggle') data
.toggle()
227 else if (option
) data
.setState(option
)
231 $.fn
.button
.Constructor
= Button
234 // BUTTON NO CONFLICT
235 // ==================
237 $.fn
.button
.noConflict = function () {
246 $(document
).on('click.bs.button.data-api', '[data-toggle^=button]', function (e
) {
247 var $btn
= $(e
.target
)
248 if (!$btn
.hasClass('btn')) $btn
= $btn
.closest('.btn')
249 $btn
.button('toggle')
255 /* ========================================================================
256 * Bootstrap: carousel.js v3.1.1
257 * http://getbootstrap.com/javascript/#carousel
258 * ========================================================================
259 * Copyright 2011-2014 Twitter, Inc.
260 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
261 * ======================================================================== */
267 // CAROUSEL CLASS DEFINITION
268 // =========================
270 var Carousel = function (element
, options
) {
271 this.$element
= $(element
)
272 this.$indicators
= this.$element
.find('.carousel-indicators')
273 this.options
= options
280 this.options
.pause
== 'hover' && this.$element
281 .on('mouseenter', $.proxy(this.pause
, this))
282 .on('mouseleave', $.proxy(this.cycle
, this))
285 Carousel
.DEFAULTS
= {
291 Carousel
.prototype.cycle = function (e
) {
292 e
|| (this.paused
= false)
294 this.interval
&& clearInterval(this.interval
)
296 this.options
.interval
298 && (this.interval
= setInterval($.proxy(this.next
, this), this.options
.interval
))
303 Carousel
.prototype.getActiveIndex = function () {
304 this.$active
= this.$element
.find('.item.active')
305 this.$items
= this.$active
.parent().children()
307 return this.$items
.index(this.$active
)
310 Carousel
.prototype.to = function (pos
) {
312 var activeIndex
= this.getActiveIndex()
314 if (pos
> (this.$items
.length
- 1) || pos
< 0) return
316 if (this.sliding
) return this.$element
.one('slid.bs.carousel', function () { that
.to(pos
) })
317 if (activeIndex
== pos
) return this.pause().cycle()
319 return this.slide(pos
> activeIndex
? 'next' : 'prev', $(this.$items
[pos
]))
322 Carousel
.prototype.pause = function (e
) {
323 e
|| (this.paused
= true)
325 if (this.$element
.find('.next, .prev').length
&& $.support
.transition
) {
326 this.$element
.trigger($.support
.transition
.end
)
330 this.interval
= clearInterval(this.interval
)
335 Carousel
.prototype.next = function () {
336 if (this.sliding
) return
337 return this.slide('next')
340 Carousel
.prototype.prev = function () {
341 if (this.sliding
) return
342 return this.slide('prev')
345 Carousel
.prototype.slide = function (type
, next
) {
346 var $active
= this.$element
.find('.item.active')
347 var $next
= next
|| $active
[type
]()
348 var isCycling
= this.interval
349 var direction
= type
== 'next' ? 'left' : 'right'
350 var fallback
= type
== 'next' ? 'first' : 'last'
354 if (!this.options
.wrap
) return
355 $next
= this.$element
.find('.item')[fallback
]()
358 if ($next
.hasClass('active')) return this.sliding
= false
360 var e
= $.Event('slide.bs.carousel', { relatedTarget
: $next
[0], direction
: direction
})
361 this.$element
.trigger(e
)
362 if (e
.isDefaultPrevented()) return
366 isCycling
&& this.pause()
368 if (this.$indicators
.length
) {
369 this.$indicators
.find('.active').removeClass('active')
370 this.$element
.one('slid.bs.carousel', function () {
371 var $nextIndicator
= $(that
.$indicators
.children()[that
.getActiveIndex()])
372 $nextIndicator
&& $nextIndicator
.addClass('active')
376 if ($.support
.transition
&& this.$element
.hasClass('slide')) {
378 $next
[0].offsetWidth
// force reflow
379 $active
.addClass(direction
)
380 $next
.addClass(direction
)
382 .one($.support
.transition
.end
, function () {
383 $next
.removeClass([type
, direction
].join(' ')).addClass('active')
384 $active
.removeClass(['active', direction
].join(' '))
386 setTimeout(function () { that
.$element
.trigger('slid.bs.carousel') }, 0)
388 .emulateTransitionEnd($active
.css('transition-duration').slice(0, -1) * 1000)
390 $active
.removeClass('active')
391 $next
.addClass('active')
393 this.$element
.trigger('slid.bs.carousel')
396 isCycling
&& this.cycle()
402 // CAROUSEL PLUGIN DEFINITION
403 // ==========================
405 var old
= $.fn
.carousel
407 $.fn
.carousel = function (option
) {
408 return this.each(function () {
410 var data
= $this.data('bs.carousel')
411 var options
= $.extend({}, Carousel
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
412 var action
= typeof option
== 'string' ? option
: options
.slide
414 if (!data
) $this.data('bs.carousel', (data
= new Carousel(this, options
)))
415 if (typeof option
== 'number') data
.to(option
)
416 else if (action
) data
[action
]()
417 else if (options
.interval
) data
.pause().cycle()
421 $.fn
.carousel
.Constructor
= Carousel
424 // CAROUSEL NO CONFLICT
425 // ====================
427 $.fn
.carousel
.noConflict = function () {
436 $(document
).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e
) {
437 var $this = $(this), href
438 var $target
= $($this.attr('data-target') || (href
= $this.attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
439 var options
= $.extend({}, $target
.data(), $this.data())
440 var slideIndex
= $this.attr('data-slide-to')
441 if (slideIndex
) options
.interval
= false
443 $target
.carousel(options
)
445 if (slideIndex
= $this.attr('data-slide-to')) {
446 $target
.data('bs.carousel').to(slideIndex
)
452 $(window
).on('load', function () {
453 $('[data-ride="carousel"]').each(function () {
454 var $carousel
= $(this)
455 $carousel
.carousel($carousel
.data())
461 /* ========================================================================
462 * Bootstrap: collapse.js v3.1.1
463 * http://getbootstrap.com/javascript/#collapse
464 * ========================================================================
465 * Copyright 2011-2014 Twitter, Inc.
466 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
467 * ======================================================================== */
473 // COLLAPSE PUBLIC CLASS DEFINITION
474 // ================================
476 var Collapse = function (element
, options
) {
477 this.$element
= $(element
)
478 this.options
= $.extend({}, Collapse
.DEFAULTS
, options
)
479 this.transitioning
= null
481 if (this.options
.parent
) this.$parent
= $(this.options
.parent
)
482 if (this.options
.toggle
) this.toggle()
485 Collapse
.DEFAULTS
= {
489 Collapse
.prototype.dimension = function () {
490 var hasWidth
= this.$element
.hasClass('width')
491 return hasWidth
? 'width' : 'height'
494 Collapse
.prototype.show = function () {
495 if (this.transitioning
|| this.$element
.hasClass('in')) return
497 var startEvent
= $.Event('show.bs.collapse')
498 this.$element
.trigger(startEvent
)
499 if (startEvent
.isDefaultPrevented()) return
501 var actives
= this.$parent
&& this.$parent
.find('> .panel > .in')
503 if (actives
&& actives
.length
) {
504 var hasData
= actives
.data('bs.collapse')
505 if (hasData
&& hasData
.transitioning
) return
506 actives
.collapse('hide')
507 hasData
|| actives
.data('bs.collapse', null)
510 var dimension
= this.dimension()
513 .removeClass('collapse')
514 .addClass('collapsing')
517 this.transitioning
= 1
519 var complete = function () {
521 .removeClass('collapsing')
522 .addClass('collapse in')
524 this.transitioning
= 0
525 this.$element
.trigger('shown.bs.collapse')
528 if (!$.support
.transition
) return complete
.call(this)
530 var scrollSize
= $.camelCase(['scroll', dimension
].join('-'))
533 .one($.support
.transition
.end
, $.proxy(complete
, this))
534 .emulateTransitionEnd(350)
535 [dimension
](this.$element
[0][scrollSize
])
538 Collapse
.prototype.hide = function () {
539 if (this.transitioning
|| !this.$element
.hasClass('in')) return
541 var startEvent
= $.Event('hide.bs.collapse')
542 this.$element
.trigger(startEvent
)
543 if (startEvent
.isDefaultPrevented()) return
545 var dimension
= this.dimension()
548 [dimension
](this.$element
[dimension
]())
552 .addClass('collapsing')
553 .removeClass('collapse')
556 this.transitioning
= 1
558 var complete = function () {
559 this.transitioning
= 0
561 .trigger('hidden.bs.collapse')
562 .removeClass('collapsing')
563 .addClass('collapse')
566 if (!$.support
.transition
) return complete
.call(this)
570 .one($.support
.transition
.end
, $.proxy(complete
, this))
571 .emulateTransitionEnd(350)
574 Collapse
.prototype.toggle = function () {
575 this[this.$element
.hasClass('in') ? 'hide' : 'show']()
579 // COLLAPSE PLUGIN DEFINITION
580 // ==========================
582 var old
= $.fn
.collapse
584 $.fn
.collapse = function (option
) {
585 return this.each(function () {
587 var data
= $this.data('bs.collapse')
588 var options
= $.extend({}, Collapse
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
590 if (!data
&& options
.toggle
&& option
== 'show') option
= !option
591 if (!data
) $this.data('bs.collapse', (data
= new Collapse(this, options
)))
592 if (typeof option
== 'string') data
[option
]()
596 $.fn
.collapse
.Constructor
= Collapse
599 // COLLAPSE NO CONFLICT
600 // ====================
602 $.fn
.collapse
.noConflict = function () {
611 $(document
).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e
) {
612 var $this = $(this), href
613 var target
= $this.attr('data-target')
614 || e
.preventDefault()
615 || (href
= $this.attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
616 var $target
= $(target
)
617 var data
= $target
.data('bs.collapse')
618 var option
= data
? 'toggle' : $this.data()
619 var parent
= $this.attr('data-parent')
620 var $parent
= parent
&& $(parent
)
622 if (!data
|| !data
.transitioning
) {
623 if ($parent
) $parent
.find('[data-toggle=collapse][data-parent="' + parent
+ '"]').not($this).addClass('collapsed')
624 $this[$target
.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
627 $target
.collapse(option
)
632 /* ========================================================================
633 * Bootstrap: dropdown.js v3.1.1
634 * http://getbootstrap.com/javascript/#dropdowns
635 * ========================================================================
636 * Copyright 2011-2014 Twitter, Inc.
637 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
638 * ======================================================================== */
644 // DROPDOWN CLASS DEFINITION
645 // =========================
647 var backdrop
= '.dropdown-backdrop'
648 var toggle
= '[data-toggle=dropdown]'
649 var Dropdown = function (element
) {
650 $(element
).on('click.bs.dropdown', this.toggle
)
653 Dropdown
.prototype.toggle = function (e
) {
656 if ($this.is('.disabled, :disabled')) return
658 var $parent
= getParent($this)
659 var isActive
= $parent
.hasClass('open')
664 if ('ontouchstart' in document
.documentElement
&& !$parent
.closest('.navbar-nav').length
) {
665 // if mobile we use a backdrop because click events don't delegate
666 $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus
)
669 var relatedTarget
= { relatedTarget
: this }
670 $parent
.trigger(e
= $.Event('show.bs.dropdown', relatedTarget
))
672 if (e
.isDefaultPrevented()) return
676 .trigger('shown.bs.dropdown', relatedTarget
)
684 Dropdown
.prototype.keydown = function (e
) {
685 if (!/(38|40|27)/.test(e
.keyCode
)) return
692 if ($this.is('.disabled, :disabled')) return
694 var $parent
= getParent($this)
695 var isActive
= $parent
.hasClass('open')
697 if (!isActive
|| (isActive
&& e
.keyCode
== 27)) {
698 if (e
.which
== 27) $parent
.find(toggle
).focus()
702 var desc
= ' li:not(.divider):visible a'
703 var $items
= $parent
.find('[role=menu]' + desc
+ ', [role=listbox]' + desc
)
705 if (!$items
.length
) return
707 var index
= $items
.index($items
.filter(':focus'))
709 if (e
.keyCode
== 38 && index
> 0) index
-- // up
710 if (e
.keyCode
== 40 && index
< $items
.length
- 1) index
++ // down
711 if (!~index
) index
= 0
713 $items
.eq(index
).focus()
716 function clearMenus(e
) {
718 $(toggle
).each(function () {
719 var $parent
= getParent($(this))
720 var relatedTarget
= { relatedTarget
: this }
721 if (!$parent
.hasClass('open')) return
722 $parent
.trigger(e
= $.Event('hide.bs.dropdown', relatedTarget
))
723 if (e
.isDefaultPrevented()) return
724 $parent
.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget
)
728 function getParent($this) {
729 var selector
= $this.attr('data-target')
732 selector
= $this.attr('href')
733 selector
= selector
&& /#[A-Za-z]/.test(selector
) && selector
.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
736 var $parent
= selector
&& $(selector
)
738 return $parent
&& $parent
.length
? $parent
: $this.parent()
742 // DROPDOWN PLUGIN DEFINITION
743 // ==========================
745 var old
= $.fn
.dropdown
747 $.fn
.dropdown = function (option
) {
748 return this.each(function () {
750 var data
= $this.data('bs.dropdown')
752 if (!data
) $this.data('bs.dropdown', (data
= new Dropdown(this)))
753 if (typeof option
== 'string') data
[option
].call($this)
757 $.fn
.dropdown
.Constructor
= Dropdown
760 // DROPDOWN NO CONFLICT
761 // ====================
763 $.fn
.dropdown
.noConflict = function () {
769 // APPLY TO STANDARD DROPDOWN ELEMENTS
770 // ===================================
773 .on('click.bs.dropdown.data-api', clearMenus
)
774 .on('click.bs.dropdown.data-api', '.dropdown form', function (e
) { e
.stopPropagation() })
775 .on('click.bs.dropdown.data-api', toggle
, Dropdown
.prototype.toggle
)
776 .on('keydown.bs.dropdown.data-api', toggle
+ ', [role=menu], [role=listbox]', Dropdown
.prototype.keydown
)
780 /* ========================================================================
781 * Bootstrap: modal.js v3.1.1
782 * http://getbootstrap.com/javascript/#modals
783 * ========================================================================
784 * Copyright 2011-2014 Twitter, Inc.
785 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
786 * ======================================================================== */
792 // MODAL CLASS DEFINITION
793 // ======================
795 var Modal = function (element
, options
) {
796 this.options
= options
797 this.$element
= $(element
)
801 if (this.options
.remote
) {
803 .find('.modal-content')
804 .load(this.options
.remote
, $.proxy(function () {
805 this.$element
.trigger('loaded.bs.modal')
816 Modal
.prototype.toggle = function (_relatedTarget
) {
817 return this[!this.isShown
? 'show' : 'hide'](_relatedTarget
)
820 Modal
.prototype.show = function (_relatedTarget
) {
822 var e
= $.Event('show.bs.modal', { relatedTarget
: _relatedTarget
})
824 this.$element
.trigger(e
)
826 if (this.isShown
|| e
.isDefaultPrevented()) return
832 this.$element
.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide
, this))
834 this.backdrop(function () {
835 var transition
= $.support
.transition
&& that
.$element
.hasClass('fade')
837 if (!that
.$element
.parent().length
) {
838 that
.$element
.appendTo(document
.body
) // don't move modals dom position
846 that
.$element
[0].offsetWidth
// force reflow
851 .attr('aria-hidden', false)
855 var e
= $.Event('shown.bs.modal', { relatedTarget
: _relatedTarget
})
858 that
.$element
.find('.modal-dialog') // wait for modal to slide in
859 .one($.support
.transition
.end
, function () {
860 that
.$element
.focus().trigger(e
)
862 .emulateTransitionEnd(300) :
863 that
.$element
.focus().trigger(e
)
867 Modal
.prototype.hide = function (e
) {
868 if (e
) e
.preventDefault()
870 e
= $.Event('hide.bs.modal')
872 this.$element
.trigger(e
)
874 if (!this.isShown
|| e
.isDefaultPrevented()) return
880 $(document
).off('focusin.bs.modal')
884 .attr('aria-hidden', true)
885 .off('click.dismiss.bs.modal')
887 $.support
.transition
&& this.$element
.hasClass('fade') ?
889 .one($.support
.transition
.end
, $.proxy(this.hideModal
, this))
890 .emulateTransitionEnd(300) :
894 Modal
.prototype.enforceFocus = function () {
896 .off('focusin.bs.modal') // guard against infinite focus loop
897 .on('focusin.bs.modal', $.proxy(function (e
) {
898 if (this.$element
[0] !== e
.target
&& !this.$element
.has(e
.target
).length
) {
899 this.$element
.focus()
904 Modal
.prototype.escape = function () {
905 if (this.isShown
&& this.options
.keyboard
) {
906 this.$element
.on('keyup.dismiss.bs.modal', $.proxy(function (e
) {
907 e
.which
== 27 && this.hide()
909 } else if (!this.isShown
) {
910 this.$element
.off('keyup.dismiss.bs.modal')
914 Modal
.prototype.hideModal = function () {
917 this.backdrop(function () {
918 that
.removeBackdrop()
919 that
.$element
.trigger('hidden.bs.modal')
923 Modal
.prototype.removeBackdrop = function () {
924 this.$backdrop
&& this.$backdrop
.remove()
925 this.$backdrop
= null
928 Modal
.prototype.backdrop = function (callback
) {
929 var animate
= this.$element
.hasClass('fade') ? 'fade' : ''
931 if (this.isShown
&& this.options
.backdrop
) {
932 var doAnimate
= $.support
.transition
&& animate
934 this.$backdrop
= $('<div class="modal-backdrop ' + animate
+ '" />')
935 .appendTo(document
.body
)
937 this.$element
.on('click.dismiss.bs.modal', $.proxy(function (e
) {
938 if (e
.target
!== e
.currentTarget
) return
939 this.options
.backdrop
== 'static'
940 ? this.$element
[0].focus
.call(this.$element
[0])
941 : this.hide
.call(this)
944 if (doAnimate
) this.$backdrop
[0].offsetWidth
// force reflow
946 this.$backdrop
.addClass('in')
948 if (!callback
) return
952 .one($.support
.transition
.end
, callback
)
953 .emulateTransitionEnd(150) :
956 } else if (!this.isShown
&& this.$backdrop
) {
957 this.$backdrop
.removeClass('in')
959 $.support
.transition
&& this.$element
.hasClass('fade') ?
961 .one($.support
.transition
.end
, callback
)
962 .emulateTransitionEnd(150) :
965 } else if (callback
) {
971 // MODAL PLUGIN DEFINITION
972 // =======================
976 $.fn
.modal = function (option
, _relatedTarget
) {
977 return this.each(function () {
979 var data
= $this.data('bs.modal')
980 var options
= $.extend({}, Modal
.DEFAULTS
, $this.data(), typeof option
== 'object' && option
)
982 if (!data
) $this.data('bs.modal', (data
= new Modal(this, options
)))
983 if (typeof option
== 'string') data
[option
](_relatedTarget
)
984 else if (options
.show
) data
.show(_relatedTarget
)
988 $.fn
.modal
.Constructor
= Modal
994 $.fn
.modal
.noConflict = function () {
1003 $(document
).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e
) {
1005 var href
= $this.attr('href')
1006 var $target
= $($this.attr('data-target') || (href
&& href
.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
1007 var option
= $target
.data('bs.modal') ? 'toggle' : $.extend({ remote
: !/#/.test(href
) && href
}, $target
.data(), $this.data())
1009 if ($this.is('a')) e
.preventDefault()
1012 .modal(option
, this)
1013 .one('hide', function () {
1014 $this.is(':visible') && $this.focus()
1019 .on('show.bs.modal', '.modal', function () { $(document
.body
).addClass('modal-open') })
1020 .on('hidden.bs.modal', '.modal', function () { $(document
.body
).removeClass('modal-open') })
1024 /* ========================================================================
1025 * Bootstrap: tooltip.js v3.1.1
1026 * http://getbootstrap.com/javascript/#tooltip
1027 * Inspired by the original jQuery.tipsy by Jason Frame
1028 * ========================================================================
1029 * Copyright 2011-2014 Twitter, Inc.
1030 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1031 * ======================================================================== */
1037 // TOOLTIP PUBLIC CLASS DEFINITION
1038 // ===============================
1040 var Tooltip = function (element
, options
) {
1046 this.$element
= null
1048 this.init('tooltip', element
, options
)
1051 Tooltip
.DEFAULTS
= {
1055 template
: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
1056 trigger
: 'hover focus',
1063 Tooltip
.prototype.init = function (type
, element
, options
) {
1066 this.$element
= $(element
)
1067 this.options
= this.getOptions(options
)
1069 var triggers
= this.options
.trigger
.split(' ')
1071 for (var i
= triggers
.length
; i
--;) {
1072 var trigger
= triggers
[i
]
1074 if (trigger
== 'click') {
1075 this.$element
.on('click.' + this.type
, this.options
.selector
, $.proxy(this.toggle
, this))
1076 } else if (trigger
!= 'manual') {
1077 var eventIn
= trigger
== 'hover' ? 'mouseenter' : 'focusin'
1078 var eventOut
= trigger
== 'hover' ? 'mouseleave' : 'focusout'
1080 this.$element
.on(eventIn
+ '.' + this.type
, this.options
.selector
, $.proxy(this.enter
, this))
1081 this.$element
.on(eventOut
+ '.' + this.type
, this.options
.selector
, $.proxy(this.leave
, this))
1085 this.options
.selector
?
1086 (this._options
= $.extend({}, this.options
, { trigger
: 'manual', selector
: '' })) :
1090 Tooltip
.prototype.getDefaults = function () {
1091 return Tooltip
.DEFAULTS
1094 Tooltip
.prototype.getOptions = function (options
) {
1095 options
= $.extend({}, this.getDefaults(), this.$element
.data(), options
)
1097 if (options
.delay
&& typeof options
.delay
== 'number') {
1099 show
: options
.delay
,
1107 Tooltip
.prototype.getDelegateOptions = function () {
1109 var defaults
= this.getDefaults()
1111 this._options
&& $.each(this._options
, function (key
, value
) {
1112 if (defaults
[key
] != value
) options
[key
] = value
1118 Tooltip
.prototype.enter = function (obj
) {
1119 var self
= obj
instanceof this.constructor ?
1120 obj
: $(obj
.currentTarget
)[this.type
](this.getDelegateOptions()).data('bs.' + this.type
)
1122 clearTimeout(self
.timeout
)
1124 self
.hoverState
= 'in'
1126 if (!self
.options
.delay
|| !self
.options
.delay
.show
) return self
.show()
1128 self
.timeout
= setTimeout(function () {
1129 if (self
.hoverState
== 'in') self
.show()
1130 }, self
.options
.delay
.show
)
1133 Tooltip
.prototype.leave = function (obj
) {
1134 var self
= obj
instanceof this.constructor ?
1135 obj
: $(obj
.currentTarget
)[this.type
](this.getDelegateOptions()).data('bs.' + this.type
)
1137 clearTimeout(self
.timeout
)
1139 self
.hoverState
= 'out'
1141 if (!self
.options
.delay
|| !self
.options
.delay
.hide
) return self
.hide()
1143 self
.timeout
= setTimeout(function () {
1144 if (self
.hoverState
== 'out') self
.hide()
1145 }, self
.options
.delay
.hide
)
1148 Tooltip
.prototype.show = function () {
1149 var e
= $.Event('show.bs.' + this.type
)
1151 if (this.hasContent() && this.enabled
) {
1152 this.$element
.trigger(e
)
1154 if (e
.isDefaultPrevented()) return
1157 var $tip
= this.tip()
1161 if (this.options
.animation
) $tip
.addClass('fade')
1163 var placement
= typeof this.options
.placement
== 'function' ?
1164 this.options
.placement
.call(this, $tip
[0], this.$element
[0]) :
1165 this.options
.placement
1167 var autoToken
= /\s?auto?\s?/i
1168 var autoPlace
= autoToken
.test(placement
)
1169 if (autoPlace
) placement
= placement
.replace(autoToken
, '') || 'top'
1173 .css({ top
: 0, left
: 0, display
: 'block' })
1174 .addClass(placement
)
1176 this.options
.container
? $tip
.appendTo(this.options
.container
) : $tip
.insertAfter(this.$element
)
1178 var pos
= this.getPosition()
1179 var actualWidth
= $tip
[0].offsetWidth
1180 var actualHeight
= $tip
[0].offsetHeight
1183 var $parent
= this.$element
.parent()
1185 var orgPlacement
= placement
1186 var docScroll
= document
.documentElement
.scrollTop
|| document
.body
.scrollTop
1187 var parentWidth
= this.options
.container
== 'body' ? window
.innerWidth
: $parent
.outerWidth()
1188 var parentHeight
= this.options
.container
== 'body' ? window
.innerHeight
: $parent
.outerHeight()
1189 var parentLeft
= this.options
.container
== 'body' ? 0 : $parent
.offset().left
1191 placement
= placement
== 'bottom' && pos
.top
+ pos
.height
+ actualHeight
- docScroll
> parentHeight
? 'top' :
1192 placement
== 'top' && pos
.top
- docScroll
- actualHeight
< 0 ? 'bottom' :
1193 placement
== 'right' && pos
.right
+ actualWidth
> parentWidth
? 'left' :
1194 placement
== 'left' && pos
.left
- actualWidth
< parentLeft
? 'right' :
1198 .removeClass(orgPlacement
)
1199 .addClass(placement
)
1202 var calculatedOffset
= this.getCalculatedOffset(placement
, pos
, actualWidth
, actualHeight
)
1204 this.applyPlacement(calculatedOffset
, placement
)
1205 this.hoverState
= null
1207 var complete = function() {
1208 that
.$element
.trigger('shown.bs.' + that
.type
)
1211 $.support
.transition
&& this.$tip
.hasClass('fade') ?
1213 .one($.support
.transition
.end
, complete
)
1214 .emulateTransitionEnd(150) :
1219 Tooltip
.prototype.applyPlacement = function (offset
, placement
) {
1221 var $tip
= this.tip()
1222 var width
= $tip
[0].offsetWidth
1223 var height
= $tip
[0].offsetHeight
1225 // manually read margins because getBoundingClientRect includes difference
1226 var marginTop
= parseInt($tip
.css('margin-top'), 10)
1227 var marginLeft
= parseInt($tip
.css('margin-left'), 10)
1229 // we must check for NaN for ie 8/9
1230 if (isNaN(marginTop
)) marginTop
= 0
1231 if (isNaN(marginLeft
)) marginLeft
= 0
1233 offset
.top
= offset
.top
+ marginTop
1234 offset
.left
= offset
.left
+ marginLeft
1236 // $.fn.offset doesn't round pixel values
1237 // so we use setOffset directly with our own function B-0
1238 $.offset
.setOffset($tip
[0], $.extend({
1239 using: function (props
) {
1241 top
: Math
.round(props
.top
),
1242 left
: Math
.round(props
.left
)
1249 // check to see if placing tip in new offset caused the tip to resize itself
1250 var actualWidth
= $tip
[0].offsetWidth
1251 var actualHeight
= $tip
[0].offsetHeight
1253 if (placement
== 'top' && actualHeight
!= height
) {
1255 offset
.top
= offset
.top
+ height
- actualHeight
1258 if (/bottom|top/.test(placement
)) {
1261 if (offset
.left
< 0) {
1262 delta
= offset
.left
* -2
1267 actualWidth
= $tip
[0].offsetWidth
1268 actualHeight
= $tip
[0].offsetHeight
1271 this.replaceArrow(delta
- width
+ actualWidth
, actualWidth
, 'left')
1273 this.replaceArrow(actualHeight
- height
, actualHeight
, 'top')
1276 if (replace
) $tip
.offset(offset
)
1279 Tooltip
.prototype.replaceArrow = function (delta
, dimension
, position
) {
1280 this.arrow().css(position
, delta
? (50 * (1 - delta
/ dimension
) + '%') : '')
1283 Tooltip
.prototype.setContent = function () {
1284 var $tip
= this.tip()
1285 var title
= this.getTitle()
1287 $tip
.find('.tooltip-inner')[this.options
.html
? 'html' : 'text'](title
)
1288 $tip
.removeClass('fade in top bottom left right')
1291 Tooltip
.prototype.hide = function () {
1293 var $tip
= this.tip()
1294 var e
= $.Event('hide.bs.' + this.type
)
1296 function complete() {
1297 if (that
.hoverState
!= 'in') $tip
.detach()
1298 that
.$element
.trigger('hidden.bs.' + that
.type
)
1301 this.$element
.trigger(e
)
1303 if (e
.isDefaultPrevented()) return
1305 $tip
.removeClass('in')
1307 $.support
.transition
&& this.$tip
.hasClass('fade') ?
1309 .one($.support
.transition
.end
, complete
)
1310 .emulateTransitionEnd(150) :
1313 this.hoverState
= null
1318 Tooltip
.prototype.fixTitle = function () {
1319 var $e
= this.$element
1320 if ($e
.attr('title') || typeof($e
.attr('data-original-title')) != 'string') {
1321 $e
.attr('data-original-title', $e
.attr('title') || '').attr('title', '')
1325 Tooltip
.prototype.hasContent = function () {
1326 return this.getTitle()
1329 Tooltip
.prototype.getPosition = function () {
1330 var el
= this.$element
[0]
1331 return $.extend({}, (typeof el
.getBoundingClientRect
== 'function') ? el
.getBoundingClientRect() : {
1332 width
: el
.offsetWidth
,
1333 height
: el
.offsetHeight
1334 }, this.$element
.offset())
1337 Tooltip
.prototype.getCalculatedOffset = function (placement
, pos
, actualWidth
, actualHeight
) {
1338 return placement
== 'bottom' ? { top
: pos
.top
+ pos
.height
, left
: pos
.left
+ pos
.width
/ 2 - actualWidth
/ 2 } :
1339 placement
== 'top' ? { top
: pos
.top
- actualHeight
, left
: pos
.left
+ pos
.width
/ 2 - actualWidth
/ 2 } :
1340 placement
== 'left' ? { top
: pos
.top
+ pos
.height
/ 2 - actualHeight
/ 2, left
: pos
.left
- actualWidth
} :
1341 /* placement == 'right' */ { top
: pos
.top
+ pos
.height
/ 2 - actualHeight
/ 2, left
: pos
.left
+ pos
.width
}
1344 Tooltip
.prototype.getTitle = function () {
1346 var $e
= this.$element
1347 var o
= this.options
1349 title
= $e
.attr('data-original-title')
1350 || (typeof o
.title
== 'function' ? o
.title
.call($e
[0]) : o
.title
)
1355 Tooltip
.prototype.tip = function () {
1356 return this.$tip
= this.$tip
|| $(this.options
.template
)
1359 Tooltip
.prototype.arrow = function () {
1360 return this.$arrow
= this.$arrow
|| this.tip().find('.tooltip-arrow')
1363 Tooltip
.prototype.validate = function () {
1364 if (!this.$element
[0].parentNode
) {
1366 this.$element
= null
1371 Tooltip
.prototype.enable = function () {
1375 Tooltip
.prototype.disable = function () {
1376 this.enabled
= false
1379 Tooltip
.prototype.toggleEnabled = function () {
1380 this.enabled
= !this.enabled
1383 Tooltip
.prototype.toggle = function (e
) {
1384 var self
= e
? $(e
.currentTarget
)[this.type
](this.getDelegateOptions()).data('bs.' + this.type
) : this
1385 self
.tip().hasClass('in') ? self
.leave(self
) : self
.enter(self
)
1388 Tooltip
.prototype.destroy = function () {
1389 clearTimeout(this.timeout
)
1390 this.hide().$element
.off('.' + this.type
).removeData('bs.' + this.type
)
1394 // TOOLTIP PLUGIN DEFINITION
1395 // =========================
1397 var old
= $.fn
.tooltip
1399 $.fn
.tooltip = function (option
) {
1400 return this.each(function () {
1402 var data
= $this.data('bs.tooltip')
1403 var options
= typeof option
== 'object' && option
1405 if (!data
&& option
== 'destroy') return
1406 if (!data
) $this.data('bs.tooltip', (data
= new Tooltip(this, options
)))
1407 if (typeof option
== 'string') data
[option
]()
1411 $.fn
.tooltip
.Constructor
= Tooltip
1414 // TOOLTIP NO CONFLICT
1415 // ===================
1417 $.fn
.tooltip
.noConflict = function () {
1424 /* ========================================================================
1425 * Bootstrap: popover.js v3.1.1
1426 * http://getbootstrap.com/javascript/#popovers
1427 * ========================================================================
1428 * Copyright 2011-2014 Twitter, Inc.
1429 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1430 * ======================================================================== */
1436 // POPOVER PUBLIC CLASS DEFINITION
1437 // ===============================
1439 var Popover = function (element
, options
) {
1440 this.init('popover', element
, options
)
1443 if (!$.fn
.tooltip
) throw new Error('Popover requires tooltip.js')
1445 Popover
.DEFAULTS
= $.extend({}, $.fn
.tooltip
.Constructor
.DEFAULTS
, {
1449 template
: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
1453 // NOTE: POPOVER EXTENDS tooltip.js
1454 // ================================
1456 Popover
.prototype = $.extend({}, $.fn
.tooltip
.Constructor
.prototype)
1458 Popover
.prototype.constructor = Popover
1460 Popover
.prototype.getDefaults = function () {
1461 return Popover
.DEFAULTS
1464 Popover
.prototype.setContent = function () {
1465 var $tip
= this.tip()
1466 var title
= this.getTitle()
1467 var content
= this.getContent()
1469 $tip
.find('.popover-title')[this.options
.html
? 'html' : 'text'](title
)
1470 $tip
.find('.popover-content')[ // we use append for html objects to maintain js events
1471 this.options
.html
? (typeof content
== 'string' ? 'html' : 'append') : 'text'
1474 $tip
.removeClass('fade top bottom left right in')
1476 // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
1477 // this manually by checking the contents.
1478 if (!$tip
.find('.popover-title').html()) $tip
.find('.popover-title').hide()
1481 Popover
.prototype.hasContent = function () {
1482 return this.getTitle() || this.getContent()
1485 Popover
.prototype.getContent = function () {
1486 var $e
= this.$element
1487 var o
= this.options
1489 return $e
.attr('data-content')
1490 || (typeof o
.content
== 'function' ?
1491 o
.content
.call($e
[0]) :
1495 Popover
.prototype.arrow = function () {
1496 return this.$arrow
= this.$arrow
|| this.tip().find('.arrow')
1499 Popover
.prototype.tip = function () {
1500 if (!this.$tip
) this.$tip
= $(this.options
.template
)
1505 // POPOVER PLUGIN DEFINITION
1506 // =========================
1508 var old
= $.fn
.popover
1510 $.fn
.popover = function (option
) {
1511 return this.each(function () {
1513 var data
= $this.data('bs.popover')
1514 var options
= typeof option
== 'object' && option
1516 if (!data
&& option
== 'destroy') return
1517 if (!data
) $this.data('bs.popover', (data
= new Popover(this, options
)))
1518 if (typeof option
== 'string') data
[option
]()
1522 $.fn
.popover
.Constructor
= Popover
1525 // POPOVER NO CONFLICT
1526 // ===================
1528 $.fn
.popover
.noConflict = function () {
1535 /* ========================================================================
1536 * Bootstrap: scrollspy.js v3.1.1
1537 * http://getbootstrap.com/javascript/#scrollspy
1538 * ========================================================================
1539 * Copyright 2011-2014 Twitter, Inc.
1540 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1541 * ======================================================================== */
1547 // SCROLLSPY CLASS DEFINITION
1548 // ==========================
1550 function ScrollSpy(element
, options
) {
1552 var process
= $.proxy(this.process
, this)
1554 this.$element
= $(element
).is('body') ? $(window
) : $(element
)
1555 this.$body
= $('body')
1556 this.$scrollElement
= this.$element
.on('scroll.bs.scroll-spy.data-api', process
)
1557 this.options
= $.extend({}, ScrollSpy
.DEFAULTS
, options
)
1558 this.selector
= (this.options
.target
1559 || ((href
= $(element
).attr('href')) && href
.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
1560 || '') + ' .nav li > a'
1561 this.offsets
= $([])
1562 this.targets
= $([])
1563 this.activeTarget
= null
1569 ScrollSpy
.DEFAULTS
= {
1573 ScrollSpy
.prototype.refresh = function () {
1574 var offsetMethod
= this.$element
[0] == window
? 'offset' : 'position'
1576 this.offsets
= $([])
1577 this.targets
= $([])
1580 var $targets
= this.$body
1581 .find(this.selector
)
1584 var href
= $el
.data('target') || $el
.attr('href')
1585 var $href
= /^#./.test(href
) && $(href
)
1589 && $href
.is(':visible')
1590 && [[ $href
[offsetMethod
]().top
+ (!$.isWindow(self
.$scrollElement
.get(0)) && self
.$scrollElement
.scrollTop()), href
]]) || null
1592 .sort(function (a
, b
) { return a
[0] - b
[0] })
1594 self
.offsets
.push(this[0])
1595 self
.targets
.push(this[1])
1599 ScrollSpy
.prototype.process = function () {
1600 var scrollTop
= this.$scrollElement
.scrollTop() + this.options
.offset
1601 var scrollHeight
= this.$scrollElement
[0].scrollHeight
|| this.$body
[0].scrollHeight
1602 var maxScroll
= scrollHeight
- this.$scrollElement
.height()
1603 var offsets
= this.offsets
1604 var targets
= this.targets
1605 var activeTarget
= this.activeTarget
1608 if (scrollTop
>= maxScroll
) {
1609 return activeTarget
!= (i
= targets
.last()[0]) && this.activate(i
)
1612 if (activeTarget
&& scrollTop
<= offsets
[0]) {
1613 return activeTarget
!= (i
= targets
[0]) && this.activate(i
)
1616 for (i
= offsets
.length
; i
--;) {
1617 activeTarget
!= targets
[i
]
1618 && scrollTop
>= offsets
[i
]
1619 && (!offsets
[i
+ 1] || scrollTop
<= offsets
[i
+ 1])
1620 && this.activate( targets
[i
] )
1624 ScrollSpy
.prototype.activate = function (target
) {
1625 this.activeTarget
= target
1628 .parentsUntil(this.options
.target
, '.active')
1629 .removeClass('active')
1631 var selector
= this.selector
+
1632 '[data-target="' + target
+ '"],' +
1633 this.selector
+ '[href="' + target
+ '"]'
1635 var active
= $(selector
)
1639 if (active
.parent('.dropdown-menu').length
) {
1641 .closest('li.dropdown')
1645 active
.trigger('activate.bs.scrollspy')
1649 // SCROLLSPY PLUGIN DEFINITION
1650 // ===========================
1652 var old
= $.fn
.scrollspy
1654 $.fn
.scrollspy = function (option
) {
1655 return this.each(function () {
1657 var data
= $this.data('bs.scrollspy')
1658 var options
= typeof option
== 'object' && option
1660 if (!data
) $this.data('bs.scrollspy', (data
= new ScrollSpy(this, options
)))
1661 if (typeof option
== 'string') data
[option
]()
1665 $.fn
.scrollspy
.Constructor
= ScrollSpy
1668 // SCROLLSPY NO CONFLICT
1669 // =====================
1671 $.fn
.scrollspy
.noConflict = function () {
1672 $.fn
.scrollspy
= old
1677 // SCROLLSPY DATA-API
1678 // ==================
1680 $(window
).on('load', function () {
1681 $('[data-spy="scroll"]').each(function () {
1683 $spy
.scrollspy($spy
.data())
1689 /* ========================================================================
1690 * Bootstrap: tab.js v3.1.1
1691 * http://getbootstrap.com/javascript/#tabs
1692 * ========================================================================
1693 * Copyright 2011-2014 Twitter, Inc.
1694 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1695 * ======================================================================== */
1701 // TAB CLASS DEFINITION
1702 // ====================
1704 var Tab = function (element
) {
1705 this.element
= $(element
)
1708 Tab
.prototype.show = function () {
1709 var $this = this.element
1710 var $ul
= $this.closest('ul:not(.dropdown-menu)')
1711 var selector
= $this.data('target')
1714 selector
= $this.attr('href')
1715 selector
= selector
&& selector
.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
1718 if ($this.parent('li').hasClass('active')) return
1720 var previous
= $ul
.find('.active:last a')[0]
1721 var e
= $.Event('show.bs.tab', {
1722 relatedTarget
: previous
1727 if (e
.isDefaultPrevented()) return
1729 var $target
= $(selector
)
1731 this.activate($this.parent('li'), $ul
)
1732 this.activate($target
, $target
.parent(), function () {
1734 type
: 'shown.bs.tab',
1735 relatedTarget
: previous
1740 Tab
.prototype.activate = function (element
, container
, callback
) {
1741 var $active
= container
.find('> .active')
1742 var transition
= callback
1743 && $.support
.transition
1744 && $active
.hasClass('fade')
1748 .removeClass('active')
1749 .find('> .dropdown-menu > .active')
1750 .removeClass('active')
1752 element
.addClass('active')
1755 element
[0].offsetWidth
// reflow for transition
1756 element
.addClass('in')
1758 element
.removeClass('fade')
1761 if (element
.parent('.dropdown-menu')) {
1762 element
.closest('li.dropdown').addClass('active')
1765 callback
&& callback()
1770 .one($.support
.transition
.end
, next
)
1771 .emulateTransitionEnd(150) :
1774 $active
.removeClass('in')
1778 // TAB PLUGIN DEFINITION
1779 // =====================
1783 $.fn
.tab = function ( option
) {
1784 return this.each(function () {
1786 var data
= $this.data('bs.tab')
1788 if (!data
) $this.data('bs.tab', (data
= new Tab(this)))
1789 if (typeof option
== 'string') data
[option
]()
1793 $.fn
.tab
.Constructor
= Tab
1799 $.fn
.tab
.noConflict = function () {
1808 $(document
).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e
) {
1815 /* ========================================================================
1816 * Bootstrap: affix.js v3.1.1
1817 * http://getbootstrap.com/javascript/#affix
1818 * ========================================================================
1819 * Copyright 2011-2014 Twitter, Inc.
1820 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
1821 * ======================================================================== */
1827 // AFFIX CLASS DEFINITION
1828 // ======================
1830 var Affix = function (element
, options
) {
1831 this.options
= $.extend({}, Affix
.DEFAULTS
, options
)
1832 this.$window
= $(window
)
1833 .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition
, this))
1834 .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop
, this))
1836 this.$element
= $(element
)
1839 this.pinnedOffset
= null
1841 this.checkPosition()
1844 Affix
.RESET
= 'affix affix-top affix-bottom'
1850 Affix
.prototype.getPinnedOffset = function () {
1851 if (this.pinnedOffset
) return this.pinnedOffset
1852 this.$element
.removeClass(Affix
.RESET
).addClass('affix')
1853 var scrollTop
= this.$window
.scrollTop()
1854 var position
= this.$element
.offset()
1855 return (this.pinnedOffset
= position
.top
- scrollTop
)
1858 Affix
.prototype.checkPositionWithEventLoop = function () {
1859 setTimeout($.proxy(this.checkPosition
, this), 1)
1862 Affix
.prototype.checkPosition = function () {
1863 if (!this.$element
.is(':visible')) return
1865 var scrollHeight
= $(document
).height()
1866 var scrollTop
= this.$window
.scrollTop()
1867 var position
= this.$element
.offset()
1868 var offset
= this.options
.offset
1869 var offsetTop
= offset
.top
1870 var offsetBottom
= offset
.bottom
1872 if (this.affixed
== 'top') position
.top
+= scrollTop
1874 if (typeof offset
!= 'object') offsetBottom
= offsetTop
= offset
1875 if (typeof offsetTop
== 'function') offsetTop
= offset
.top(this.$element
)
1876 if (typeof offsetBottom
== 'function') offsetBottom
= offset
.bottom(this.$element
)
1878 var affix
= this.unpin
!= null && (scrollTop
+ this.unpin
<= position
.top
) ? false :
1879 offsetBottom
!= null && (position
.top
+ this.$element
.height() >= scrollHeight
- offsetBottom
) ? 'bottom' :
1880 offsetTop
!= null && (scrollTop
<= offsetTop
) ? 'top' : false
1882 if (this.affixed
=== affix
) return
1883 if (this.unpin
) this.$element
.css('top', '')
1885 var affixType
= 'affix' + (affix
? '-' + affix
: '')
1886 var e
= $.Event(affixType
+ '.bs.affix')
1888 this.$element
.trigger(e
)
1890 if (e
.isDefaultPrevented()) return
1892 this.affixed
= affix
1893 this.unpin
= affix
== 'bottom' ? this.getPinnedOffset() : null
1896 .removeClass(Affix
.RESET
)
1897 .addClass(affixType
)
1898 .trigger($.Event(affixType
.replace('affix', 'affixed')))
1900 if (affix
== 'bottom') {
1901 this.$element
.offset({ top
: scrollHeight
- offsetBottom
- this.$element
.height() })
1906 // AFFIX PLUGIN DEFINITION
1907 // =======================
1909 var old
= $.fn
.affix
1911 $.fn
.affix = function (option
) {
1912 return this.each(function () {
1914 var data
= $this.data('bs.affix')
1915 var options
= typeof option
== 'object' && option
1917 if (!data
) $this.data('bs.affix', (data
= new Affix(this, options
)))
1918 if (typeof option
== 'string') data
[option
]()
1922 $.fn
.affix
.Constructor
= Affix
1925 // AFFIX NO CONFLICT
1926 // =================
1928 $.fn
.affix
.noConflict = function () {
1937 $(window
).on('load', function () {
1938 $('[data-spy="affix"]').each(function () {
1940 var data
= $spy
.data()
1942 data
.offset
= data
.offset
|| {}
1944 if (data
.offsetBottom
) data
.offset
.bottom
= data
.offsetBottom
1945 if (data
.offsetTop
) data
.offset
.top
= data
.offsetTop