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