Subversion Repositories eFlore/Applications.cel

Rev

Details | Last modification | View Log | RSS feed

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