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