source: src/main/resources/static/js/bootstrap.js@ 5577566

Last change on this file since 5577566 was 5577566, checked in by NikolaCenevski <cenevskinikola@…>, 3 years ago

prototip part 2

  • Property mode set to 100644
File size: 147.3 KB
Line 
1/*!
2 * Bootstrap v5.0.0-beta3 (https://getbootstrap.com/)
3 * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5 */
6(function (global, factory) {
7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) :
8 typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) :
9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory(global.Popper));
10}(this, (function (Popper) { 'use strict';
11
12 function _interopNamespace(e) {
13 if (e && e.__esModule) return e;
14 var n = Object.create(null);
15 if (e) {
16 Object.keys(e).forEach(function (k) {
17 if (k !== 'default') {
18 var d = Object.getOwnPropertyDescriptor(e, k);
19 Object.defineProperty(n, k, d.get ? d : {
20 enumerable: true,
21 get: function () {
22 return e[k];
23 }
24 });
25 }
26 });
27 }
28 n['default'] = e;
29 return Object.freeze(n);
30 }
31
32 var Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
33
34 /**
35 * --------------------------------------------------------------------------
36 * Bootstrap (v5.0.0-beta3): util/index.js
37 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
38 * --------------------------------------------------------------------------
39 */
40 const MAX_UID = 1000000;
41 const MILLISECONDS_MULTIPLIER = 1000;
42 const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
43
44 const toType = obj => {
45 if (obj === null || obj === undefined) {
46 return `${obj}`;
47 }
48
49 return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
50 };
51 /**
52 * --------------------------------------------------------------------------
53 * Public Util Api
54 * --------------------------------------------------------------------------
55 */
56
57
58 const getUID = prefix => {
59 do {
60 prefix += Math.floor(Math.random() * MAX_UID);
61 } while (document.getElementById(prefix));
62
63 return prefix;
64 };
65
66 const getSelector = element => {
67 let selector = element.getAttribute('data-bs-target');
68
69 if (!selector || selector === '#') {
70 let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
71 // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
72 // `document.querySelector` will rightfully complain it is invalid.
73 // See https://github.com/twbs/bootstrap/issues/32273
74
75 if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
76 return null;
77 } // Just in case some CMS puts out a full URL with the anchor appended
78
79
80 if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
81 hrefAttr = '#' + hrefAttr.split('#')[1];
82 }
83
84 selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
85 }
86
87 return selector;
88 };
89
90 const getSelectorFromElement = element => {
91 const selector = getSelector(element);
92
93 if (selector) {
94 return document.querySelector(selector) ? selector : null;
95 }
96
97 return null;
98 };
99
100 const getElementFromSelector = element => {
101 const selector = getSelector(element);
102 return selector ? document.querySelector(selector) : null;
103 };
104
105 const getTransitionDurationFromElement = element => {
106 if (!element) {
107 return 0;
108 } // Get transition-duration of the element
109
110
111 let {
112 transitionDuration,
113 transitionDelay
114 } = window.getComputedStyle(element);
115 const floatTransitionDuration = Number.parseFloat(transitionDuration);
116 const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
117
118 if (!floatTransitionDuration && !floatTransitionDelay) {
119 return 0;
120 } // If multiple durations are defined, take the first
121
122
123 transitionDuration = transitionDuration.split(',')[0];
124 transitionDelay = transitionDelay.split(',')[0];
125 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
126 };
127
128 const triggerTransitionEnd = element => {
129 element.dispatchEvent(new Event(TRANSITION_END));
130 };
131
132 const isElement = obj => (obj[0] || obj).nodeType;
133
134 const emulateTransitionEnd = (element, duration) => {
135 let called = false;
136 const durationPadding = 5;
137 const emulatedDuration = duration + durationPadding;
138
139 function listener() {
140 called = true;
141 element.removeEventListener(TRANSITION_END, listener);
142 }
143
144 element.addEventListener(TRANSITION_END, listener);
145 setTimeout(() => {
146 if (!called) {
147 triggerTransitionEnd(element);
148 }
149 }, emulatedDuration);
150 };
151
152 const typeCheckConfig = (componentName, config, configTypes) => {
153 Object.keys(configTypes).forEach(property => {
154 const expectedTypes = configTypes[property];
155 const value = config[property];
156 const valueType = value && isElement(value) ? 'element' : toType(value);
157
158 if (!new RegExp(expectedTypes).test(valueType)) {
159 throw new TypeError(`${componentName.toUpperCase()}: ` + `Option "${property}" provided type "${valueType}" ` + `but expected type "${expectedTypes}".`);
160 }
161 });
162 };
163
164 const isVisible = element => {
165 if (!element) {
166 return false;
167 }
168
169 if (element.style && element.parentNode && element.parentNode.style) {
170 const elementStyle = getComputedStyle(element);
171 const parentNodeStyle = getComputedStyle(element.parentNode);
172 return elementStyle.display !== 'none' && parentNodeStyle.display !== 'none' && elementStyle.visibility !== 'hidden';
173 }
174
175 return false;
176 };
177
178 const isDisabled = element => {
179 if (!element || element.nodeType !== Node.ELEMENT_NODE) {
180 return true;
181 }
182
183 if (element.classList.contains('disabled')) {
184 return true;
185 }
186
187 if (typeof element.disabled !== 'undefined') {
188 return element.disabled;
189 }
190
191 return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
192 };
193
194 const findShadowRoot = element => {
195 if (!document.documentElement.attachShadow) {
196 return null;
197 } // Can find the shadow root otherwise it'll return the document
198
199
200 if (typeof element.getRootNode === 'function') {
201 const root = element.getRootNode();
202 return root instanceof ShadowRoot ? root : null;
203 }
204
205 if (element instanceof ShadowRoot) {
206 return element;
207 } // when we don't find a shadow root
208
209
210 if (!element.parentNode) {
211 return null;
212 }
213
214 return findShadowRoot(element.parentNode);
215 };
216
217 const noop = () => function () {};
218
219 const reflow = element => element.offsetHeight;
220
221 const getjQuery = () => {
222 const {
223 jQuery
224 } = window;
225
226 if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
227 return jQuery;
228 }
229
230 return null;
231 };
232
233 const onDOMContentLoaded = callback => {
234 if (document.readyState === 'loading') {
235 document.addEventListener('DOMContentLoaded', callback);
236 } else {
237 callback();
238 }
239 };
240
241 const isRTL = () => document.documentElement.dir === 'rtl';
242
243 const defineJQueryPlugin = (name, plugin) => {
244 onDOMContentLoaded(() => {
245 const $ = getjQuery();
246 /* istanbul ignore if */
247
248 if ($) {
249 const JQUERY_NO_CONFLICT = $.fn[name];
250 $.fn[name] = plugin.jQueryInterface;
251 $.fn[name].Constructor = plugin;
252
253 $.fn[name].noConflict = () => {
254 $.fn[name] = JQUERY_NO_CONFLICT;
255 return plugin.jQueryInterface;
256 };
257 }
258 });
259 };
260
261 /**
262 * --------------------------------------------------------------------------
263 * Bootstrap (v5.0.0-beta3): dom/data.js
264 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
265 * --------------------------------------------------------------------------
266 */
267
268 /**
269 * ------------------------------------------------------------------------
270 * Constants
271 * ------------------------------------------------------------------------
272 */
273 const elementMap = new Map();
274 var Data = {
275 set(element, key, instance) {
276 if (!elementMap.has(element)) {
277 elementMap.set(element, new Map());
278 }
279
280 const instanceMap = elementMap.get(element); // make it clear we only want one instance per element
281 // can be removed later when multiple key/instances are fine to be used
282
283 if (!instanceMap.has(key) && instanceMap.size !== 0) {
284 // eslint-disable-next-line no-console
285 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);
286 return;
287 }
288
289 instanceMap.set(key, instance);
290 },
291
292 get(element, key) {
293 if (elementMap.has(element)) {
294 return elementMap.get(element).get(key) || null;
295 }
296
297 return null;
298 },
299
300 remove(element, key) {
301 if (!elementMap.has(element)) {
302 return;
303 }
304
305 const instanceMap = elementMap.get(element);
306 instanceMap.delete(key); // free up element references if there are no instances left for an element
307
308 if (instanceMap.size === 0) {
309 elementMap.delete(element);
310 }
311 }
312
313 };
314
315 /**
316 * --------------------------------------------------------------------------
317 * Bootstrap (v5.0.0-beta3): dom/event-handler.js
318 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
319 * --------------------------------------------------------------------------
320 */
321 /**
322 * ------------------------------------------------------------------------
323 * Constants
324 * ------------------------------------------------------------------------
325 */
326
327 const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
328 const stripNameRegex = /\..*/;
329 const stripUidRegex = /::\d+$/;
330 const eventRegistry = {}; // Events storage
331
332 let uidEvent = 1;
333 const customEvents = {
334 mouseenter: 'mouseover',
335 mouseleave: 'mouseout'
336 };
337 const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']);
338 /**
339 * ------------------------------------------------------------------------
340 * Private methods
341 * ------------------------------------------------------------------------
342 */
343
344 function getUidEvent(element, uid) {
345 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;
346 }
347
348 function getEvent(element) {
349 const uid = getUidEvent(element);
350 element.uidEvent = uid;
351 eventRegistry[uid] = eventRegistry[uid] || {};
352 return eventRegistry[uid];
353 }
354
355 function bootstrapHandler(element, fn) {
356 return function handler(event) {
357 event.delegateTarget = element;
358
359 if (handler.oneOff) {
360 EventHandler.off(element, event.type, fn);
361 }
362
363 return fn.apply(element, [event]);
364 };
365 }
366
367 function bootstrapDelegationHandler(element, selector, fn) {
368 return function handler(event) {
369 const domElements = element.querySelectorAll(selector);
370
371 for (let {
372 target
373 } = event; target && target !== this; target = target.parentNode) {
374 for (let i = domElements.length; i--;) {
375 if (domElements[i] === target) {
376 event.delegateTarget = target;
377
378 if (handler.oneOff) {
379 // eslint-disable-next-line unicorn/consistent-destructuring
380 EventHandler.off(element, event.type, fn);
381 }
382
383 return fn.apply(target, [event]);
384 }
385 }
386 } // To please ESLint
387
388
389 return null;
390 };
391 }
392
393 function findHandler(events, handler, delegationSelector = null) {
394 const uidEventList = Object.keys(events);
395
396 for (let i = 0, len = uidEventList.length; i < len; i++) {
397 const event = events[uidEventList[i]];
398
399 if (event.originalHandler === handler && event.delegationSelector === delegationSelector) {
400 return event;
401 }
402 }
403
404 return null;
405 }
406
407 function normalizeParams(originalTypeEvent, handler, delegationFn) {
408 const delegation = typeof handler === 'string';
409 const originalHandler = delegation ? delegationFn : handler; // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
410
411 let typeEvent = originalTypeEvent.replace(stripNameRegex, '');
412 const custom = customEvents[typeEvent];
413
414 if (custom) {
415 typeEvent = custom;
416 }
417
418 const isNative = nativeEvents.has(typeEvent);
419
420 if (!isNative) {
421 typeEvent = originalTypeEvent;
422 }
423
424 return [delegation, originalHandler, typeEvent];
425 }
426
427 function addHandler(element, originalTypeEvent, handler, delegationFn, oneOff) {
428 if (typeof originalTypeEvent !== 'string' || !element) {
429 return;
430 }
431
432 if (!handler) {
433 handler = delegationFn;
434 delegationFn = null;
435 }
436
437 const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);
438 const events = getEvent(element);
439 const handlers = events[typeEvent] || (events[typeEvent] = {});
440 const previousFn = findHandler(handlers, originalHandler, delegation ? handler : null);
441
442 if (previousFn) {
443 previousFn.oneOff = previousFn.oneOff && oneOff;
444 return;
445 }
446
447 const uid = getUidEvent(originalHandler, originalTypeEvent.replace(namespaceRegex, ''));
448 const fn = delegation ? bootstrapDelegationHandler(element, handler, delegationFn) : bootstrapHandler(element, handler);
449 fn.delegationSelector = delegation ? handler : null;
450 fn.originalHandler = originalHandler;
451 fn.oneOff = oneOff;
452 fn.uidEvent = uid;
453 handlers[uid] = fn;
454 element.addEventListener(typeEvent, fn, delegation);
455 }
456
457 function removeHandler(element, events, typeEvent, handler, delegationSelector) {
458 const fn = findHandler(events[typeEvent], handler, delegationSelector);
459
460 if (!fn) {
461 return;
462 }
463
464 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
465 delete events[typeEvent][fn.uidEvent];
466 }
467
468 function removeNamespacedHandlers(element, events, typeEvent, namespace) {
469 const storeElementEvent = events[typeEvent] || {};
470 Object.keys(storeElementEvent).forEach(handlerKey => {
471 if (handlerKey.includes(namespace)) {
472 const event = storeElementEvent[handlerKey];
473 removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);
474 }
475 });
476 }
477
478 const EventHandler = {
479 on(element, event, handler, delegationFn) {
480 addHandler(element, event, handler, delegationFn, false);
481 },
482
483 one(element, event, handler, delegationFn) {
484 addHandler(element, event, handler, delegationFn, true);
485 },
486
487 off(element, originalTypeEvent, handler, delegationFn) {
488 if (typeof originalTypeEvent !== 'string' || !element) {
489 return;
490 }
491
492 const [delegation, originalHandler, typeEvent] = normalizeParams(originalTypeEvent, handler, delegationFn);
493 const inNamespace = typeEvent !== originalTypeEvent;
494 const events = getEvent(element);
495 const isNamespace = originalTypeEvent.startsWith('.');
496
497 if (typeof originalHandler !== 'undefined') {
498 // Simplest case: handler is passed, remove that listener ONLY.
499 if (!events || !events[typeEvent]) {
500 return;
501 }
502
503 removeHandler(element, events, typeEvent, originalHandler, delegation ? handler : null);
504 return;
505 }
506
507 if (isNamespace) {
508 Object.keys(events).forEach(elementEvent => {
509 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
510 });
511 }
512
513 const storeElementEvent = events[typeEvent] || {};
514 Object.keys(storeElementEvent).forEach(keyHandlers => {
515 const handlerKey = keyHandlers.replace(stripUidRegex, '');
516
517 if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
518 const event = storeElementEvent[keyHandlers];
519 removeHandler(element, events, typeEvent, event.originalHandler, event.delegationSelector);
520 }
521 });
522 },
523
524 trigger(element, event, args) {
525 if (typeof event !== 'string' || !element) {
526 return null;
527 }
528
529 const $ = getjQuery();
530 const typeEvent = event.replace(stripNameRegex, '');
531 const inNamespace = event !== typeEvent;
532 const isNative = nativeEvents.has(typeEvent);
533 let jQueryEvent;
534 let bubbles = true;
535 let nativeDispatch = true;
536 let defaultPrevented = false;
537 let evt = null;
538
539 if (inNamespace && $) {
540 jQueryEvent = $.Event(event, args);
541 $(element).trigger(jQueryEvent);
542 bubbles = !jQueryEvent.isPropagationStopped();
543 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
544 defaultPrevented = jQueryEvent.isDefaultPrevented();
545 }
546
547 if (isNative) {
548 evt = document.createEvent('HTMLEvents');
549 evt.initEvent(typeEvent, bubbles, true);
550 } else {
551 evt = new CustomEvent(event, {
552 bubbles,
553 cancelable: true
554 });
555 } // merge custom information in our event
556
557
558 if (typeof args !== 'undefined') {
559 Object.keys(args).forEach(key => {
560 Object.defineProperty(evt, key, {
561 get() {
562 return args[key];
563 }
564
565 });
566 });
567 }
568
569 if (defaultPrevented) {
570 evt.preventDefault();
571 }
572
573 if (nativeDispatch) {
574 element.dispatchEvent(evt);
575 }
576
577 if (evt.defaultPrevented && typeof jQueryEvent !== 'undefined') {
578 jQueryEvent.preventDefault();
579 }
580
581 return evt;
582 }
583
584 };
585
586 /**
587 * --------------------------------------------------------------------------
588 * Bootstrap (v5.0.0-beta3): base-component.js
589 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
590 * --------------------------------------------------------------------------
591 */
592 /**
593 * ------------------------------------------------------------------------
594 * Constants
595 * ------------------------------------------------------------------------
596 */
597
598 const VERSION = '5.0.0-beta3';
599
600 class BaseComponent {
601 constructor(element) {
602 element = typeof element === 'string' ? document.querySelector(element) : element;
603
604 if (!element) {
605 return;
606 }
607
608 this._element = element;
609 Data.set(this._element, this.constructor.DATA_KEY, this);
610 }
611
612 dispose() {
613 Data.remove(this._element, this.constructor.DATA_KEY);
614 this._element = null;
615 }
616 /** Static */
617
618
619 static getInstance(element) {
620 return Data.get(element, this.DATA_KEY);
621 }
622
623 static get VERSION() {
624 return VERSION;
625 }
626
627 }
628
629 /**
630 * --------------------------------------------------------------------------
631 * Bootstrap (v5.0.0-beta3): alert.js
632 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
633 * --------------------------------------------------------------------------
634 */
635 /**
636 * ------------------------------------------------------------------------
637 * Constants
638 * ------------------------------------------------------------------------
639 */
640
641 const NAME$b = 'alert';
642 const DATA_KEY$b = 'bs.alert';
643 const EVENT_KEY$b = `.${DATA_KEY$b}`;
644 const DATA_API_KEY$8 = '.data-api';
645 const SELECTOR_DISMISS = '[data-bs-dismiss="alert"]';
646 const EVENT_CLOSE = `close${EVENT_KEY$b}`;
647 const EVENT_CLOSED = `closed${EVENT_KEY$b}`;
648 const EVENT_CLICK_DATA_API$7 = `click${EVENT_KEY$b}${DATA_API_KEY$8}`;
649 const CLASS_NAME_ALERT = 'alert';
650 const CLASS_NAME_FADE$5 = 'fade';
651 const CLASS_NAME_SHOW$8 = 'show';
652 /**
653 * ------------------------------------------------------------------------
654 * Class Definition
655 * ------------------------------------------------------------------------
656 */
657
658 class Alert extends BaseComponent {
659 // Getters
660 static get DATA_KEY() {
661 return DATA_KEY$b;
662 } // Public
663
664
665 close(element) {
666 const rootElement = element ? this._getRootElement(element) : this._element;
667
668 const customEvent = this._triggerCloseEvent(rootElement);
669
670 if (customEvent === null || customEvent.defaultPrevented) {
671 return;
672 }
673
674 this._removeElement(rootElement);
675 } // Private
676
677
678 _getRootElement(element) {
679 return getElementFromSelector(element) || element.closest(`.${CLASS_NAME_ALERT}`);
680 }
681
682 _triggerCloseEvent(element) {
683 return EventHandler.trigger(element, EVENT_CLOSE);
684 }
685
686 _removeElement(element) {
687 element.classList.remove(CLASS_NAME_SHOW$8);
688
689 if (!element.classList.contains(CLASS_NAME_FADE$5)) {
690 this._destroyElement(element);
691
692 return;
693 }
694
695 const transitionDuration = getTransitionDurationFromElement(element);
696 EventHandler.one(element, 'transitionend', () => this._destroyElement(element));
697 emulateTransitionEnd(element, transitionDuration);
698 }
699
700 _destroyElement(element) {
701 if (element.parentNode) {
702 element.parentNode.removeChild(element);
703 }
704
705 EventHandler.trigger(element, EVENT_CLOSED);
706 } // Static
707
708
709 static jQueryInterface(config) {
710 return this.each(function () {
711 let data = Data.get(this, DATA_KEY$b);
712
713 if (!data) {
714 data = new Alert(this);
715 }
716
717 if (config === 'close') {
718 data[config](this);
719 }
720 });
721 }
722
723 static handleDismiss(alertInstance) {
724 return function (event) {
725 if (event) {
726 event.preventDefault();
727 }
728
729 alertInstance.close(this);
730 };
731 }
732
733 }
734 /**
735 * ------------------------------------------------------------------------
736 * Data Api implementation
737 * ------------------------------------------------------------------------
738 */
739
740
741 EventHandler.on(document, EVENT_CLICK_DATA_API$7, SELECTOR_DISMISS, Alert.handleDismiss(new Alert()));
742 /**
743 * ------------------------------------------------------------------------
744 * jQuery
745 * ------------------------------------------------------------------------
746 * add .Alert to jQuery only if jQuery is present
747 */
748
749 defineJQueryPlugin(NAME$b, Alert);
750
751 /**
752 * --------------------------------------------------------------------------
753 * Bootstrap (v5.0.0-beta3): button.js
754 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
755 * --------------------------------------------------------------------------
756 */
757 /**
758 * ------------------------------------------------------------------------
759 * Constants
760 * ------------------------------------------------------------------------
761 */
762
763 const NAME$a = 'button';
764 const DATA_KEY$a = 'bs.button';
765 const EVENT_KEY$a = `.${DATA_KEY$a}`;
766 const DATA_API_KEY$7 = '.data-api';
767 const CLASS_NAME_ACTIVE$3 = 'active';
768 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]';
769 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$7}`;
770 /**
771 * ------------------------------------------------------------------------
772 * Class Definition
773 * ------------------------------------------------------------------------
774 */
775
776 class Button extends BaseComponent {
777 // Getters
778 static get DATA_KEY() {
779 return DATA_KEY$a;
780 } // Public
781
782
783 toggle() {
784 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
785 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
786 } // Static
787
788
789 static jQueryInterface(config) {
790 return this.each(function () {
791 let data = Data.get(this, DATA_KEY$a);
792
793 if (!data) {
794 data = new Button(this);
795 }
796
797 if (config === 'toggle') {
798 data[config]();
799 }
800 });
801 }
802
803 }
804 /**
805 * ------------------------------------------------------------------------
806 * Data Api implementation
807 * ------------------------------------------------------------------------
808 */
809
810
811 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {
812 event.preventDefault();
813 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);
814 let data = Data.get(button, DATA_KEY$a);
815
816 if (!data) {
817 data = new Button(button);
818 }
819
820 data.toggle();
821 });
822 /**
823 * ------------------------------------------------------------------------
824 * jQuery
825 * ------------------------------------------------------------------------
826 * add .Button to jQuery only if jQuery is present
827 */
828
829 defineJQueryPlugin(NAME$a, Button);
830
831 /**
832 * --------------------------------------------------------------------------
833 * Bootstrap (v5.0.0-beta3): dom/manipulator.js
834 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
835 * --------------------------------------------------------------------------
836 */
837 function normalizeData(val) {
838 if (val === 'true') {
839 return true;
840 }
841
842 if (val === 'false') {
843 return false;
844 }
845
846 if (val === Number(val).toString()) {
847 return Number(val);
848 }
849
850 if (val === '' || val === 'null') {
851 return null;
852 }
853
854 return val;
855 }
856
857 function normalizeDataKey(key) {
858 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);
859 }
860
861 const Manipulator = {
862 setDataAttribute(element, key, value) {
863 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
864 },
865
866 removeDataAttribute(element, key) {
867 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
868 },
869
870 getDataAttributes(element) {
871 if (!element) {
872 return {};
873 }
874
875 const attributes = {};
876 Object.keys(element.dataset).filter(key => key.startsWith('bs')).forEach(key => {
877 let pureKey = key.replace(/^bs/, '');
878 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
879 attributes[pureKey] = normalizeData(element.dataset[key]);
880 });
881 return attributes;
882 },
883
884 getDataAttribute(element, key) {
885 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
886 },
887
888 offset(element) {
889 const rect = element.getBoundingClientRect();
890 return {
891 top: rect.top + document.body.scrollTop,
892 left: rect.left + document.body.scrollLeft
893 };
894 },
895
896 position(element) {
897 return {
898 top: element.offsetTop,
899 left: element.offsetLeft
900 };
901 }
902
903 };
904
905 /**
906 * --------------------------------------------------------------------------
907 * Bootstrap (v5.0.0-beta3): dom/selector-engine.js
908 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
909 * --------------------------------------------------------------------------
910 */
911
912 /**
913 * ------------------------------------------------------------------------
914 * Constants
915 * ------------------------------------------------------------------------
916 */
917 const NODE_TEXT = 3;
918 const SelectorEngine = {
919 find(selector, element = document.documentElement) {
920 return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
921 },
922
923 findOne(selector, element = document.documentElement) {
924 return Element.prototype.querySelector.call(element, selector);
925 },
926
927 children(element, selector) {
928 return [].concat(...element.children).filter(child => child.matches(selector));
929 },
930
931 parents(element, selector) {
932 const parents = [];
933 let ancestor = element.parentNode;
934
935 while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== NODE_TEXT) {
936 if (ancestor.matches(selector)) {
937 parents.push(ancestor);
938 }
939
940 ancestor = ancestor.parentNode;
941 }
942
943 return parents;
944 },
945
946 prev(element, selector) {
947 let previous = element.previousElementSibling;
948
949 while (previous) {
950 if (previous.matches(selector)) {
951 return [previous];
952 }
953
954 previous = previous.previousElementSibling;
955 }
956
957 return [];
958 },
959
960 next(element, selector) {
961 let next = element.nextElementSibling;
962
963 while (next) {
964 if (next.matches(selector)) {
965 return [next];
966 }
967
968 next = next.nextElementSibling;
969 }
970
971 return [];
972 }
973
974 };
975
976 /**
977 * --------------------------------------------------------------------------
978 * Bootstrap (v5.0.0-beta3): carousel.js
979 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
980 * --------------------------------------------------------------------------
981 */
982 /**
983 * ------------------------------------------------------------------------
984 * Constants
985 * ------------------------------------------------------------------------
986 */
987
988 const NAME$9 = 'carousel';
989 const DATA_KEY$9 = 'bs.carousel';
990 const EVENT_KEY$9 = `.${DATA_KEY$9}`;
991 const DATA_API_KEY$6 = '.data-api';
992 const ARROW_LEFT_KEY = 'ArrowLeft';
993 const ARROW_RIGHT_KEY = 'ArrowRight';
994 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
995
996 const SWIPE_THRESHOLD = 40;
997 const Default$8 = {
998 interval: 5000,
999 keyboard: true,
1000 slide: false,
1001 pause: 'hover',
1002 wrap: true,
1003 touch: true
1004 };
1005 const DefaultType$8 = {
1006 interval: '(number|boolean)',
1007 keyboard: 'boolean',
1008 slide: '(boolean|string)',
1009 pause: '(string|boolean)',
1010 wrap: 'boolean',
1011 touch: 'boolean'
1012 };
1013 const ORDER_NEXT = 'next';
1014 const ORDER_PREV = 'prev';
1015 const DIRECTION_LEFT = 'left';
1016 const DIRECTION_RIGHT = 'right';
1017 const EVENT_SLIDE = `slide${EVENT_KEY$9}`;
1018 const EVENT_SLID = `slid${EVENT_KEY$9}`;
1019 const EVENT_KEYDOWN = `keydown${EVENT_KEY$9}`;
1020 const EVENT_MOUSEENTER = `mouseenter${EVENT_KEY$9}`;
1021 const EVENT_MOUSELEAVE = `mouseleave${EVENT_KEY$9}`;
1022 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;
1023 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;
1024 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;
1025 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;
1026 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;
1027 const EVENT_DRAG_START = `dragstart${EVENT_KEY$9}`;
1028 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$9}${DATA_API_KEY$6}`;
1029 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$9}${DATA_API_KEY$6}`;
1030 const CLASS_NAME_CAROUSEL = 'carousel';
1031 const CLASS_NAME_ACTIVE$2 = 'active';
1032 const CLASS_NAME_SLIDE = 'slide';
1033 const CLASS_NAME_END = 'carousel-item-end';
1034 const CLASS_NAME_START = 'carousel-item-start';
1035 const CLASS_NAME_NEXT = 'carousel-item-next';
1036 const CLASS_NAME_PREV = 'carousel-item-prev';
1037 const CLASS_NAME_POINTER_EVENT = 'pointer-event';
1038 const SELECTOR_ACTIVE$1 = '.active';
1039 const SELECTOR_ACTIVE_ITEM = '.active.carousel-item';
1040 const SELECTOR_ITEM = '.carousel-item';
1041 const SELECTOR_ITEM_IMG = '.carousel-item img';
1042 const SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';
1043 const SELECTOR_INDICATORS = '.carousel-indicators';
1044 const SELECTOR_INDICATOR = '[data-bs-target]';
1045 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
1046 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
1047 const POINTER_TYPE_TOUCH = 'touch';
1048 const POINTER_TYPE_PEN = 'pen';
1049 /**
1050 * ------------------------------------------------------------------------
1051 * Class Definition
1052 * ------------------------------------------------------------------------
1053 */
1054
1055 class Carousel extends BaseComponent {
1056 constructor(element, config) {
1057 super(element);
1058 this._items = null;
1059 this._interval = null;
1060 this._activeElement = null;
1061 this._isPaused = false;
1062 this._isSliding = false;
1063 this.touchTimeout = null;
1064 this.touchStartX = 0;
1065 this.touchDeltaX = 0;
1066 this._config = this._getConfig(config);
1067 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
1068 this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
1069 this._pointerEvent = Boolean(window.PointerEvent);
1070
1071 this._addEventListeners();
1072 } // Getters
1073
1074
1075 static get Default() {
1076 return Default$8;
1077 }
1078
1079 static get DATA_KEY() {
1080 return DATA_KEY$9;
1081 } // Public
1082
1083
1084 next() {
1085 if (!this._isSliding) {
1086 this._slide(ORDER_NEXT);
1087 }
1088 }
1089
1090 nextWhenVisible() {
1091 // Don't call next when the page isn't visible
1092 // or the carousel or its parent isn't visible
1093 if (!document.hidden && isVisible(this._element)) {
1094 this.next();
1095 }
1096 }
1097
1098 prev() {
1099 if (!this._isSliding) {
1100 this._slide(ORDER_PREV);
1101 }
1102 }
1103
1104 pause(event) {
1105 if (!event) {
1106 this._isPaused = true;
1107 }
1108
1109 if (SelectorEngine.findOne(SELECTOR_NEXT_PREV, this._element)) {
1110 triggerTransitionEnd(this._element);
1111 this.cycle(true);
1112 }
1113
1114 clearInterval(this._interval);
1115 this._interval = null;
1116 }
1117
1118 cycle(event) {
1119 if (!event) {
1120 this._isPaused = false;
1121 }
1122
1123 if (this._interval) {
1124 clearInterval(this._interval);
1125 this._interval = null;
1126 }
1127
1128 if (this._config && this._config.interval && !this._isPaused) {
1129 this._updateInterval();
1130
1131 this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
1132 }
1133 }
1134
1135 to(index) {
1136 this._activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
1137
1138 const activeIndex = this._getItemIndex(this._activeElement);
1139
1140 if (index > this._items.length - 1 || index < 0) {
1141 return;
1142 }
1143
1144 if (this._isSliding) {
1145 EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
1146 return;
1147 }
1148
1149 if (activeIndex === index) {
1150 this.pause();
1151 this.cycle();
1152 return;
1153 }
1154
1155 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
1156
1157 this._slide(order, this._items[index]);
1158 }
1159
1160 dispose() {
1161 EventHandler.off(this._element, EVENT_KEY$9);
1162 this._items = null;
1163 this._config = null;
1164 this._interval = null;
1165 this._isPaused = null;
1166 this._isSliding = null;
1167 this._activeElement = null;
1168 this._indicatorsElement = null;
1169 super.dispose();
1170 } // Private
1171
1172
1173 _getConfig(config) {
1174 config = { ...Default$8,
1175 ...config
1176 };
1177 typeCheckConfig(NAME$9, config, DefaultType$8);
1178 return config;
1179 }
1180
1181 _handleSwipe() {
1182 const absDeltax = Math.abs(this.touchDeltaX);
1183
1184 if (absDeltax <= SWIPE_THRESHOLD) {
1185 return;
1186 }
1187
1188 const direction = absDeltax / this.touchDeltaX;
1189 this.touchDeltaX = 0;
1190
1191 if (!direction) {
1192 return;
1193 }
1194
1195 this._slide(direction > 0 ? DIRECTION_RIGHT : DIRECTION_LEFT);
1196 }
1197
1198 _addEventListeners() {
1199 if (this._config.keyboard) {
1200 EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
1201 }
1202
1203 if (this._config.pause === 'hover') {
1204 EventHandler.on(this._element, EVENT_MOUSEENTER, event => this.pause(event));
1205 EventHandler.on(this._element, EVENT_MOUSELEAVE, event => this.cycle(event));
1206 }
1207
1208 if (this._config.touch && this._touchSupported) {
1209 this._addTouchEventListeners();
1210 }
1211 }
1212
1213 _addTouchEventListeners() {
1214 const start = event => {
1215 if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {
1216 this.touchStartX = event.clientX;
1217 } else if (!this._pointerEvent) {
1218 this.touchStartX = event.touches[0].clientX;
1219 }
1220 };
1221
1222 const move = event => {
1223 // ensure swiping with one touch and not pinching
1224 this.touchDeltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this.touchStartX;
1225 };
1226
1227 const end = event => {
1228 if (this._pointerEvent && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH)) {
1229 this.touchDeltaX = event.clientX - this.touchStartX;
1230 }
1231
1232 this._handleSwipe();
1233
1234 if (this._config.pause === 'hover') {
1235 // If it's a touch-enabled device, mouseenter/leave are fired as
1236 // part of the mouse compatibility events on first tap - the carousel
1237 // would stop cycling until user tapped out of it;
1238 // here, we listen for touchend, explicitly pause the carousel
1239 // (as if it's the second time we tap on it, mouseenter compat event
1240 // is NOT fired) and after a timeout (to allow for mouse compatibility
1241 // events to fire) we explicitly restart cycling
1242 this.pause();
1243
1244 if (this.touchTimeout) {
1245 clearTimeout(this.touchTimeout);
1246 }
1247
1248 this.touchTimeout = setTimeout(event => this.cycle(event), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
1249 }
1250 };
1251
1252 SelectorEngine.find(SELECTOR_ITEM_IMG, this._element).forEach(itemImg => {
1253 EventHandler.on(itemImg, EVENT_DRAG_START, e => e.preventDefault());
1254 });
1255
1256 if (this._pointerEvent) {
1257 EventHandler.on(this._element, EVENT_POINTERDOWN, event => start(event));
1258 EventHandler.on(this._element, EVENT_POINTERUP, event => end(event));
1259
1260 this._element.classList.add(CLASS_NAME_POINTER_EVENT);
1261 } else {
1262 EventHandler.on(this._element, EVENT_TOUCHSTART, event => start(event));
1263 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => move(event));
1264 EventHandler.on(this._element, EVENT_TOUCHEND, event => end(event));
1265 }
1266 }
1267
1268 _keydown(event) {
1269 if (/input|textarea/i.test(event.target.tagName)) {
1270 return;
1271 }
1272
1273 if (event.key === ARROW_LEFT_KEY) {
1274 event.preventDefault();
1275
1276 this._slide(DIRECTION_LEFT);
1277 } else if (event.key === ARROW_RIGHT_KEY) {
1278 event.preventDefault();
1279
1280 this._slide(DIRECTION_RIGHT);
1281 }
1282 }
1283
1284 _getItemIndex(element) {
1285 this._items = element && element.parentNode ? SelectorEngine.find(SELECTOR_ITEM, element.parentNode) : [];
1286 return this._items.indexOf(element);
1287 }
1288
1289 _getItemByOrder(order, activeElement) {
1290 const isNext = order === ORDER_NEXT;
1291 const isPrev = order === ORDER_PREV;
1292
1293 const activeIndex = this._getItemIndex(activeElement);
1294
1295 const lastItemIndex = this._items.length - 1;
1296 const isGoingToWrap = isPrev && activeIndex === 0 || isNext && activeIndex === lastItemIndex;
1297
1298 if (isGoingToWrap && !this._config.wrap) {
1299 return activeElement;
1300 }
1301
1302 const delta = isPrev ? -1 : 1;
1303 const itemIndex = (activeIndex + delta) % this._items.length;
1304 return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
1305 }
1306
1307 _triggerSlideEvent(relatedTarget, eventDirectionName) {
1308 const targetIndex = this._getItemIndex(relatedTarget);
1309
1310 const fromIndex = this._getItemIndex(SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element));
1311
1312 return EventHandler.trigger(this._element, EVENT_SLIDE, {
1313 relatedTarget,
1314 direction: eventDirectionName,
1315 from: fromIndex,
1316 to: targetIndex
1317 });
1318 }
1319
1320 _setActiveIndicatorElement(element) {
1321 if (this._indicatorsElement) {
1322 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE$1, this._indicatorsElement);
1323 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);
1324 activeIndicator.removeAttribute('aria-current');
1325 const indicators = SelectorEngine.find(SELECTOR_INDICATOR, this._indicatorsElement);
1326
1327 for (let i = 0; i < indicators.length; i++) {
1328 if (Number.parseInt(indicators[i].getAttribute('data-bs-slide-to'), 10) === this._getItemIndex(element)) {
1329 indicators[i].classList.add(CLASS_NAME_ACTIVE$2);
1330 indicators[i].setAttribute('aria-current', 'true');
1331 break;
1332 }
1333 }
1334 }
1335 }
1336
1337 _updateInterval() {
1338 const element = this._activeElement || SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
1339
1340 if (!element) {
1341 return;
1342 }
1343
1344 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
1345
1346 if (elementInterval) {
1347 this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
1348 this._config.interval = elementInterval;
1349 } else {
1350 this._config.interval = this._config.defaultInterval || this._config.interval;
1351 }
1352 }
1353
1354 _slide(directionOrOrder, element) {
1355 const order = this._directionToOrder(directionOrOrder);
1356
1357 const activeElement = SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
1358
1359 const activeElementIndex = this._getItemIndex(activeElement);
1360
1361 const nextElement = element || this._getItemByOrder(order, activeElement);
1362
1363 const nextElementIndex = this._getItemIndex(nextElement);
1364
1365 const isCycling = Boolean(this._interval);
1366 const isNext = order === ORDER_NEXT;
1367 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
1368 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
1369
1370 const eventDirectionName = this._orderToDirection(order);
1371
1372 if (nextElement && nextElement.classList.contains(CLASS_NAME_ACTIVE$2)) {
1373 this._isSliding = false;
1374 return;
1375 }
1376
1377 const slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
1378
1379 if (slideEvent.defaultPrevented) {
1380 return;
1381 }
1382
1383 if (!activeElement || !nextElement) {
1384 // Some weirdness is happening, so we bail
1385 return;
1386 }
1387
1388 this._isSliding = true;
1389
1390 if (isCycling) {
1391 this.pause();
1392 }
1393
1394 this._setActiveIndicatorElement(nextElement);
1395
1396 this._activeElement = nextElement;
1397
1398 if (this._element.classList.contains(CLASS_NAME_SLIDE)) {
1399 nextElement.classList.add(orderClassName);
1400 reflow(nextElement);
1401 activeElement.classList.add(directionalClassName);
1402 nextElement.classList.add(directionalClassName);
1403 const transitionDuration = getTransitionDurationFromElement(activeElement);
1404 EventHandler.one(activeElement, 'transitionend', () => {
1405 nextElement.classList.remove(directionalClassName, orderClassName);
1406 nextElement.classList.add(CLASS_NAME_ACTIVE$2);
1407 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);
1408 this._isSliding = false;
1409 setTimeout(() => {
1410 EventHandler.trigger(this._element, EVENT_SLID, {
1411 relatedTarget: nextElement,
1412 direction: eventDirectionName,
1413 from: activeElementIndex,
1414 to: nextElementIndex
1415 });
1416 }, 0);
1417 });
1418 emulateTransitionEnd(activeElement, transitionDuration);
1419 } else {
1420 activeElement.classList.remove(CLASS_NAME_ACTIVE$2);
1421 nextElement.classList.add(CLASS_NAME_ACTIVE$2);
1422 this._isSliding = false;
1423 EventHandler.trigger(this._element, EVENT_SLID, {
1424 relatedTarget: nextElement,
1425 direction: eventDirectionName,
1426 from: activeElementIndex,
1427 to: nextElementIndex
1428 });
1429 }
1430
1431 if (isCycling) {
1432 this.cycle();
1433 }
1434 }
1435
1436 _directionToOrder(direction) {
1437 if (![DIRECTION_RIGHT, DIRECTION_LEFT].includes(direction)) {
1438 return direction;
1439 }
1440
1441 if (isRTL()) {
1442 return direction === DIRECTION_RIGHT ? ORDER_PREV : ORDER_NEXT;
1443 }
1444
1445 return direction === DIRECTION_RIGHT ? ORDER_NEXT : ORDER_PREV;
1446 }
1447
1448 _orderToDirection(order) {
1449 if (![ORDER_NEXT, ORDER_PREV].includes(order)) {
1450 return order;
1451 }
1452
1453 if (isRTL()) {
1454 return order === ORDER_NEXT ? DIRECTION_LEFT : DIRECTION_RIGHT;
1455 }
1456
1457 return order === ORDER_NEXT ? DIRECTION_RIGHT : DIRECTION_LEFT;
1458 } // Static
1459
1460
1461 static carouselInterface(element, config) {
1462 let data = Data.get(element, DATA_KEY$9);
1463 let _config = { ...Default$8,
1464 ...Manipulator.getDataAttributes(element)
1465 };
1466
1467 if (typeof config === 'object') {
1468 _config = { ..._config,
1469 ...config
1470 };
1471 }
1472
1473 const action = typeof config === 'string' ? config : _config.slide;
1474
1475 if (!data) {
1476 data = new Carousel(element, _config);
1477 }
1478
1479 if (typeof config === 'number') {
1480 data.to(config);
1481 } else if (typeof action === 'string') {
1482 if (typeof data[action] === 'undefined') {
1483 throw new TypeError(`No method named "${action}"`);
1484 }
1485
1486 data[action]();
1487 } else if (_config.interval && _config.ride) {
1488 data.pause();
1489 data.cycle();
1490 }
1491 }
1492
1493 static jQueryInterface(config) {
1494 return this.each(function () {
1495 Carousel.carouselInterface(this, config);
1496 });
1497 }
1498
1499 static dataApiClickHandler(event) {
1500 const target = getElementFromSelector(this);
1501
1502 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
1503 return;
1504 }
1505
1506 const config = { ...Manipulator.getDataAttributes(target),
1507 ...Manipulator.getDataAttributes(this)
1508 };
1509 const slideIndex = this.getAttribute('data-bs-slide-to');
1510
1511 if (slideIndex) {
1512 config.interval = false;
1513 }
1514
1515 Carousel.carouselInterface(target, config);
1516
1517 if (slideIndex) {
1518 Data.get(target, DATA_KEY$9).to(slideIndex);
1519 }
1520
1521 event.preventDefault();
1522 }
1523
1524 }
1525 /**
1526 * ------------------------------------------------------------------------
1527 * Data Api implementation
1528 * ------------------------------------------------------------------------
1529 */
1530
1531
1532 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, Carousel.dataApiClickHandler);
1533 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {
1534 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
1535
1536 for (let i = 0, len = carousels.length; i < len; i++) {
1537 Carousel.carouselInterface(carousels[i], Data.get(carousels[i], DATA_KEY$9));
1538 }
1539 });
1540 /**
1541 * ------------------------------------------------------------------------
1542 * jQuery
1543 * ------------------------------------------------------------------------
1544 * add .Carousel to jQuery only if jQuery is present
1545 */
1546
1547 defineJQueryPlugin(NAME$9, Carousel);
1548
1549 /**
1550 * --------------------------------------------------------------------------
1551 * Bootstrap (v5.0.0-beta3): collapse.js
1552 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1553 * --------------------------------------------------------------------------
1554 */
1555 /**
1556 * ------------------------------------------------------------------------
1557 * Constants
1558 * ------------------------------------------------------------------------
1559 */
1560
1561 const NAME$8 = 'collapse';
1562 const DATA_KEY$8 = 'bs.collapse';
1563 const EVENT_KEY$8 = `.${DATA_KEY$8}`;
1564 const DATA_API_KEY$5 = '.data-api';
1565 const Default$7 = {
1566 toggle: true,
1567 parent: ''
1568 };
1569 const DefaultType$7 = {
1570 toggle: 'boolean',
1571 parent: '(string|element)'
1572 };
1573 const EVENT_SHOW$5 = `show${EVENT_KEY$8}`;
1574 const EVENT_SHOWN$5 = `shown${EVENT_KEY$8}`;
1575 const EVENT_HIDE$5 = `hide${EVENT_KEY$8}`;
1576 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$8}`;
1577 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
1578 const CLASS_NAME_SHOW$7 = 'show';
1579 const CLASS_NAME_COLLAPSE = 'collapse';
1580 const CLASS_NAME_COLLAPSING = 'collapsing';
1581 const CLASS_NAME_COLLAPSED = 'collapsed';
1582 const WIDTH = 'width';
1583 const HEIGHT = 'height';
1584 const SELECTOR_ACTIVES = '.show, .collapsing';
1585 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]';
1586 /**
1587 * ------------------------------------------------------------------------
1588 * Class Definition
1589 * ------------------------------------------------------------------------
1590 */
1591
1592 class Collapse extends BaseComponent {
1593 constructor(element, config) {
1594 super(element);
1595 this._isTransitioning = false;
1596 this._config = this._getConfig(config);
1597 this._triggerArray = SelectorEngine.find(`${SELECTOR_DATA_TOGGLE$4}[href="#${this._element.id}"],` + `${SELECTOR_DATA_TOGGLE$4}[data-bs-target="#${this._element.id}"]`);
1598 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);
1599
1600 for (let i = 0, len = toggleList.length; i < len; i++) {
1601 const elem = toggleList[i];
1602 const selector = getSelectorFromElement(elem);
1603 const filterElement = SelectorEngine.find(selector).filter(foundElem => foundElem === this._element);
1604
1605 if (selector !== null && filterElement.length) {
1606 this._selector = selector;
1607
1608 this._triggerArray.push(elem);
1609 }
1610 }
1611
1612 this._parent = this._config.parent ? this._getParent() : null;
1613
1614 if (!this._config.parent) {
1615 this._addAriaAndCollapsedClass(this._element, this._triggerArray);
1616 }
1617
1618 if (this._config.toggle) {
1619 this.toggle();
1620 }
1621 } // Getters
1622
1623
1624 static get Default() {
1625 return Default$7;
1626 }
1627
1628 static get DATA_KEY() {
1629 return DATA_KEY$8;
1630 } // Public
1631
1632
1633 toggle() {
1634 if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
1635 this.hide();
1636 } else {
1637 this.show();
1638 }
1639 }
1640
1641 show() {
1642 if (this._isTransitioning || this._element.classList.contains(CLASS_NAME_SHOW$7)) {
1643 return;
1644 }
1645
1646 let actives;
1647 let activesData;
1648
1649 if (this._parent) {
1650 actives = SelectorEngine.find(SELECTOR_ACTIVES, this._parent).filter(elem => {
1651 if (typeof this._config.parent === 'string') {
1652 return elem.getAttribute('data-bs-parent') === this._config.parent;
1653 }
1654
1655 return elem.classList.contains(CLASS_NAME_COLLAPSE);
1656 });
1657
1658 if (actives.length === 0) {
1659 actives = null;
1660 }
1661 }
1662
1663 const container = SelectorEngine.findOne(this._selector);
1664
1665 if (actives) {
1666 const tempActiveData = actives.find(elem => container !== elem);
1667 activesData = tempActiveData ? Data.get(tempActiveData, DATA_KEY$8) : null;
1668
1669 if (activesData && activesData._isTransitioning) {
1670 return;
1671 }
1672 }
1673
1674 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$5);
1675
1676 if (startEvent.defaultPrevented) {
1677 return;
1678 }
1679
1680 if (actives) {
1681 actives.forEach(elemActive => {
1682 if (container !== elemActive) {
1683 Collapse.collapseInterface(elemActive, 'hide');
1684 }
1685
1686 if (!activesData) {
1687 Data.set(elemActive, DATA_KEY$8, null);
1688 }
1689 });
1690 }
1691
1692 const dimension = this._getDimension();
1693
1694 this._element.classList.remove(CLASS_NAME_COLLAPSE);
1695
1696 this._element.classList.add(CLASS_NAME_COLLAPSING);
1697
1698 this._element.style[dimension] = 0;
1699
1700 if (this._triggerArray.length) {
1701 this._triggerArray.forEach(element => {
1702 element.classList.remove(CLASS_NAME_COLLAPSED);
1703 element.setAttribute('aria-expanded', true);
1704 });
1705 }
1706
1707 this.setTransitioning(true);
1708
1709 const complete = () => {
1710 this._element.classList.remove(CLASS_NAME_COLLAPSING);
1711
1712 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1713
1714 this._element.style[dimension] = '';
1715 this.setTransitioning(false);
1716 EventHandler.trigger(this._element, EVENT_SHOWN$5);
1717 };
1718
1719 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
1720 const scrollSize = `scroll${capitalizedDimension}`;
1721 const transitionDuration = getTransitionDurationFromElement(this._element);
1722 EventHandler.one(this._element, 'transitionend', complete);
1723 emulateTransitionEnd(this._element, transitionDuration);
1724 this._element.style[dimension] = `${this._element[scrollSize]}px`;
1725 }
1726
1727 hide() {
1728 if (this._isTransitioning || !this._element.classList.contains(CLASS_NAME_SHOW$7)) {
1729 return;
1730 }
1731
1732 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$5);
1733
1734 if (startEvent.defaultPrevented) {
1735 return;
1736 }
1737
1738 const dimension = this._getDimension();
1739
1740 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
1741 reflow(this._element);
1742
1743 this._element.classList.add(CLASS_NAME_COLLAPSING);
1744
1745 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1746
1747 const triggerArrayLength = this._triggerArray.length;
1748
1749 if (triggerArrayLength > 0) {
1750 for (let i = 0; i < triggerArrayLength; i++) {
1751 const trigger = this._triggerArray[i];
1752 const elem = getElementFromSelector(trigger);
1753
1754 if (elem && !elem.classList.contains(CLASS_NAME_SHOW$7)) {
1755 trigger.classList.add(CLASS_NAME_COLLAPSED);
1756 trigger.setAttribute('aria-expanded', false);
1757 }
1758 }
1759 }
1760
1761 this.setTransitioning(true);
1762
1763 const complete = () => {
1764 this.setTransitioning(false);
1765
1766 this._element.classList.remove(CLASS_NAME_COLLAPSING);
1767
1768 this._element.classList.add(CLASS_NAME_COLLAPSE);
1769
1770 EventHandler.trigger(this._element, EVENT_HIDDEN$5);
1771 };
1772
1773 this._element.style[dimension] = '';
1774 const transitionDuration = getTransitionDurationFromElement(this._element);
1775 EventHandler.one(this._element, 'transitionend', complete);
1776 emulateTransitionEnd(this._element, transitionDuration);
1777 }
1778
1779 setTransitioning(isTransitioning) {
1780 this._isTransitioning = isTransitioning;
1781 }
1782
1783 dispose() {
1784 super.dispose();
1785 this._config = null;
1786 this._parent = null;
1787 this._triggerArray = null;
1788 this._isTransitioning = null;
1789 } // Private
1790
1791
1792 _getConfig(config) {
1793 config = { ...Default$7,
1794 ...config
1795 };
1796 config.toggle = Boolean(config.toggle); // Coerce string values
1797
1798 typeCheckConfig(NAME$8, config, DefaultType$7);
1799 return config;
1800 }
1801
1802 _getDimension() {
1803 return this._element.classList.contains(WIDTH) ? WIDTH : HEIGHT;
1804 }
1805
1806 _getParent() {
1807 let {
1808 parent
1809 } = this._config;
1810
1811 if (isElement(parent)) {
1812 // it's a jQuery object
1813 if (typeof parent.jquery !== 'undefined' || typeof parent[0] !== 'undefined') {
1814 parent = parent[0];
1815 }
1816 } else {
1817 parent = SelectorEngine.findOne(parent);
1818 }
1819
1820 const selector = `${SELECTOR_DATA_TOGGLE$4}[data-bs-parent="${parent}"]`;
1821 SelectorEngine.find(selector, parent).forEach(element => {
1822 const selected = getElementFromSelector(element);
1823
1824 this._addAriaAndCollapsedClass(selected, [element]);
1825 });
1826 return parent;
1827 }
1828
1829 _addAriaAndCollapsedClass(element, triggerArray) {
1830 if (!element || !triggerArray.length) {
1831 return;
1832 }
1833
1834 const isOpen = element.classList.contains(CLASS_NAME_SHOW$7);
1835 triggerArray.forEach(elem => {
1836 if (isOpen) {
1837 elem.classList.remove(CLASS_NAME_COLLAPSED);
1838 } else {
1839 elem.classList.add(CLASS_NAME_COLLAPSED);
1840 }
1841
1842 elem.setAttribute('aria-expanded', isOpen);
1843 });
1844 } // Static
1845
1846
1847 static collapseInterface(element, config) {
1848 let data = Data.get(element, DATA_KEY$8);
1849 const _config = { ...Default$7,
1850 ...Manipulator.getDataAttributes(element),
1851 ...(typeof config === 'object' && config ? config : {})
1852 };
1853
1854 if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
1855 _config.toggle = false;
1856 }
1857
1858 if (!data) {
1859 data = new Collapse(element, _config);
1860 }
1861
1862 if (typeof config === 'string') {
1863 if (typeof data[config] === 'undefined') {
1864 throw new TypeError(`No method named "${config}"`);
1865 }
1866
1867 data[config]();
1868 }
1869 }
1870
1871 static jQueryInterface(config) {
1872 return this.each(function () {
1873 Collapse.collapseInterface(this, config);
1874 });
1875 }
1876
1877 }
1878 /**
1879 * ------------------------------------------------------------------------
1880 * Data Api implementation
1881 * ------------------------------------------------------------------------
1882 */
1883
1884
1885 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {
1886 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
1887 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {
1888 event.preventDefault();
1889 }
1890
1891 const triggerData = Manipulator.getDataAttributes(this);
1892 const selector = getSelectorFromElement(this);
1893 const selectorElements = SelectorEngine.find(selector);
1894 selectorElements.forEach(element => {
1895 const data = Data.get(element, DATA_KEY$8);
1896 let config;
1897
1898 if (data) {
1899 // update parent attribute
1900 if (data._parent === null && typeof triggerData.parent === 'string') {
1901 data._config.parent = triggerData.parent;
1902 data._parent = data._getParent();
1903 }
1904
1905 config = 'toggle';
1906 } else {
1907 config = triggerData;
1908 }
1909
1910 Collapse.collapseInterface(element, config);
1911 });
1912 });
1913 /**
1914 * ------------------------------------------------------------------------
1915 * jQuery
1916 * ------------------------------------------------------------------------
1917 * add .Collapse to jQuery only if jQuery is present
1918 */
1919
1920 defineJQueryPlugin(NAME$8, Collapse);
1921
1922 /**
1923 * --------------------------------------------------------------------------
1924 * Bootstrap (v5.0.0-beta3): dropdown.js
1925 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1926 * --------------------------------------------------------------------------
1927 */
1928 /**
1929 * ------------------------------------------------------------------------
1930 * Constants
1931 * ------------------------------------------------------------------------
1932 */
1933
1934 const NAME$7 = 'dropdown';
1935 const DATA_KEY$7 = 'bs.dropdown';
1936 const EVENT_KEY$7 = `.${DATA_KEY$7}`;
1937 const DATA_API_KEY$4 = '.data-api';
1938 const ESCAPE_KEY$2 = 'Escape';
1939 const SPACE_KEY = 'Space';
1940 const TAB_KEY = 'Tab';
1941 const ARROW_UP_KEY = 'ArrowUp';
1942 const ARROW_DOWN_KEY = 'ArrowDown';
1943 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
1944
1945 const REGEXP_KEYDOWN = new RegExp(`${ARROW_UP_KEY}|${ARROW_DOWN_KEY}|${ESCAPE_KEY$2}`);
1946 const EVENT_HIDE$4 = `hide${EVENT_KEY$7}`;
1947 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$7}`;
1948 const EVENT_SHOW$4 = `show${EVENT_KEY$7}`;
1949 const EVENT_SHOWN$4 = `shown${EVENT_KEY$7}`;
1950 const EVENT_CLICK = `click${EVENT_KEY$7}`;
1951 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;
1952 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$7}${DATA_API_KEY$4}`;
1953 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$7}${DATA_API_KEY$4}`;
1954 const CLASS_NAME_DISABLED = 'disabled';
1955 const CLASS_NAME_SHOW$6 = 'show';
1956 const CLASS_NAME_DROPUP = 'dropup';
1957 const CLASS_NAME_DROPEND = 'dropend';
1958 const CLASS_NAME_DROPSTART = 'dropstart';
1959 const CLASS_NAME_NAVBAR = 'navbar';
1960 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]';
1961 const SELECTOR_MENU = '.dropdown-menu';
1962 const SELECTOR_NAVBAR_NAV = '.navbar-nav';
1963 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
1964 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
1965 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
1966 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
1967 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
1968 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
1969 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
1970 const Default$6 = {
1971 offset: [0, 2],
1972 boundary: 'clippingParents',
1973 reference: 'toggle',
1974 display: 'dynamic',
1975 popperConfig: null
1976 };
1977 const DefaultType$6 = {
1978 offset: '(array|string|function)',
1979 boundary: '(string|element)',
1980 reference: '(string|element|object)',
1981 display: 'string',
1982 popperConfig: '(null|object|function)'
1983 };
1984 /**
1985 * ------------------------------------------------------------------------
1986 * Class Definition
1987 * ------------------------------------------------------------------------
1988 */
1989
1990 class Dropdown extends BaseComponent {
1991 constructor(element, config) {
1992 super(element);
1993 this._popper = null;
1994 this._config = this._getConfig(config);
1995 this._menu = this._getMenuElement();
1996 this._inNavbar = this._detectNavbar();
1997
1998 this._addEventListeners();
1999 } // Getters
2000
2001
2002 static get Default() {
2003 return Default$6;
2004 }
2005
2006 static get DefaultType() {
2007 return DefaultType$6;
2008 }
2009
2010 static get DATA_KEY() {
2011 return DATA_KEY$7;
2012 } // Public
2013
2014
2015 toggle() {
2016 if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED)) {
2017 return;
2018 }
2019
2020 const isActive = this._element.classList.contains(CLASS_NAME_SHOW$6);
2021
2022 Dropdown.clearMenus();
2023
2024 if (isActive) {
2025 return;
2026 }
2027
2028 this.show();
2029 }
2030
2031 show() {
2032 if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || this._menu.classList.contains(CLASS_NAME_SHOW$6)) {
2033 return;
2034 }
2035
2036 const parent = Dropdown.getParentFromElement(this._element);
2037 const relatedTarget = {
2038 relatedTarget: this._element
2039 };
2040 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, relatedTarget);
2041
2042 if (showEvent.defaultPrevented) {
2043 return;
2044 } // Totally disable Popper for Dropdowns in Navbar
2045
2046
2047 if (this._inNavbar) {
2048 Manipulator.setDataAttribute(this._menu, 'popper', 'none');
2049 } else {
2050 if (typeof Popper__namespace === 'undefined') {
2051 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
2052 }
2053
2054 let referenceElement = this._element;
2055
2056 if (this._config.reference === 'parent') {
2057 referenceElement = parent;
2058 } else if (isElement(this._config.reference)) {
2059 referenceElement = this._config.reference; // Check if it's jQuery element
2060
2061 if (typeof this._config.reference.jquery !== 'undefined') {
2062 referenceElement = this._config.reference[0];
2063 }
2064 } else if (typeof this._config.reference === 'object') {
2065 referenceElement = this._config.reference;
2066 }
2067
2068 const popperConfig = this._getPopperConfig();
2069
2070 const isDisplayStatic = popperConfig.modifiers.find(modifier => modifier.name === 'applyStyles' && modifier.enabled === false);
2071 this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
2072
2073 if (isDisplayStatic) {
2074 Manipulator.setDataAttribute(this._menu, 'popper', 'static');
2075 }
2076 } // If this is a touch-enabled device we add extra
2077 // empty mouseover listeners to the body's immediate children;
2078 // only needed because of broken event delegation on iOS
2079 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
2080
2081
2082 if ('ontouchstart' in document.documentElement && !parent.closest(SELECTOR_NAVBAR_NAV)) {
2083 [].concat(...document.body.children).forEach(elem => EventHandler.on(elem, 'mouseover', null, noop()));
2084 }
2085
2086 this._element.focus();
2087
2088 this._element.setAttribute('aria-expanded', true);
2089
2090 this._menu.classList.toggle(CLASS_NAME_SHOW$6);
2091
2092 this._element.classList.toggle(CLASS_NAME_SHOW$6);
2093
2094 EventHandler.trigger(this._element, EVENT_SHOWN$4, relatedTarget);
2095 }
2096
2097 hide() {
2098 if (this._element.disabled || this._element.classList.contains(CLASS_NAME_DISABLED) || !this._menu.classList.contains(CLASS_NAME_SHOW$6)) {
2099 return;
2100 }
2101
2102 const relatedTarget = {
2103 relatedTarget: this._element
2104 };
2105 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4, relatedTarget);
2106
2107 if (hideEvent.defaultPrevented) {
2108 return;
2109 }
2110
2111 if (this._popper) {
2112 this._popper.destroy();
2113 }
2114
2115 this._menu.classList.toggle(CLASS_NAME_SHOW$6);
2116
2117 this._element.classList.toggle(CLASS_NAME_SHOW$6);
2118
2119 Manipulator.removeDataAttribute(this._menu, 'popper');
2120 EventHandler.trigger(this._element, EVENT_HIDDEN$4, relatedTarget);
2121 }
2122
2123 dispose() {
2124 EventHandler.off(this._element, EVENT_KEY$7);
2125 this._menu = null;
2126
2127 if (this._popper) {
2128 this._popper.destroy();
2129
2130 this._popper = null;
2131 }
2132
2133 super.dispose();
2134 }
2135
2136 update() {
2137 this._inNavbar = this._detectNavbar();
2138
2139 if (this._popper) {
2140 this._popper.update();
2141 }
2142 } // Private
2143
2144
2145 _addEventListeners() {
2146 EventHandler.on(this._element, EVENT_CLICK, event => {
2147 event.preventDefault();
2148 this.toggle();
2149 });
2150 }
2151
2152 _getConfig(config) {
2153 config = { ...this.constructor.Default,
2154 ...Manipulator.getDataAttributes(this._element),
2155 ...config
2156 };
2157 typeCheckConfig(NAME$7, config, this.constructor.DefaultType);
2158
2159 if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
2160 // Popper virtual elements require a getBoundingClientRect method
2161 throw new TypeError(`${NAME$7.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
2162 }
2163
2164 return config;
2165 }
2166
2167 _getMenuElement() {
2168 return SelectorEngine.next(this._element, SELECTOR_MENU)[0];
2169 }
2170
2171 _getPlacement() {
2172 const parentDropdown = this._element.parentNode;
2173
2174 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
2175 return PLACEMENT_RIGHT;
2176 }
2177
2178 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
2179 return PLACEMENT_LEFT;
2180 } // We need to trim the value because custom properties can also include spaces
2181
2182
2183 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
2184
2185 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
2186 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
2187 }
2188
2189 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
2190 }
2191
2192 _detectNavbar() {
2193 return this._element.closest(`.${CLASS_NAME_NAVBAR}`) !== null;
2194 }
2195
2196 _getOffset() {
2197 const {
2198 offset
2199 } = this._config;
2200
2201 if (typeof offset === 'string') {
2202 return offset.split(',').map(val => Number.parseInt(val, 10));
2203 }
2204
2205 if (typeof offset === 'function') {
2206 return popperData => offset(popperData, this._element);
2207 }
2208
2209 return offset;
2210 }
2211
2212 _getPopperConfig() {
2213 const defaultBsPopperConfig = {
2214 placement: this._getPlacement(),
2215 modifiers: [{
2216 name: 'preventOverflow',
2217 options: {
2218 boundary: this._config.boundary
2219 }
2220 }, {
2221 name: 'offset',
2222 options: {
2223 offset: this._getOffset()
2224 }
2225 }]
2226 }; // Disable Popper if we have a static display
2227
2228 if (this._config.display === 'static') {
2229 defaultBsPopperConfig.modifiers = [{
2230 name: 'applyStyles',
2231 enabled: false
2232 }];
2233 }
2234
2235 return { ...defaultBsPopperConfig,
2236 ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
2237 };
2238 } // Static
2239
2240
2241 static dropdownInterface(element, config) {
2242 let data = Data.get(element, DATA_KEY$7);
2243
2244 const _config = typeof config === 'object' ? config : null;
2245
2246 if (!data) {
2247 data = new Dropdown(element, _config);
2248 }
2249
2250 if (typeof config === 'string') {
2251 if (typeof data[config] === 'undefined') {
2252 throw new TypeError(`No method named "${config}"`);
2253 }
2254
2255 data[config]();
2256 }
2257 }
2258
2259 static jQueryInterface(config) {
2260 return this.each(function () {
2261 Dropdown.dropdownInterface(this, config);
2262 });
2263 }
2264
2265 static clearMenus(event) {
2266 if (event) {
2267 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY) {
2268 return;
2269 }
2270
2271 if (/input|select|textarea|form/i.test(event.target.tagName)) {
2272 return;
2273 }
2274 }
2275
2276 const toggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE$3);
2277
2278 for (let i = 0, len = toggles.length; i < len; i++) {
2279 const context = Data.get(toggles[i], DATA_KEY$7);
2280 const relatedTarget = {
2281 relatedTarget: toggles[i]
2282 };
2283
2284 if (event && event.type === 'click') {
2285 relatedTarget.clickEvent = event;
2286 }
2287
2288 if (!context) {
2289 continue;
2290 }
2291
2292 const dropdownMenu = context._menu;
2293
2294 if (!toggles[i].classList.contains(CLASS_NAME_SHOW$6)) {
2295 continue;
2296 }
2297
2298 if (event) {
2299 // Don't close the menu if the clicked element or one of its parents is the dropdown button
2300 if ([context._element].some(element => event.composedPath().includes(element))) {
2301 continue;
2302 } // Tab navigation through the dropdown menu shouldn't close the menu
2303
2304
2305 if (event.type === 'keyup' && event.key === TAB_KEY && dropdownMenu.contains(event.target)) {
2306 continue;
2307 }
2308 }
2309
2310 const hideEvent = EventHandler.trigger(toggles[i], EVENT_HIDE$4, relatedTarget);
2311
2312 if (hideEvent.defaultPrevented) {
2313 continue;
2314 } // If this is a touch-enabled device we remove the extra
2315 // empty mouseover listeners we added for iOS support
2316
2317
2318 if ('ontouchstart' in document.documentElement) {
2319 [].concat(...document.body.children).forEach(elem => EventHandler.off(elem, 'mouseover', null, noop()));
2320 }
2321
2322 toggles[i].setAttribute('aria-expanded', 'false');
2323
2324 if (context._popper) {
2325 context._popper.destroy();
2326 }
2327
2328 dropdownMenu.classList.remove(CLASS_NAME_SHOW$6);
2329 toggles[i].classList.remove(CLASS_NAME_SHOW$6);
2330 Manipulator.removeDataAttribute(dropdownMenu, 'popper');
2331 EventHandler.trigger(toggles[i], EVENT_HIDDEN$4, relatedTarget);
2332 }
2333 }
2334
2335 static getParentFromElement(element) {
2336 return getElementFromSelector(element) || element.parentNode;
2337 }
2338
2339 static dataApiKeydownHandler(event) {
2340 // If not input/textarea:
2341 // - And not a key in REGEXP_KEYDOWN => not a dropdown command
2342 // If input/textarea:
2343 // - If space key => not a dropdown command
2344 // - If key is other than escape
2345 // - If key is not up or down => not a dropdown command
2346 // - If trigger inside the menu => not a dropdown command
2347 if (/input|textarea/i.test(event.target.tagName) ? event.key === SPACE_KEY || event.key !== ESCAPE_KEY$2 && (event.key !== ARROW_DOWN_KEY && event.key !== ARROW_UP_KEY || event.target.closest(SELECTOR_MENU)) : !REGEXP_KEYDOWN.test(event.key)) {
2348 return;
2349 }
2350
2351 event.preventDefault();
2352 event.stopPropagation();
2353
2354 if (this.disabled || this.classList.contains(CLASS_NAME_DISABLED)) {
2355 return;
2356 }
2357
2358 const parent = Dropdown.getParentFromElement(this);
2359 const isActive = this.classList.contains(CLASS_NAME_SHOW$6);
2360
2361 if (event.key === ESCAPE_KEY$2) {
2362 const button = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0];
2363 button.focus();
2364 Dropdown.clearMenus();
2365 return;
2366 }
2367
2368 if (!isActive && (event.key === ARROW_UP_KEY || event.key === ARROW_DOWN_KEY)) {
2369 const button = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0];
2370 button.click();
2371 return;
2372 }
2373
2374 if (!isActive || event.key === SPACE_KEY) {
2375 Dropdown.clearMenus();
2376 return;
2377 }
2378
2379 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, parent).filter(isVisible);
2380
2381 if (!items.length) {
2382 return;
2383 }
2384
2385 let index = items.indexOf(event.target); // Up
2386
2387 if (event.key === ARROW_UP_KEY && index > 0) {
2388 index--;
2389 } // Down
2390
2391
2392 if (event.key === ARROW_DOWN_KEY && index < items.length - 1) {
2393 index++;
2394 } // index is -1 if the first keydown is an ArrowUp
2395
2396
2397 index = index === -1 ? 0 : index;
2398 items[index].focus();
2399 }
2400
2401 }
2402 /**
2403 * ------------------------------------------------------------------------
2404 * Data Api implementation
2405 * ------------------------------------------------------------------------
2406 */
2407
2408
2409 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
2410 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
2411 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);
2412 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
2413 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {
2414 event.preventDefault();
2415 Dropdown.dropdownInterface(this);
2416 });
2417 /**
2418 * ------------------------------------------------------------------------
2419 * jQuery
2420 * ------------------------------------------------------------------------
2421 * add .Dropdown to jQuery only if jQuery is present
2422 */
2423
2424 defineJQueryPlugin(NAME$7, Dropdown);
2425
2426 /**
2427 * --------------------------------------------------------------------------
2428 * Bootstrap (v5.0.0-beta3): modal.js
2429 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2430 * --------------------------------------------------------------------------
2431 */
2432 /**
2433 * ------------------------------------------------------------------------
2434 * Constants
2435 * ------------------------------------------------------------------------
2436 */
2437
2438 const NAME$6 = 'modal';
2439 const DATA_KEY$6 = 'bs.modal';
2440 const EVENT_KEY$6 = `.${DATA_KEY$6}`;
2441 const DATA_API_KEY$3 = '.data-api';
2442 const ESCAPE_KEY$1 = 'Escape';
2443 const Default$5 = {
2444 backdrop: true,
2445 keyboard: true,
2446 focus: true
2447 };
2448 const DefaultType$5 = {
2449 backdrop: '(boolean|string)',
2450 keyboard: 'boolean',
2451 focus: 'boolean'
2452 };
2453 const EVENT_HIDE$3 = `hide${EVENT_KEY$6}`;
2454 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$6}`;
2455 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$6}`;
2456 const EVENT_SHOW$3 = `show${EVENT_KEY$6}`;
2457 const EVENT_SHOWN$3 = `shown${EVENT_KEY$6}`;
2458 const EVENT_FOCUSIN$1 = `focusin${EVENT_KEY$6}`;
2459 const EVENT_RESIZE = `resize${EVENT_KEY$6}`;
2460 const EVENT_CLICK_DISMISS$2 = `click.dismiss${EVENT_KEY$6}`;
2461 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$6}`;
2462 const EVENT_MOUSEUP_DISMISS = `mouseup.dismiss${EVENT_KEY$6}`;
2463 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$6}`;
2464 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;
2465 const CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
2466 const CLASS_NAME_BACKDROP = 'modal-backdrop';
2467 const CLASS_NAME_OPEN = 'modal-open';
2468 const CLASS_NAME_FADE$4 = 'fade';
2469 const CLASS_NAME_SHOW$5 = 'show';
2470 const CLASS_NAME_STATIC = 'modal-static';
2471 const SELECTOR_DIALOG = '.modal-dialog';
2472 const SELECTOR_MODAL_BODY = '.modal-body';
2473 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]';
2474 const SELECTOR_DATA_DISMISS$2 = '[data-bs-dismiss="modal"]';
2475 const SELECTOR_FIXED_CONTENT$1 = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
2476 const SELECTOR_STICKY_CONTENT$1 = '.sticky-top';
2477 /**
2478 * ------------------------------------------------------------------------
2479 * Class Definition
2480 * ------------------------------------------------------------------------
2481 */
2482
2483 class Modal extends BaseComponent {
2484 constructor(element, config) {
2485 super(element);
2486 this._config = this._getConfig(config);
2487 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
2488 this._backdrop = null;
2489 this._isShown = false;
2490 this._isBodyOverflowing = false;
2491 this._ignoreBackdropClick = false;
2492 this._isTransitioning = false;
2493 this._scrollbarWidth = 0;
2494 } // Getters
2495
2496
2497 static get Default() {
2498 return Default$5;
2499 }
2500
2501 static get DATA_KEY() {
2502 return DATA_KEY$6;
2503 } // Public
2504
2505
2506 toggle(relatedTarget) {
2507 return this._isShown ? this.hide() : this.show(relatedTarget);
2508 }
2509
2510 show(relatedTarget) {
2511 if (this._isShown || this._isTransitioning) {
2512 return;
2513 }
2514
2515 if (this._isAnimated()) {
2516 this._isTransitioning = true;
2517 }
2518
2519 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {
2520 relatedTarget
2521 });
2522
2523 if (this._isShown || showEvent.defaultPrevented) {
2524 return;
2525 }
2526
2527 this._isShown = true;
2528
2529 this._checkScrollbar();
2530
2531 this._setScrollbar();
2532
2533 this._adjustDialog();
2534
2535 this._setEscapeEvent();
2536
2537 this._setResizeEvent();
2538
2539 EventHandler.on(this._element, EVENT_CLICK_DISMISS$2, SELECTOR_DATA_DISMISS$2, event => this.hide(event));
2540 EventHandler.on(this._dialog, EVENT_MOUSEDOWN_DISMISS, () => {
2541 EventHandler.one(this._element, EVENT_MOUSEUP_DISMISS, event => {
2542 if (event.target === this._element) {
2543 this._ignoreBackdropClick = true;
2544 }
2545 });
2546 });
2547
2548 this._showBackdrop(() => this._showElement(relatedTarget));
2549 }
2550
2551 hide(event) {
2552 if (event) {
2553 event.preventDefault();
2554 }
2555
2556 if (!this._isShown || this._isTransitioning) {
2557 return;
2558 }
2559
2560 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);
2561
2562 if (hideEvent.defaultPrevented) {
2563 return;
2564 }
2565
2566 this._isShown = false;
2567
2568 const isAnimated = this._isAnimated();
2569
2570 if (isAnimated) {
2571 this._isTransitioning = true;
2572 }
2573
2574 this._setEscapeEvent();
2575
2576 this._setResizeEvent();
2577
2578 EventHandler.off(document, EVENT_FOCUSIN$1);
2579
2580 this._element.classList.remove(CLASS_NAME_SHOW$5);
2581
2582 EventHandler.off(this._element, EVENT_CLICK_DISMISS$2);
2583 EventHandler.off(this._dialog, EVENT_MOUSEDOWN_DISMISS);
2584
2585 if (isAnimated) {
2586 const transitionDuration = getTransitionDurationFromElement(this._element);
2587 EventHandler.one(this._element, 'transitionend', event => this._hideModal(event));
2588 emulateTransitionEnd(this._element, transitionDuration);
2589 } else {
2590 this._hideModal();
2591 }
2592 }
2593
2594 dispose() {
2595 [window, this._element, this._dialog].forEach(htmlElement => EventHandler.off(htmlElement, EVENT_KEY$6));
2596 super.dispose();
2597 /**
2598 * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
2599 * Do not move `document` in `htmlElements` array
2600 * It will remove `EVENT_CLICK_DATA_API` event that should remain
2601 */
2602
2603 EventHandler.off(document, EVENT_FOCUSIN$1);
2604 this._config = null;
2605 this._dialog = null;
2606 this._backdrop = null;
2607 this._isShown = null;
2608 this._isBodyOverflowing = null;
2609 this._ignoreBackdropClick = null;
2610 this._isTransitioning = null;
2611 this._scrollbarWidth = null;
2612 }
2613
2614 handleUpdate() {
2615 this._adjustDialog();
2616 } // Private
2617
2618
2619 _getConfig(config) {
2620 config = { ...Default$5,
2621 ...config
2622 };
2623 typeCheckConfig(NAME$6, config, DefaultType$5);
2624 return config;
2625 }
2626
2627 _showElement(relatedTarget) {
2628 const isAnimated = this._isAnimated();
2629
2630 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
2631
2632 if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
2633 // Don't move modal's DOM position
2634 document.body.appendChild(this._element);
2635 }
2636
2637 this._element.style.display = 'block';
2638
2639 this._element.removeAttribute('aria-hidden');
2640
2641 this._element.setAttribute('aria-modal', true);
2642
2643 this._element.setAttribute('role', 'dialog');
2644
2645 this._element.scrollTop = 0;
2646
2647 if (modalBody) {
2648 modalBody.scrollTop = 0;
2649 }
2650
2651 if (isAnimated) {
2652 reflow(this._element);
2653 }
2654
2655 this._element.classList.add(CLASS_NAME_SHOW$5);
2656
2657 if (this._config.focus) {
2658 this._enforceFocus();
2659 }
2660
2661 const transitionComplete = () => {
2662 if (this._config.focus) {
2663 this._element.focus();
2664 }
2665
2666 this._isTransitioning = false;
2667 EventHandler.trigger(this._element, EVENT_SHOWN$3, {
2668 relatedTarget
2669 });
2670 };
2671
2672 if (isAnimated) {
2673 const transitionDuration = getTransitionDurationFromElement(this._dialog);
2674 EventHandler.one(this._dialog, 'transitionend', transitionComplete);
2675 emulateTransitionEnd(this._dialog, transitionDuration);
2676 } else {
2677 transitionComplete();
2678 }
2679 }
2680
2681 _enforceFocus() {
2682 EventHandler.off(document, EVENT_FOCUSIN$1); // guard against infinite focus loop
2683
2684 EventHandler.on(document, EVENT_FOCUSIN$1, event => {
2685 if (document !== event.target && this._element !== event.target && !this._element.contains(event.target)) {
2686 this._element.focus();
2687 }
2688 });
2689 }
2690
2691 _setEscapeEvent() {
2692 if (this._isShown) {
2693 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
2694 if (this._config.keyboard && event.key === ESCAPE_KEY$1) {
2695 event.preventDefault();
2696 this.hide();
2697 } else if (!this._config.keyboard && event.key === ESCAPE_KEY$1) {
2698 this._triggerBackdropTransition();
2699 }
2700 });
2701 } else {
2702 EventHandler.off(this._element, EVENT_KEYDOWN_DISMISS);
2703 }
2704 }
2705
2706 _setResizeEvent() {
2707 if (this._isShown) {
2708 EventHandler.on(window, EVENT_RESIZE, () => this._adjustDialog());
2709 } else {
2710 EventHandler.off(window, EVENT_RESIZE);
2711 }
2712 }
2713
2714 _hideModal() {
2715 this._element.style.display = 'none';
2716
2717 this._element.setAttribute('aria-hidden', true);
2718
2719 this._element.removeAttribute('aria-modal');
2720
2721 this._element.removeAttribute('role');
2722
2723 this._isTransitioning = false;
2724
2725 this._showBackdrop(() => {
2726 document.body.classList.remove(CLASS_NAME_OPEN);
2727
2728 this._resetAdjustments();
2729
2730 this._resetScrollbar();
2731
2732 EventHandler.trigger(this._element, EVENT_HIDDEN$3);
2733 });
2734 }
2735
2736 _removeBackdrop() {
2737 this._backdrop.parentNode.removeChild(this._backdrop);
2738
2739 this._backdrop = null;
2740 }
2741
2742 _showBackdrop(callback) {
2743 const isAnimated = this._isAnimated();
2744
2745 if (this._isShown && this._config.backdrop) {
2746 this._backdrop = document.createElement('div');
2747 this._backdrop.className = CLASS_NAME_BACKDROP;
2748
2749 if (isAnimated) {
2750 this._backdrop.classList.add(CLASS_NAME_FADE$4);
2751 }
2752
2753 document.body.appendChild(this._backdrop);
2754 EventHandler.on(this._element, EVENT_CLICK_DISMISS$2, event => {
2755 if (this._ignoreBackdropClick) {
2756 this._ignoreBackdropClick = false;
2757 return;
2758 }
2759
2760 if (event.target !== event.currentTarget) {
2761 return;
2762 }
2763
2764 if (this._config.backdrop === 'static') {
2765 this._triggerBackdropTransition();
2766 } else {
2767 this.hide();
2768 }
2769 });
2770
2771 if (isAnimated) {
2772 reflow(this._backdrop);
2773 }
2774
2775 this._backdrop.classList.add(CLASS_NAME_SHOW$5);
2776
2777 if (!isAnimated) {
2778 callback();
2779 return;
2780 }
2781
2782 const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop);
2783 EventHandler.one(this._backdrop, 'transitionend', callback);
2784 emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
2785 } else if (!this._isShown && this._backdrop) {
2786 this._backdrop.classList.remove(CLASS_NAME_SHOW$5);
2787
2788 const callbackRemove = () => {
2789 this._removeBackdrop();
2790
2791 callback();
2792 };
2793
2794 if (isAnimated) {
2795 const backdropTransitionDuration = getTransitionDurationFromElement(this._backdrop);
2796 EventHandler.one(this._backdrop, 'transitionend', callbackRemove);
2797 emulateTransitionEnd(this._backdrop, backdropTransitionDuration);
2798 } else {
2799 callbackRemove();
2800 }
2801 } else {
2802 callback();
2803 }
2804 }
2805
2806 _isAnimated() {
2807 return this._element.classList.contains(CLASS_NAME_FADE$4);
2808 }
2809
2810 _triggerBackdropTransition() {
2811 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
2812
2813 if (hideEvent.defaultPrevented) {
2814 return;
2815 }
2816
2817 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
2818
2819 if (!isModalOverflowing) {
2820 this._element.style.overflowY = 'hidden';
2821 }
2822
2823 this._element.classList.add(CLASS_NAME_STATIC);
2824
2825 const modalTransitionDuration = getTransitionDurationFromElement(this._dialog);
2826 EventHandler.off(this._element, 'transitionend');
2827 EventHandler.one(this._element, 'transitionend', () => {
2828 this._element.classList.remove(CLASS_NAME_STATIC);
2829
2830 if (!isModalOverflowing) {
2831 EventHandler.one(this._element, 'transitionend', () => {
2832 this._element.style.overflowY = '';
2833 });
2834 emulateTransitionEnd(this._element, modalTransitionDuration);
2835 }
2836 });
2837 emulateTransitionEnd(this._element, modalTransitionDuration);
2838
2839 this._element.focus();
2840 } // ----------------------------------------------------------------------
2841 // the following methods are used to handle overflowing modals
2842 // ----------------------------------------------------------------------
2843
2844
2845 _adjustDialog() {
2846 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
2847
2848 if (!this._isBodyOverflowing && isModalOverflowing && !isRTL() || this._isBodyOverflowing && !isModalOverflowing && isRTL()) {
2849 this._element.style.paddingLeft = `${this._scrollbarWidth}px`;
2850 }
2851
2852 if (this._isBodyOverflowing && !isModalOverflowing && !isRTL() || !this._isBodyOverflowing && isModalOverflowing && isRTL()) {
2853 this._element.style.paddingRight = `${this._scrollbarWidth}px`;
2854 }
2855 }
2856
2857 _resetAdjustments() {
2858 this._element.style.paddingLeft = '';
2859 this._element.style.paddingRight = '';
2860 }
2861
2862 _checkScrollbar() {
2863 const rect = document.body.getBoundingClientRect();
2864 this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
2865 this._scrollbarWidth = this._getScrollbarWidth();
2866 }
2867
2868 _setScrollbar() {
2869 if (this._isBodyOverflowing) {
2870 this._setElementAttributes(SELECTOR_FIXED_CONTENT$1, 'paddingRight', calculatedValue => calculatedValue + this._scrollbarWidth);
2871
2872 this._setElementAttributes(SELECTOR_STICKY_CONTENT$1, 'marginRight', calculatedValue => calculatedValue - this._scrollbarWidth);
2873
2874 this._setElementAttributes('body', 'paddingRight', calculatedValue => calculatedValue + this._scrollbarWidth);
2875 }
2876
2877 document.body.classList.add(CLASS_NAME_OPEN);
2878 }
2879
2880 _setElementAttributes(selector, styleProp, callback) {
2881 SelectorEngine.find(selector).forEach(element => {
2882 if (element !== document.body && window.innerWidth > element.clientWidth + this._scrollbarWidth) {
2883 return;
2884 }
2885
2886 const actualValue = element.style[styleProp];
2887 const calculatedValue = window.getComputedStyle(element)[styleProp];
2888 Manipulator.setDataAttribute(element, styleProp, actualValue);
2889 element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px';
2890 });
2891 }
2892
2893 _resetScrollbar() {
2894 this._resetElementAttributes(SELECTOR_FIXED_CONTENT$1, 'paddingRight');
2895
2896 this._resetElementAttributes(SELECTOR_STICKY_CONTENT$1, 'marginRight');
2897
2898 this._resetElementAttributes('body', 'paddingRight');
2899 }
2900
2901 _resetElementAttributes(selector, styleProp) {
2902 SelectorEngine.find(selector).forEach(element => {
2903 const value = Manipulator.getDataAttribute(element, styleProp);
2904
2905 if (typeof value === 'undefined' && element === document.body) {
2906 element.style[styleProp] = '';
2907 } else {
2908 Manipulator.removeDataAttribute(element, styleProp);
2909 element.style[styleProp] = value;
2910 }
2911 });
2912 }
2913
2914 _getScrollbarWidth() {
2915 // thx d.walsh
2916 const scrollDiv = document.createElement('div');
2917 scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
2918 document.body.appendChild(scrollDiv);
2919 const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
2920 document.body.removeChild(scrollDiv);
2921 return scrollbarWidth;
2922 } // Static
2923
2924
2925 static jQueryInterface(config, relatedTarget) {
2926 return this.each(function () {
2927 let data = Data.get(this, DATA_KEY$6);
2928 const _config = { ...Default$5,
2929 ...Manipulator.getDataAttributes(this),
2930 ...(typeof config === 'object' && config ? config : {})
2931 };
2932
2933 if (!data) {
2934 data = new Modal(this, _config);
2935 }
2936
2937 if (typeof config === 'string') {
2938 if (typeof data[config] === 'undefined') {
2939 throw new TypeError(`No method named "${config}"`);
2940 }
2941
2942 data[config](relatedTarget);
2943 }
2944 });
2945 }
2946
2947 }
2948 /**
2949 * ------------------------------------------------------------------------
2950 * Data Api implementation
2951 * ------------------------------------------------------------------------
2952 */
2953
2954
2955 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {
2956 const target = getElementFromSelector(this);
2957
2958 if (this.tagName === 'A' || this.tagName === 'AREA') {
2959 event.preventDefault();
2960 }
2961
2962 EventHandler.one(target, EVENT_SHOW$3, showEvent => {
2963 if (showEvent.defaultPrevented) {
2964 // only register focus restorer if modal will actually get shown
2965 return;
2966 }
2967
2968 EventHandler.one(target, EVENT_HIDDEN$3, () => {
2969 if (isVisible(this)) {
2970 this.focus();
2971 }
2972 });
2973 });
2974 let data = Data.get(target, DATA_KEY$6);
2975
2976 if (!data) {
2977 const config = { ...Manipulator.getDataAttributes(target),
2978 ...Manipulator.getDataAttributes(this)
2979 };
2980 data = new Modal(target, config);
2981 }
2982
2983 data.toggle(this);
2984 });
2985 /**
2986 * ------------------------------------------------------------------------
2987 * jQuery
2988 * ------------------------------------------------------------------------
2989 * add .Modal to jQuery only if jQuery is present
2990 */
2991
2992 defineJQueryPlugin(NAME$6, Modal);
2993
2994 /**
2995 * --------------------------------------------------------------------------
2996 * Bootstrap (v5.0.0-beta3): util/scrollBar.js
2997 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2998 * --------------------------------------------------------------------------
2999 */
3000 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed';
3001 const SELECTOR_STICKY_CONTENT = '.sticky-top';
3002
3003 const getWidth = () => {
3004 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
3005 const documentWidth = document.documentElement.clientWidth;
3006 return Math.abs(window.innerWidth - documentWidth);
3007 };
3008
3009 const hide = (width = getWidth()) => {
3010 document.body.style.overflow = 'hidden';
3011
3012 _setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
3013
3014 _setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
3015
3016 _setElementAttributes('body', 'paddingRight', calculatedValue => calculatedValue + width);
3017 };
3018
3019 const _setElementAttributes = (selector, styleProp, callback) => {
3020 const scrollbarWidth = getWidth();
3021 SelectorEngine.find(selector).forEach(element => {
3022 if (element !== document.body && window.innerWidth > element.clientWidth + scrollbarWidth) {
3023 return;
3024 }
3025
3026 const actualValue = element.style[styleProp];
3027 const calculatedValue = window.getComputedStyle(element)[styleProp];
3028 Manipulator.setDataAttribute(element, styleProp, actualValue);
3029 element.style[styleProp] = callback(Number.parseFloat(calculatedValue)) + 'px';
3030 });
3031 };
3032
3033 const reset = () => {
3034 document.body.style.overflow = 'auto';
3035
3036 _resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
3037
3038 _resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
3039
3040 _resetElementAttributes('body', 'paddingRight');
3041 };
3042
3043 const _resetElementAttributes = (selector, styleProp) => {
3044 SelectorEngine.find(selector).forEach(element => {
3045 const value = Manipulator.getDataAttribute(element, styleProp);
3046
3047 if (typeof value === 'undefined' && element === document.body) {
3048 element.style.removeProperty(styleProp);
3049 } else {
3050 Manipulator.removeDataAttribute(element, styleProp);
3051 element.style[styleProp] = value;
3052 }
3053 });
3054 };
3055
3056 /**
3057 * --------------------------------------------------------------------------
3058 * Bootstrap (v5.0.0-beta3): offcanvas.js
3059 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
3060 * --------------------------------------------------------------------------
3061 */
3062 /**
3063 * ------------------------------------------------------------------------
3064 * Constants
3065 * ------------------------------------------------------------------------
3066 */
3067
3068 const NAME$5 = 'offcanvas';
3069 const DATA_KEY$5 = 'bs.offcanvas';
3070 const EVENT_KEY$5 = `.${DATA_KEY$5}`;
3071 const DATA_API_KEY$2 = '.data-api';
3072 const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$5}${DATA_API_KEY$2}`;
3073 const ESCAPE_KEY = 'Escape';
3074 const Default$4 = {
3075 backdrop: true,
3076 keyboard: true,
3077 scroll: false
3078 };
3079 const DefaultType$4 = {
3080 backdrop: 'boolean',
3081 keyboard: 'boolean',
3082 scroll: 'boolean'
3083 };
3084 const CLASS_NAME_BACKDROP_BODY = 'offcanvas-backdrop';
3085 const CLASS_NAME_SHOW$4 = 'show';
3086 const CLASS_NAME_TOGGLING = 'offcanvas-toggling';
3087 const OPEN_SELECTOR = '.offcanvas.show';
3088 const ACTIVE_SELECTOR = `${OPEN_SELECTOR}, .${CLASS_NAME_TOGGLING}`;
3089 const EVENT_SHOW$2 = `show${EVENT_KEY$5}`;
3090 const EVENT_SHOWN$2 = `shown${EVENT_KEY$5}`;
3091 const EVENT_HIDE$2 = `hide${EVENT_KEY$5}`;
3092 const EVENT_HIDDEN$2 = `hidden${EVENT_KEY$5}`;
3093 const EVENT_FOCUSIN = `focusin${EVENT_KEY$5}`;
3094 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$5}${DATA_API_KEY$2}`;
3095 const EVENT_CLICK_DISMISS$1 = `click.dismiss${EVENT_KEY$5}`;
3096 const SELECTOR_DATA_DISMISS$1 = '[data-bs-dismiss="offcanvas"]';
3097 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]';
3098 /**
3099 * ------------------------------------------------------------------------
3100 * Class Definition
3101 * ------------------------------------------------------------------------
3102 */
3103
3104 class Offcanvas extends BaseComponent {
3105 constructor(element, config) {
3106 super(element);
3107 this._config = this._getConfig(config);
3108 this._isShown = false;
3109
3110 this._addEventListeners();
3111 } // Getters
3112
3113
3114 static get Default() {
3115 return Default$4;
3116 }
3117
3118 static get DATA_KEY() {
3119 return DATA_KEY$5;
3120 } // Public
3121
3122
3123 toggle(relatedTarget) {
3124 return this._isShown ? this.hide() : this.show(relatedTarget);
3125 }
3126
3127 show(relatedTarget) {
3128 if (this._isShown) {
3129 return;
3130 }
3131
3132 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$2, {
3133 relatedTarget
3134 });
3135
3136 if (showEvent.defaultPrevented) {
3137 return;
3138 }
3139
3140 this._isShown = true;
3141 this._element.style.visibility = 'visible';
3142
3143 if (this._config.backdrop) {
3144 document.body.classList.add(CLASS_NAME_BACKDROP_BODY);
3145 }
3146
3147 if (!this._config.scroll) {
3148 hide();
3149 }
3150
3151 this._element.classList.add(CLASS_NAME_TOGGLING);
3152
3153 this._element.removeAttribute('aria-hidden');
3154
3155 this._element.setAttribute('aria-modal', true);
3156
3157 this._element.setAttribute('role', 'dialog');
3158
3159 this._element.classList.add(CLASS_NAME_SHOW$4);
3160
3161 const completeCallBack = () => {
3162 this._element.classList.remove(CLASS_NAME_TOGGLING);
3163
3164 EventHandler.trigger(this._element, EVENT_SHOWN$2, {
3165 relatedTarget
3166 });
3167
3168 this._enforceFocusOnElement(this._element);
3169 };
3170
3171 setTimeout(completeCallBack, getTransitionDurationFromElement(this._element));
3172 }
3173
3174 hide() {
3175 if (!this._isShown) {
3176 return;
3177 }
3178
3179 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$2);
3180
3181 if (hideEvent.defaultPrevented) {
3182 return;
3183 }
3184
3185 this._element.classList.add(CLASS_NAME_TOGGLING);
3186
3187 EventHandler.off(document, EVENT_FOCUSIN);
3188
3189 this._element.blur();
3190
3191 this._isShown = false;
3192
3193 this._element.classList.remove(CLASS_NAME_SHOW$4);
3194
3195 const completeCallback = () => {
3196 this._element.setAttribute('aria-hidden', true);
3197
3198 this._element.removeAttribute('aria-modal');
3199
3200 this._element.removeAttribute('role');
3201
3202 this._element.style.visibility = 'hidden';
3203
3204 if (this._config.backdrop) {
3205 document.body.classList.remove(CLASS_NAME_BACKDROP_BODY);
3206 }
3207
3208 if (!this._config.scroll) {
3209 reset();
3210 }
3211
3212 EventHandler.trigger(this._element, EVENT_HIDDEN$2);
3213
3214 this._element.classList.remove(CLASS_NAME_TOGGLING);
3215 };
3216
3217 setTimeout(completeCallback, getTransitionDurationFromElement(this._element));
3218 } // Private
3219
3220
3221 _getConfig(config) {
3222 config = { ...Default$4,
3223 ...Manipulator.getDataAttributes(this._element),
3224 ...(typeof config === 'object' ? config : {})
3225 };
3226 typeCheckConfig(NAME$5, config, DefaultType$4);
3227 return config;
3228 }
3229
3230 _enforceFocusOnElement(element) {
3231 EventHandler.off(document, EVENT_FOCUSIN); // guard against infinite focus loop
3232
3233 EventHandler.on(document, EVENT_FOCUSIN, event => {
3234 if (document !== event.target && element !== event.target && !element.contains(event.target)) {
3235 element.focus();
3236 }
3237 });
3238 element.focus();
3239 }
3240
3241 _addEventListeners() {
3242 EventHandler.on(this._element, EVENT_CLICK_DISMISS$1, SELECTOR_DATA_DISMISS$1, () => this.hide());
3243 EventHandler.on(document, 'keydown', event => {
3244 if (this._config.keyboard && event.key === ESCAPE_KEY) {
3245 this.hide();
3246 }
3247 });
3248 EventHandler.on(document, EVENT_CLICK_DATA_API$1, event => {
3249 const target = SelectorEngine.findOne(getSelectorFromElement(event.target));
3250
3251 if (!this._element.contains(event.target) && target !== this._element) {
3252 this.hide();
3253 }
3254 });
3255 } // Static
3256
3257
3258 static jQueryInterface(config) {
3259 return this.each(function () {
3260 const data = Data.get(this, DATA_KEY$5) || new Offcanvas(this, typeof config === 'object' ? config : {});
3261
3262 if (typeof config !== 'string') {
3263 return;
3264 }
3265
3266 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
3267 throw new TypeError(`No method named "${config}"`);
3268 }
3269
3270 data[config](this);
3271 });
3272 }
3273
3274 }
3275 /**
3276 * ------------------------------------------------------------------------
3277 * Data Api implementation
3278 * ------------------------------------------------------------------------
3279 */
3280
3281
3282 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {
3283 const target = getElementFromSelector(this);
3284
3285 if (['A', 'AREA'].includes(this.tagName)) {
3286 event.preventDefault();
3287 }
3288
3289 if (isDisabled(this)) {
3290 return;
3291 }
3292
3293 EventHandler.one(target, EVENT_HIDDEN$2, () => {
3294 // focus on trigger when it is closed
3295 if (isVisible(this)) {
3296 this.focus();
3297 }
3298 }); // avoid conflict when clicking a toggler of an offcanvas, while another is open
3299
3300 const allReadyOpen = SelectorEngine.findOne(ACTIVE_SELECTOR);
3301
3302 if (allReadyOpen && allReadyOpen !== target) {
3303 return;
3304 }
3305
3306 const data = Data.get(target, DATA_KEY$5) || new Offcanvas(target);
3307 data.toggle(this);
3308 });
3309 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => {
3310 SelectorEngine.find(OPEN_SELECTOR).forEach(el => (Data.get(el, DATA_KEY$5) || new Offcanvas(el)).show());
3311 });
3312 /**
3313 * ------------------------------------------------------------------------
3314 * jQuery
3315 * ------------------------------------------------------------------------
3316 */
3317
3318 defineJQueryPlugin(NAME$5, Offcanvas);
3319
3320 /**
3321 * --------------------------------------------------------------------------
3322 * Bootstrap (v5.0.0-beta3): util/sanitizer.js
3323 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3324 * --------------------------------------------------------------------------
3325 */
3326 const uriAttrs = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
3327 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
3328 /**
3329 * A pattern that recognizes a commonly useful subset of URLs that are safe.
3330 *
3331 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
3332 */
3333
3334 const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i;
3335 /**
3336 * A pattern that matches safe data URLs. Only matches image, video and audio types.
3337 *
3338 * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
3339 */
3340
3341 const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
3342
3343 const allowedAttribute = (attr, allowedAttributeList) => {
3344 const attrName = attr.nodeName.toLowerCase();
3345
3346 if (allowedAttributeList.includes(attrName)) {
3347 if (uriAttrs.has(attrName)) {
3348 return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue));
3349 }
3350
3351 return true;
3352 }
3353
3354 const regExp = allowedAttributeList.filter(attrRegex => attrRegex instanceof RegExp); // Check if a regular expression validates the attribute.
3355
3356 for (let i = 0, len = regExp.length; i < len; i++) {
3357 if (regExp[i].test(attrName)) {
3358 return true;
3359 }
3360 }
3361
3362 return false;
3363 };
3364
3365 const DefaultAllowlist = {
3366 // Global attributes allowed on any supplied element below.
3367 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
3368 a: ['target', 'href', 'title', 'rel'],
3369 area: [],
3370 b: [],
3371 br: [],
3372 col: [],
3373 code: [],
3374 div: [],
3375 em: [],
3376 hr: [],
3377 h1: [],
3378 h2: [],
3379 h3: [],
3380 h4: [],
3381 h5: [],
3382 h6: [],
3383 i: [],
3384 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
3385 li: [],
3386 ol: [],
3387 p: [],
3388 pre: [],
3389 s: [],
3390 small: [],
3391 span: [],
3392 sub: [],
3393 sup: [],
3394 strong: [],
3395 u: [],
3396 ul: []
3397 };
3398 function sanitizeHtml(unsafeHtml, allowList, sanitizeFn) {
3399 if (!unsafeHtml.length) {
3400 return unsafeHtml;
3401 }
3402
3403 if (sanitizeFn && typeof sanitizeFn === 'function') {
3404 return sanitizeFn(unsafeHtml);
3405 }
3406
3407 const domParser = new window.DOMParser();
3408 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
3409 const allowlistKeys = Object.keys(allowList);
3410 const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
3411
3412 for (let i = 0, len = elements.length; i < len; i++) {
3413 const el = elements[i];
3414 const elName = el.nodeName.toLowerCase();
3415
3416 if (!allowlistKeys.includes(elName)) {
3417 el.parentNode.removeChild(el);
3418 continue;
3419 }
3420
3421 const attributeList = [].concat(...el.attributes);
3422 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elName] || []);
3423 attributeList.forEach(attr => {
3424 if (!allowedAttribute(attr, allowedAttributes)) {
3425 el.removeAttribute(attr.nodeName);
3426 }
3427 });
3428 }
3429
3430 return createdDocument.body.innerHTML;
3431 }
3432
3433 /**
3434 * --------------------------------------------------------------------------
3435 * Bootstrap (v5.0.0-beta3): tooltip.js
3436 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3437 * --------------------------------------------------------------------------
3438 */
3439 /**
3440 * ------------------------------------------------------------------------
3441 * Constants
3442 * ------------------------------------------------------------------------
3443 */
3444
3445 const NAME$4 = 'tooltip';
3446 const DATA_KEY$4 = 'bs.tooltip';
3447 const EVENT_KEY$4 = `.${DATA_KEY$4}`;
3448 const CLASS_PREFIX$1 = 'bs-tooltip';
3449 const BSCLS_PREFIX_REGEX$1 = new RegExp(`(^|\\s)${CLASS_PREFIX$1}\\S+`, 'g');
3450 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
3451 const DefaultType$3 = {
3452 animation: 'boolean',
3453 template: 'string',
3454 title: '(string|element|function)',
3455 trigger: 'string',
3456 delay: '(number|object)',
3457 html: 'boolean',
3458 selector: '(string|boolean)',
3459 placement: '(string|function)',
3460 offset: '(array|string|function)',
3461 container: '(string|element|boolean)',
3462 fallbackPlacements: 'array',
3463 boundary: '(string|element)',
3464 customClass: '(string|function)',
3465 sanitize: 'boolean',
3466 sanitizeFn: '(null|function)',
3467 allowList: 'object',
3468 popperConfig: '(null|object|function)'
3469 };
3470 const AttachmentMap = {
3471 AUTO: 'auto',
3472 TOP: 'top',
3473 RIGHT: isRTL() ? 'left' : 'right',
3474 BOTTOM: 'bottom',
3475 LEFT: isRTL() ? 'right' : 'left'
3476 };
3477 const Default$3 = {
3478 animation: true,
3479 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
3480 trigger: 'hover focus',
3481 title: '',
3482 delay: 0,
3483 html: false,
3484 selector: false,
3485 placement: 'top',
3486 offset: [0, 0],
3487 container: false,
3488 fallbackPlacements: ['top', 'right', 'bottom', 'left'],
3489 boundary: 'clippingParents',
3490 customClass: '',
3491 sanitize: true,
3492 sanitizeFn: null,
3493 allowList: DefaultAllowlist,
3494 popperConfig: null
3495 };
3496 const Event$2 = {
3497 HIDE: `hide${EVENT_KEY$4}`,
3498 HIDDEN: `hidden${EVENT_KEY$4}`,
3499 SHOW: `show${EVENT_KEY$4}`,
3500 SHOWN: `shown${EVENT_KEY$4}`,
3501 INSERTED: `inserted${EVENT_KEY$4}`,
3502 CLICK: `click${EVENT_KEY$4}`,
3503 FOCUSIN: `focusin${EVENT_KEY$4}`,
3504 FOCUSOUT: `focusout${EVENT_KEY$4}`,
3505 MOUSEENTER: `mouseenter${EVENT_KEY$4}`,
3506 MOUSELEAVE: `mouseleave${EVENT_KEY$4}`
3507 };
3508 const CLASS_NAME_FADE$3 = 'fade';
3509 const CLASS_NAME_MODAL = 'modal';
3510 const CLASS_NAME_SHOW$3 = 'show';
3511 const HOVER_STATE_SHOW = 'show';
3512 const HOVER_STATE_OUT = 'out';
3513 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
3514 const TRIGGER_HOVER = 'hover';
3515 const TRIGGER_FOCUS = 'focus';
3516 const TRIGGER_CLICK = 'click';
3517 const TRIGGER_MANUAL = 'manual';
3518 /**
3519 * ------------------------------------------------------------------------
3520 * Class Definition
3521 * ------------------------------------------------------------------------
3522 */
3523
3524 class Tooltip extends BaseComponent {
3525 constructor(element, config) {
3526 if (typeof Popper__namespace === 'undefined') {
3527 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
3528 }
3529
3530 super(element); // private
3531
3532 this._isEnabled = true;
3533 this._timeout = 0;
3534 this._hoverState = '';
3535 this._activeTrigger = {};
3536 this._popper = null; // Protected
3537
3538 this.config = this._getConfig(config);
3539 this.tip = null;
3540
3541 this._setListeners();
3542 } // Getters
3543
3544
3545 static get Default() {
3546 return Default$3;
3547 }
3548
3549 static get NAME() {
3550 return NAME$4;
3551 }
3552
3553 static get DATA_KEY() {
3554 return DATA_KEY$4;
3555 }
3556
3557 static get Event() {
3558 return Event$2;
3559 }
3560
3561 static get EVENT_KEY() {
3562 return EVENT_KEY$4;
3563 }
3564
3565 static get DefaultType() {
3566 return DefaultType$3;
3567 } // Public
3568
3569
3570 enable() {
3571 this._isEnabled = true;
3572 }
3573
3574 disable() {
3575 this._isEnabled = false;
3576 }
3577
3578 toggleEnabled() {
3579 this._isEnabled = !this._isEnabled;
3580 }
3581
3582 toggle(event) {
3583 if (!this._isEnabled) {
3584 return;
3585 }
3586
3587 if (event) {
3588 const context = this._initializeOnDelegatedTarget(event);
3589
3590 context._activeTrigger.click = !context._activeTrigger.click;
3591
3592 if (context._isWithActiveTrigger()) {
3593 context._enter(null, context);
3594 } else {
3595 context._leave(null, context);
3596 }
3597 } else {
3598 if (this.getTipElement().classList.contains(CLASS_NAME_SHOW$3)) {
3599 this._leave(null, this);
3600
3601 return;
3602 }
3603
3604 this._enter(null, this);
3605 }
3606 }
3607
3608 dispose() {
3609 clearTimeout(this._timeout);
3610 EventHandler.off(this._element, this.constructor.EVENT_KEY);
3611 EventHandler.off(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler);
3612
3613 if (this.tip && this.tip.parentNode) {
3614 this.tip.parentNode.removeChild(this.tip);
3615 }
3616
3617 this._isEnabled = null;
3618 this._timeout = null;
3619 this._hoverState = null;
3620 this._activeTrigger = null;
3621
3622 if (this._popper) {
3623 this._popper.destroy();
3624 }
3625
3626 this._popper = null;
3627 this.config = null;
3628 this.tip = null;
3629 super.dispose();
3630 }
3631
3632 show() {
3633 if (this._element.style.display === 'none') {
3634 throw new Error('Please use show on visible elements');
3635 }
3636
3637 if (!(this.isWithContent() && this._isEnabled)) {
3638 return;
3639 }
3640
3641 const showEvent = EventHandler.trigger(this._element, this.constructor.Event.SHOW);
3642 const shadowRoot = findShadowRoot(this._element);
3643 const isInTheDom = shadowRoot === null ? this._element.ownerDocument.documentElement.contains(this._element) : shadowRoot.contains(this._element);
3644
3645 if (showEvent.defaultPrevented || !isInTheDom) {
3646 return;
3647 }
3648
3649 const tip = this.getTipElement();
3650 const tipId = getUID(this.constructor.NAME);
3651 tip.setAttribute('id', tipId);
3652
3653 this._element.setAttribute('aria-describedby', tipId);
3654
3655 this.setContent();
3656
3657 if (this.config.animation) {
3658 tip.classList.add(CLASS_NAME_FADE$3);
3659 }
3660
3661 const placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this._element) : this.config.placement;
3662
3663 const attachment = this._getAttachment(placement);
3664
3665 this._addAttachmentClass(attachment);
3666
3667 const container = this._getContainer();
3668
3669 Data.set(tip, this.constructor.DATA_KEY, this);
3670
3671 if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
3672 container.appendChild(tip);
3673 EventHandler.trigger(this._element, this.constructor.Event.INSERTED);
3674 }
3675
3676 if (this._popper) {
3677 this._popper.update();
3678 } else {
3679 this._popper = Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment));
3680 }
3681
3682 tip.classList.add(CLASS_NAME_SHOW$3);
3683 const customClass = typeof this.config.customClass === 'function' ? this.config.customClass() : this.config.customClass;
3684
3685 if (customClass) {
3686 tip.classList.add(...customClass.split(' '));
3687 } // If this is a touch-enabled device we add extra
3688 // empty mouseover listeners to the body's immediate children;
3689 // only needed because of broken event delegation on iOS
3690 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
3691
3692
3693 if ('ontouchstart' in document.documentElement) {
3694 [].concat(...document.body.children).forEach(element => {
3695 EventHandler.on(element, 'mouseover', noop());
3696 });
3697 }
3698
3699 const complete = () => {
3700 const prevHoverState = this._hoverState;
3701 this._hoverState = null;
3702 EventHandler.trigger(this._element, this.constructor.Event.SHOWN);
3703
3704 if (prevHoverState === HOVER_STATE_OUT) {
3705 this._leave(null, this);
3706 }
3707 };
3708
3709 if (this.tip.classList.contains(CLASS_NAME_FADE$3)) {
3710 const transitionDuration = getTransitionDurationFromElement(this.tip);
3711 EventHandler.one(this.tip, 'transitionend', complete);
3712 emulateTransitionEnd(this.tip, transitionDuration);
3713 } else {
3714 complete();
3715 }
3716 }
3717
3718 hide() {
3719 if (!this._popper) {
3720 return;
3721 }
3722
3723 const tip = this.getTipElement();
3724
3725 const complete = () => {
3726 if (this._isWithActiveTrigger()) {
3727 return;
3728 }
3729
3730 if (this._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
3731 tip.parentNode.removeChild(tip);
3732 }
3733
3734 this._cleanTipClass();
3735
3736 this._element.removeAttribute('aria-describedby');
3737
3738 EventHandler.trigger(this._element, this.constructor.Event.HIDDEN);
3739
3740 if (this._popper) {
3741 this._popper.destroy();
3742
3743 this._popper = null;
3744 }
3745 };
3746
3747 const hideEvent = EventHandler.trigger(this._element, this.constructor.Event.HIDE);
3748
3749 if (hideEvent.defaultPrevented) {
3750 return;
3751 }
3752
3753 tip.classList.remove(CLASS_NAME_SHOW$3); // If this is a touch-enabled device we remove the extra
3754 // empty mouseover listeners we added for iOS support
3755
3756 if ('ontouchstart' in document.documentElement) {
3757 [].concat(...document.body.children).forEach(element => EventHandler.off(element, 'mouseover', noop));
3758 }
3759
3760 this._activeTrigger[TRIGGER_CLICK] = false;
3761 this._activeTrigger[TRIGGER_FOCUS] = false;
3762 this._activeTrigger[TRIGGER_HOVER] = false;
3763
3764 if (this.tip.classList.contains(CLASS_NAME_FADE$3)) {
3765 const transitionDuration = getTransitionDurationFromElement(tip);
3766 EventHandler.one(tip, 'transitionend', complete);
3767 emulateTransitionEnd(tip, transitionDuration);
3768 } else {
3769 complete();
3770 }
3771
3772 this._hoverState = '';
3773 }
3774
3775 update() {
3776 if (this._popper !== null) {
3777 this._popper.update();
3778 }
3779 } // Protected
3780
3781
3782 isWithContent() {
3783 return Boolean(this.getTitle());
3784 }
3785
3786 getTipElement() {
3787 if (this.tip) {
3788 return this.tip;
3789 }
3790
3791 const element = document.createElement('div');
3792 element.innerHTML = this.config.template;
3793 this.tip = element.children[0];
3794 return this.tip;
3795 }
3796
3797 setContent() {
3798 const tip = this.getTipElement();
3799 this.setElementContent(SelectorEngine.findOne(SELECTOR_TOOLTIP_INNER, tip), this.getTitle());
3800 tip.classList.remove(CLASS_NAME_FADE$3, CLASS_NAME_SHOW$3);
3801 }
3802
3803 setElementContent(element, content) {
3804 if (element === null) {
3805 return;
3806 }
3807
3808 if (typeof content === 'object' && isElement(content)) {
3809 if (content.jquery) {
3810 content = content[0];
3811 } // content is a DOM node or a jQuery
3812
3813
3814 if (this.config.html) {
3815 if (content.parentNode !== element) {
3816 element.innerHTML = '';
3817 element.appendChild(content);
3818 }
3819 } else {
3820 element.textContent = content.textContent;
3821 }
3822
3823 return;
3824 }
3825
3826 if (this.config.html) {
3827 if (this.config.sanitize) {
3828 content = sanitizeHtml(content, this.config.allowList, this.config.sanitizeFn);
3829 }
3830
3831 element.innerHTML = content;
3832 } else {
3833 element.textContent = content;
3834 }
3835 }
3836
3837 getTitle() {
3838 let title = this._element.getAttribute('data-bs-original-title');
3839
3840 if (!title) {
3841 title = typeof this.config.title === 'function' ? this.config.title.call(this._element) : this.config.title;
3842 }
3843
3844 return title;
3845 }
3846
3847 updateAttachment(attachment) {
3848 if (attachment === 'right') {
3849 return 'end';
3850 }
3851
3852 if (attachment === 'left') {
3853 return 'start';
3854 }
3855
3856 return attachment;
3857 } // Private
3858
3859
3860 _initializeOnDelegatedTarget(event, context) {
3861 const dataKey = this.constructor.DATA_KEY;
3862 context = context || Data.get(event.delegateTarget, dataKey);
3863
3864 if (!context) {
3865 context = new this.constructor(event.delegateTarget, this._getDelegateConfig());
3866 Data.set(event.delegateTarget, dataKey, context);
3867 }
3868
3869 return context;
3870 }
3871
3872 _getOffset() {
3873 const {
3874 offset
3875 } = this.config;
3876
3877 if (typeof offset === 'string') {
3878 return offset.split(',').map(val => Number.parseInt(val, 10));
3879 }
3880
3881 if (typeof offset === 'function') {
3882 return popperData => offset(popperData, this._element);
3883 }
3884
3885 return offset;
3886 }
3887
3888 _getPopperConfig(attachment) {
3889 const defaultBsPopperConfig = {
3890 placement: attachment,
3891 modifiers: [{
3892 name: 'flip',
3893 options: {
3894 altBoundary: true,
3895 fallbackPlacements: this.config.fallbackPlacements
3896 }
3897 }, {
3898 name: 'offset',
3899 options: {
3900 offset: this._getOffset()
3901 }
3902 }, {
3903 name: 'preventOverflow',
3904 options: {
3905 boundary: this.config.boundary
3906 }
3907 }, {
3908 name: 'arrow',
3909 options: {
3910 element: `.${this.constructor.NAME}-arrow`
3911 }
3912 }, {
3913 name: 'onChange',
3914 enabled: true,
3915 phase: 'afterWrite',
3916 fn: data => this._handlePopperPlacementChange(data)
3917 }],
3918 onFirstUpdate: data => {
3919 if (data.options.placement !== data.placement) {
3920 this._handlePopperPlacementChange(data);
3921 }
3922 }
3923 };
3924 return { ...defaultBsPopperConfig,
3925 ...(typeof this.config.popperConfig === 'function' ? this.config.popperConfig(defaultBsPopperConfig) : this.config.popperConfig)
3926 };
3927 }
3928
3929 _addAttachmentClass(attachment) {
3930 this.getTipElement().classList.add(`${CLASS_PREFIX$1}-${this.updateAttachment(attachment)}`);
3931 }
3932
3933 _getContainer() {
3934 if (this.config.container === false) {
3935 return document.body;
3936 }
3937
3938 if (isElement(this.config.container)) {
3939 return this.config.container;
3940 }
3941
3942 return SelectorEngine.findOne(this.config.container);
3943 }
3944
3945 _getAttachment(placement) {
3946 return AttachmentMap[placement.toUpperCase()];
3947 }
3948
3949 _setListeners() {
3950 const triggers = this.config.trigger.split(' ');
3951 triggers.forEach(trigger => {
3952 if (trigger === 'click') {
3953 EventHandler.on(this._element, this.constructor.Event.CLICK, this.config.selector, event => this.toggle(event));
3954 } else if (trigger !== TRIGGER_MANUAL) {
3955 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSEENTER : this.constructor.Event.FOCUSIN;
3956 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.Event.MOUSELEAVE : this.constructor.Event.FOCUSOUT;
3957 EventHandler.on(this._element, eventIn, this.config.selector, event => this._enter(event));
3958 EventHandler.on(this._element, eventOut, this.config.selector, event => this._leave(event));
3959 }
3960 });
3961
3962 this._hideModalHandler = () => {
3963 if (this._element) {
3964 this.hide();
3965 }
3966 };
3967
3968 EventHandler.on(this._element.closest(`.${CLASS_NAME_MODAL}`), 'hide.bs.modal', this._hideModalHandler);
3969
3970 if (this.config.selector) {
3971 this.config = { ...this.config,
3972 trigger: 'manual',
3973 selector: ''
3974 };
3975 } else {
3976 this._fixTitle();
3977 }
3978 }
3979
3980 _fixTitle() {
3981 const title = this._element.getAttribute('title');
3982
3983 const originalTitleType = typeof this._element.getAttribute('data-bs-original-title');
3984
3985 if (title || originalTitleType !== 'string') {
3986 this._element.setAttribute('data-bs-original-title', title || '');
3987
3988 if (title && !this._element.getAttribute('aria-label') && !this._element.textContent) {
3989 this._element.setAttribute('aria-label', title);
3990 }
3991
3992 this._element.setAttribute('title', '');
3993 }
3994 }
3995
3996 _enter(event, context) {
3997 context = this._initializeOnDelegatedTarget(event, context);
3998
3999 if (event) {
4000 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
4001 }
4002
4003 if (context.getTipElement().classList.contains(CLASS_NAME_SHOW$3) || context._hoverState === HOVER_STATE_SHOW) {
4004 context._hoverState = HOVER_STATE_SHOW;
4005 return;
4006 }
4007
4008 clearTimeout(context._timeout);
4009 context._hoverState = HOVER_STATE_SHOW;
4010
4011 if (!context.config.delay || !context.config.delay.show) {
4012 context.show();
4013 return;
4014 }
4015
4016 context._timeout = setTimeout(() => {
4017 if (context._hoverState === HOVER_STATE_SHOW) {
4018 context.show();
4019 }
4020 }, context.config.delay.show);
4021 }
4022
4023 _leave(event, context) {
4024 context = this._initializeOnDelegatedTarget(event, context);
4025
4026 if (event) {
4027 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);
4028 }
4029
4030 if (context._isWithActiveTrigger()) {
4031 return;
4032 }
4033
4034 clearTimeout(context._timeout);
4035 context._hoverState = HOVER_STATE_OUT;
4036
4037 if (!context.config.delay || !context.config.delay.hide) {
4038 context.hide();
4039 return;
4040 }
4041
4042 context._timeout = setTimeout(() => {
4043 if (context._hoverState === HOVER_STATE_OUT) {
4044 context.hide();
4045 }
4046 }, context.config.delay.hide);
4047 }
4048
4049 _isWithActiveTrigger() {
4050 for (const trigger in this._activeTrigger) {
4051 if (this._activeTrigger[trigger]) {
4052 return true;
4053 }
4054 }
4055
4056 return false;
4057 }
4058
4059 _getConfig(config) {
4060 const dataAttributes = Manipulator.getDataAttributes(this._element);
4061 Object.keys(dataAttributes).forEach(dataAttr => {
4062 if (DISALLOWED_ATTRIBUTES.has(dataAttr)) {
4063 delete dataAttributes[dataAttr];
4064 }
4065 });
4066
4067 if (config && typeof config.container === 'object' && config.container.jquery) {
4068 config.container = config.container[0];
4069 }
4070
4071 config = { ...this.constructor.Default,
4072 ...dataAttributes,
4073 ...(typeof config === 'object' && config ? config : {})
4074 };
4075
4076 if (typeof config.delay === 'number') {
4077 config.delay = {
4078 show: config.delay,
4079 hide: config.delay
4080 };
4081 }
4082
4083 if (typeof config.title === 'number') {
4084 config.title = config.title.toString();
4085 }
4086
4087 if (typeof config.content === 'number') {
4088 config.content = config.content.toString();
4089 }
4090
4091 typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
4092
4093 if (config.sanitize) {
4094 config.template = sanitizeHtml(config.template, config.allowList, config.sanitizeFn);
4095 }
4096
4097 return config;
4098 }
4099
4100 _getDelegateConfig() {
4101 const config = {};
4102
4103 if (this.config) {
4104 for (const key in this.config) {
4105 if (this.constructor.Default[key] !== this.config[key]) {
4106 config[key] = this.config[key];
4107 }
4108 }
4109 }
4110
4111 return config;
4112 }
4113
4114 _cleanTipClass() {
4115 const tip = this.getTipElement();
4116 const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX$1);
4117
4118 if (tabClass !== null && tabClass.length > 0) {
4119 tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));
4120 }
4121 }
4122
4123 _handlePopperPlacementChange(popperData) {
4124 const {
4125 state
4126 } = popperData;
4127
4128 if (!state) {
4129 return;
4130 }
4131
4132 this.tip = state.elements.popper;
4133
4134 this._cleanTipClass();
4135
4136 this._addAttachmentClass(this._getAttachment(state.placement));
4137 } // Static
4138
4139
4140 static jQueryInterface(config) {
4141 return this.each(function () {
4142 let data = Data.get(this, DATA_KEY$4);
4143
4144 const _config = typeof config === 'object' && config;
4145
4146 if (!data && /dispose|hide/.test(config)) {
4147 return;
4148 }
4149
4150 if (!data) {
4151 data = new Tooltip(this, _config);
4152 }
4153
4154 if (typeof config === 'string') {
4155 if (typeof data[config] === 'undefined') {
4156 throw new TypeError(`No method named "${config}"`);
4157 }
4158
4159 data[config]();
4160 }
4161 });
4162 }
4163
4164 }
4165 /**
4166 * ------------------------------------------------------------------------
4167 * jQuery
4168 * ------------------------------------------------------------------------
4169 * add .Tooltip to jQuery only if jQuery is present
4170 */
4171
4172
4173 defineJQueryPlugin(NAME$4, Tooltip);
4174
4175 /**
4176 * --------------------------------------------------------------------------
4177 * Bootstrap (v5.0.0-beta3): popover.js
4178 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4179 * --------------------------------------------------------------------------
4180 */
4181 /**
4182 * ------------------------------------------------------------------------
4183 * Constants
4184 * ------------------------------------------------------------------------
4185 */
4186
4187 const NAME$3 = 'popover';
4188 const DATA_KEY$3 = 'bs.popover';
4189 const EVENT_KEY$3 = `.${DATA_KEY$3}`;
4190 const CLASS_PREFIX = 'bs-popover';
4191 const BSCLS_PREFIX_REGEX = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g');
4192 const Default$2 = { ...Tooltip.Default,
4193 placement: 'right',
4194 offset: [0, 8],
4195 trigger: 'click',
4196 content: '',
4197 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>'
4198 };
4199 const DefaultType$2 = { ...Tooltip.DefaultType,
4200 content: '(string|element|function)'
4201 };
4202 const Event$1 = {
4203 HIDE: `hide${EVENT_KEY$3}`,
4204 HIDDEN: `hidden${EVENT_KEY$3}`,
4205 SHOW: `show${EVENT_KEY$3}`,
4206 SHOWN: `shown${EVENT_KEY$3}`,
4207 INSERTED: `inserted${EVENT_KEY$3}`,
4208 CLICK: `click${EVENT_KEY$3}`,
4209 FOCUSIN: `focusin${EVENT_KEY$3}`,
4210 FOCUSOUT: `focusout${EVENT_KEY$3}`,
4211 MOUSEENTER: `mouseenter${EVENT_KEY$3}`,
4212 MOUSELEAVE: `mouseleave${EVENT_KEY$3}`
4213 };
4214 const CLASS_NAME_FADE$2 = 'fade';
4215 const CLASS_NAME_SHOW$2 = 'show';
4216 const SELECTOR_TITLE = '.popover-header';
4217 const SELECTOR_CONTENT = '.popover-body';
4218 /**
4219 * ------------------------------------------------------------------------
4220 * Class Definition
4221 * ------------------------------------------------------------------------
4222 */
4223
4224 class Popover extends Tooltip {
4225 // Getters
4226 static get Default() {
4227 return Default$2;
4228 }
4229
4230 static get NAME() {
4231 return NAME$3;
4232 }
4233
4234 static get DATA_KEY() {
4235 return DATA_KEY$3;
4236 }
4237
4238 static get Event() {
4239 return Event$1;
4240 }
4241
4242 static get EVENT_KEY() {
4243 return EVENT_KEY$3;
4244 }
4245
4246 static get DefaultType() {
4247 return DefaultType$2;
4248 } // Overrides
4249
4250
4251 isWithContent() {
4252 return this.getTitle() || this._getContent();
4253 }
4254
4255 setContent() {
4256 const tip = this.getTipElement(); // we use append for html objects to maintain js events
4257
4258 this.setElementContent(SelectorEngine.findOne(SELECTOR_TITLE, tip), this.getTitle());
4259
4260 let content = this._getContent();
4261
4262 if (typeof content === 'function') {
4263 content = content.call(this._element);
4264 }
4265
4266 this.setElementContent(SelectorEngine.findOne(SELECTOR_CONTENT, tip), content);
4267 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);
4268 } // Private
4269
4270
4271 _addAttachmentClass(attachment) {
4272 this.getTipElement().classList.add(`${CLASS_PREFIX}-${this.updateAttachment(attachment)}`);
4273 }
4274
4275 _getContent() {
4276 return this._element.getAttribute('data-bs-content') || this.config.content;
4277 }
4278
4279 _cleanTipClass() {
4280 const tip = this.getTipElement();
4281 const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX);
4282
4283 if (tabClass !== null && tabClass.length > 0) {
4284 tabClass.map(token => token.trim()).forEach(tClass => tip.classList.remove(tClass));
4285 }
4286 } // Static
4287
4288
4289 static jQueryInterface(config) {
4290 return this.each(function () {
4291 let data = Data.get(this, DATA_KEY$3);
4292
4293 const _config = typeof config === 'object' ? config : null;
4294
4295 if (!data && /dispose|hide/.test(config)) {
4296 return;
4297 }
4298
4299 if (!data) {
4300 data = new Popover(this, _config);
4301 Data.set(this, DATA_KEY$3, data);
4302 }
4303
4304 if (typeof config === 'string') {
4305 if (typeof data[config] === 'undefined') {
4306 throw new TypeError(`No method named "${config}"`);
4307 }
4308
4309 data[config]();
4310 }
4311 });
4312 }
4313
4314 }
4315 /**
4316 * ------------------------------------------------------------------------
4317 * jQuery
4318 * ------------------------------------------------------------------------
4319 * add .Popover to jQuery only if jQuery is present
4320 */
4321
4322
4323 defineJQueryPlugin(NAME$3, Popover);
4324
4325 /**
4326 * --------------------------------------------------------------------------
4327 * Bootstrap (v5.0.0-beta3): scrollspy.js
4328 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4329 * --------------------------------------------------------------------------
4330 */
4331 /**
4332 * ------------------------------------------------------------------------
4333 * Constants
4334 * ------------------------------------------------------------------------
4335 */
4336
4337 const NAME$2 = 'scrollspy';
4338 const DATA_KEY$2 = 'bs.scrollspy';
4339 const EVENT_KEY$2 = `.${DATA_KEY$2}`;
4340 const DATA_API_KEY$1 = '.data-api';
4341 const Default$1 = {
4342 offset: 10,
4343 method: 'auto',
4344 target: ''
4345 };
4346 const DefaultType$1 = {
4347 offset: 'number',
4348 method: 'string',
4349 target: '(string|element)'
4350 };
4351 const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;
4352 const EVENT_SCROLL = `scroll${EVENT_KEY$2}`;
4353 const EVENT_LOAD_DATA_API = `load${EVENT_KEY$2}${DATA_API_KEY$1}`;
4354 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
4355 const CLASS_NAME_ACTIVE$1 = 'active';
4356 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
4357 const SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';
4358 const SELECTOR_NAV_LINKS = '.nav-link';
4359 const SELECTOR_NAV_ITEMS = '.nav-item';
4360 const SELECTOR_LIST_ITEMS = '.list-group-item';
4361 const SELECTOR_DROPDOWN$1 = '.dropdown';
4362 const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
4363 const METHOD_OFFSET = 'offset';
4364 const METHOD_POSITION = 'position';
4365 /**
4366 * ------------------------------------------------------------------------
4367 * Class Definition
4368 * ------------------------------------------------------------------------
4369 */
4370
4371 class ScrollSpy extends BaseComponent {
4372 constructor(element, config) {
4373 super(element);
4374 this._scrollElement = this._element.tagName === 'BODY' ? window : this._element;
4375 this._config = this._getConfig(config);
4376 this._selector = `${this._config.target} ${SELECTOR_NAV_LINKS}, ${this._config.target} ${SELECTOR_LIST_ITEMS}, ${this._config.target} .${CLASS_NAME_DROPDOWN_ITEM}`;
4377 this._offsets = [];
4378 this._targets = [];
4379 this._activeTarget = null;
4380 this._scrollHeight = 0;
4381 EventHandler.on(this._scrollElement, EVENT_SCROLL, () => this._process());
4382 this.refresh();
4383
4384 this._process();
4385 } // Getters
4386
4387
4388 static get Default() {
4389 return Default$1;
4390 }
4391
4392 static get DATA_KEY() {
4393 return DATA_KEY$2;
4394 } // Public
4395
4396
4397 refresh() {
4398 const autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
4399 const offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
4400 const offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
4401 this._offsets = [];
4402 this._targets = [];
4403 this._scrollHeight = this._getScrollHeight();
4404 const targets = SelectorEngine.find(this._selector);
4405 targets.map(element => {
4406 const targetSelector = getSelectorFromElement(element);
4407 const target = targetSelector ? SelectorEngine.findOne(targetSelector) : null;
4408
4409 if (target) {
4410 const targetBCR = target.getBoundingClientRect();
4411
4412 if (targetBCR.width || targetBCR.height) {
4413 return [Manipulator[offsetMethod](target).top + offsetBase, targetSelector];
4414 }
4415 }
4416
4417 return null;
4418 }).filter(item => item).sort((a, b) => a[0] - b[0]).forEach(item => {
4419 this._offsets.push(item[0]);
4420
4421 this._targets.push(item[1]);
4422 });
4423 }
4424
4425 dispose() {
4426 super.dispose();
4427 EventHandler.off(this._scrollElement, EVENT_KEY$2);
4428 this._scrollElement = null;
4429 this._config = null;
4430 this._selector = null;
4431 this._offsets = null;
4432 this._targets = null;
4433 this._activeTarget = null;
4434 this._scrollHeight = null;
4435 } // Private
4436
4437
4438 _getConfig(config) {
4439 config = { ...Default$1,
4440 ...(typeof config === 'object' && config ? config : {})
4441 };
4442
4443 if (typeof config.target !== 'string' && isElement(config.target)) {
4444 let {
4445 id
4446 } = config.target;
4447
4448 if (!id) {
4449 id = getUID(NAME$2);
4450 config.target.id = id;
4451 }
4452
4453 config.target = `#${id}`;
4454 }
4455
4456 typeCheckConfig(NAME$2, config, DefaultType$1);
4457 return config;
4458 }
4459
4460 _getScrollTop() {
4461 return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
4462 }
4463
4464 _getScrollHeight() {
4465 return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
4466 }
4467
4468 _getOffsetHeight() {
4469 return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
4470 }
4471
4472 _process() {
4473 const scrollTop = this._getScrollTop() + this._config.offset;
4474
4475 const scrollHeight = this._getScrollHeight();
4476
4477 const maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
4478
4479 if (this._scrollHeight !== scrollHeight) {
4480 this.refresh();
4481 }
4482
4483 if (scrollTop >= maxScroll) {
4484 const target = this._targets[this._targets.length - 1];
4485
4486 if (this._activeTarget !== target) {
4487 this._activate(target);
4488 }
4489
4490 return;
4491 }
4492
4493 if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
4494 this._activeTarget = null;
4495
4496 this._clear();
4497
4498 return;
4499 }
4500
4501 for (let i = this._offsets.length; i--;) {
4502 const isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
4503
4504 if (isActiveTarget) {
4505 this._activate(this._targets[i]);
4506 }
4507 }
4508 }
4509
4510 _activate(target) {
4511 this._activeTarget = target;
4512
4513 this._clear();
4514
4515 const queries = this._selector.split(',').map(selector => `${selector}[data-bs-target="${target}"],${selector}[href="${target}"]`);
4516
4517 const link = SelectorEngine.findOne(queries.join(','));
4518
4519 if (link.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
4520 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, link.closest(SELECTOR_DROPDOWN$1)).classList.add(CLASS_NAME_ACTIVE$1);
4521 link.classList.add(CLASS_NAME_ACTIVE$1);
4522 } else {
4523 // Set triggered link as active
4524 link.classList.add(CLASS_NAME_ACTIVE$1);
4525 SelectorEngine.parents(link, SELECTOR_NAV_LIST_GROUP$1).forEach(listGroup => {
4526 // Set triggered links parents as active
4527 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
4528 SelectorEngine.prev(listGroup, `${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1)); // Handle special case when .nav-link is inside .nav-item
4529
4530 SelectorEngine.prev(listGroup, SELECTOR_NAV_ITEMS).forEach(navItem => {
4531 SelectorEngine.children(navItem, SELECTOR_NAV_LINKS).forEach(item => item.classList.add(CLASS_NAME_ACTIVE$1));
4532 });
4533 });
4534 }
4535
4536 EventHandler.trigger(this._scrollElement, EVENT_ACTIVATE, {
4537 relatedTarget: target
4538 });
4539 }
4540
4541 _clear() {
4542 SelectorEngine.find(this._selector).filter(node => node.classList.contains(CLASS_NAME_ACTIVE$1)).forEach(node => node.classList.remove(CLASS_NAME_ACTIVE$1));
4543 } // Static
4544
4545
4546 static jQueryInterface(config) {
4547 return this.each(function () {
4548 let data = Data.get(this, DATA_KEY$2);
4549
4550 const _config = typeof config === 'object' && config;
4551
4552 if (!data) {
4553 data = new ScrollSpy(this, _config);
4554 }
4555
4556 if (typeof config === 'string') {
4557 if (typeof data[config] === 'undefined') {
4558 throw new TypeError(`No method named "${config}"`);
4559 }
4560
4561 data[config]();
4562 }
4563 });
4564 }
4565
4566 }
4567 /**
4568 * ------------------------------------------------------------------------
4569 * Data Api implementation
4570 * ------------------------------------------------------------------------
4571 */
4572
4573
4574 EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
4575 SelectorEngine.find(SELECTOR_DATA_SPY).forEach(spy => new ScrollSpy(spy, Manipulator.getDataAttributes(spy)));
4576 });
4577 /**
4578 * ------------------------------------------------------------------------
4579 * jQuery
4580 * ------------------------------------------------------------------------
4581 * add .ScrollSpy to jQuery only if jQuery is present
4582 */
4583
4584 defineJQueryPlugin(NAME$2, ScrollSpy);
4585
4586 /**
4587 * --------------------------------------------------------------------------
4588 * Bootstrap (v5.0.0-beta3): tab.js
4589 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4590 * --------------------------------------------------------------------------
4591 */
4592 /**
4593 * ------------------------------------------------------------------------
4594 * Constants
4595 * ------------------------------------------------------------------------
4596 */
4597
4598 const NAME$1 = 'tab';
4599 const DATA_KEY$1 = 'bs.tab';
4600 const EVENT_KEY$1 = `.${DATA_KEY$1}`;
4601 const DATA_API_KEY = '.data-api';
4602 const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;
4603 const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;
4604 const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;
4605 const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;
4606 const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}${DATA_API_KEY}`;
4607 const CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';
4608 const CLASS_NAME_ACTIVE = 'active';
4609 const CLASS_NAME_FADE$1 = 'fade';
4610 const CLASS_NAME_SHOW$1 = 'show';
4611 const SELECTOR_DROPDOWN = '.dropdown';
4612 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
4613 const SELECTOR_ACTIVE = '.active';
4614 const SELECTOR_ACTIVE_UL = ':scope > li > .active';
4615 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]';
4616 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
4617 const SELECTOR_DROPDOWN_ACTIVE_CHILD = ':scope > .dropdown-menu .active';
4618 /**
4619 * ------------------------------------------------------------------------
4620 * Class Definition
4621 * ------------------------------------------------------------------------
4622 */
4623
4624 class Tab extends BaseComponent {
4625 // Getters
4626 static get DATA_KEY() {
4627 return DATA_KEY$1;
4628 } // Public
4629
4630
4631 show() {
4632 if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && this._element.classList.contains(CLASS_NAME_ACTIVE) || isDisabled(this._element)) {
4633 return;
4634 }
4635
4636 let previous;
4637 const target = getElementFromSelector(this._element);
4638
4639 const listElement = this._element.closest(SELECTOR_NAV_LIST_GROUP);
4640
4641 if (listElement) {
4642 const itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE;
4643 previous = SelectorEngine.find(itemSelector, listElement);
4644 previous = previous[previous.length - 1];
4645 }
4646
4647 const hideEvent = previous ? EventHandler.trigger(previous, EVENT_HIDE$1, {
4648 relatedTarget: this._element
4649 }) : null;
4650 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$1, {
4651 relatedTarget: previous
4652 });
4653
4654 if (showEvent.defaultPrevented || hideEvent !== null && hideEvent.defaultPrevented) {
4655 return;
4656 }
4657
4658 this._activate(this._element, listElement);
4659
4660 const complete = () => {
4661 EventHandler.trigger(previous, EVENT_HIDDEN$1, {
4662 relatedTarget: this._element
4663 });
4664 EventHandler.trigger(this._element, EVENT_SHOWN$1, {
4665 relatedTarget: previous
4666 });
4667 };
4668
4669 if (target) {
4670 this._activate(target, target.parentNode, complete);
4671 } else {
4672 complete();
4673 }
4674 } // Private
4675
4676
4677 _activate(element, container, callback) {
4678 const activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? SelectorEngine.find(SELECTOR_ACTIVE_UL, container) : SelectorEngine.children(container, SELECTOR_ACTIVE);
4679 const active = activeElements[0];
4680 const isTransitioning = callback && active && active.classList.contains(CLASS_NAME_FADE$1);
4681
4682 const complete = () => this._transitionComplete(element, active, callback);
4683
4684 if (active && isTransitioning) {
4685 const transitionDuration = getTransitionDurationFromElement(active);
4686 active.classList.remove(CLASS_NAME_SHOW$1);
4687 EventHandler.one(active, 'transitionend', complete);
4688 emulateTransitionEnd(active, transitionDuration);
4689 } else {
4690 complete();
4691 }
4692 }
4693
4694 _transitionComplete(element, active, callback) {
4695 if (active) {
4696 active.classList.remove(CLASS_NAME_ACTIVE);
4697 const dropdownChild = SelectorEngine.findOne(SELECTOR_DROPDOWN_ACTIVE_CHILD, active.parentNode);
4698
4699 if (dropdownChild) {
4700 dropdownChild.classList.remove(CLASS_NAME_ACTIVE);
4701 }
4702
4703 if (active.getAttribute('role') === 'tab') {
4704 active.setAttribute('aria-selected', false);
4705 }
4706 }
4707
4708 element.classList.add(CLASS_NAME_ACTIVE);
4709
4710 if (element.getAttribute('role') === 'tab') {
4711 element.setAttribute('aria-selected', true);
4712 }
4713
4714 reflow(element);
4715
4716 if (element.classList.contains(CLASS_NAME_FADE$1)) {
4717 element.classList.add(CLASS_NAME_SHOW$1);
4718 }
4719
4720 if (element.parentNode && element.parentNode.classList.contains(CLASS_NAME_DROPDOWN_MENU)) {
4721 const dropdownElement = element.closest(SELECTOR_DROPDOWN);
4722
4723 if (dropdownElement) {
4724 SelectorEngine.find(SELECTOR_DROPDOWN_TOGGLE).forEach(dropdown => dropdown.classList.add(CLASS_NAME_ACTIVE));
4725 }
4726
4727 element.setAttribute('aria-expanded', true);
4728 }
4729
4730 if (callback) {
4731 callback();
4732 }
4733 } // Static
4734
4735
4736 static jQueryInterface(config) {
4737 return this.each(function () {
4738 const data = Data.get(this, DATA_KEY$1) || new Tab(this);
4739
4740 if (typeof config === 'string') {
4741 if (typeof data[config] === 'undefined') {
4742 throw new TypeError(`No method named "${config}"`);
4743 }
4744
4745 data[config]();
4746 }
4747 });
4748 }
4749
4750 }
4751 /**
4752 * ------------------------------------------------------------------------
4753 * Data Api implementation
4754 * ------------------------------------------------------------------------
4755 */
4756
4757
4758 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
4759 event.preventDefault();
4760 const data = Data.get(this, DATA_KEY$1) || new Tab(this);
4761 data.show();
4762 });
4763 /**
4764 * ------------------------------------------------------------------------
4765 * jQuery
4766 * ------------------------------------------------------------------------
4767 * add .Tab to jQuery only if jQuery is present
4768 */
4769
4770 defineJQueryPlugin(NAME$1, Tab);
4771
4772 /**
4773 * --------------------------------------------------------------------------
4774 * Bootstrap (v5.0.0-beta3): toast.js
4775 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4776 * --------------------------------------------------------------------------
4777 */
4778 /**
4779 * ------------------------------------------------------------------------
4780 * Constants
4781 * ------------------------------------------------------------------------
4782 */
4783
4784 const NAME = 'toast';
4785 const DATA_KEY = 'bs.toast';
4786 const EVENT_KEY = `.${DATA_KEY}`;
4787 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
4788 const EVENT_HIDE = `hide${EVENT_KEY}`;
4789 const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
4790 const EVENT_SHOW = `show${EVENT_KEY}`;
4791 const EVENT_SHOWN = `shown${EVENT_KEY}`;
4792 const CLASS_NAME_FADE = 'fade';
4793 const CLASS_NAME_HIDE = 'hide';
4794 const CLASS_NAME_SHOW = 'show';
4795 const CLASS_NAME_SHOWING = 'showing';
4796 const DefaultType = {
4797 animation: 'boolean',
4798 autohide: 'boolean',
4799 delay: 'number'
4800 };
4801 const Default = {
4802 animation: true,
4803 autohide: true,
4804 delay: 5000
4805 };
4806 const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="toast"]';
4807 /**
4808 * ------------------------------------------------------------------------
4809 * Class Definition
4810 * ------------------------------------------------------------------------
4811 */
4812
4813 class Toast extends BaseComponent {
4814 constructor(element, config) {
4815 super(element);
4816 this._config = this._getConfig(config);
4817 this._timeout = null;
4818
4819 this._setListeners();
4820 } // Getters
4821
4822
4823 static get DefaultType() {
4824 return DefaultType;
4825 }
4826
4827 static get Default() {
4828 return Default;
4829 }
4830
4831 static get DATA_KEY() {
4832 return DATA_KEY;
4833 } // Public
4834
4835
4836 show() {
4837 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);
4838
4839 if (showEvent.defaultPrevented) {
4840 return;
4841 }
4842
4843 this._clearTimeout();
4844
4845 if (this._config.animation) {
4846 this._element.classList.add(CLASS_NAME_FADE);
4847 }
4848
4849 const complete = () => {
4850 this._element.classList.remove(CLASS_NAME_SHOWING);
4851
4852 this._element.classList.add(CLASS_NAME_SHOW);
4853
4854 EventHandler.trigger(this._element, EVENT_SHOWN);
4855
4856 if (this._config.autohide) {
4857 this._timeout = setTimeout(() => {
4858 this.hide();
4859 }, this._config.delay);
4860 }
4861 };
4862
4863 this._element.classList.remove(CLASS_NAME_HIDE);
4864
4865 reflow(this._element);
4866
4867 this._element.classList.add(CLASS_NAME_SHOWING);
4868
4869 if (this._config.animation) {
4870 const transitionDuration = getTransitionDurationFromElement(this._element);
4871 EventHandler.one(this._element, 'transitionend', complete);
4872 emulateTransitionEnd(this._element, transitionDuration);
4873 } else {
4874 complete();
4875 }
4876 }
4877
4878 hide() {
4879 if (!this._element.classList.contains(CLASS_NAME_SHOW)) {
4880 return;
4881 }
4882
4883 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
4884
4885 if (hideEvent.defaultPrevented) {
4886 return;
4887 }
4888
4889 const complete = () => {
4890 this._element.classList.add(CLASS_NAME_HIDE);
4891
4892 EventHandler.trigger(this._element, EVENT_HIDDEN);
4893 };
4894
4895 this._element.classList.remove(CLASS_NAME_SHOW);
4896
4897 if (this._config.animation) {
4898 const transitionDuration = getTransitionDurationFromElement(this._element);
4899 EventHandler.one(this._element, 'transitionend', complete);
4900 emulateTransitionEnd(this._element, transitionDuration);
4901 } else {
4902 complete();
4903 }
4904 }
4905
4906 dispose() {
4907 this._clearTimeout();
4908
4909 if (this._element.classList.contains(CLASS_NAME_SHOW)) {
4910 this._element.classList.remove(CLASS_NAME_SHOW);
4911 }
4912
4913 EventHandler.off(this._element, EVENT_CLICK_DISMISS);
4914 super.dispose();
4915 this._config = null;
4916 } // Private
4917
4918
4919 _getConfig(config) {
4920 config = { ...Default,
4921 ...Manipulator.getDataAttributes(this._element),
4922 ...(typeof config === 'object' && config ? config : {})
4923 };
4924 typeCheckConfig(NAME, config, this.constructor.DefaultType);
4925 return config;
4926 }
4927
4928 _setListeners() {
4929 EventHandler.on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
4930 }
4931
4932 _clearTimeout() {
4933 clearTimeout(this._timeout);
4934 this._timeout = null;
4935 } // Static
4936
4937
4938 static jQueryInterface(config) {
4939 return this.each(function () {
4940 let data = Data.get(this, DATA_KEY);
4941
4942 const _config = typeof config === 'object' && config;
4943
4944 if (!data) {
4945 data = new Toast(this, _config);
4946 }
4947
4948 if (typeof config === 'string') {
4949 if (typeof data[config] === 'undefined') {
4950 throw new TypeError(`No method named "${config}"`);
4951 }
4952
4953 data[config](this);
4954 }
4955 });
4956 }
4957
4958 }
4959 /**
4960 * ------------------------------------------------------------------------
4961 * jQuery
4962 * ------------------------------------------------------------------------
4963 * add .Toast to jQuery only if jQuery is present
4964 */
4965
4966
4967 defineJQueryPlugin(NAME, Toast);
4968
4969 /**
4970 * --------------------------------------------------------------------------
4971 * Bootstrap (v5.0.0-beta3): index.umd.js
4972 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4973 * --------------------------------------------------------------------------
4974 */
4975 var index_umd = {
4976 Alert,
4977 Button,
4978 Carousel,
4979 Collapse,
4980 Dropdown,
4981 Modal,
4982 Offcanvas,
4983 Popover,
4984 ScrollSpy,
4985 Tab,
4986 Toast,
4987 Tooltip
4988 };
4989
4990 return index_umd;
4991
4992})));
4993//# sourceMappingURL=bootstrap.js.map
Note: See TracBrowser for help on using the repository browser.