File indexing completed on 2025-05-04 05:28:52
0001 /* =================================================== 0002 * bootstrap-transition.js v2.0.4 0003 * http://twitter.github.com/bootstrap/javascript.html#transitions 0004 * =================================================== 0005 * Copyright 2012 Twitter, Inc. 0006 * 0007 * Licensed under the Apache License, Version 2.0 (the "License"); 0008 * you may not use this file except in compliance with the License. 0009 * You may obtain a copy of the License at 0010 * 0011 * http://www.apache.org/licenses/LICENSE-2.0 0012 * 0013 * Unless required by applicable law or agreed to in writing, software 0014 * distributed under the License is distributed on an "AS IS" BASIS, 0015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0016 * See the License for the specific language governing permissions and 0017 * limitations under the License. 0018 * ========================================================== */ 0019 0020 0021 !function ($) { 0022 0023 $(function () { 0024 0025 "use strict"; // jshint ;_; 0026 0027 0028 /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) 0029 * ======================================================= */ 0030 0031 $.support.transition = (function () { 0032 0033 var transitionEnd = (function () { 0034 0035 var el = document.createElement('bootstrap') 0036 , transEndEventNames = { 0037 'WebkitTransition' : 'webkitTransitionEnd' 0038 , 'MozTransition' : 'transitionend' 0039 , 'OTransition' : 'oTransitionEnd' 0040 , 'msTransition' : 'MSTransitionEnd' 0041 , 'transition' : 'transitionend' 0042 } 0043 , name 0044 0045 for (name in transEndEventNames){ 0046 if (el.style[name] !== undefined) { 0047 return transEndEventNames[name] 0048 } 0049 } 0050 0051 }()) 0052 0053 return transitionEnd && { 0054 end: transitionEnd 0055 } 0056 0057 })() 0058 0059 }) 0060 0061 }(window.jQuery);/* ========================================================== 0062 * bootstrap-alert.js v2.0.4 0063 * http://twitter.github.com/bootstrap/javascript.html#alerts 0064 * ========================================================== 0065 * Copyright 2012 Twitter, Inc. 0066 * 0067 * Licensed under the Apache License, Version 2.0 (the "License"); 0068 * you may not use this file except in compliance with the License. 0069 * You may obtain a copy of the License at 0070 * 0071 * http://www.apache.org/licenses/LICENSE-2.0 0072 * 0073 * Unless required by applicable law or agreed to in writing, software 0074 * distributed under the License is distributed on an "AS IS" BASIS, 0075 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0076 * See the License for the specific language governing permissions and 0077 * limitations under the License. 0078 * ========================================================== */ 0079 0080 0081 !function ($) { 0082 0083 "use strict"; // jshint ;_; 0084 0085 0086 /* ALERT CLASS DEFINITION 0087 * ====================== */ 0088 0089 var dismiss = '[data-dismiss="alert"]' 0090 , Alert = function (el) { 0091 $(el).on('click', dismiss, this.close) 0092 } 0093 0094 Alert.prototype.close = function (e) { 0095 var $this = $(this) 0096 , selector = $this.attr('data-target') 0097 , $parent 0098 0099 if (!selector) { 0100 selector = $this.attr('href') 0101 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 0102 } 0103 0104 $parent = $(selector) 0105 0106 e && e.preventDefault() 0107 0108 $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) 0109 0110 $parent.trigger(e = $.Event('close')) 0111 0112 if (e.isDefaultPrevented()) return 0113 0114 $parent.removeClass('in') 0115 0116 function removeElement() { 0117 $parent 0118 .trigger('closed') 0119 .remove() 0120 } 0121 0122 $.support.transition && $parent.hasClass('fade') ? 0123 $parent.on($.support.transition.end, removeElement) : 0124 removeElement() 0125 } 0126 0127 0128 /* ALERT PLUGIN DEFINITION 0129 * ======================= */ 0130 0131 $.fn.alert = function (option) { 0132 return this.each(function () { 0133 var $this = $(this) 0134 , data = $this.data('alert') 0135 if (!data) $this.data('alert', (data = new Alert(this))) 0136 if (typeof option == 'string') data[option].call($this) 0137 }) 0138 } 0139 0140 $.fn.alert.Constructor = Alert 0141 0142 0143 /* ALERT DATA-API 0144 * ============== */ 0145 0146 $(function () { 0147 $('body').on('click.alert.data-api', dismiss, Alert.prototype.close) 0148 }) 0149 0150 }(window.jQuery);/* ============================================================ 0151 * bootstrap-button.js v2.0.4 0152 * http://twitter.github.com/bootstrap/javascript.html#buttons 0153 * ============================================================ 0154 * Copyright 2012 Twitter, Inc. 0155 * 0156 * Licensed under the Apache License, Version 2.0 (the "License"); 0157 * you may not use this file except in compliance with the License. 0158 * You may obtain a copy of the License at 0159 * 0160 * http://www.apache.org/licenses/LICENSE-2.0 0161 * 0162 * Unless required by applicable law or agreed to in writing, software 0163 * distributed under the License is distributed on an "AS IS" BASIS, 0164 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0165 * See the License for the specific language governing permissions and 0166 * limitations under the License. 0167 * ============================================================ */ 0168 0169 0170 !function ($) { 0171 0172 "use strict"; // jshint ;_; 0173 0174 0175 /* BUTTON PUBLIC CLASS DEFINITION 0176 * ============================== */ 0177 0178 var Button = function (element, options) { 0179 this.$element = $(element) 0180 this.options = $.extend({}, $.fn.button.defaults, options) 0181 } 0182 0183 Button.prototype.setState = function (state) { 0184 var d = 'disabled' 0185 , $el = this.$element 0186 , data = $el.data() 0187 , val = $el.is('input') ? 'val' : 'html' 0188 0189 state = state + 'Text' 0190 data.resetText || $el.data('resetText', $el[val]()) 0191 0192 $el[val](data[state] || this.options[state]) 0193 0194 // push to event loop to allow forms to submit 0195 setTimeout(function () { 0196 state == 'loadingText' ? 0197 $el.addClass(d).attr(d, d) : 0198 $el.removeClass(d).removeAttr(d) 0199 }, 0) 0200 } 0201 0202 Button.prototype.toggle = function () { 0203 var $parent = this.$element.parent('[data-toggle="buttons-radio"]') 0204 0205 $parent && $parent 0206 .find('.active') 0207 .removeClass('active') 0208 0209 this.$element.toggleClass('active') 0210 } 0211 0212 0213 /* BUTTON PLUGIN DEFINITION 0214 * ======================== */ 0215 0216 $.fn.button = function (option) { 0217 return this.each(function () { 0218 var $this = $(this) 0219 , data = $this.data('button') 0220 , options = typeof option == 'object' && option 0221 if (!data) $this.data('button', (data = new Button(this, options))) 0222 if (option == 'toggle') data.toggle() 0223 else if (option) data.setState(option) 0224 }) 0225 } 0226 0227 $.fn.button.defaults = { 0228 loadingText: 'loading...' 0229 } 0230 0231 $.fn.button.Constructor = Button 0232 0233 0234 /* BUTTON DATA-API 0235 * =============== */ 0236 0237 $(function () { 0238 $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) { 0239 var $btn = $(e.target) 0240 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') 0241 $btn.button('toggle') 0242 }) 0243 }) 0244 0245 }(window.jQuery);/* ========================================================== 0246 * bootstrap-carousel.js v2.0.4 0247 * http://twitter.github.com/bootstrap/javascript.html#carousel 0248 * ========================================================== 0249 * Copyright 2012 Twitter, Inc. 0250 * 0251 * Licensed under the Apache License, Version 2.0 (the "License"); 0252 * you may not use this file except in compliance with the License. 0253 * You may obtain a copy of the License at 0254 * 0255 * http://www.apache.org/licenses/LICENSE-2.0 0256 * 0257 * Unless required by applicable law or agreed to in writing, software 0258 * distributed under the License is distributed on an "AS IS" BASIS, 0259 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0260 * See the License for the specific language governing permissions and 0261 * limitations under the License. 0262 * ========================================================== */ 0263 0264 0265 !function ($) { 0266 0267 "use strict"; // jshint ;_; 0268 0269 0270 /* CAROUSEL CLASS DEFINITION 0271 * ========================= */ 0272 0273 var Carousel = function (element, options) { 0274 this.$element = $(element) 0275 this.options = options 0276 this.options.slide && this.slide(this.options.slide) 0277 this.options.pause == 'hover' && this.$element 0278 .on('mouseenter', $.proxy(this.pause, this)) 0279 .on('mouseleave', $.proxy(this.cycle, this)) 0280 } 0281 0282 Carousel.prototype = { 0283 0284 cycle: function (e) { 0285 if (!e) this.paused = false 0286 this.options.interval 0287 && !this.paused 0288 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) 0289 return this 0290 } 0291 0292 , to: function (pos) { 0293 var $active = this.$element.find('.active') 0294 , children = $active.parent().children() 0295 , activePos = children.index($active) 0296 , that = this 0297 0298 if (pos > (children.length - 1) || pos < 0) return 0299 0300 if (this.sliding) { 0301 return this.$element.one('slid', function () { 0302 that.to(pos) 0303 }) 0304 } 0305 0306 if (activePos == pos) { 0307 return this.pause().cycle() 0308 } 0309 0310 return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos])) 0311 } 0312 0313 , pause: function (e) { 0314 if (!e) this.paused = true 0315 clearInterval(this.interval) 0316 this.interval = null 0317 return this 0318 } 0319 0320 , next: function () { 0321 if (this.sliding) return 0322 return this.slide('next') 0323 } 0324 0325 , prev: function () { 0326 if (this.sliding) return 0327 return this.slide('prev') 0328 } 0329 0330 , slide: function (type, next) { 0331 var $active = this.$element.find('.active') 0332 , $next = next || $active[type]() 0333 , isCycling = this.interval 0334 , direction = type == 'next' ? 'left' : 'right' 0335 , fallback = type == 'next' ? 'first' : 'last' 0336 , that = this 0337 , e = $.Event('slide') 0338 0339 this.sliding = true 0340 0341 isCycling && this.pause() 0342 0343 $next = $next.length ? $next : this.$element.find('.item')[fallback]() 0344 0345 if ($next.hasClass('active')) return 0346 0347 if ($.support.transition && this.$element.hasClass('slide')) { 0348 this.$element.trigger(e) 0349 if (e.isDefaultPrevented()) return 0350 $next.addClass(type) 0351 $next[0].offsetWidth // force reflow 0352 $active.addClass(direction) 0353 $next.addClass(direction) 0354 this.$element.one($.support.transition.end, function () { 0355 $next.removeClass([type, direction].join(' ')).addClass('active') 0356 $active.removeClass(['active', direction].join(' ')) 0357 that.sliding = false 0358 setTimeout(function () { that.$element.trigger('slid') }, 0) 0359 }) 0360 } else { 0361 this.$element.trigger(e) 0362 if (e.isDefaultPrevented()) return 0363 $active.removeClass('active') 0364 $next.addClass('active') 0365 this.sliding = false 0366 this.$element.trigger('slid') 0367 } 0368 0369 isCycling && this.cycle() 0370 0371 return this 0372 } 0373 0374 } 0375 0376 0377 /* CAROUSEL PLUGIN DEFINITION 0378 * ========================== */ 0379 0380 $.fn.carousel = function (option) { 0381 return this.each(function () { 0382 var $this = $(this) 0383 , data = $this.data('carousel') 0384 , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) 0385 if (!data) $this.data('carousel', (data = new Carousel(this, options))) 0386 if (typeof option == 'number') data.to(option) 0387 else if (typeof option == 'string' || (option = options.slide)) data[option]() 0388 else if (options.interval) data.cycle() 0389 }) 0390 } 0391 0392 $.fn.carousel.defaults = { 0393 interval: 5000 0394 , pause: 'hover' 0395 } 0396 0397 $.fn.carousel.Constructor = Carousel 0398 0399 0400 /* CAROUSEL DATA-API 0401 * ================= */ 0402 0403 $(function () { 0404 $('body').on('click.carousel.data-api', '[data-slide]', function ( e ) { 0405 var $this = $(this), href 0406 , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 0407 , options = !$target.data('modal') && $.extend({}, $target.data(), $this.data()) 0408 $target.carousel(options) 0409 e.preventDefault() 0410 }) 0411 }) 0412 0413 }(window.jQuery);/* ============================================================= 0414 * bootstrap-collapse.js v2.0.4 0415 * http://twitter.github.com/bootstrap/javascript.html#collapse 0416 * ============================================================= 0417 * Copyright 2012 Twitter, Inc. 0418 * 0419 * Licensed under the Apache License, Version 2.0 (the "License"); 0420 * you may not use this file except in compliance with the License. 0421 * You may obtain a copy of the License at 0422 * 0423 * http://www.apache.org/licenses/LICENSE-2.0 0424 * 0425 * Unless required by applicable law or agreed to in writing, software 0426 * distributed under the License is distributed on an "AS IS" BASIS, 0427 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0428 * See the License for the specific language governing permissions and 0429 * limitations under the License. 0430 * ============================================================ */ 0431 0432 0433 !function ($) { 0434 0435 "use strict"; // jshint ;_; 0436 0437 0438 /* COLLAPSE PUBLIC CLASS DEFINITION 0439 * ================================ */ 0440 0441 var Collapse = function (element, options) { 0442 this.$element = $(element) 0443 this.options = $.extend({}, $.fn.collapse.defaults, options) 0444 0445 if (this.options.parent) { 0446 this.$parent = $(this.options.parent) 0447 } 0448 0449 this.options.toggle && this.toggle() 0450 } 0451 0452 Collapse.prototype = { 0453 0454 constructor: Collapse 0455 0456 , dimension: function () { 0457 var hasWidth = this.$element.hasClass('width') 0458 return hasWidth ? 'width' : 'height' 0459 } 0460 0461 , show: function () { 0462 var dimension 0463 , scroll 0464 , actives 0465 , hasData 0466 0467 if (this.transitioning) return 0468 0469 dimension = this.dimension() 0470 scroll = $.camelCase(['scroll', dimension].join('-')) 0471 actives = this.$parent && this.$parent.find('> .accordion-group > .in') 0472 0473 if (actives && actives.length) { 0474 hasData = actives.data('collapse') 0475 if (hasData && hasData.transitioning) return 0476 actives.collapse('hide') 0477 hasData || actives.data('collapse', null) 0478 } 0479 0480 this.$element[dimension](0) 0481 this.transition('addClass', $.Event('show'), 'shown') 0482 this.$element[dimension](this.$element[0][scroll]) 0483 } 0484 0485 , hide: function () { 0486 var dimension 0487 if (this.transitioning) return 0488 dimension = this.dimension() 0489 this.reset(this.$element[dimension]()) 0490 this.transition('removeClass', $.Event('hide'), 'hidden') 0491 this.$element[dimension](0) 0492 } 0493 0494 , reset: function (size) { 0495 var dimension = this.dimension() 0496 0497 this.$element 0498 .removeClass('collapse') 0499 [dimension](size || 'auto') 0500 [0].offsetWidth 0501 0502 this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') 0503 0504 return this 0505 } 0506 0507 , transition: function (method, startEvent, completeEvent) { 0508 var that = this 0509 , complete = function () { 0510 if (startEvent.type == 'show') that.reset() 0511 that.transitioning = 0 0512 that.$element.trigger(completeEvent) 0513 } 0514 0515 this.$element.trigger(startEvent) 0516 0517 if (startEvent.isDefaultPrevented()) return 0518 0519 this.transitioning = 1 0520 0521 this.$element[method]('in') 0522 0523 $.support.transition && this.$element.hasClass('collapse') ? 0524 this.$element.one($.support.transition.end, complete) : 0525 complete() 0526 } 0527 0528 , toggle: function () { 0529 this[this.$element.hasClass('in') ? 'hide' : 'show']() 0530 } 0531 0532 } 0533 0534 0535 /* COLLAPSIBLE PLUGIN DEFINITION 0536 * ============================== */ 0537 0538 $.fn.collapse = function (option) { 0539 return this.each(function () { 0540 var $this = $(this) 0541 , data = $this.data('collapse') 0542 , options = typeof option == 'object' && option 0543 if (!data) $this.data('collapse', (data = new Collapse(this, options))) 0544 if (typeof option == 'string') data[option]() 0545 }) 0546 } 0547 0548 $.fn.collapse.defaults = { 0549 toggle: true 0550 } 0551 0552 $.fn.collapse.Constructor = Collapse 0553 0554 0555 /* COLLAPSIBLE DATA-API 0556 * ==================== */ 0557 0558 $(function () { 0559 $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) { 0560 var $this = $(this), href 0561 , target = $this.attr('data-target') 0562 || e.preventDefault() 0563 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 0564 , option = $(target).data('collapse') ? 'toggle' : $this.data() 0565 $(target).collapse(option) 0566 }) 0567 }) 0568 0569 }(window.jQuery);/* ============================================================ 0570 * bootstrap-dropdown.js v2.0.4 0571 * http://twitter.github.com/bootstrap/javascript.html#dropdowns 0572 * ============================================================ 0573 * Copyright 2012 Twitter, Inc. 0574 * 0575 * Licensed under the Apache License, Version 2.0 (the "License"); 0576 * you may not use this file except in compliance with the License. 0577 * You may obtain a copy of the License at 0578 * 0579 * http://www.apache.org/licenses/LICENSE-2.0 0580 * 0581 * Unless required by applicable law or agreed to in writing, software 0582 * distributed under the License is distributed on an "AS IS" BASIS, 0583 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0584 * See the License for the specific language governing permissions and 0585 * limitations under the License. 0586 * ============================================================ */ 0587 0588 0589 !function ($) { 0590 0591 "use strict"; // jshint ;_; 0592 0593 0594 /* DROPDOWN CLASS DEFINITION 0595 * ========================= */ 0596 0597 var toggle = '[data-toggle="dropdown"]' 0598 , Dropdown = function (element) { 0599 var $el = $(element).on('click.dropdown.data-api', this.toggle) 0600 $('html').on('click.dropdown.data-api', function () { 0601 $el.parent().removeClass('open') 0602 }) 0603 } 0604 0605 Dropdown.prototype = { 0606 0607 constructor: Dropdown 0608 0609 , toggle: function (e) { 0610 var $this = $(this) 0611 , $parent 0612 , selector 0613 , isActive 0614 0615 if ($this.is('.disabled, :disabled')) return 0616 0617 selector = $this.attr('data-target') 0618 0619 if (!selector) { 0620 selector = $this.attr('href') 0621 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 0622 } 0623 0624 $parent = $(selector) 0625 $parent.length || ($parent = $this.parent()) 0626 0627 isActive = $parent.hasClass('open') 0628 0629 clearMenus() 0630 0631 if (!isActive) $parent.toggleClass('open') 0632 0633 return false 0634 } 0635 0636 } 0637 0638 function clearMenus() { 0639 $(toggle).parent().removeClass('open') 0640 } 0641 0642 0643 /* DROPDOWN PLUGIN DEFINITION 0644 * ========================== */ 0645 0646 $.fn.dropdown = function (option) { 0647 return this.each(function () { 0648 var $this = $(this) 0649 , data = $this.data('dropdown') 0650 if (!data) $this.data('dropdown', (data = new Dropdown(this))) 0651 if (typeof option == 'string') data[option].call($this) 0652 }) 0653 } 0654 0655 $.fn.dropdown.Constructor = Dropdown 0656 0657 0658 /* APPLY TO STANDARD DROPDOWN ELEMENTS 0659 * =================================== */ 0660 0661 $(function () { 0662 $('html').on('click.dropdown.data-api', clearMenus) 0663 $('body') 0664 .on('click.dropdown', '.dropdown form', function (e) { e.stopPropagation() }) 0665 .on('click.dropdown.data-api', toggle, Dropdown.prototype.toggle) 0666 }) 0667 0668 }(window.jQuery);/* ========================================================= 0669 * bootstrap-modal.js v2.0.4 0670 * http://twitter.github.com/bootstrap/javascript.html#modals 0671 * ========================================================= 0672 * Copyright 2012 Twitter, Inc. 0673 * 0674 * Licensed under the Apache License, Version 2.0 (the "License"); 0675 * you may not use this file except in compliance with the License. 0676 * You may obtain a copy of the License at 0677 * 0678 * http://www.apache.org/licenses/LICENSE-2.0 0679 * 0680 * Unless required by applicable law or agreed to in writing, software 0681 * distributed under the License is distributed on an "AS IS" BASIS, 0682 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0683 * See the License for the specific language governing permissions and 0684 * limitations under the License. 0685 * ========================================================= */ 0686 0687 0688 !function ($) { 0689 0690 "use strict"; // jshint ;_; 0691 0692 0693 /* MODAL CLASS DEFINITION 0694 * ====================== */ 0695 0696 var Modal = function (content, options) { 0697 this.options = options 0698 this.$element = $(content) 0699 .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) 0700 } 0701 0702 Modal.prototype = { 0703 0704 constructor: Modal 0705 0706 , toggle: function () { 0707 return this[!this.isShown ? 'show' : 'hide']() 0708 } 0709 0710 , show: function () { 0711 var that = this 0712 , e = $.Event('show') 0713 0714 this.$element.trigger(e) 0715 0716 if (this.isShown || e.isDefaultPrevented()) return 0717 0718 $('body').addClass('modal-open') 0719 0720 this.isShown = true 0721 0722 escape.call(this) 0723 backdrop.call(this, function () { 0724 var transition = $.support.transition && that.$element.hasClass('fade') 0725 0726 if (!that.$element.parent().length) { 0727 that.$element.appendTo(document.body) //don't move modals dom position 0728 } 0729 0730 that.$element 0731 .show() 0732 0733 if (transition) { 0734 that.$element[0].offsetWidth // force reflow 0735 } 0736 0737 that.$element.addClass('in') 0738 0739 transition ? 0740 that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) : 0741 that.$element.trigger('shown') 0742 0743 }) 0744 } 0745 0746 , hide: function (e) { 0747 e && e.preventDefault() 0748 0749 var that = this 0750 0751 e = $.Event('hide') 0752 0753 this.$element.trigger(e) 0754 0755 if (!this.isShown || e.isDefaultPrevented()) return 0756 0757 this.isShown = false 0758 0759 $('body').removeClass('modal-open') 0760 0761 escape.call(this) 0762 0763 this.$element.removeClass('in') 0764 0765 $.support.transition && this.$element.hasClass('fade') ? 0766 hideWithTransition.call(this) : 0767 hideModal.call(this) 0768 } 0769 0770 } 0771 0772 0773 /* MODAL PRIVATE METHODS 0774 * ===================== */ 0775 0776 function hideWithTransition() { 0777 var that = this 0778 , timeout = setTimeout(function () { 0779 that.$element.off($.support.transition.end) 0780 hideModal.call(that) 0781 }, 500) 0782 0783 this.$element.one($.support.transition.end, function () { 0784 clearTimeout(timeout) 0785 hideModal.call(that) 0786 }) 0787 } 0788 0789 function hideModal(that) { 0790 this.$element 0791 .hide() 0792 .trigger('hidden') 0793 0794 backdrop.call(this) 0795 } 0796 0797 function backdrop(callback) { 0798 var that = this 0799 , animate = this.$element.hasClass('fade') ? 'fade' : '' 0800 0801 if (this.isShown && this.options.backdrop) { 0802 var doAnimate = $.support.transition && animate 0803 0804 this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />') 0805 .appendTo(document.body) 0806 0807 if (this.options.backdrop != 'static') { 0808 this.$backdrop.click($.proxy(this.hide, this)) 0809 } 0810 0811 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow 0812 0813 this.$backdrop.addClass('in') 0814 0815 doAnimate ? 0816 this.$backdrop.one($.support.transition.end, callback) : 0817 callback() 0818 0819 } else if (!this.isShown && this.$backdrop) { 0820 this.$backdrop.removeClass('in') 0821 0822 $.support.transition && this.$element.hasClass('fade')? 0823 this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) : 0824 removeBackdrop.call(this) 0825 0826 } else if (callback) { 0827 callback() 0828 } 0829 } 0830 0831 function removeBackdrop() { 0832 this.$backdrop.remove() 0833 this.$backdrop = null 0834 } 0835 0836 function escape() { 0837 var that = this 0838 if (this.isShown && this.options.keyboard) { 0839 $(document).on('keyup.dismiss.modal', function ( e ) { 0840 e.which == 27 && that.hide() 0841 }) 0842 } else if (!this.isShown) { 0843 $(document).off('keyup.dismiss.modal') 0844 } 0845 } 0846 0847 0848 /* MODAL PLUGIN DEFINITION 0849 * ======================= */ 0850 0851 $.fn.modal = function (option) { 0852 return this.each(function () { 0853 var $this = $(this) 0854 , data = $this.data('modal') 0855 , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option) 0856 if (!data) $this.data('modal', (data = new Modal(this, options))) 0857 if (typeof option == 'string') data[option]() 0858 else if (options.show) data.show() 0859 }) 0860 } 0861 0862 $.fn.modal.defaults = { 0863 backdrop: true 0864 , keyboard: true 0865 , show: true 0866 } 0867 0868 $.fn.modal.Constructor = Modal 0869 0870 0871 /* MODAL DATA-API 0872 * ============== */ 0873 0874 $(function () { 0875 $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) { 0876 var $this = $(this), href 0877 , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 0878 , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data()) 0879 0880 e.preventDefault() 0881 $target.modal(option) 0882 }) 0883 }) 0884 0885 }(window.jQuery);/* =========================================================== 0886 * bootstrap-tooltip.js v2.0.4 0887 * http://twitter.github.com/bootstrap/javascript.html#tooltips 0888 * Inspired by the original jQuery.tipsy by Jason Frame 0889 * =========================================================== 0890 * Copyright 2012 Twitter, Inc. 0891 * 0892 * Licensed under the Apache License, Version 2.0 (the "License"); 0893 * you may not use this file except in compliance with the License. 0894 * You may obtain a copy of the License at 0895 * 0896 * http://www.apache.org/licenses/LICENSE-2.0 0897 * 0898 * Unless required by applicable law or agreed to in writing, software 0899 * distributed under the License is distributed on an "AS IS" BASIS, 0900 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 0901 * See the License for the specific language governing permissions and 0902 * limitations under the License. 0903 * ========================================================== */ 0904 0905 0906 !function ($) { 0907 0908 "use strict"; // jshint ;_; 0909 0910 0911 /* TOOLTIP PUBLIC CLASS DEFINITION 0912 * =============================== */ 0913 0914 var Tooltip = function (element, options) { 0915 this.init('tooltip', element, options) 0916 } 0917 0918 Tooltip.prototype = { 0919 0920 constructor: Tooltip 0921 0922 , init: function (type, element, options) { 0923 var eventIn 0924 , eventOut 0925 0926 this.type = type 0927 this.$element = $(element) 0928 this.options = this.getOptions(options) 0929 this.enabled = true 0930 0931 if (this.options.trigger != 'manual') { 0932 eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus' 0933 eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur' 0934 this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this)) 0935 this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this)) 0936 } 0937 0938 this.options.selector ? 0939 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : 0940 this.fixTitle() 0941 } 0942 0943 , getOptions: function (options) { 0944 options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data()) 0945 0946 if (options.delay && typeof options.delay == 'number') { 0947 options.delay = { 0948 show: options.delay 0949 , hide: options.delay 0950 } 0951 } 0952 0953 return options 0954 } 0955 0956 , enter: function (e) { 0957 var self = $(e.currentTarget)[this.type](this._options).data(this.type) 0958 0959 if (!self.options.delay || !self.options.delay.show) return self.show() 0960 0961 clearTimeout(this.timeout) 0962 self.hoverState = 'in' 0963 this.timeout = setTimeout(function() { 0964 if (self.hoverState == 'in') self.show() 0965 }, self.options.delay.show) 0966 } 0967 0968 , leave: function (e) { 0969 var self = $(e.currentTarget)[this.type](this._options).data(this.type) 0970 0971 if (this.timeout) clearTimeout(this.timeout) 0972 if (!self.options.delay || !self.options.delay.hide) return self.hide() 0973 0974 self.hoverState = 'out' 0975 this.timeout = setTimeout(function() { 0976 if (self.hoverState == 'out') self.hide() 0977 }, self.options.delay.hide) 0978 } 0979 0980 , show: function () { 0981 var $tip 0982 , inside 0983 , pos 0984 , actualWidth 0985 , actualHeight 0986 , placement 0987 , tp 0988 0989 if (this.hasContent() && this.enabled) { 0990 $tip = this.tip() 0991 this.setContent() 0992 0993 if (this.options.animation) { 0994 $tip.addClass('fade') 0995 } 0996 0997 placement = typeof this.options.placement == 'function' ? 0998 this.options.placement.call(this, $tip[0], this.$element[0]) : 0999 this.options.placement 1000 1001 inside = /in/.test(placement) 1002 1003 $tip 1004 .remove() 1005 .css({ top: 0, left: 0, display: 'block' }) 1006 .appendTo(inside ? this.$element : document.body) 1007 1008 pos = this.getPosition(inside) 1009 1010 actualWidth = $tip[0].offsetWidth 1011 actualHeight = $tip[0].offsetHeight 1012 1013 switch (inside ? placement.split(' ')[1] : placement) { 1014 case 'bottom': 1015 tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} 1016 break 1017 case 'top': 1018 tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} 1019 break 1020 case 'left': 1021 tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} 1022 break 1023 case 'right': 1024 tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} 1025 break 1026 } 1027 1028 $tip 1029 .css(tp) 1030 .addClass(placement) 1031 .addClass('in') 1032 } 1033 } 1034 1035 , isHTML: function(text) { 1036 // html string detection logic adapted from jQuery 1037 return typeof text != 'string' 1038 || ( text.charAt(0) === "<" 1039 && text.charAt( text.length - 1 ) === ">" 1040 && text.length >= 3 1041 ) || /^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(text) 1042 } 1043 1044 , setContent: function () { 1045 var $tip = this.tip() 1046 , title = this.getTitle() 1047 1048 $tip.find('.tooltip-inner')[this.isHTML(title) ? 'html' : 'text'](title) 1049 $tip.removeClass('fade in top bottom left right') 1050 } 1051 1052 , hide: function () { 1053 var that = this 1054 , $tip = this.tip() 1055 1056 $tip.removeClass('in') 1057 1058 function removeWithAnimation() { 1059 var timeout = setTimeout(function () { 1060 $tip.off($.support.transition.end).remove() 1061 }, 500) 1062 1063 $tip.one($.support.transition.end, function () { 1064 clearTimeout(timeout) 1065 $tip.remove() 1066 }) 1067 } 1068 1069 $.support.transition && this.$tip.hasClass('fade') ? 1070 removeWithAnimation() : 1071 $tip.remove() 1072 } 1073 1074 , fixTitle: function () { 1075 var $e = this.$element 1076 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { 1077 $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title') 1078 } 1079 } 1080 1081 , hasContent: function () { 1082 return this.getTitle() 1083 } 1084 1085 , getPosition: function (inside) { 1086 return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), { 1087 width: this.$element[0].offsetWidth 1088 , height: this.$element[0].offsetHeight 1089 }) 1090 } 1091 1092 , getTitle: function () { 1093 var title 1094 , $e = this.$element 1095 , o = this.options 1096 1097 title = $e.attr('data-original-title') 1098 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) 1099 1100 return title 1101 } 1102 1103 , tip: function () { 1104 return this.$tip = this.$tip || $(this.options.template) 1105 } 1106 1107 , validate: function () { 1108 if (!this.$element[0].parentNode) { 1109 this.hide() 1110 this.$element = null 1111 this.options = null 1112 } 1113 } 1114 1115 , enable: function () { 1116 this.enabled = true 1117 } 1118 1119 , disable: function () { 1120 this.enabled = false 1121 } 1122 1123 , toggleEnabled: function () { 1124 this.enabled = !this.enabled 1125 } 1126 1127 , toggle: function () { 1128 this[this.tip().hasClass('in') ? 'hide' : 'show']() 1129 } 1130 1131 } 1132 1133 1134 /* TOOLTIP PLUGIN DEFINITION 1135 * ========================= */ 1136 1137 $.fn.tooltip = function ( option ) { 1138 return this.each(function () { 1139 var $this = $(this) 1140 , data = $this.data('tooltip') 1141 , options = typeof option == 'object' && option 1142 if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) 1143 if (typeof option == 'string') data[option]() 1144 }) 1145 } 1146 1147 $.fn.tooltip.Constructor = Tooltip 1148 1149 $.fn.tooltip.defaults = { 1150 animation: true 1151 , placement: 'top' 1152 , selector: false 1153 , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>' 1154 , trigger: 'hover' 1155 , title: '' 1156 , delay: 0 1157 } 1158 1159 }(window.jQuery); 1160 /* =========================================================== 1161 * bootstrap-popover.js v2.0.4 1162 * http://twitter.github.com/bootstrap/javascript.html#popovers 1163 * =========================================================== 1164 * Copyright 2012 Twitter, Inc. 1165 * 1166 * Licensed under the Apache License, Version 2.0 (the "License"); 1167 * you may not use this file except in compliance with the License. 1168 * You may obtain a copy of the License at 1169 * 1170 * http://www.apache.org/licenses/LICENSE-2.0 1171 * 1172 * Unless required by applicable law or agreed to in writing, software 1173 * distributed under the License is distributed on an "AS IS" BASIS, 1174 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1175 * See the License for the specific language governing permissions and 1176 * limitations under the License. 1177 * =========================================================== */ 1178 1179 1180 !function ($) { 1181 1182 "use strict"; // jshint ;_; 1183 1184 1185 /* POPOVER PUBLIC CLASS DEFINITION 1186 * =============================== */ 1187 1188 var Popover = function ( element, options ) { 1189 this.init('popover', element, options) 1190 } 1191 1192 1193 /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js 1194 ========================================== */ 1195 1196 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { 1197 1198 constructor: Popover 1199 1200 , setContent: function () { 1201 var $tip = this.tip() 1202 , title = this.getTitle() 1203 , content = this.getContent() 1204 1205 $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title) 1206 $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content) 1207 1208 $tip.removeClass('fade top bottom left right in') 1209 } 1210 1211 , hasContent: function () { 1212 return this.getTitle() || this.getContent() 1213 } 1214 1215 , getContent: function () { 1216 var content 1217 , $e = this.$element 1218 , o = this.options 1219 1220 content = $e.attr('data-content') 1221 || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) 1222 1223 return content 1224 } 1225 1226 , tip: function () { 1227 if (!this.$tip) { 1228 this.$tip = $(this.options.template) 1229 } 1230 return this.$tip 1231 } 1232 1233 }) 1234 1235 1236 /* POPOVER PLUGIN DEFINITION 1237 * ======================= */ 1238 1239 $.fn.popover = function (option) { 1240 return this.each(function () { 1241 var $this = $(this) 1242 , data = $this.data('popover') 1243 , options = typeof option == 'object' && option 1244 if (!data) $this.data('popover', (data = new Popover(this, options))) 1245 if (typeof option == 'string') data[option]() 1246 }) 1247 } 1248 1249 $.fn.popover.Constructor = Popover 1250 1251 $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { 1252 placement: 'right' 1253 , content: '' 1254 , 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>' 1255 }) 1256 1257 }(window.jQuery);/* ============================================================= 1258 * bootstrap-scrollspy.js v2.0.4 1259 * http://twitter.github.com/bootstrap/javascript.html#scrollspy 1260 * ============================================================= 1261 * Copyright 2012 Twitter, Inc. 1262 * 1263 * Licensed under the Apache License, Version 2.0 (the "License"); 1264 * you may not use this file except in compliance with the License. 1265 * You may obtain a copy of the License at 1266 * 1267 * http://www.apache.org/licenses/LICENSE-2.0 1268 * 1269 * Unless required by applicable law or agreed to in writing, software 1270 * distributed under the License is distributed on an "AS IS" BASIS, 1271 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1272 * See the License for the specific language governing permissions and 1273 * limitations under the License. 1274 * ============================================================== */ 1275 1276 1277 !function ($) { 1278 1279 "use strict"; // jshint ;_; 1280 1281 1282 /* SCROLLSPY CLASS DEFINITION 1283 * ========================== */ 1284 1285 function ScrollSpy( element, options) { 1286 var process = $.proxy(this.process, this) 1287 , $element = $(element).is('body') ? $(window) : $(element) 1288 , href 1289 this.options = $.extend({}, $.fn.scrollspy.defaults, options) 1290 this.$scrollElement = $element.on('scroll.scroll.data-api', process) 1291 this.selector = (this.options.target 1292 || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 1293 || '') + ' .nav li > a' 1294 this.$body = $('body') 1295 this.refresh() 1296 this.process() 1297 } 1298 1299 ScrollSpy.prototype = { 1300 1301 constructor: ScrollSpy 1302 1303 , refresh: function () { 1304 var self = this 1305 , $targets 1306 1307 this.offsets = $([]) 1308 this.targets = $([]) 1309 1310 $targets = this.$body 1311 .find(this.selector) 1312 .map(function () { 1313 var $el = $(this) 1314 , href = $el.data('target') || $el.attr('href') 1315 , $href = /^#\w/.test(href) && $(href) 1316 return ( $href 1317 && href.length 1318 && [[ $href.position().top, href ]] ) || null 1319 }) 1320 .sort(function (a, b) { return a[0] - b[0] }) 1321 .each(function () { 1322 self.offsets.push(this[0]) 1323 self.targets.push(this[1]) 1324 }) 1325 } 1326 1327 , process: function () { 1328 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset 1329 , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight 1330 , maxScroll = scrollHeight - this.$scrollElement.height() 1331 , offsets = this.offsets 1332 , targets = this.targets 1333 , activeTarget = this.activeTarget 1334 , i 1335 1336 if (scrollTop >= maxScroll) { 1337 return activeTarget != (i = targets.last()[0]) 1338 && this.activate ( i ) 1339 } 1340 1341 for (i = offsets.length; i--;) { 1342 activeTarget != targets[i] 1343 && scrollTop >= offsets[i] 1344 && (!offsets[i + 1] || scrollTop <= offsets[i + 1]) 1345 && this.activate( targets[i] ) 1346 } 1347 } 1348 1349 , activate: function (target) { 1350 var active 1351 , selector 1352 1353 this.activeTarget = target 1354 1355 $(this.selector) 1356 .parent('.active') 1357 .removeClass('active') 1358 1359 selector = this.selector 1360 + '[data-target="' + target + '"],' 1361 + this.selector + '[href="' + target + '"]' 1362 1363 active = $(selector) 1364 .parent('li') 1365 .addClass('active') 1366 1367 if (active.parent('.dropdown-menu')) { 1368 active = active.closest('li.dropdown').addClass('active') 1369 } 1370 1371 active.trigger('activate') 1372 } 1373 1374 } 1375 1376 1377 /* SCROLLSPY PLUGIN DEFINITION 1378 * =========================== */ 1379 1380 $.fn.scrollspy = function ( option ) { 1381 return this.each(function () { 1382 var $this = $(this) 1383 , data = $this.data('scrollspy') 1384 , options = typeof option == 'object' && option 1385 if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options))) 1386 if (typeof option == 'string') data[option]() 1387 }) 1388 } 1389 1390 $.fn.scrollspy.Constructor = ScrollSpy 1391 1392 $.fn.scrollspy.defaults = { 1393 offset: 10 1394 } 1395 1396 1397 /* SCROLLSPY DATA-API 1398 * ================== */ 1399 1400 $(function () { 1401 $('[data-spy="scroll"]').each(function () { 1402 var $spy = $(this) 1403 $spy.scrollspy($spy.data()) 1404 }) 1405 }) 1406 1407 }(window.jQuery);/* ======================================================== 1408 * bootstrap-tab.js v2.0.4 1409 * http://twitter.github.com/bootstrap/javascript.html#tabs 1410 * ======================================================== 1411 * Copyright 2012 Twitter, Inc. 1412 * 1413 * Licensed under the Apache License, Version 2.0 (the "License"); 1414 * you may not use this file except in compliance with the License. 1415 * You may obtain a copy of the License at 1416 * 1417 * http://www.apache.org/licenses/LICENSE-2.0 1418 * 1419 * Unless required by applicable law or agreed to in writing, software 1420 * distributed under the License is distributed on an "AS IS" BASIS, 1421 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1422 * See the License for the specific language governing permissions and 1423 * limitations under the License. 1424 * ======================================================== */ 1425 1426 1427 !function ($) { 1428 1429 "use strict"; // jshint ;_; 1430 1431 1432 /* TAB CLASS DEFINITION 1433 * ==================== */ 1434 1435 var Tab = function ( element ) { 1436 this.element = $(element) 1437 } 1438 1439 Tab.prototype = { 1440 1441 constructor: Tab 1442 1443 , show: function () { 1444 var $this = this.element 1445 , $ul = $this.closest('ul:not(.dropdown-menu)') 1446 , selector = $this.attr('data-target') 1447 , previous 1448 , $target 1449 , e 1450 1451 if (!selector) { 1452 selector = $this.attr('href') 1453 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 1454 } 1455 1456 if ( $this.parent('li').hasClass('active') ) return 1457 1458 previous = $ul.find('.active a').last()[0] 1459 1460 e = $.Event('show', { 1461 relatedTarget: previous 1462 }) 1463 1464 $this.trigger(e) 1465 1466 if (e.isDefaultPrevented()) return 1467 1468 $target = $(selector) 1469 1470 this.activate($this.parent('li'), $ul) 1471 this.activate($target, $target.parent(), function () { 1472 $this.trigger({ 1473 type: 'shown' 1474 , relatedTarget: previous 1475 }) 1476 }) 1477 } 1478 1479 , activate: function ( element, container, callback) { 1480 var $active = container.find('> .active') 1481 , transition = callback 1482 && $.support.transition 1483 && $active.hasClass('fade') 1484 1485 function next() { 1486 $active 1487 .removeClass('active') 1488 .find('> .dropdown-menu > .active') 1489 .removeClass('active') 1490 1491 element.addClass('active') 1492 1493 if (transition) { 1494 element[0].offsetWidth // reflow for transition 1495 element.addClass('in') 1496 } else { 1497 element.removeClass('fade') 1498 } 1499 1500 if ( element.parent('.dropdown-menu') ) { 1501 element.closest('li.dropdown').addClass('active') 1502 } 1503 1504 callback && callback() 1505 } 1506 1507 transition ? 1508 $active.one($.support.transition.end, next) : 1509 next() 1510 1511 $active.removeClass('in') 1512 } 1513 } 1514 1515 1516 /* TAB PLUGIN DEFINITION 1517 * ===================== */ 1518 1519 $.fn.tab = function ( option ) { 1520 return this.each(function () { 1521 var $this = $(this) 1522 , data = $this.data('tab') 1523 if (!data) $this.data('tab', (data = new Tab(this))) 1524 if (typeof option == 'string') data[option]() 1525 }) 1526 } 1527 1528 $.fn.tab.Constructor = Tab 1529 1530 1531 /* TAB DATA-API 1532 * ============ */ 1533 1534 $(function () { 1535 $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 1536 e.preventDefault() 1537 $(this).tab('show') 1538 }) 1539 }) 1540 1541 }(window.jQuery);/* ============================================================= 1542 * bootstrap-typeahead.js v2.0.4 1543 * http://twitter.github.com/bootstrap/javascript.html#typeahead 1544 * ============================================================= 1545 * Copyright 2012 Twitter, Inc. 1546 * 1547 * Licensed under the Apache License, Version 2.0 (the "License"); 1548 * you may not use this file except in compliance with the License. 1549 * You may obtain a copy of the License at 1550 * 1551 * http://www.apache.org/licenses/LICENSE-2.0 1552 * 1553 * Unless required by applicable law or agreed to in writing, software 1554 * distributed under the License is distributed on an "AS IS" BASIS, 1555 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1556 * See the License for the specific language governing permissions and 1557 * limitations under the License. 1558 * ============================================================ */ 1559 1560 1561 !function($){ 1562 1563 "use strict"; // jshint ;_; 1564 1565 1566 /* TYPEAHEAD PUBLIC CLASS DEFINITION 1567 * ================================= */ 1568 1569 var Typeahead = function (element, options) { 1570 this.$element = $(element) 1571 this.options = $.extend({}, $.fn.typeahead.defaults, options) 1572 this.matcher = this.options.matcher || this.matcher 1573 this.sorter = this.options.sorter || this.sorter 1574 this.highlighter = this.options.highlighter || this.highlighter 1575 this.updater = this.options.updater || this.updater 1576 this.$menu = $(this.options.menu).appendTo('body') 1577 this.source = this.options.source 1578 this.shown = false 1579 this.listen() 1580 } 1581 1582 Typeahead.prototype = { 1583 1584 constructor: Typeahead 1585 1586 , select: function () { 1587 var val = this.$menu.find('.active').attr('data-value') 1588 this.$element 1589 .val(this.updater(val)) 1590 .change() 1591 return this.hide() 1592 } 1593 1594 , updater: function (item) { 1595 return item 1596 } 1597 1598 , show: function () { 1599 var pos = $.extend({}, this.$element.offset(), { 1600 height: this.$element[0].offsetHeight 1601 }) 1602 1603 this.$menu.css({ 1604 top: pos.top + pos.height 1605 , left: pos.left 1606 }) 1607 1608 this.$menu.show() 1609 this.shown = true 1610 return this 1611 } 1612 1613 , hide: function () { 1614 this.$menu.hide() 1615 this.shown = false 1616 return this 1617 } 1618 1619 , lookup: function (event) { 1620 var that = this 1621 , items 1622 , q 1623 1624 this.query = this.$element.val() 1625 1626 if (!this.query) { 1627 return this.shown ? this.hide() : this 1628 } 1629 1630 items = $.grep(this.source, function (item) { 1631 return that.matcher(item) 1632 }) 1633 1634 items = this.sorter(items) 1635 1636 if (!items.length) { 1637 return this.shown ? this.hide() : this 1638 } 1639 1640 return this.render(items.slice(0, this.options.items)).show() 1641 } 1642 1643 , matcher: function (item) { 1644 return ~item.toLowerCase().indexOf(this.query.toLowerCase()) 1645 } 1646 1647 , sorter: function (items) { 1648 var beginswith = [] 1649 , caseSensitive = [] 1650 , caseInsensitive = [] 1651 , item 1652 1653 while (item = items.shift()) { 1654 if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item) 1655 else if (~item.indexOf(this.query)) caseSensitive.push(item) 1656 else caseInsensitive.push(item) 1657 } 1658 1659 return beginswith.concat(caseSensitive, caseInsensitive) 1660 } 1661 1662 , highlighter: function (item) { 1663 var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&') 1664 return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) { 1665 return '<strong>' + match + '</strong>' 1666 }) 1667 } 1668 1669 , render: function (items) { 1670 var that = this 1671 1672 items = $(items).map(function (i, item) { 1673 i = $(that.options.item).attr('data-value', item) 1674 i.find('a').html(that.highlighter(item)) 1675 return i[0] 1676 }) 1677 1678 items.first().addClass('active') 1679 this.$menu.html(items) 1680 return this 1681 } 1682 1683 , next: function (event) { 1684 var active = this.$menu.find('.active').removeClass('active') 1685 , next = active.next() 1686 1687 if (!next.length) { 1688 next = $(this.$menu.find('li')[0]) 1689 } 1690 1691 next.addClass('active') 1692 } 1693 1694 , prev: function (event) { 1695 var active = this.$menu.find('.active').removeClass('active') 1696 , prev = active.prev() 1697 1698 if (!prev.length) { 1699 prev = this.$menu.find('li').last() 1700 } 1701 1702 prev.addClass('active') 1703 } 1704 1705 , listen: function () { 1706 this.$element 1707 .on('blur', $.proxy(this.blur, this)) 1708 .on('keypress', $.proxy(this.keypress, this)) 1709 .on('keyup', $.proxy(this.keyup, this)) 1710 1711 if ($.browser.webkit || $.browser.msie) { 1712 this.$element.on('keydown', $.proxy(this.keypress, this)) 1713 } 1714 1715 this.$menu 1716 .on('click', $.proxy(this.click, this)) 1717 .on('mouseenter', 'li', $.proxy(this.mouseenter, this)) 1718 } 1719 1720 , keyup: function (e) { 1721 switch(e.keyCode) { 1722 case 40: // down arrow 1723 case 38: // up arrow 1724 break 1725 1726 case 9: // tab 1727 case 13: // enter 1728 if (!this.shown) return 1729 this.select() 1730 break 1731 1732 case 27: // escape 1733 if (!this.shown) return 1734 this.hide() 1735 break 1736 1737 default: 1738 this.lookup() 1739 } 1740 1741 e.stopPropagation() 1742 e.preventDefault() 1743 } 1744 1745 , keypress: function (e) { 1746 if (!this.shown) return 1747 1748 switch(e.keyCode) { 1749 case 9: // tab 1750 case 13: // enter 1751 case 27: // escape 1752 e.preventDefault() 1753 break 1754 1755 case 38: // up arrow 1756 if (e.type != 'keydown') break 1757 e.preventDefault() 1758 this.prev() 1759 break 1760 1761 case 40: // down arrow 1762 if (e.type != 'keydown') break 1763 e.preventDefault() 1764 this.next() 1765 break 1766 } 1767 1768 e.stopPropagation() 1769 } 1770 1771 , blur: function (e) { 1772 var that = this 1773 setTimeout(function () { that.hide() }, 150) 1774 } 1775 1776 , click: function (e) { 1777 e.stopPropagation() 1778 e.preventDefault() 1779 this.select() 1780 } 1781 1782 , mouseenter: function (e) { 1783 this.$menu.find('.active').removeClass('active') 1784 $(e.currentTarget).addClass('active') 1785 } 1786 1787 } 1788 1789 1790 /* TYPEAHEAD PLUGIN DEFINITION 1791 * =========================== */ 1792 1793 $.fn.typeahead = function (option) { 1794 return this.each(function () { 1795 var $this = $(this) 1796 , data = $this.data('typeahead') 1797 , options = typeof option == 'object' && option 1798 if (!data) $this.data('typeahead', (data = new Typeahead(this, options))) 1799 if (typeof option == 'string') data[option]() 1800 }) 1801 } 1802 1803 $.fn.typeahead.defaults = { 1804 source: [] 1805 , items: 8 1806 , menu: '<ul class="typeahead dropdown-menu"></ul>' 1807 , item: '<li><a href="#"></a></li>' 1808 } 1809 1810 $.fn.typeahead.Constructor = Typeahead 1811 1812 1813 /* TYPEAHEAD DATA-API 1814 * ================== */ 1815 1816 $(function () { 1817 $('body').on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) { 1818 var $this = $(this) 1819 if ($this.data('typeahead')) return 1820 e.preventDefault() 1821 $this.typeahead($this.data()) 1822 }) 1823 }) 1824 1825 }(window.jQuery);