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