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