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