2 * Bootstrap v5.3.3 (https://getbootstrap.com/)
3 * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6(function (global, factory) {
7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8 typeof define === 'function' && define.amd ? define(factory) :
9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory());
10})(this, (function () { 'use strict';
13 * --------------------------------------------------------------------------
14 * Bootstrap dom/data.js
15 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
16 * --------------------------------------------------------------------------
23 const elementMap = new Map();
25 set(element, key, instance) {
26 if (!elementMap.has(element)) {
27 elementMap.set(element, new Map());
29 const instanceMap = elementMap.get(element);
31 // make it clear we only want one instance per element
32 // can be removed later when multiple key/instances are fine to be used
33 if (!instanceMap.has(key) && instanceMap.size !== 0) {
34 // eslint-disable-next-line no-console
35 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);
38 instanceMap.set(key, instance);
41 if (elementMap.has(element)) {
42 return elementMap.get(element).get(key) || null;
46 remove(element, key) {
47 if (!elementMap.has(element)) {
50 const instanceMap = elementMap.get(element);
51 instanceMap.delete(key);
53 // free up element references if there are no instances left for an element
54 if (instanceMap.size === 0) {
55 elementMap.delete(element);
61 * --------------------------------------------------------------------------
62 * Bootstrap util/index.js
63 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
64 * --------------------------------------------------------------------------
67 const MAX_UID = 1000000;
68 const MILLISECONDS_MULTIPLIER = 1000;
69 const TRANSITION_END = 'transitionend';
72 * Properly escape IDs selectors to handle weird IDs
73 * @param {string} selector
76 const parseSelector = selector => {
77 if (selector && window.CSS && window.CSS.escape) {
78 // document.querySelector needs escaping to handle IDs (html5+) containing for instance /
79 selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`);
84 // Shout-out Angus Croll (https://goo.gl/pxwQGp)
85 const toType = object => {
86 if (object === null || object === undefined) {
89 return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
96 const getUID = prefix => {
98 prefix += Math.floor(Math.random() * MAX_UID);
99 } while (document.getElementById(prefix));
102 const getTransitionDurationFromElement = element => {
107 // Get transition-duration of the element
111 } = window.getComputedStyle(element);
112 const floatTransitionDuration = Number.parseFloat(transitionDuration);
113 const floatTransitionDelay = Number.parseFloat(transitionDelay);
115 // Return 0 if element or transition duration is not found
116 if (!floatTransitionDuration && !floatTransitionDelay) {
120 // If multiple durations are defined, take the first
121 transitionDuration = transitionDuration.split(',')[0];
122 transitionDelay = transitionDelay.split(',')[0];
123 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
125 const triggerTransitionEnd = element => {
126 element.dispatchEvent(new Event(TRANSITION_END));
128 const isElement$1 = object => {
129 if (!object || typeof object !== 'object') {
132 if (typeof object.jquery !== 'undefined') {
135 return typeof object.nodeType !== 'undefined';
137 const getElement = object => {
138 // it's a jQuery object or a node element
139 if (isElement$1(object)) {
140 return object.jquery ? object[0] : object;
142 if (typeof object === 'string' && object.length > 0) {
143 return document.querySelector(parseSelector(object));
147 const isVisible = element => {
148 if (!isElement$1(element) || element.getClientRects().length === 0) {
151 const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible';
152 // Handle `details` element as its content may falsie appear visible when it is closed
153 const closedDetails = element.closest('details:not([open])');
154 if (!closedDetails) {
155 return elementIsVisible;
157 if (closedDetails !== element) {
158 const summary = element.closest('summary');
159 if (summary && summary.parentNode !== closedDetails) {
162 if (summary === null) {
166 return elementIsVisible;
168 const isDisabled = element => {
169 if (!element || element.nodeType !== Node.ELEMENT_NODE) {
172 if (element.classList.contains('disabled')) {
175 if (typeof element.disabled !== 'undefined') {
176 return element.disabled;
178 return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
180 const findShadowRoot = element => {
181 if (!document.documentElement.attachShadow) {
185 // Can find the shadow root otherwise it'll return the document
186 if (typeof element.getRootNode === 'function') {
187 const root = element.getRootNode();
188 return root instanceof ShadowRoot ? root : null;
190 if (element instanceof ShadowRoot) {
194 // when we don't find a shadow root
195 if (!element.parentNode) {
198 return findShadowRoot(element.parentNode);
200 const noop = () => {};
203 * Trick to restart an element's animation
205 * @param {HTMLElement} element
208 * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
210 const reflow = element => {
211 element.offsetHeight; // eslint-disable-line no-unused-expressions
213 const getjQuery = () => {
214 if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
215 return window.jQuery;
219 const DOMContentLoadedCallbacks = [];
220 const onDOMContentLoaded = callback => {
221 if (document.readyState === 'loading') {
222 // add listener on the first call when the document is in loading state
223 if (!DOMContentLoadedCallbacks.length) {
224 document.addEventListener('DOMContentLoaded', () => {
225 for (const callback of DOMContentLoadedCallbacks) {
230 DOMContentLoadedCallbacks.push(callback);
235 const isRTL = () => document.documentElement.dir === 'rtl';
236 const defineJQueryPlugin = plugin => {
237 onDOMContentLoaded(() => {
238 const $ = getjQuery();
239 /* istanbul ignore if */
241 const name = plugin.NAME;
242 const JQUERY_NO_CONFLICT = $.fn[name];
243 $.fn[name] = plugin.jQueryInterface;
244 $.fn[name].Constructor = plugin;
245 $.fn[name].noConflict = () => {
246 $.fn[name] = JQUERY_NO_CONFLICT;
247 return plugin.jQueryInterface;
252 const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => {
253 return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue;
255 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
256 if (!waitForTransition) {
260 const durationPadding = 5;
261 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
266 if (target !== transitionElement) {
270 transitionElement.removeEventListener(TRANSITION_END, handler);
273 transitionElement.addEventListener(TRANSITION_END, handler);
276 triggerTransitionEnd(transitionElement);
278 }, emulatedDuration);
282 * Return the previous/next element of a list.
284 * @param {array} list The list of elements
285 * @param activeElement The active element
286 * @param shouldGetNext Choose to get next or previous element
287 * @param isCycleAllowed
288 * @return {Element|elem} The proper element
290 const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
291 const listLength = list.length;
292 let index = list.indexOf(activeElement);
294 // if the element does not exist in the list return an element
295 // depending on the direction and if cycle is allowed
297 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
299 index += shouldGetNext ? 1 : -1;
300 if (isCycleAllowed) {
301 index = (index + listLength) % listLength;
303 return list[Math.max(0, Math.min(index, listLength - 1))];
307 * --------------------------------------------------------------------------
308 * Bootstrap dom/event-handler.js
309 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
310 * --------------------------------------------------------------------------
318 const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
319 const stripNameRegex = /\..*/;
320 const stripUidRegex = /::\d+$/;
321 const eventRegistry = {}; // Events storage
323 const customEvents = {
324 mouseenter: 'mouseover',
325 mouseleave: 'mouseout'
327 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']);
333 function makeEventUid(element, uid) {
334 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;
336 function getElementEvents(element) {
337 const uid = makeEventUid(element);
338 element.uidEvent = uid;
339 eventRegistry[uid] = eventRegistry[uid] || {};
340 return eventRegistry[uid];
342 function bootstrapHandler(element, fn) {
343 return function handler(event) {
345 delegateTarget: element
347 if (handler.oneOff) {
348 EventHandler.off(element, event.type, fn);
350 return fn.apply(element, [event]);
353 function bootstrapDelegationHandler(element, selector, fn) {
354 return function handler(event) {
355 const domElements = element.querySelectorAll(selector);
358 } = event; target && target !== this; target = target.parentNode) {
359 for (const domElement of domElements) {
360 if (domElement !== target) {
364 delegateTarget: target
366 if (handler.oneOff) {
367 EventHandler.off(element, event.type, selector, fn);
369 return fn.apply(target, [event]);
374 function findHandler(events, callable, delegationSelector = null) {
375 return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);
377 function normalizeParameters(originalTypeEvent, handler, delegationFunction) {
378 const isDelegated = typeof handler === 'string';
379 // TODO: tooltip passes `false` instead of selector, so we need to check
380 const callable = isDelegated ? delegationFunction : handler || delegationFunction;
381 let typeEvent = getTypeEvent(originalTypeEvent);
382 if (!nativeEvents.has(typeEvent)) {
383 typeEvent = originalTypeEvent;
385 return [isDelegated, callable, typeEvent];
387 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {
388 if (typeof originalTypeEvent !== 'string' || !element) {
391 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
393 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
394 // this prevents the handler from being dispatched the same way as mouseover or mouseout does
395 if (originalTypeEvent in customEvents) {
396 const wrapFunction = fn => {
397 return function (event) {
398 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {
399 return fn.call(this, event);
403 callable = wrapFunction(callable);
405 const events = getElementEvents(element);
406 const handlers = events[typeEvent] || (events[typeEvent] = {});
407 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);
408 if (previousFunction) {
409 previousFunction.oneOff = previousFunction.oneOff && oneOff;
412 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));
413 const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);
414 fn.delegationSelector = isDelegated ? handler : null;
415 fn.callable = callable;
419 element.addEventListener(typeEvent, fn, isDelegated);
421 function removeHandler(element, events, typeEvent, handler, delegationSelector) {
422 const fn = findHandler(events[typeEvent], handler, delegationSelector);
426 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
427 delete events[typeEvent][fn.uidEvent];
429 function removeNamespacedHandlers(element, events, typeEvent, namespace) {
430 const storeElementEvent = events[typeEvent] || {};
431 for (const [handlerKey, event] of Object.entries(storeElementEvent)) {
432 if (handlerKey.includes(namespace)) {
433 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
437 function getTypeEvent(event) {
438 // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
439 event = event.replace(stripNameRegex, '');
440 return customEvents[event] || event;
442 const EventHandler = {
443 on(element, event, handler, delegationFunction) {
444 addHandler(element, event, handler, delegationFunction, false);
446 one(element, event, handler, delegationFunction) {
447 addHandler(element, event, handler, delegationFunction, true);
449 off(element, originalTypeEvent, handler, delegationFunction) {
450 if (typeof originalTypeEvent !== 'string' || !element) {
453 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
454 const inNamespace = typeEvent !== originalTypeEvent;
455 const events = getElementEvents(element);
456 const storeElementEvent = events[typeEvent] || {};
457 const isNamespace = originalTypeEvent.startsWith('.');
458 if (typeof callable !== 'undefined') {
459 // Simplest case: handler is passed, remove that listener ONLY.
460 if (!Object.keys(storeElementEvent).length) {
463 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);
467 for (const elementEvent of Object.keys(events)) {
468 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
471 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) {
472 const handlerKey = keyHandlers.replace(stripUidRegex, '');
473 if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
474 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
478 trigger(element, event, args) {
479 if (typeof event !== 'string' || !element) {
482 const $ = getjQuery();
483 const typeEvent = getTypeEvent(event);
484 const inNamespace = event !== typeEvent;
485 let jQueryEvent = null;
487 let nativeDispatch = true;
488 let defaultPrevented = false;
489 if (inNamespace && $) {
490 jQueryEvent = $.Event(event, args);
491 $(element).trigger(jQueryEvent);
492 bubbles = !jQueryEvent.isPropagationStopped();
493 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
494 defaultPrevented = jQueryEvent.isDefaultPrevented();
496 const evt = hydrateObj(new Event(event, {
500 if (defaultPrevented) {
501 evt.preventDefault();
503 if (nativeDispatch) {
504 element.dispatchEvent(evt);
506 if (evt.defaultPrevented && jQueryEvent) {
507 jQueryEvent.preventDefault();
512 function hydrateObj(obj, meta = {}) {
513 for (const [key, value] of Object.entries(meta)) {
517 Object.defineProperty(obj, key, {
529 * --------------------------------------------------------------------------
530 * Bootstrap dom/manipulator.js
531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
532 * --------------------------------------------------------------------------
535 function normalizeData(value) {
536 if (value === 'true') {
539 if (value === 'false') {
542 if (value === Number(value).toString()) {
543 return Number(value);
545 if (value === '' || value === 'null') {
548 if (typeof value !== 'string') {
552 return JSON.parse(decodeURIComponent(value));
557 function normalizeDataKey(key) {
558 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);
560 const Manipulator = {
561 setDataAttribute(element, key, value) {
562 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
564 removeDataAttribute(element, key) {
565 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
567 getDataAttributes(element) {
571 const attributes = {};
572 const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));
573 for (const key of bsKeys) {
574 let pureKey = key.replace(/^bs/, '');
575 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
576 attributes[pureKey] = normalizeData(element.dataset[key]);
580 getDataAttribute(element, key) {
581 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
586 * --------------------------------------------------------------------------
587 * Bootstrap util/config.js
588 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
589 * --------------------------------------------------------------------------
599 static get Default() {
602 static get DefaultType() {
606 throw new Error('You have to implement the static method "NAME", for each component!');
609 config = this._mergeConfigObj(config);
610 config = this._configAfterMerge(config);
611 this._typeCheckConfig(config);
614 _configAfterMerge(config) {
617 _mergeConfigObj(config, element) {
618 const jsonConfig = isElement$1(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse
621 ...this.constructor.Default,
622 ...(typeof jsonConfig === 'object' ? jsonConfig : {}),
623 ...(isElement$1(element) ? Manipulator.getDataAttributes(element) : {}),
624 ...(typeof config === 'object' ? config : {})
627 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
628 for (const [property, expectedTypes] of Object.entries(configTypes)) {
629 const value = config[property];
630 const valueType = isElement$1(value) ? 'element' : toType(value);
631 if (!new RegExp(expectedTypes).test(valueType)) {
632 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
639 * --------------------------------------------------------------------------
640 * Bootstrap base-component.js
641 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
642 * --------------------------------------------------------------------------
650 const VERSION = '5.3.3';
656 class BaseComponent extends Config {
657 constructor(element, config) {
659 element = getElement(element);
663 this._element = element;
664 this._config = this._getConfig(config);
665 Data.set(this._element, this.constructor.DATA_KEY, this);
670 Data.remove(this._element, this.constructor.DATA_KEY);
671 EventHandler.off(this._element, this.constructor.EVENT_KEY);
672 for (const propertyName of Object.getOwnPropertyNames(this)) {
673 this[propertyName] = null;
676 _queueCallback(callback, element, isAnimated = true) {
677 executeAfterTransition(callback, element, isAnimated);
680 config = this._mergeConfigObj(config, this._element);
681 config = this._configAfterMerge(config);
682 this._typeCheckConfig(config);
687 static getInstance(element) {
688 return Data.get(getElement(element), this.DATA_KEY);
690 static getOrCreateInstance(element, config = {}) {
691 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);
693 static get VERSION() {
696 static get DATA_KEY() {
697 return `bs.${this.NAME}`;
699 static get EVENT_KEY() {
700 return `.${this.DATA_KEY}`;
702 static eventName(name) {
703 return `${name}${this.EVENT_KEY}`;
708 * --------------------------------------------------------------------------
709 * Bootstrap dom/selector-engine.js
710 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
711 * --------------------------------------------------------------------------
714 const getSelector = element => {
715 let selector = element.getAttribute('data-bs-target');
716 if (!selector || selector === '#') {
717 let hrefAttribute = element.getAttribute('href');
719 // The only valid content that could double as a selector are IDs or classes,
720 // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
721 // `document.querySelector` will rightfully complain it is invalid.
722 // See https://github.com/twbs/bootstrap/issues/32273
723 if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {
727 // Just in case some CMS puts out a full URL with the anchor appended
728 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
729 hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
731 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
733 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null;
735 const SelectorEngine = {
736 find(selector, element = document.documentElement) {
737 return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
739 findOne(selector, element = document.documentElement) {
740 return Element.prototype.querySelector.call(element, selector);
742 children(element, selector) {
743 return [].concat(...element.children).filter(child => child.matches(selector));
745 parents(element, selector) {
747 let ancestor = element.parentNode.closest(selector);
749 parents.push(ancestor);
750 ancestor = ancestor.parentNode.closest(selector);
754 prev(element, selector) {
755 let previous = element.previousElementSibling;
757 if (previous.matches(selector)) {
760 previous = previous.previousElementSibling;
764 // TODO: this is now unused; remove later along with prev()
765 next(element, selector) {
766 let next = element.nextElementSibling;
768 if (next.matches(selector)) {
771 next = next.nextElementSibling;
775 focusableChildren(element) {
776 const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(',');
777 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));
779 getSelectorFromElement(element) {
780 const selector = getSelector(element);
782 return SelectorEngine.findOne(selector) ? selector : null;
786 getElementFromSelector(element) {
787 const selector = getSelector(element);
788 return selector ? SelectorEngine.findOne(selector) : null;
790 getMultipleElementsFromSelector(element) {
791 const selector = getSelector(element);
792 return selector ? SelectorEngine.find(selector) : [];
797 * --------------------------------------------------------------------------
798 * Bootstrap util/component-functions.js
799 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
800 * --------------------------------------------------------------------------
803 const enableDismissTrigger = (component, method = 'hide') => {
804 const clickEvent = `click.dismiss${component.EVENT_KEY}`;
805 const name = component.NAME;
806 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
807 if (['A', 'AREA'].includes(this.tagName)) {
808 event.preventDefault();
810 if (isDisabled(this)) {
813 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`);
814 const instance = component.getOrCreateInstance(target);
816 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
822 * --------------------------------------------------------------------------
824 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
825 * --------------------------------------------------------------------------
833 const NAME$f = 'alert';
834 const DATA_KEY$a = 'bs.alert';
835 const EVENT_KEY$b = `.${DATA_KEY$a}`;
836 const EVENT_CLOSE = `close${EVENT_KEY$b}`;
837 const EVENT_CLOSED = `closed${EVENT_KEY$b}`;
838 const CLASS_NAME_FADE$5 = 'fade';
839 const CLASS_NAME_SHOW$8 = 'show';
845 class Alert extends BaseComponent {
853 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
854 if (closeEvent.defaultPrevented) {
857 this._element.classList.remove(CLASS_NAME_SHOW$8);
858 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);
859 this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
864 this._element.remove();
865 EventHandler.trigger(this._element, EVENT_CLOSED);
870 static jQueryInterface(config) {
871 return this.each(function () {
872 const data = Alert.getOrCreateInstance(this);
873 if (typeof config !== 'string') {
876 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
877 throw new TypeError(`No method named "${config}"`);
885 * Data API implementation
888 enableDismissTrigger(Alert, 'close');
894 defineJQueryPlugin(Alert);
897 * --------------------------------------------------------------------------
898 * Bootstrap button.js
899 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
900 * --------------------------------------------------------------------------
908 const NAME$e = 'button';
909 const DATA_KEY$9 = 'bs.button';
910 const EVENT_KEY$a = `.${DATA_KEY$9}`;
911 const DATA_API_KEY$6 = '.data-api';
912 const CLASS_NAME_ACTIVE$3 = 'active';
913 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]';
914 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;
920 class Button extends BaseComponent {
928 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
929 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
933 static jQueryInterface(config) {
934 return this.each(function () {
935 const data = Button.getOrCreateInstance(this);
936 if (config === 'toggle') {
944 * Data API implementation
947 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {
948 event.preventDefault();
949 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);
950 const data = Button.getOrCreateInstance(button);
958 defineJQueryPlugin(Button);
961 * --------------------------------------------------------------------------
962 * Bootstrap util/swipe.js
963 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
964 * --------------------------------------------------------------------------
972 const NAME$d = 'swipe';
973 const EVENT_KEY$9 = '.bs.swipe';
974 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;
975 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;
976 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;
977 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;
978 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;
979 const POINTER_TYPE_TOUCH = 'touch';
980 const POINTER_TYPE_PEN = 'pen';
981 const CLASS_NAME_POINTER_EVENT = 'pointer-event';
982 const SWIPE_THRESHOLD = 40;
988 const DefaultType$c = {
989 endCallback: '(function|null)',
990 leftCallback: '(function|null)',
991 rightCallback: '(function|null)'
998 class Swipe extends Config {
999 constructor(element, config) {
1001 this._element = element;
1002 if (!element || !Swipe.isSupported()) {
1005 this._config = this._getConfig(config);
1007 this._supportPointerEvents = Boolean(window.PointerEvent);
1012 static get Default() {
1015 static get DefaultType() {
1016 return DefaultType$c;
1024 EventHandler.off(this._element, EVENT_KEY$9);
1029 if (!this._supportPointerEvents) {
1030 this._deltaX = event.touches[0].clientX;
1033 if (this._eventIsPointerPenTouch(event)) {
1034 this._deltaX = event.clientX;
1038 if (this._eventIsPointerPenTouch(event)) {
1039 this._deltaX = event.clientX - this._deltaX;
1041 this._handleSwipe();
1042 execute(this._config.endCallback);
1045 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;
1048 const absDeltaX = Math.abs(this._deltaX);
1049 if (absDeltaX <= SWIPE_THRESHOLD) {
1052 const direction = absDeltaX / this._deltaX;
1057 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);
1060 if (this._supportPointerEvents) {
1061 EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));
1062 EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));
1063 this._element.classList.add(CLASS_NAME_POINTER_EVENT);
1065 EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));
1066 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));
1067 EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));
1070 _eventIsPointerPenTouch(event) {
1071 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);
1075 static isSupported() {
1076 return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
1081 * --------------------------------------------------------------------------
1082 * Bootstrap carousel.js
1083 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1084 * --------------------------------------------------------------------------
1092 const NAME$c = 'carousel';
1093 const DATA_KEY$8 = 'bs.carousel';
1094 const EVENT_KEY$8 = `.${DATA_KEY$8}`;
1095 const DATA_API_KEY$5 = '.data-api';
1096 const ARROW_LEFT_KEY$1 = 'ArrowLeft';
1097 const ARROW_RIGHT_KEY$1 = 'ArrowRight';
1098 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
1100 const ORDER_NEXT = 'next';
1101 const ORDER_PREV = 'prev';
1102 const DIRECTION_LEFT = 'left';
1103 const DIRECTION_RIGHT = 'right';
1104 const EVENT_SLIDE = `slide${EVENT_KEY$8}`;
1105 const EVENT_SLID = `slid${EVENT_KEY$8}`;
1106 const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;
1107 const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;
1108 const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;
1109 const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;
1110 const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;
1111 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
1112 const CLASS_NAME_CAROUSEL = 'carousel';
1113 const CLASS_NAME_ACTIVE$2 = 'active';
1114 const CLASS_NAME_SLIDE = 'slide';
1115 const CLASS_NAME_END = 'carousel-item-end';
1116 const CLASS_NAME_START = 'carousel-item-start';
1117 const CLASS_NAME_NEXT = 'carousel-item-next';
1118 const CLASS_NAME_PREV = 'carousel-item-prev';
1119 const SELECTOR_ACTIVE = '.active';
1120 const SELECTOR_ITEM = '.carousel-item';
1121 const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;
1122 const SELECTOR_ITEM_IMG = '.carousel-item img';
1123 const SELECTOR_INDICATORS = '.carousel-indicators';
1124 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
1125 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
1126 const KEY_TO_DIRECTION = {
1127 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,
1128 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT
1138 const DefaultType$b = {
1139 interval: '(number|boolean)',
1140 // TODO:v6 remove boolean support
1141 keyboard: 'boolean',
1142 pause: '(string|boolean)',
1143 ride: '(boolean|string)',
1152 class Carousel extends BaseComponent {
1153 constructor(element, config) {
1154 super(element, config);
1155 this._interval = null;
1156 this._activeElement = null;
1157 this._isSliding = false;
1158 this.touchTimeout = null;
1159 this._swipeHelper = null;
1160 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
1161 this._addEventListeners();
1162 if (this._config.ride === CLASS_NAME_CAROUSEL) {
1168 static get Default() {
1171 static get DefaultType() {
1172 return DefaultType$b;
1180 this._slide(ORDER_NEXT);
1183 // FIXME TODO use `document.visibilityState`
1184 // Don't call next when the page isn't visible
1185 // or the carousel or its parent isn't visible
1186 if (!document.hidden && isVisible(this._element)) {
1191 this._slide(ORDER_PREV);
1194 if (this._isSliding) {
1195 triggerTransitionEnd(this._element);
1197 this._clearInterval();
1200 this._clearInterval();
1201 this._updateInterval();
1202 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);
1204 _maybeEnableCycle() {
1205 if (!this._config.ride) {
1208 if (this._isSliding) {
1209 EventHandler.one(this._element, EVENT_SLID, () => this.cycle());
1215 const items = this._getItems();
1216 if (index > items.length - 1 || index < 0) {
1219 if (this._isSliding) {
1220 EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
1223 const activeIndex = this._getItemIndex(this._getActive());
1224 if (activeIndex === index) {
1227 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
1228 this._slide(order, items[index]);
1231 if (this._swipeHelper) {
1232 this._swipeHelper.dispose();
1238 _configAfterMerge(config) {
1239 config.defaultInterval = config.interval;
1242 _addEventListeners() {
1243 if (this._config.keyboard) {
1244 EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));
1246 if (this._config.pause === 'hover') {
1247 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());
1248 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());
1250 if (this._config.touch && Swipe.isSupported()) {
1251 this._addTouchEventListeners();
1254 _addTouchEventListeners() {
1255 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {
1256 EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());
1258 const endCallBack = () => {
1259 if (this._config.pause !== 'hover') {
1263 // If it's a touch-enabled device, mouseenter/leave are fired as
1264 // part of the mouse compatibility events on first tap - the carousel
1265 // would stop cycling until user tapped out of it;
1266 // here, we listen for touchend, explicitly pause the carousel
1267 // (as if it's the second time we tap on it, mouseenter compat event
1268 // is NOT fired) and after a timeout (to allow for mouse compatibility
1269 // events to fire) we explicitly restart cycling
1272 if (this.touchTimeout) {
1273 clearTimeout(this.touchTimeout);
1275 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
1277 const swipeConfig = {
1278 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),
1279 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),
1280 endCallback: endCallBack
1282 this._swipeHelper = new Swipe(this._element, swipeConfig);
1285 if (/input|textarea/i.test(event.target.tagName)) {
1288 const direction = KEY_TO_DIRECTION[event.key];
1290 event.preventDefault();
1291 this._slide(this._directionToOrder(direction));
1294 _getItemIndex(element) {
1295 return this._getItems().indexOf(element);
1297 _setActiveIndicatorElement(index) {
1298 if (!this._indicatorsElement) {
1301 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
1302 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);
1303 activeIndicator.removeAttribute('aria-current');
1304 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement);
1305 if (newActiveIndicator) {
1306 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);
1307 newActiveIndicator.setAttribute('aria-current', 'true');
1311 const element = this._activeElement || this._getActive();
1315 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
1316 this._config.interval = elementInterval || this._config.defaultInterval;
1318 _slide(order, element = null) {
1319 if (this._isSliding) {
1322 const activeElement = this._getActive();
1323 const isNext = order === ORDER_NEXT;
1324 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);
1325 if (nextElement === activeElement) {
1328 const nextElementIndex = this._getItemIndex(nextElement);
1329 const triggerEvent = eventName => {
1330 return EventHandler.trigger(this._element, eventName, {
1331 relatedTarget: nextElement,
1332 direction: this._orderToDirection(order),
1333 from: this._getItemIndex(activeElement),
1334 to: nextElementIndex
1337 const slideEvent = triggerEvent(EVENT_SLIDE);
1338 if (slideEvent.defaultPrevented) {
1341 if (!activeElement || !nextElement) {
1342 // Some weirdness is happening, so we bail
1343 // TODO: change tests that use empty divs to avoid this check
1346 const isCycling = Boolean(this._interval);
1348 this._isSliding = true;
1349 this._setActiveIndicatorElement(nextElementIndex);
1350 this._activeElement = nextElement;
1351 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
1352 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
1353 nextElement.classList.add(orderClassName);
1354 reflow(nextElement);
1355 activeElement.classList.add(directionalClassName);
1356 nextElement.classList.add(directionalClassName);
1357 const completeCallBack = () => {
1358 nextElement.classList.remove(directionalClassName, orderClassName);
1359 nextElement.classList.add(CLASS_NAME_ACTIVE$2);
1360 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);
1361 this._isSliding = false;
1362 triggerEvent(EVENT_SLID);
1364 this._queueCallback(completeCallBack, activeElement, this._isAnimated());
1370 return this._element.classList.contains(CLASS_NAME_SLIDE);
1373 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
1376 return SelectorEngine.find(SELECTOR_ITEM, this._element);
1379 if (this._interval) {
1380 clearInterval(this._interval);
1381 this._interval = null;
1384 _directionToOrder(direction) {
1386 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
1388 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
1390 _orderToDirection(order) {
1392 return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
1394 return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
1398 static jQueryInterface(config) {
1399 return this.each(function () {
1400 const data = Carousel.getOrCreateInstance(this, config);
1401 if (typeof config === 'number') {
1405 if (typeof config === 'string') {
1406 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
1407 throw new TypeError(`No method named "${config}"`);
1416 * Data API implementation
1419 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {
1420 const target = SelectorEngine.getElementFromSelector(this);
1421 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
1424 event.preventDefault();
1425 const carousel = Carousel.getOrCreateInstance(target);
1426 const slideIndex = this.getAttribute('data-bs-slide-to');
1428 carousel.to(slideIndex);
1429 carousel._maybeEnableCycle();
1432 if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
1434 carousel._maybeEnableCycle();
1438 carousel._maybeEnableCycle();
1440 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {
1441 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
1442 for (const carousel of carousels) {
1443 Carousel.getOrCreateInstance(carousel);
1451 defineJQueryPlugin(Carousel);
1454 * --------------------------------------------------------------------------
1455 * Bootstrap collapse.js
1456 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1457 * --------------------------------------------------------------------------
1465 const NAME$b = 'collapse';
1466 const DATA_KEY$7 = 'bs.collapse';
1467 const EVENT_KEY$7 = `.${DATA_KEY$7}`;
1468 const DATA_API_KEY$4 = '.data-api';
1469 const EVENT_SHOW$6 = `show${EVENT_KEY$7}`;
1470 const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;
1471 const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;
1472 const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;
1473 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;
1474 const CLASS_NAME_SHOW$7 = 'show';
1475 const CLASS_NAME_COLLAPSE = 'collapse';
1476 const CLASS_NAME_COLLAPSING = 'collapsing';
1477 const CLASS_NAME_COLLAPSED = 'collapsed';
1478 const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;
1479 const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';
1480 const WIDTH = 'width';
1481 const HEIGHT = 'height';
1482 const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
1483 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]';
1488 const DefaultType$a = {
1489 parent: '(null|element)',
1497 class Collapse extends BaseComponent {
1498 constructor(element, config) {
1499 super(element, config);
1500 this._isTransitioning = false;
1501 this._triggerArray = [];
1502 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);
1503 for (const elem of toggleList) {
1504 const selector = SelectorEngine.getSelectorFromElement(elem);
1505 const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);
1506 if (selector !== null && filterElement.length) {
1507 this._triggerArray.push(elem);
1510 this._initializeChildren();
1511 if (!this._config.parent) {
1512 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
1514 if (this._config.toggle) {
1520 static get Default() {
1523 static get DefaultType() {
1524 return DefaultType$a;
1532 if (this._isShown()) {
1539 if (this._isTransitioning || this._isShown()) {
1542 let activeChildren = [];
1544 // find active children
1545 if (this._config.parent) {
1546 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {
1550 if (activeChildren.length && activeChildren[0]._isTransitioning) {
1553 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);
1554 if (startEvent.defaultPrevented) {
1557 for (const activeInstance of activeChildren) {
1558 activeInstance.hide();
1560 const dimension = this._getDimension();
1561 this._element.classList.remove(CLASS_NAME_COLLAPSE);
1562 this._element.classList.add(CLASS_NAME_COLLAPSING);
1563 this._element.style[dimension] = 0;
1564 this._addAriaAndCollapsedClass(this._triggerArray, true);
1565 this._isTransitioning = true;
1566 const complete = () => {
1567 this._isTransitioning = false;
1568 this._element.classList.remove(CLASS_NAME_COLLAPSING);
1569 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1570 this._element.style[dimension] = '';
1571 EventHandler.trigger(this._element, EVENT_SHOWN$6);
1573 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
1574 const scrollSize = `scroll${capitalizedDimension}`;
1575 this._queueCallback(complete, this._element, true);
1576 this._element.style[dimension] = `${this._element[scrollSize]}px`;
1579 if (this._isTransitioning || !this._isShown()) {
1582 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);
1583 if (startEvent.defaultPrevented) {
1586 const dimension = this._getDimension();
1587 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
1588 reflow(this._element);
1589 this._element.classList.add(CLASS_NAME_COLLAPSING);
1590 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1591 for (const trigger of this._triggerArray) {
1592 const element = SelectorEngine.getElementFromSelector(trigger);
1593 if (element && !this._isShown(element)) {
1594 this._addAriaAndCollapsedClass([trigger], false);
1597 this._isTransitioning = true;
1598 const complete = () => {
1599 this._isTransitioning = false;
1600 this._element.classList.remove(CLASS_NAME_COLLAPSING);
1601 this._element.classList.add(CLASS_NAME_COLLAPSE);
1602 EventHandler.trigger(this._element, EVENT_HIDDEN$6);
1604 this._element.style[dimension] = '';
1605 this._queueCallback(complete, this._element, true);
1607 _isShown(element = this._element) {
1608 return element.classList.contains(CLASS_NAME_SHOW$7);
1612 _configAfterMerge(config) {
1613 config.toggle = Boolean(config.toggle); // Coerce string values
1614 config.parent = getElement(config.parent);
1618 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
1620 _initializeChildren() {
1621 if (!this._config.parent) {
1624 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);
1625 for (const element of children) {
1626 const selected = SelectorEngine.getElementFromSelector(element);
1628 this._addAriaAndCollapsedClass([element], this._isShown(selected));
1632 _getFirstLevelChildren(selector) {
1633 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent);
1634 // remove children if greater depth
1635 return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));
1637 _addAriaAndCollapsedClass(triggerArray, isOpen) {
1638 if (!triggerArray.length) {
1641 for (const element of triggerArray) {
1642 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);
1643 element.setAttribute('aria-expanded', isOpen);
1648 static jQueryInterface(config) {
1650 if (typeof config === 'string' && /show|hide/.test(config)) {
1651 _config.toggle = false;
1653 return this.each(function () {
1654 const data = Collapse.getOrCreateInstance(this, _config);
1655 if (typeof config === 'string') {
1656 if (typeof data[config] === 'undefined') {
1657 throw new TypeError(`No method named "${config}"`);
1666 * Data API implementation
1669 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {
1670 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
1671 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {
1672 event.preventDefault();
1674 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) {
1675 Collapse.getOrCreateInstance(element, {
1685 defineJQueryPlugin(Collapse);
1688 var bottom = 'bottom';
1689 var right = 'right';
1692 var basePlacements = [top, bottom, right, left];
1693 var start = 'start';
1695 var clippingParents = 'clippingParents';
1696 var viewport = 'viewport';
1697 var popper = 'popper';
1698 var reference = 'reference';
1699 var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {
1700 return acc.concat([placement + "-" + start, placement + "-" + end]);
1702 var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {
1703 return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
1704 }, []); // modifiers that need to read the DOM
1706 var beforeRead = 'beforeRead';
1708 var afterRead = 'afterRead'; // pure-logic modifiers
1710 var beforeMain = 'beforeMain';
1712 var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)
1714 var beforeWrite = 'beforeWrite';
1715 var write = 'write';
1716 var afterWrite = 'afterWrite';
1717 var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
1719 function getNodeName(element) {
1720 return element ? (element.nodeName || '').toLowerCase() : null;
1723 function getWindow(node) {
1728 if (node.toString() !== '[object Window]') {
1729 var ownerDocument = node.ownerDocument;
1730 return ownerDocument ? ownerDocument.defaultView || window : window;
1736 function isElement(node) {
1737 var OwnElement = getWindow(node).Element;
1738 return node instanceof OwnElement || node instanceof Element;
1741 function isHTMLElement(node) {
1742 var OwnElement = getWindow(node).HTMLElement;
1743 return node instanceof OwnElement || node instanceof HTMLElement;
1746 function isShadowRoot(node) {
1747 // IE 11 has no ShadowRoot
1748 if (typeof ShadowRoot === 'undefined') {
1752 var OwnElement = getWindow(node).ShadowRoot;
1753 return node instanceof OwnElement || node instanceof ShadowRoot;
1756 // and applies them to the HTMLElements such as popper and arrow
1758 function applyStyles(_ref) {
1759 var state = _ref.state;
1760 Object.keys(state.elements).forEach(function (name) {
1761 var style = state.styles[name] || {};
1762 var attributes = state.attributes[name] || {};
1763 var element = state.elements[name]; // arrow is optional + virtual elements
1765 if (!isHTMLElement(element) || !getNodeName(element)) {
1767 } // Flow doesn't support to extend this property, but it's the most
1768 // effective way to apply styles to an HTMLElement
1769 // $FlowFixMe[cannot-write]
1772 Object.assign(element.style, style);
1773 Object.keys(attributes).forEach(function (name) {
1774 var value = attributes[name];
1776 if (value === false) {
1777 element.removeAttribute(name);
1779 element.setAttribute(name, value === true ? '' : value);
1785 function effect$2(_ref2) {
1786 var state = _ref2.state;
1787 var initialStyles = {
1789 position: state.options.strategy,
1795 position: 'absolute'
1799 Object.assign(state.elements.popper.style, initialStyles.popper);
1800 state.styles = initialStyles;
1802 if (state.elements.arrow) {
1803 Object.assign(state.elements.arrow.style, initialStyles.arrow);
1806 return function () {
1807 Object.keys(state.elements).forEach(function (name) {
1808 var element = state.elements[name];
1809 var attributes = state.attributes[name] || {};
1810 var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them
1812 var style = styleProperties.reduce(function (style, property) {
1813 style[property] = '';
1815 }, {}); // arrow is optional + virtual elements
1817 if (!isHTMLElement(element) || !getNodeName(element)) {
1821 Object.assign(element.style, style);
1822 Object.keys(attributes).forEach(function (attribute) {
1823 element.removeAttribute(attribute);
1827 } // eslint-disable-next-line import/no-unused-modules
1830 const applyStyles$1 = {
1831 name: 'applyStyles',
1836 requires: ['computeStyles']
1839 function getBasePlacement(placement) {
1840 return placement.split('-')[0];
1845 var round = Math.round;
1847 function getUAString() {
1848 var uaData = navigator.userAgentData;
1850 if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
1851 return uaData.brands.map(function (item) {
1852 return item.brand + "/" + item.version;
1856 return navigator.userAgent;
1859 function isLayoutViewport() {
1860 return !/^((?!chrome|android).)*safari/i.test(getUAString());
1863 function getBoundingClientRect(element, includeScale, isFixedStrategy) {
1864 if (includeScale === void 0) {
1865 includeScale = false;
1868 if (isFixedStrategy === void 0) {
1869 isFixedStrategy = false;
1872 var clientRect = element.getBoundingClientRect();
1876 if (includeScale && isHTMLElement(element)) {
1877 scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
1878 scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
1881 var _ref = isElement(element) ? getWindow(element) : window,
1882 visualViewport = _ref.visualViewport;
1884 var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
1885 var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
1886 var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
1887 var width = clientRect.width / scaleX;
1888 var height = clientRect.height / scaleY;
1901 // means it doesn't take into account transforms.
1903 function getLayoutRect(element) {
1904 var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed.
1905 // Fixes https://github.com/popperjs/popper-core/issues/1223
1907 var width = element.offsetWidth;
1908 var height = element.offsetHeight;
1910 if (Math.abs(clientRect.width - width) <= 1) {
1911 width = clientRect.width;
1914 if (Math.abs(clientRect.height - height) <= 1) {
1915 height = clientRect.height;
1919 x: element.offsetLeft,
1920 y: element.offsetTop,
1926 function contains(parent, child) {
1927 var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method
1929 if (parent.contains(child)) {
1931 } // then fallback to custom implementation with Shadow DOM support
1932 else if (rootNode && isShadowRoot(rootNode)) {
1936 if (next && parent.isSameNode(next)) {
1938 } // $FlowFixMe[prop-missing]: need a better way to handle this...
1941 next = next.parentNode || next.host;
1943 } // Give up, the result is false
1949 function getComputedStyle$1(element) {
1950 return getWindow(element).getComputedStyle(element);
1953 function isTableElement(element) {
1954 return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0;
1957 function getDocumentElement(element) {
1958 // $FlowFixMe[incompatible-return]: assume body is always available
1959 return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing]
1960 element.document) || window.document).documentElement;
1963 function getParentNode(element) {
1964 if (getNodeName(element) === 'html') {
1968 return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle
1969 // $FlowFixMe[incompatible-return]
1970 // $FlowFixMe[prop-missing]
1971 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node
1972 element.parentNode || ( // DOM Element detected
1973 isShadowRoot(element) ? element.host : null) || // ShadowRoot detected
1974 // $FlowFixMe[incompatible-call]: HTMLElement is a Node
1975 getDocumentElement(element) // fallback
1980 function getTrueOffsetParent(element) {
1981 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837
1982 getComputedStyle$1(element).position === 'fixed') {
1986 return element.offsetParent;
1987 } // `.offsetParent` reports `null` for fixed elements, while absolute elements
1988 // return the containing block
1991 function getContainingBlock(element) {
1992 var isFirefox = /firefox/i.test(getUAString());
1993 var isIE = /Trident/i.test(getUAString());
1995 if (isIE && isHTMLElement(element)) {
1996 // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
1997 var elementCss = getComputedStyle$1(element);
1999 if (elementCss.position === 'fixed') {
2004 var currentNode = getParentNode(element);
2006 if (isShadowRoot(currentNode)) {
2007 currentNode = currentNode.host;
2010 while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) {
2011 var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that
2012 // create a containing block.
2013 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block
2015 if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {
2018 currentNode = currentNode.parentNode;
2023 } // Gets the closest ancestor positioned element. Handles some edge cases,
2024 // such as table ancestors and cross browser bugs.
2027 function getOffsetParent(element) {
2028 var window = getWindow(element);
2029 var offsetParent = getTrueOffsetParent(element);
2031 while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') {
2032 offsetParent = getTrueOffsetParent(offsetParent);
2035 if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) {
2039 return offsetParent || getContainingBlock(element) || window;
2042 function getMainAxisFromPlacement(placement) {
2043 return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
2046 function within(min$1, value, max$1) {
2047 return max(min$1, min(value, max$1));
2049 function withinMaxClamp(min, value, max) {
2050 var v = within(min, value, max);
2051 return v > max ? max : v;
2054 function getFreshSideObject() {
2063 function mergePaddingObject(paddingObject) {
2064 return Object.assign({}, getFreshSideObject(), paddingObject);
2067 function expandToHashMap(value, keys) {
2068 return keys.reduce(function (hashMap, key) {
2069 hashMap[key] = value;
2074 var toPaddingObject = function toPaddingObject(padding, state) {
2075 padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {
2076 placement: state.placement
2078 return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
2081 function arrow(_ref) {
2082 var _state$modifiersData$;
2084 var state = _ref.state,
2086 options = _ref.options;
2087 var arrowElement = state.elements.arrow;
2088 var popperOffsets = state.modifiersData.popperOffsets;
2089 var basePlacement = getBasePlacement(state.placement);
2090 var axis = getMainAxisFromPlacement(basePlacement);
2091 var isVertical = [left, right].indexOf(basePlacement) >= 0;
2092 var len = isVertical ? 'height' : 'width';
2094 if (!arrowElement || !popperOffsets) {
2098 var paddingObject = toPaddingObject(options.padding, state);
2099 var arrowRect = getLayoutRect(arrowElement);
2100 var minProp = axis === 'y' ? top : left;
2101 var maxProp = axis === 'y' ? bottom : right;
2102 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
2103 var startDiff = popperOffsets[axis] - state.rects.reference[axis];
2104 var arrowOffsetParent = getOffsetParent(arrowElement);
2105 var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
2106 var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
2107 // outside of the popper bounds
2109 var min = paddingObject[minProp];
2110 var max = clientSize - arrowRect[len] - paddingObject[maxProp];
2111 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
2112 var offset = within(min, center, max); // Prevents breaking syntax highlighting...
2114 var axisProp = axis;
2115 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
2118 function effect$1(_ref2) {
2119 var state = _ref2.state,
2120 options = _ref2.options;
2121 var _options$element = options.element,
2122 arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;
2124 if (arrowElement == null) {
2129 if (typeof arrowElement === 'string') {
2130 arrowElement = state.elements.popper.querySelector(arrowElement);
2132 if (!arrowElement) {
2137 if (!contains(state.elements.popper, arrowElement)) {
2141 state.elements.arrow = arrowElement;
2142 } // eslint-disable-next-line import/no-unused-modules
2151 requires: ['popperOffsets'],
2152 requiresIfExists: ['preventOverflow']
2155 function getVariation(placement) {
2156 return placement.split('-')[1];
2164 }; // Round the offsets to the nearest suitable subpixel based on the DPR.
2165 // Zooming can change the DPR, but it seems to report a value that will
2166 // cleanly divide the values into the appropriate subpixels.
2168 function roundOffsetsByDPR(_ref, win) {
2171 var dpr = win.devicePixelRatio || 1;
2173 x: round(x * dpr) / dpr || 0,
2174 y: round(y * dpr) / dpr || 0
2178 function mapToStyles(_ref2) {
2179 var _Object$assign2;
2181 var popper = _ref2.popper,
2182 popperRect = _ref2.popperRect,
2183 placement = _ref2.placement,
2184 variation = _ref2.variation,
2185 offsets = _ref2.offsets,
2186 position = _ref2.position,
2187 gpuAcceleration = _ref2.gpuAcceleration,
2188 adaptive = _ref2.adaptive,
2189 roundOffsets = _ref2.roundOffsets,
2190 isFixed = _ref2.isFixed;
2191 var _offsets$x = offsets.x,
2192 x = _offsets$x === void 0 ? 0 : _offsets$x,
2193 _offsets$y = offsets.y,
2194 y = _offsets$y === void 0 ? 0 : _offsets$y;
2196 var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
2206 var hasX = offsets.hasOwnProperty('x');
2207 var hasY = offsets.hasOwnProperty('y');
2213 var offsetParent = getOffsetParent(popper);
2214 var heightProp = 'clientHeight';
2215 var widthProp = 'clientWidth';
2217 if (offsetParent === getWindow(popper)) {
2218 offsetParent = getDocumentElement(popper);
2220 if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') {
2221 heightProp = 'scrollHeight';
2222 widthProp = 'scrollWidth';
2224 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it
2227 offsetParent = offsetParent;
2229 if (placement === top || (placement === left || placement === right) && variation === end) {
2231 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing]
2232 offsetParent[heightProp];
2233 y -= offsetY - popperRect.height;
2234 y *= gpuAcceleration ? 1 : -1;
2237 if (placement === left || (placement === top || placement === bottom) && variation === end) {
2239 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing]
2240 offsetParent[widthProp];
2241 x -= offsetX - popperRect.width;
2242 x *= gpuAcceleration ? 1 : -1;
2246 var commonStyles = Object.assign({
2248 }, adaptive && unsetSides);
2250 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
2253 }, getWindow(popper)) : {
2261 if (gpuAcceleration) {
2264 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
2267 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
2270 function computeStyles(_ref5) {
2271 var state = _ref5.state,
2272 options = _ref5.options;
2273 var _options$gpuAccelerat = options.gpuAcceleration,
2274 gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
2275 _options$adaptive = options.adaptive,
2276 adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
2277 _options$roundOffsets = options.roundOffsets,
2278 roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
2279 var commonStyles = {
2280 placement: getBasePlacement(state.placement),
2281 variation: getVariation(state.placement),
2282 popper: state.elements.popper,
2283 popperRect: state.rects.popper,
2284 gpuAcceleration: gpuAcceleration,
2285 isFixed: state.options.strategy === 'fixed'
2288 if (state.modifiersData.popperOffsets != null) {
2289 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
2290 offsets: state.modifiersData.popperOffsets,
2291 position: state.options.strategy,
2293 roundOffsets: roundOffsets
2297 if (state.modifiersData.arrow != null) {
2298 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
2299 offsets: state.modifiersData.arrow,
2300 position: 'absolute',
2302 roundOffsets: roundOffsets
2306 state.attributes.popper = Object.assign({}, state.attributes.popper, {
2307 'data-popper-placement': state.placement
2309 } // eslint-disable-next-line import/no-unused-modules
2312 const computeStyles$1 = {
2313 name: 'computeStyles',
2315 phase: 'beforeWrite',
2324 function effect(_ref) {
2325 var state = _ref.state,
2326 instance = _ref.instance,
2327 options = _ref.options;
2328 var _options$scroll = options.scroll,
2329 scroll = _options$scroll === void 0 ? true : _options$scroll,
2330 _options$resize = options.resize,
2331 resize = _options$resize === void 0 ? true : _options$resize;
2332 var window = getWindow(state.elements.popper);
2333 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
2336 scrollParents.forEach(function (scrollParent) {
2337 scrollParent.addEventListener('scroll', instance.update, passive);
2342 window.addEventListener('resize', instance.update, passive);
2345 return function () {
2347 scrollParents.forEach(function (scrollParent) {
2348 scrollParent.removeEventListener('scroll', instance.update, passive);
2353 window.removeEventListener('resize', instance.update, passive);
2356 } // eslint-disable-next-line import/no-unused-modules
2359 const eventListeners = {
2360 name: 'eventListeners',
2363 fn: function fn() {},
2374 function getOppositePlacement(placement) {
2375 return placement.replace(/left|right|bottom|top/g, function (matched) {
2376 return hash$1[matched];
2384 function getOppositeVariationPlacement(placement) {
2385 return placement.replace(/start|end/g, function (matched) {
2386 return hash[matched];
2390 function getWindowScroll(node) {
2391 var win = getWindow(node);
2392 var scrollLeft = win.pageXOffset;
2393 var scrollTop = win.pageYOffset;
2395 scrollLeft: scrollLeft,
2396 scrollTop: scrollTop
2400 function getWindowScrollBarX(element) {
2401 // If <html> has a CSS width greater than the viewport, then this will be
2402 // incorrect for RTL.
2403 // Popper 1 is broken in this case and never had a bug report so let's assume
2404 // it's not an issue. I don't think anyone ever specifies width on <html>
2406 // Browsers where the left scrollbar doesn't cause an issue report `0` for
2407 // this (e.g. Edge 2019, IE11, Safari)
2408 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
2411 function getViewportRect(element, strategy) {
2412 var win = getWindow(element);
2413 var html = getDocumentElement(element);
2414 var visualViewport = win.visualViewport;
2415 var width = html.clientWidth;
2416 var height = html.clientHeight;
2420 if (visualViewport) {
2421 width = visualViewport.width;
2422 height = visualViewport.height;
2423 var layoutViewport = isLayoutViewport();
2425 if (layoutViewport || !layoutViewport && strategy === 'fixed') {
2426 x = visualViewport.offsetLeft;
2427 y = visualViewport.offsetTop;
2434 x: x + getWindowScrollBarX(element),
2439 // of the `<html>` and `<body>` rect bounds if horizontally scrollable
2441 function getDocumentRect(element) {
2442 var _element$ownerDocumen;
2444 var html = getDocumentElement(element);
2445 var winScroll = getWindowScroll(element);
2446 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
2447 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
2448 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
2449 var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
2450 var y = -winScroll.scrollTop;
2452 if (getComputedStyle$1(body || html).direction === 'rtl') {
2453 x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
2464 function isScrollParent(element) {
2465 // Firefox wants us to check `-x` and `-y` variations as well
2466 var _getComputedStyle = getComputedStyle$1(element),
2467 overflow = _getComputedStyle.overflow,
2468 overflowX = _getComputedStyle.overflowX,
2469 overflowY = _getComputedStyle.overflowY;
2471 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
2474 function getScrollParent(node) {
2475 if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) {
2476 // $FlowFixMe[incompatible-return]: assume body is always available
2477 return node.ownerDocument.body;
2480 if (isHTMLElement(node) && isScrollParent(node)) {
2484 return getScrollParent(getParentNode(node));
2488 given a DOM element, return the list of all scroll parents, up the list of ancesors
2489 until we get to the top window object. This list is what we attach scroll listeners
2490 to, because if any of these parent elements scroll, we'll need to re-calculate the
2491 reference element's position.
2494 function listScrollParents(element, list) {
2495 var _element$ownerDocumen;
2497 if (list === void 0) {
2501 var scrollParent = getScrollParent(element);
2502 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
2503 var win = getWindow(scrollParent);
2504 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
2505 var updatedList = list.concat(target);
2506 return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
2507 updatedList.concat(listScrollParents(getParentNode(target)));
2510 function rectToClientRect(rect) {
2511 return Object.assign({}, rect, {
2514 right: rect.x + rect.width,
2515 bottom: rect.y + rect.height
2519 function getInnerBoundingClientRect(element, strategy) {
2520 var rect = getBoundingClientRect(element, false, strategy === 'fixed');
2521 rect.top = rect.top + element.clientTop;
2522 rect.left = rect.left + element.clientLeft;
2523 rect.bottom = rect.top + element.clientHeight;
2524 rect.right = rect.left + element.clientWidth;
2525 rect.width = element.clientWidth;
2526 rect.height = element.clientHeight;
2532 function getClientRectFromMixedType(element, clippingParent, strategy) {
2533 return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
2534 } // A "clipping parent" is an overflowable container with the characteristic of
2535 // clipping (or hiding) overflowing elements with a position different from
2539 function getClippingParents(element) {
2540 var clippingParents = listScrollParents(getParentNode(element));
2541 var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0;
2542 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
2544 if (!isElement(clipperElement)) {
2546 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414
2549 return clippingParents.filter(function (clippingParent) {
2550 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body';
2552 } // Gets the maximum area that the element is visible in due to any number of
2556 function getClippingRect(element, boundary, rootBoundary, strategy) {
2557 var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
2558 var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
2559 var firstClippingParent = clippingParents[0];
2560 var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
2561 var rect = getClientRectFromMixedType(element, clippingParent, strategy);
2562 accRect.top = max(rect.top, accRect.top);
2563 accRect.right = min(rect.right, accRect.right);
2564 accRect.bottom = min(rect.bottom, accRect.bottom);
2565 accRect.left = max(rect.left, accRect.left);
2567 }, getClientRectFromMixedType(element, firstClippingParent, strategy));
2568 clippingRect.width = clippingRect.right - clippingRect.left;
2569 clippingRect.height = clippingRect.bottom - clippingRect.top;
2570 clippingRect.x = clippingRect.left;
2571 clippingRect.y = clippingRect.top;
2572 return clippingRect;
2575 function computeOffsets(_ref) {
2576 var reference = _ref.reference,
2577 element = _ref.element,
2578 placement = _ref.placement;
2579 var basePlacement = placement ? getBasePlacement(placement) : null;
2580 var variation = placement ? getVariation(placement) : null;
2581 var commonX = reference.x + reference.width / 2 - element.width / 2;
2582 var commonY = reference.y + reference.height / 2 - element.height / 2;
2585 switch (basePlacement) {
2589 y: reference.y - element.height
2596 y: reference.y + reference.height
2602 x: reference.x + reference.width,
2609 x: reference.x - element.width,
2621 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
2623 if (mainAxis != null) {
2624 var len = mainAxis === 'y' ? 'height' : 'width';
2626 switch (variation) {
2628 offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
2632 offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
2640 function detectOverflow(state, options) {
2641 if (options === void 0) {
2645 var _options = options,
2646 _options$placement = _options.placement,
2647 placement = _options$placement === void 0 ? state.placement : _options$placement,
2648 _options$strategy = _options.strategy,
2649 strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,
2650 _options$boundary = _options.boundary,
2651 boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,
2652 _options$rootBoundary = _options.rootBoundary,
2653 rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,
2654 _options$elementConte = _options.elementContext,
2655 elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,
2656 _options$altBoundary = _options.altBoundary,
2657 altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
2658 _options$padding = _options.padding,
2659 padding = _options$padding === void 0 ? 0 : _options$padding;
2660 var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
2661 var altContext = elementContext === popper ? reference : popper;
2662 var popperRect = state.rects.popper;
2663 var element = state.elements[altBoundary ? altContext : elementContext];
2664 var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);
2665 var referenceClientRect = getBoundingClientRect(state.elements.reference);
2666 var popperOffsets = computeOffsets({
2667 reference: referenceClientRect,
2668 element: popperRect,
2669 strategy: 'absolute',
2670 placement: placement
2672 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));
2673 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
2674 // 0 or negative = within the clipping rect
2676 var overflowOffsets = {
2677 top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
2678 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
2679 left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
2680 right: elementClientRect.right - clippingClientRect.right + paddingObject.right
2682 var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element
2684 if (elementContext === popper && offsetData) {
2685 var offset = offsetData[placement];
2686 Object.keys(overflowOffsets).forEach(function (key) {
2687 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
2688 var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';
2689 overflowOffsets[key] += offset[axis] * multiply;
2693 return overflowOffsets;
2696 function computeAutoPlacement(state, options) {
2697 if (options === void 0) {
2701 var _options = options,
2702 placement = _options.placement,
2703 boundary = _options.boundary,
2704 rootBoundary = _options.rootBoundary,
2705 padding = _options.padding,
2706 flipVariations = _options.flipVariations,
2707 _options$allowedAutoP = _options.allowedAutoPlacements,
2708 allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
2709 var variation = getVariation(placement);
2710 var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) {
2711 return getVariation(placement) === variation;
2712 }) : basePlacements;
2713 var allowedPlacements = placements$1.filter(function (placement) {
2714 return allowedAutoPlacements.indexOf(placement) >= 0;
2717 if (allowedPlacements.length === 0) {
2718 allowedPlacements = placements$1;
2719 } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...
2722 var overflows = allowedPlacements.reduce(function (acc, placement) {
2723 acc[placement] = detectOverflow(state, {
2724 placement: placement,
2726 rootBoundary: rootBoundary,
2728 })[getBasePlacement(placement)];
2731 return Object.keys(overflows).sort(function (a, b) {
2732 return overflows[a] - overflows[b];
2736 function getExpandedFallbackPlacements(placement) {
2737 if (getBasePlacement(placement) === auto) {
2741 var oppositePlacement = getOppositePlacement(placement);
2742 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
2745 function flip(_ref) {
2746 var state = _ref.state,
2747 options = _ref.options,
2750 if (state.modifiersData[name]._skip) {
2754 var _options$mainAxis = options.mainAxis,
2755 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
2756 _options$altAxis = options.altAxis,
2757 checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
2758 specifiedFallbackPlacements = options.fallbackPlacements,
2759 padding = options.padding,
2760 boundary = options.boundary,
2761 rootBoundary = options.rootBoundary,
2762 altBoundary = options.altBoundary,
2763 _options$flipVariatio = options.flipVariations,
2764 flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
2765 allowedAutoPlacements = options.allowedAutoPlacements;
2766 var preferredPlacement = state.options.placement;
2767 var basePlacement = getBasePlacement(preferredPlacement);
2768 var isBasePlacement = basePlacement === preferredPlacement;
2769 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
2770 var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
2771 return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
2772 placement: placement,
2774 rootBoundary: rootBoundary,
2776 flipVariations: flipVariations,
2777 allowedAutoPlacements: allowedAutoPlacements
2780 var referenceRect = state.rects.reference;
2781 var popperRect = state.rects.popper;
2782 var checksMap = new Map();
2783 var makeFallbackChecks = true;
2784 var firstFittingPlacement = placements[0];
2786 for (var i = 0; i < placements.length; i++) {
2787 var placement = placements[i];
2789 var _basePlacement = getBasePlacement(placement);
2791 var isStartVariation = getVariation(placement) === start;
2792 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
2793 var len = isVertical ? 'width' : 'height';
2794 var overflow = detectOverflow(state, {
2795 placement: placement,
2797 rootBoundary: rootBoundary,
2798 altBoundary: altBoundary,
2801 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
2803 if (referenceRect[len] > popperRect[len]) {
2804 mainVariationSide = getOppositePlacement(mainVariationSide);
2807 var altVariationSide = getOppositePlacement(mainVariationSide);
2810 if (checkMainAxis) {
2811 checks.push(overflow[_basePlacement] <= 0);
2815 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
2818 if (checks.every(function (check) {
2821 firstFittingPlacement = placement;
2822 makeFallbackChecks = false;
2826 checksMap.set(placement, checks);
2829 if (makeFallbackChecks) {
2830 // `2` may be desired in some cases – research later
2831 var numberOfChecks = flipVariations ? 3 : 1;
2833 var _loop = function _loop(_i) {
2834 var fittingPlacement = placements.find(function (placement) {
2835 var checks = checksMap.get(placement);
2838 return checks.slice(0, _i).every(function (check) {
2844 if (fittingPlacement) {
2845 firstFittingPlacement = fittingPlacement;
2850 for (var _i = numberOfChecks; _i > 0; _i--) {
2851 var _ret = _loop(_i);
2853 if (_ret === "break") break;
2857 if (state.placement !== firstFittingPlacement) {
2858 state.modifiersData[name]._skip = true;
2859 state.placement = firstFittingPlacement;
2862 } // eslint-disable-next-line import/no-unused-modules
2870 requiresIfExists: ['offset'],
2876 function getSideOffsets(overflow, rect, preventedOffsets) {
2877 if (preventedOffsets === void 0) {
2878 preventedOffsets = {
2885 top: overflow.top - rect.height - preventedOffsets.y,
2886 right: overflow.right - rect.width + preventedOffsets.x,
2887 bottom: overflow.bottom - rect.height + preventedOffsets.y,
2888 left: overflow.left - rect.width - preventedOffsets.x
2892 function isAnySideFullyClipped(overflow) {
2893 return [top, right, bottom, left].some(function (side) {
2894 return overflow[side] >= 0;
2898 function hide(_ref) {
2899 var state = _ref.state,
2901 var referenceRect = state.rects.reference;
2902 var popperRect = state.rects.popper;
2903 var preventedOffsets = state.modifiersData.preventOverflow;
2904 var referenceOverflow = detectOverflow(state, {
2905 elementContext: 'reference'
2907 var popperAltOverflow = detectOverflow(state, {
2910 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
2911 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
2912 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
2913 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
2914 state.modifiersData[name] = {
2915 referenceClippingOffsets: referenceClippingOffsets,
2916 popperEscapeOffsets: popperEscapeOffsets,
2917 isReferenceHidden: isReferenceHidden,
2918 hasPopperEscaped: hasPopperEscaped
2920 state.attributes.popper = Object.assign({}, state.attributes.popper, {
2921 'data-popper-reference-hidden': isReferenceHidden,
2922 'data-popper-escaped': hasPopperEscaped
2924 } // eslint-disable-next-line import/no-unused-modules
2931 requiresIfExists: ['preventOverflow'],
2935 function distanceAndSkiddingToXY(placement, rects, offset) {
2936 var basePlacement = getBasePlacement(placement);
2937 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
2939 var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
2940 placement: placement
2945 skidding = skidding || 0;
2946 distance = (distance || 0) * invertDistance;
2947 return [left, right].indexOf(basePlacement) >= 0 ? {
2956 function offset(_ref2) {
2957 var state = _ref2.state,
2958 options = _ref2.options,
2960 var _options$offset = options.offset,
2961 offset = _options$offset === void 0 ? [0, 0] : _options$offset;
2962 var data = placements.reduce(function (acc, placement) {
2963 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
2966 var _data$state$placement = data[state.placement],
2967 x = _data$state$placement.x,
2968 y = _data$state$placement.y;
2970 if (state.modifiersData.popperOffsets != null) {
2971 state.modifiersData.popperOffsets.x += x;
2972 state.modifiersData.popperOffsets.y += y;
2975 state.modifiersData[name] = data;
2976 } // eslint-disable-next-line import/no-unused-modules
2983 requires: ['popperOffsets'],
2987 function popperOffsets(_ref) {
2988 var state = _ref.state,
2990 // Offsets are the actual position the popper needs to have to be
2991 // properly positioned near its reference element
2992 // This is the most basic placement, and will be adjusted by
2993 // the modifiers in the next step
2994 state.modifiersData[name] = computeOffsets({
2995 reference: state.rects.reference,
2996 element: state.rects.popper,
2997 strategy: 'absolute',
2998 placement: state.placement
3000 } // eslint-disable-next-line import/no-unused-modules
3003 const popperOffsets$1 = {
3004 name: 'popperOffsets',
3011 function getAltAxis(axis) {
3012 return axis === 'x' ? 'y' : 'x';
3015 function preventOverflow(_ref) {
3016 var state = _ref.state,
3017 options = _ref.options,
3019 var _options$mainAxis = options.mainAxis,
3020 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
3021 _options$altAxis = options.altAxis,
3022 checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
3023 boundary = options.boundary,
3024 rootBoundary = options.rootBoundary,
3025 altBoundary = options.altBoundary,
3026 padding = options.padding,
3027 _options$tether = options.tether,
3028 tether = _options$tether === void 0 ? true : _options$tether,
3029 _options$tetherOffset = options.tetherOffset,
3030 tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
3031 var overflow = detectOverflow(state, {
3033 rootBoundary: rootBoundary,
3035 altBoundary: altBoundary
3037 var basePlacement = getBasePlacement(state.placement);
3038 var variation = getVariation(state.placement);
3039 var isBasePlacement = !variation;
3040 var mainAxis = getMainAxisFromPlacement(basePlacement);
3041 var altAxis = getAltAxis(mainAxis);
3042 var popperOffsets = state.modifiersData.popperOffsets;
3043 var referenceRect = state.rects.reference;
3044 var popperRect = state.rects.popper;
3045 var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
3046 placement: state.placement
3048 var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {
3049 mainAxis: tetherOffsetValue,
3050 altAxis: tetherOffsetValue
3054 }, tetherOffsetValue);
3055 var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
3061 if (!popperOffsets) {
3065 if (checkMainAxis) {
3066 var _offsetModifierState$;
3068 var mainSide = mainAxis === 'y' ? top : left;
3069 var altSide = mainAxis === 'y' ? bottom : right;
3070 var len = mainAxis === 'y' ? 'height' : 'width';
3071 var offset = popperOffsets[mainAxis];
3072 var min$1 = offset + overflow[mainSide];
3073 var max$1 = offset - overflow[altSide];
3074 var additive = tether ? -popperRect[len] / 2 : 0;
3075 var minLen = variation === start ? referenceRect[len] : popperRect[len];
3076 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
3077 // outside the reference bounds
3079 var arrowElement = state.elements.arrow;
3080 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
3084 var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject();
3085 var arrowPaddingMin = arrowPaddingObject[mainSide];
3086 var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
3087 // to include its full size in the calculation. If the reference is small
3088 // and near the edge of a boundary, the popper can overflow even if the
3089 // reference is not overflowing as well (e.g. virtual elements with no
3092 var arrowLen = within(0, referenceRect[len], arrowRect[len]);
3093 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
3094 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
3095 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
3096 var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
3097 var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
3098 var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;
3099 var tetherMax = offset + maxOffset - offsetModifierValue;
3100 var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1);
3101 popperOffsets[mainAxis] = preventedOffset;
3102 data[mainAxis] = preventedOffset - offset;
3106 var _offsetModifierState$2;
3108 var _mainSide = mainAxis === 'x' ? top : left;
3110 var _altSide = mainAxis === 'x' ? bottom : right;
3112 var _offset = popperOffsets[altAxis];
3114 var _len = altAxis === 'y' ? 'height' : 'width';
3116 var _min = _offset + overflow[_mainSide];
3118 var _max = _offset - overflow[_altSide];
3120 var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
3122 var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
3124 var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
3126 var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
3128 var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
3130 popperOffsets[altAxis] = _preventedOffset;
3131 data[altAxis] = _preventedOffset - _offset;
3134 state.modifiersData[name] = data;
3135 } // eslint-disable-next-line import/no-unused-modules
3138 const preventOverflow$1 = {
3139 name: 'preventOverflow',
3142 fn: preventOverflow,
3143 requiresIfExists: ['offset']
3146 function getHTMLElementScroll(element) {
3148 scrollLeft: element.scrollLeft,
3149 scrollTop: element.scrollTop
3153 function getNodeScroll(node) {
3154 if (node === getWindow(node) || !isHTMLElement(node)) {
3155 return getWindowScroll(node);
3157 return getHTMLElementScroll(node);
3161 function isElementScaled(element) {
3162 var rect = element.getBoundingClientRect();
3163 var scaleX = round(rect.width) / element.offsetWidth || 1;
3164 var scaleY = round(rect.height) / element.offsetHeight || 1;
3165 return scaleX !== 1 || scaleY !== 1;
3166 } // Returns the composite rect of an element relative to its offsetParent.
3167 // Composite means it takes into account transforms as well as layout.
3170 function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
3171 if (isFixed === void 0) {
3175 var isOffsetParentAnElement = isHTMLElement(offsetParent);
3176 var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
3177 var documentElement = getDocumentElement(offsetParent);
3178 var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
3188 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
3189 if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078
3190 isScrollParent(documentElement)) {
3191 scroll = getNodeScroll(offsetParent);
3194 if (isHTMLElement(offsetParent)) {
3195 offsets = getBoundingClientRect(offsetParent, true);
3196 offsets.x += offsetParent.clientLeft;
3197 offsets.y += offsetParent.clientTop;
3198 } else if (documentElement) {
3199 offsets.x = getWindowScrollBarX(documentElement);
3204 x: rect.left + scroll.scrollLeft - offsets.x,
3205 y: rect.top + scroll.scrollTop - offsets.y,
3211 function order(modifiers) {
3212 var map = new Map();
3213 var visited = new Set();
3215 modifiers.forEach(function (modifier) {
3216 map.set(modifier.name, modifier);
3217 }); // On visiting object, check for its dependencies and visit them recursively
3219 function sort(modifier) {
3220 visited.add(modifier.name);
3221 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
3222 requires.forEach(function (dep) {
3223 if (!visited.has(dep)) {
3224 var depModifier = map.get(dep);
3231 result.push(modifier);
3234 modifiers.forEach(function (modifier) {
3235 if (!visited.has(modifier.name)) {
3236 // check for visited object
3243 function orderModifiers(modifiers) {
3244 // order based on dependencies
3245 var orderedModifiers = order(modifiers); // order based on phase
3247 return modifierPhases.reduce(function (acc, phase) {
3248 return acc.concat(orderedModifiers.filter(function (modifier) {
3249 return modifier.phase === phase;
3254 function debounce(fn) {
3256 return function () {
3258 pending = new Promise(function (resolve) {
3259 Promise.resolve().then(function () {
3260 pending = undefined;
3270 function mergeByName(modifiers) {
3271 var merged = modifiers.reduce(function (merged, current) {
3272 var existing = merged[current.name];
3273 merged[current.name] = existing ? Object.assign({}, existing, current, {
3274 options: Object.assign({}, existing.options, current.options),
3275 data: Object.assign({}, existing.data, current.data)
3278 }, {}); // IE11 does not support Object.values
3280 return Object.keys(merged).map(function (key) {
3285 var DEFAULT_OPTIONS = {
3286 placement: 'bottom',
3288 strategy: 'absolute'
3291 function areValidElements() {
3292 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
3293 args[_key] = arguments[_key];
3296 return !args.some(function (element) {
3297 return !(element && typeof element.getBoundingClientRect === 'function');
3301 function popperGenerator(generatorOptions) {
3302 if (generatorOptions === void 0) {
3303 generatorOptions = {};
3306 var _generatorOptions = generatorOptions,
3307 _generatorOptions$def = _generatorOptions.defaultModifiers,
3308 defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
3309 _generatorOptions$def2 = _generatorOptions.defaultOptions,
3310 defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
3311 return function createPopper(reference, popper, options) {
3312 if (options === void 0) {
3313 options = defaultOptions;
3317 placement: 'bottom',
3318 orderedModifiers: [],
3319 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
3322 reference: reference,
3328 var effectCleanupFns = [];
3329 var isDestroyed = false;
3332 setOptions: function setOptions(setOptionsAction) {
3333 var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;
3334 cleanupModifierEffects();
3335 state.options = Object.assign({}, defaultOptions, state.options, options);
3336 state.scrollParents = {
3337 reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [],
3338 popper: listScrollParents(popper)
3339 }; // Orders the modifiers based on their dependencies and `phase`
3342 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers
3344 state.orderedModifiers = orderedModifiers.filter(function (m) {
3347 runModifierEffects();
3348 return instance.update();
3350 // Sync update – it will always be executed, even if not necessary. This
3351 // is useful for low frequency updates where sync behavior simplifies the
3353 // For high frequency updates (e.g. `resize` and `scroll` events), always
3354 // prefer the async Popper#update method
3355 forceUpdate: function forceUpdate() {
3360 var _state$elements = state.elements,
3361 reference = _state$elements.reference,
3362 popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
3365 if (!areValidElements(reference, popper)) {
3367 } // Store the reference and popper rects to be read by modifiers
3371 reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'),
3372 popper: getLayoutRect(popper)
3373 }; // Modifiers have the ability to reset the current update cycle. The
3374 // most common use case for this is the `flip` modifier changing the
3375 // placement, which then needs to re-run all the modifiers, because the
3376 // logic was previously ran for the previous placement and is therefore
3379 state.reset = false;
3380 state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
3381 // is filled with the initial data specified by the modifier. This means
3382 // it doesn't persist and is fresh on each update.
3383 // To ensure persistent data, use `${name}#persistent`
3385 state.orderedModifiers.forEach(function (modifier) {
3386 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
3389 for (var index = 0; index < state.orderedModifiers.length; index++) {
3390 if (state.reset === true) {
3391 state.reset = false;
3396 var _state$orderedModifie = state.orderedModifiers[index],
3397 fn = _state$orderedModifie.fn,
3398 _state$orderedModifie2 = _state$orderedModifie.options,
3399 _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
3400 name = _state$orderedModifie.name;
3402 if (typeof fn === 'function') {
3412 // Async and optimistically optimized update – it will not be executed if
3413 // not necessary (debounced to run at most once-per-tick)
3414 update: debounce(function () {
3415 return new Promise(function (resolve) {
3416 instance.forceUpdate();
3420 destroy: function destroy() {
3421 cleanupModifierEffects();
3426 if (!areValidElements(reference, popper)) {
3430 instance.setOptions(options).then(function (state) {
3431 if (!isDestroyed && options.onFirstUpdate) {
3432 options.onFirstUpdate(state);
3434 }); // Modifiers have the ability to execute arbitrary code before the first
3435 // update cycle runs. They will be executed in the same order as the update
3436 // cycle. This is useful when a modifier adds some persistent data that
3437 // other modifiers need to use, but the modifier is run after the dependent
3440 function runModifierEffects() {
3441 state.orderedModifiers.forEach(function (_ref) {
3442 var name = _ref.name,
3443 _ref$options = _ref.options,
3444 options = _ref$options === void 0 ? {} : _ref$options,
3445 effect = _ref.effect;
3447 if (typeof effect === 'function') {
3448 var cleanupFn = effect({
3455 var noopFn = function noopFn() {};
3457 effectCleanupFns.push(cleanupFn || noopFn);
3462 function cleanupModifierEffects() {
3463 effectCleanupFns.forEach(function (fn) {
3466 effectCleanupFns = [];
3472 var createPopper$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules
3474 var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1];
3475 var createPopper$1 = /*#__PURE__*/popperGenerator({
3476 defaultModifiers: defaultModifiers$1
3477 }); // eslint-disable-next-line import/no-unused-modules
3479 var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1];
3480 var createPopper = /*#__PURE__*/popperGenerator({
3481 defaultModifiers: defaultModifiers
3482 }); // eslint-disable-next-line import/no-unused-modules
3484 const Popper = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
3489 applyStyles: applyStyles$1,
3498 computeStyles: computeStyles$1,
3500 createPopperBase: createPopper$2,
3501 createPopperLite: createPopper$1,
3514 popperOffsets: popperOffsets$1,
3515 preventOverflow: preventOverflow$1,
3521 variationPlacements,
3524 }, Symbol.toStringTag, { value: 'Module' }));
3527 * --------------------------------------------------------------------------
3528 * Bootstrap dropdown.js
3529 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3530 * --------------------------------------------------------------------------
3538 const NAME$a = 'dropdown';
3539 const DATA_KEY$6 = 'bs.dropdown';
3540 const EVENT_KEY$6 = `.${DATA_KEY$6}`;
3541 const DATA_API_KEY$3 = '.data-api';
3542 const ESCAPE_KEY$2 = 'Escape';
3543 const TAB_KEY$1 = 'Tab';
3544 const ARROW_UP_KEY$1 = 'ArrowUp';
3545 const ARROW_DOWN_KEY$1 = 'ArrowDown';
3546 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
3548 const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;
3549 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;
3550 const EVENT_SHOW$5 = `show${EVENT_KEY$6}`;
3551 const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;
3552 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;
3553 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;
3554 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;
3555 const CLASS_NAME_SHOW$6 = 'show';
3556 const CLASS_NAME_DROPUP = 'dropup';
3557 const CLASS_NAME_DROPEND = 'dropend';
3558 const CLASS_NAME_DROPSTART = 'dropstart';
3559 const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
3560 const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
3561 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
3562 const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;
3563 const SELECTOR_MENU = '.dropdown-menu';
3564 const SELECTOR_NAVBAR = '.navbar';
3565 const SELECTOR_NAVBAR_NAV = '.navbar-nav';
3566 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
3567 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
3568 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
3569 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
3570 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
3571 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
3572 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
3573 const PLACEMENT_TOPCENTER = 'top';
3574 const PLACEMENT_BOTTOMCENTER = 'bottom';
3577 boundary: 'clippingParents',
3583 const DefaultType$9 = {
3584 autoClose: '(boolean|string)',
3585 boundary: '(string|element)',
3587 offset: '(array|string|function)',
3588 popperConfig: '(null|object|function)',
3589 reference: '(string|element|object)'
3596 class Dropdown extends BaseComponent {
3597 constructor(element, config) {
3598 super(element, config);
3599 this._popper = null;
3600 this._parent = this._element.parentNode; // dropdown wrapper
3601 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
3602 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);
3603 this._inNavbar = this._detectNavbar();
3607 static get Default() {
3610 static get DefaultType() {
3611 return DefaultType$9;
3619 return this._isShown() ? this.hide() : this.show();
3622 if (isDisabled(this._element) || this._isShown()) {
3625 const relatedTarget = {
3626 relatedTarget: this._element
3628 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);
3629 if (showEvent.defaultPrevented) {
3632 this._createPopper();
3634 // If this is a touch-enabled device we add extra
3635 // empty mouseover listeners to the body's immediate children;
3636 // only needed because of broken event delegation on iOS
3637 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
3638 if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
3639 for (const element of [].concat(...document.body.children)) {
3640 EventHandler.on(element, 'mouseover', noop);
3643 this._element.focus();
3644 this._element.setAttribute('aria-expanded', true);
3645 this._menu.classList.add(CLASS_NAME_SHOW$6);
3646 this._element.classList.add(CLASS_NAME_SHOW$6);
3647 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);
3650 if (isDisabled(this._element) || !this._isShown()) {
3653 const relatedTarget = {
3654 relatedTarget: this._element
3656 this._completeHide(relatedTarget);
3660 this._popper.destroy();
3665 this._inNavbar = this._detectNavbar();
3667 this._popper.update();
3672 _completeHide(relatedTarget) {
3673 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);
3674 if (hideEvent.defaultPrevented) {
3678 // If this is a touch-enabled device we remove the extra
3679 // empty mouseover listeners we added for iOS support
3680 if ('ontouchstart' in document.documentElement) {
3681 for (const element of [].concat(...document.body.children)) {
3682 EventHandler.off(element, 'mouseover', noop);
3686 this._popper.destroy();
3688 this._menu.classList.remove(CLASS_NAME_SHOW$6);
3689 this._element.classList.remove(CLASS_NAME_SHOW$6);
3690 this._element.setAttribute('aria-expanded', 'false');
3691 Manipulator.removeDataAttribute(this._menu, 'popper');
3692 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);
3694 _getConfig(config) {
3695 config = super._getConfig(config);
3696 if (typeof config.reference === 'object' && !isElement$1(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
3697 // Popper virtual elements require a getBoundingClientRect method
3698 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
3703 if (typeof Popper === 'undefined') {
3704 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
3706 let referenceElement = this._element;
3707 if (this._config.reference === 'parent') {
3708 referenceElement = this._parent;
3709 } else if (isElement$1(this._config.reference)) {
3710 referenceElement = getElement(this._config.reference);
3711 } else if (typeof this._config.reference === 'object') {
3712 referenceElement = this._config.reference;
3714 const popperConfig = this._getPopperConfig();
3715 this._popper = createPopper(referenceElement, this._menu, popperConfig);
3718 return this._menu.classList.contains(CLASS_NAME_SHOW$6);
3721 const parentDropdown = this._parent;
3722 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
3723 return PLACEMENT_RIGHT;
3725 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
3726 return PLACEMENT_LEFT;
3728 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
3729 return PLACEMENT_TOPCENTER;
3731 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
3732 return PLACEMENT_BOTTOMCENTER;
3735 // We need to trim the value because custom properties can also include spaces
3736 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
3737 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
3738 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
3740 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
3743 return this._element.closest(SELECTOR_NAVBAR) !== null;
3749 if (typeof offset === 'string') {
3750 return offset.split(',').map(value => Number.parseInt(value, 10));
3752 if (typeof offset === 'function') {
3753 return popperData => offset(popperData, this._element);
3757 _getPopperConfig() {
3758 const defaultBsPopperConfig = {
3759 placement: this._getPlacement(),
3761 name: 'preventOverflow',
3763 boundary: this._config.boundary
3768 offset: this._getOffset()
3773 // Disable Popper if we have a static display or Dropdown is in Navbar
3774 if (this._inNavbar || this._config.display === 'static') {
3775 Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove
3776 defaultBsPopperConfig.modifiers = [{
3777 name: 'applyStyles',
3782 ...defaultBsPopperConfig,
3783 ...execute(this._config.popperConfig, [defaultBsPopperConfig])
3790 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));
3791 if (!items.length) {
3795 // if target isn't included in items (e.g. when expanding the dropdown)
3796 // allow cycling to get the last item in case key equals ARROW_UP_KEY
3797 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
3801 static jQueryInterface(config) {
3802 return this.each(function () {
3803 const data = Dropdown.getOrCreateInstance(this, config);
3804 if (typeof config !== 'string') {
3807 if (typeof data[config] === 'undefined') {
3808 throw new TypeError(`No method named "${config}"`);
3813 static clearMenus(event) {
3814 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
3817 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);
3818 for (const toggle of openToggles) {
3819 const context = Dropdown.getInstance(toggle);
3820 if (!context || context._config.autoClose === false) {
3823 const composedPath = event.composedPath();
3824 const isMenuTarget = composedPath.includes(context._menu);
3825 if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
3829 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
3830 if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {
3833 const relatedTarget = {
3834 relatedTarget: context._element
3836 if (event.type === 'click') {
3837 relatedTarget.clickEvent = event;
3839 context._completeHide(relatedTarget);
3842 static dataApiKeydownHandler(event) {
3843 // If not an UP | DOWN | ESCAPE key => not a dropdown command
3844 // If input/textarea && if key is other than ESCAPE => not a dropdown command
3846 const isInput = /input|textarea/i.test(event.target.tagName);
3847 const isEscapeEvent = event.key === ESCAPE_KEY$2;
3848 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);
3849 if (!isUpOrDownEvent && !isEscapeEvent) {
3852 if (isInput && !isEscapeEvent) {
3855 event.preventDefault();
3857 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/
3858 const getToggleButton = this.matches(SELECTOR_DATA_TOGGLE$3) ? this : SelectorEngine.prev(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.next(this, SELECTOR_DATA_TOGGLE$3)[0] || SelectorEngine.findOne(SELECTOR_DATA_TOGGLE$3, event.delegateTarget.parentNode);
3859 const instance = Dropdown.getOrCreateInstance(getToggleButton);
3860 if (isUpOrDownEvent) {
3861 event.stopPropagation();
3863 instance._selectMenuItem(event);
3866 if (instance._isShown()) {
3867 // else is escape and we check if it is shown
3868 event.stopPropagation();
3870 getToggleButton.focus();
3876 * Data API implementation
3879 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
3880 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
3881 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);
3882 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
3883 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {
3884 event.preventDefault();
3885 Dropdown.getOrCreateInstance(this).toggle();
3892 defineJQueryPlugin(Dropdown);
3895 * --------------------------------------------------------------------------
3896 * Bootstrap util/backdrop.js
3897 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3898 * --------------------------------------------------------------------------
3906 const NAME$9 = 'backdrop';
3907 const CLASS_NAME_FADE$4 = 'fade';
3908 const CLASS_NAME_SHOW$5 = 'show';
3909 const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;
3911 className: 'modal-backdrop',
3912 clickCallback: null,
3915 // if false, we use the backdrop helper without adding any element to the dom
3916 rootElement: 'body' // give the choice to place backdrop under different elements
3918 const DefaultType$8 = {
3919 className: 'string',
3920 clickCallback: '(function|null)',
3921 isAnimated: 'boolean',
3922 isVisible: 'boolean',
3923 rootElement: '(element|string)'
3930 class Backdrop extends Config {
3931 constructor(config) {
3933 this._config = this._getConfig(config);
3934 this._isAppended = false;
3935 this._element = null;
3939 static get Default() {
3942 static get DefaultType() {
3943 return DefaultType$8;
3951 if (!this._config.isVisible) {
3956 const element = this._getElement();
3957 if (this._config.isAnimated) {
3960 element.classList.add(CLASS_NAME_SHOW$5);
3961 this._emulateAnimation(() => {
3966 if (!this._config.isVisible) {
3970 this._getElement().classList.remove(CLASS_NAME_SHOW$5);
3971 this._emulateAnimation(() => {
3977 if (!this._isAppended) {
3980 EventHandler.off(this._element, EVENT_MOUSEDOWN);
3981 this._element.remove();
3982 this._isAppended = false;
3987 if (!this._element) {
3988 const backdrop = document.createElement('div');
3989 backdrop.className = this._config.className;
3990 if (this._config.isAnimated) {
3991 backdrop.classList.add(CLASS_NAME_FADE$4);
3993 this._element = backdrop;
3995 return this._element;
3997 _configAfterMerge(config) {
3998 // use getElement() with the default "body" to get a fresh Element on each instantiation
3999 config.rootElement = getElement(config.rootElement);
4003 if (this._isAppended) {
4006 const element = this._getElement();
4007 this._config.rootElement.append(element);
4008 EventHandler.on(element, EVENT_MOUSEDOWN, () => {
4009 execute(this._config.clickCallback);
4011 this._isAppended = true;
4013 _emulateAnimation(callback) {
4014 executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
4019 * --------------------------------------------------------------------------
4020 * Bootstrap util/focustrap.js
4021 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4022 * --------------------------------------------------------------------------
4030 const NAME$8 = 'focustrap';
4031 const DATA_KEY$5 = 'bs.focustrap';
4032 const EVENT_KEY$5 = `.${DATA_KEY$5}`;
4033 const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;
4034 const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;
4035 const TAB_KEY = 'Tab';
4036 const TAB_NAV_FORWARD = 'forward';
4037 const TAB_NAV_BACKWARD = 'backward';
4040 trapElement: null // The element to trap focus inside of
4042 const DefaultType$7 = {
4043 autofocus: 'boolean',
4044 trapElement: 'element'
4051 class FocusTrap extends Config {
4052 constructor(config) {
4054 this._config = this._getConfig(config);
4055 this._isActive = false;
4056 this._lastTabNavDirection = null;
4060 static get Default() {
4063 static get DefaultType() {
4064 return DefaultType$7;
4072 if (this._isActive) {
4075 if (this._config.autofocus) {
4076 this._config.trapElement.focus();
4078 EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop
4079 EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));
4080 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
4081 this._isActive = true;
4084 if (!this._isActive) {
4087 this._isActive = false;
4088 EventHandler.off(document, EVENT_KEY$5);
4092 _handleFocusin(event) {
4096 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
4099 const elements = SelectorEngine.focusableChildren(trapElement);
4100 if (elements.length === 0) {
4101 trapElement.focus();
4102 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
4103 elements[elements.length - 1].focus();
4105 elements[0].focus();
4108 _handleKeydown(event) {
4109 if (event.key !== TAB_KEY) {
4112 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
4117 * --------------------------------------------------------------------------
4118 * Bootstrap util/scrollBar.js
4119 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4120 * --------------------------------------------------------------------------
4128 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
4129 const SELECTOR_STICKY_CONTENT = '.sticky-top';
4130 const PROPERTY_PADDING = 'padding-right';
4131 const PROPERTY_MARGIN = 'margin-right';
4137 class ScrollBarHelper {
4139 this._element = document.body;
4144 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
4145 const documentWidth = document.documentElement.clientWidth;
4146 return Math.abs(window.innerWidth - documentWidth);
4149 const width = this.getWidth();
4150 this._disableOverFlow();
4151 // give padding to element to balance the hidden scrollbar width
4152 this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
4153 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
4154 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
4155 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
4158 this._resetElementAttributes(this._element, 'overflow');
4159 this._resetElementAttributes(this._element, PROPERTY_PADDING);
4160 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
4161 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
4164 return this.getWidth() > 0;
4168 _disableOverFlow() {
4169 this._saveInitialAttribute(this._element, 'overflow');
4170 this._element.style.overflow = 'hidden';
4172 _setElementAttributes(selector, styleProperty, callback) {
4173 const scrollbarWidth = this.getWidth();
4174 const manipulationCallBack = element => {
4175 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
4178 this._saveInitialAttribute(element, styleProperty);
4179 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
4180 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
4182 this._applyManipulationCallback(selector, manipulationCallBack);
4184 _saveInitialAttribute(element, styleProperty) {
4185 const actualValue = element.style.getPropertyValue(styleProperty);
4187 Manipulator.setDataAttribute(element, styleProperty, actualValue);
4190 _resetElementAttributes(selector, styleProperty) {
4191 const manipulationCallBack = element => {
4192 const value = Manipulator.getDataAttribute(element, styleProperty);
4193 // We only want to remove the property if the value is `null`; the value can also be zero
4194 if (value === null) {
4195 element.style.removeProperty(styleProperty);
4198 Manipulator.removeDataAttribute(element, styleProperty);
4199 element.style.setProperty(styleProperty, value);
4201 this._applyManipulationCallback(selector, manipulationCallBack);
4203 _applyManipulationCallback(selector, callBack) {
4204 if (isElement$1(selector)) {
4208 for (const sel of SelectorEngine.find(selector, this._element)) {
4215 * --------------------------------------------------------------------------
4216 * Bootstrap modal.js
4217 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4218 * --------------------------------------------------------------------------
4226 const NAME$7 = 'modal';
4227 const DATA_KEY$4 = 'bs.modal';
4228 const EVENT_KEY$4 = `.${DATA_KEY$4}`;
4229 const DATA_API_KEY$2 = '.data-api';
4230 const ESCAPE_KEY$1 = 'Escape';
4231 const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;
4232 const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;
4233 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;
4234 const EVENT_SHOW$4 = `show${EVENT_KEY$4}`;
4235 const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;
4236 const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;
4237 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;
4238 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;
4239 const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;
4240 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;
4241 const CLASS_NAME_OPEN = 'modal-open';
4242 const CLASS_NAME_FADE$3 = 'fade';
4243 const CLASS_NAME_SHOW$4 = 'show';
4244 const CLASS_NAME_STATIC = 'modal-static';
4245 const OPEN_SELECTOR$1 = '.modal.show';
4246 const SELECTOR_DIALOG = '.modal-dialog';
4247 const SELECTOR_MODAL_BODY = '.modal-body';
4248 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]';
4254 const DefaultType$6 = {
4255 backdrop: '(boolean|string)',
4264 class Modal extends BaseComponent {
4265 constructor(element, config) {
4266 super(element, config);
4267 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
4268 this._backdrop = this._initializeBackDrop();
4269 this._focustrap = this._initializeFocusTrap();
4270 this._isShown = false;
4271 this._isTransitioning = false;
4272 this._scrollBar = new ScrollBarHelper();
4273 this._addEventListeners();
4277 static get Default() {
4280 static get DefaultType() {
4281 return DefaultType$6;
4288 toggle(relatedTarget) {
4289 return this._isShown ? this.hide() : this.show(relatedTarget);
4291 show(relatedTarget) {
4292 if (this._isShown || this._isTransitioning) {
4295 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {
4298 if (showEvent.defaultPrevented) {
4301 this._isShown = true;
4302 this._isTransitioning = true;
4303 this._scrollBar.hide();
4304 document.body.classList.add(CLASS_NAME_OPEN);
4305 this._adjustDialog();
4306 this._backdrop.show(() => this._showElement(relatedTarget));
4309 if (!this._isShown || this._isTransitioning) {
4312 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);
4313 if (hideEvent.defaultPrevented) {
4316 this._isShown = false;
4317 this._isTransitioning = true;
4318 this._focustrap.deactivate();
4319 this._element.classList.remove(CLASS_NAME_SHOW$4);
4320 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());
4323 EventHandler.off(window, EVENT_KEY$4);
4324 EventHandler.off(this._dialog, EVENT_KEY$4);
4325 this._backdrop.dispose();
4326 this._focustrap.deactivate();
4330 this._adjustDialog();
4334 _initializeBackDrop() {
4335 return new Backdrop({
4336 isVisible: Boolean(this._config.backdrop),
4337 // 'static' option will be translated to true, and booleans will keep their value,
4338 isAnimated: this._isAnimated()
4341 _initializeFocusTrap() {
4342 return new FocusTrap({
4343 trapElement: this._element
4346 _showElement(relatedTarget) {
4347 // try to append dynamic modal
4348 if (!document.body.contains(this._element)) {
4349 document.body.append(this._element);
4351 this._element.style.display = 'block';
4352 this._element.removeAttribute('aria-hidden');
4353 this._element.setAttribute('aria-modal', true);
4354 this._element.setAttribute('role', 'dialog');
4355 this._element.scrollTop = 0;
4356 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
4358 modalBody.scrollTop = 0;
4360 reflow(this._element);
4361 this._element.classList.add(CLASS_NAME_SHOW$4);
4362 const transitionComplete = () => {
4363 if (this._config.focus) {
4364 this._focustrap.activate();
4366 this._isTransitioning = false;
4367 EventHandler.trigger(this._element, EVENT_SHOWN$4, {
4371 this._queueCallback(transitionComplete, this._dialog, this._isAnimated());
4373 _addEventListeners() {
4374 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {
4375 if (event.key !== ESCAPE_KEY$1) {
4378 if (this._config.keyboard) {
4382 this._triggerBackdropTransition();
4384 EventHandler.on(window, EVENT_RESIZE$1, () => {
4385 if (this._isShown && !this._isTransitioning) {
4386 this._adjustDialog();
4389 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
4390 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
4391 EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
4392 if (this._element !== event.target || this._element !== event2.target) {
4395 if (this._config.backdrop === 'static') {
4396 this._triggerBackdropTransition();
4399 if (this._config.backdrop) {
4406 this._element.style.display = 'none';
4407 this._element.setAttribute('aria-hidden', true);
4408 this._element.removeAttribute('aria-modal');
4409 this._element.removeAttribute('role');
4410 this._isTransitioning = false;
4411 this._backdrop.hide(() => {
4412 document.body.classList.remove(CLASS_NAME_OPEN);
4413 this._resetAdjustments();
4414 this._scrollBar.reset();
4415 EventHandler.trigger(this._element, EVENT_HIDDEN$4);
4419 return this._element.classList.contains(CLASS_NAME_FADE$3);
4421 _triggerBackdropTransition() {
4422 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);
4423 if (hideEvent.defaultPrevented) {
4426 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
4427 const initialOverflowY = this._element.style.overflowY;
4428 // return if the following background transition hasn't yet completed
4429 if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
4432 if (!isModalOverflowing) {
4433 this._element.style.overflowY = 'hidden';
4435 this._element.classList.add(CLASS_NAME_STATIC);
4436 this._queueCallback(() => {
4437 this._element.classList.remove(CLASS_NAME_STATIC);
4438 this._queueCallback(() => {
4439 this._element.style.overflowY = initialOverflowY;
4442 this._element.focus();
4446 * The following methods are used to handle overflowing modals
4450 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
4451 const scrollbarWidth = this._scrollBar.getWidth();
4452 const isBodyOverflowing = scrollbarWidth > 0;
4453 if (isBodyOverflowing && !isModalOverflowing) {
4454 const property = isRTL() ? 'paddingLeft' : 'paddingRight';
4455 this._element.style[property] = `${scrollbarWidth}px`;
4457 if (!isBodyOverflowing && isModalOverflowing) {
4458 const property = isRTL() ? 'paddingRight' : 'paddingLeft';
4459 this._element.style[property] = `${scrollbarWidth}px`;
4462 _resetAdjustments() {
4463 this._element.style.paddingLeft = '';
4464 this._element.style.paddingRight = '';
4468 static jQueryInterface(config, relatedTarget) {
4469 return this.each(function () {
4470 const data = Modal.getOrCreateInstance(this, config);
4471 if (typeof config !== 'string') {
4474 if (typeof data[config] === 'undefined') {
4475 throw new TypeError(`No method named "${config}"`);
4477 data[config](relatedTarget);
4483 * Data API implementation
4486 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {
4487 const target = SelectorEngine.getElementFromSelector(this);
4488 if (['A', 'AREA'].includes(this.tagName)) {
4489 event.preventDefault();
4491 EventHandler.one(target, EVENT_SHOW$4, showEvent => {
4492 if (showEvent.defaultPrevented) {
4493 // only register focus restorer if modal will actually get shown
4496 EventHandler.one(target, EVENT_HIDDEN$4, () => {
4497 if (isVisible(this)) {
4503 // avoid conflict when clicking modal toggler while another one is open
4504 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);
4506 Modal.getInstance(alreadyOpen).hide();
4508 const data = Modal.getOrCreateInstance(target);
4511 enableDismissTrigger(Modal);
4517 defineJQueryPlugin(Modal);
4520 * --------------------------------------------------------------------------
4521 * Bootstrap offcanvas.js
4522 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4523 * --------------------------------------------------------------------------
4531 const NAME$6 = 'offcanvas';
4532 const DATA_KEY$3 = 'bs.offcanvas';
4533 const EVENT_KEY$3 = `.${DATA_KEY$3}`;
4534 const DATA_API_KEY$1 = '.data-api';
4535 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;
4536 const ESCAPE_KEY = 'Escape';
4537 const CLASS_NAME_SHOW$3 = 'show';
4538 const CLASS_NAME_SHOWING$1 = 'showing';
4539 const CLASS_NAME_HIDING = 'hiding';
4540 const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
4541 const OPEN_SELECTOR = '.offcanvas.show';
4542 const EVENT_SHOW$3 = `show${EVENT_KEY$3}`;
4543 const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;
4544 const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;
4545 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;
4546 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;
4547 const EVENT_RESIZE = `resize${EVENT_KEY$3}`;
4548 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;
4549 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;
4550 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]';
4556 const DefaultType$5 = {
4557 backdrop: '(boolean|string)',
4558 keyboard: 'boolean',
4566 class Offcanvas extends BaseComponent {
4567 constructor(element, config) {
4568 super(element, config);
4569 this._isShown = false;
4570 this._backdrop = this._initializeBackDrop();
4571 this._focustrap = this._initializeFocusTrap();
4572 this._addEventListeners();
4576 static get Default() {
4579 static get DefaultType() {
4580 return DefaultType$5;
4587 toggle(relatedTarget) {
4588 return this._isShown ? this.hide() : this.show(relatedTarget);
4590 show(relatedTarget) {
4591 if (this._isShown) {
4594 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {
4597 if (showEvent.defaultPrevented) {
4600 this._isShown = true;
4601 this._backdrop.show();
4602 if (!this._config.scroll) {
4603 new ScrollBarHelper().hide();
4605 this._element.setAttribute('aria-modal', true);
4606 this._element.setAttribute('role', 'dialog');
4607 this._element.classList.add(CLASS_NAME_SHOWING$1);
4608 const completeCallBack = () => {
4609 if (!this._config.scroll || this._config.backdrop) {
4610 this._focustrap.activate();
4612 this._element.classList.add(CLASS_NAME_SHOW$3);
4613 this._element.classList.remove(CLASS_NAME_SHOWING$1);
4614 EventHandler.trigger(this._element, EVENT_SHOWN$3, {
4618 this._queueCallback(completeCallBack, this._element, true);
4621 if (!this._isShown) {
4624 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);
4625 if (hideEvent.defaultPrevented) {
4628 this._focustrap.deactivate();
4629 this._element.blur();
4630 this._isShown = false;
4631 this._element.classList.add(CLASS_NAME_HIDING);
4632 this._backdrop.hide();
4633 const completeCallback = () => {
4634 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);
4635 this._element.removeAttribute('aria-modal');
4636 this._element.removeAttribute('role');
4637 if (!this._config.scroll) {
4638 new ScrollBarHelper().reset();
4640 EventHandler.trigger(this._element, EVENT_HIDDEN$3);
4642 this._queueCallback(completeCallback, this._element, true);
4645 this._backdrop.dispose();
4646 this._focustrap.deactivate();
4651 _initializeBackDrop() {
4652 const clickCallback = () => {
4653 if (this._config.backdrop === 'static') {
4654 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
4660 // 'static' option will be translated to true, and booleans will keep their value
4661 const isVisible = Boolean(this._config.backdrop);
4662 return new Backdrop({
4663 className: CLASS_NAME_BACKDROP,
4666 rootElement: this._element.parentNode,
4667 clickCallback: isVisible ? clickCallback : null
4670 _initializeFocusTrap() {
4671 return new FocusTrap({
4672 trapElement: this._element
4675 _addEventListeners() {
4676 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
4677 if (event.key !== ESCAPE_KEY) {
4680 if (this._config.keyboard) {
4684 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
4689 static jQueryInterface(config) {
4690 return this.each(function () {
4691 const data = Offcanvas.getOrCreateInstance(this, config);
4692 if (typeof config !== 'string') {
4695 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
4696 throw new TypeError(`No method named "${config}"`);
4704 * Data API implementation
4707 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {
4708 const target = SelectorEngine.getElementFromSelector(this);
4709 if (['A', 'AREA'].includes(this.tagName)) {
4710 event.preventDefault();
4712 if (isDisabled(this)) {
4715 EventHandler.one(target, EVENT_HIDDEN$3, () => {
4716 // focus on trigger when it is closed
4717 if (isVisible(this)) {
4722 // avoid conflict when clicking a toggler of an offcanvas, while another is open
4723 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
4724 if (alreadyOpen && alreadyOpen !== target) {
4725 Offcanvas.getInstance(alreadyOpen).hide();
4727 const data = Offcanvas.getOrCreateInstance(target);
4730 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {
4731 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {
4732 Offcanvas.getOrCreateInstance(selector).show();
4735 EventHandler.on(window, EVENT_RESIZE, () => {
4736 for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
4737 if (getComputedStyle(element).position !== 'fixed') {
4738 Offcanvas.getOrCreateInstance(element).hide();
4742 enableDismissTrigger(Offcanvas);
4748 defineJQueryPlugin(Offcanvas);
4751 * --------------------------------------------------------------------------
4752 * Bootstrap util/sanitizer.js
4753 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4754 * --------------------------------------------------------------------------
4757 // js-docs-start allow-list
4758 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
4759 const DefaultAllowlist = {
4760 // Global attributes allowed on any supplied element below.
4761 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
4762 a: ['target', 'href', 'title', 'rel'],
4781 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
4795 // js-docs-end allow-list
4797 const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
4800 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
4803 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38
4805 // eslint-disable-next-line unicorn/better-regex
4806 const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i;
4807 const allowedAttribute = (attribute, allowedAttributeList) => {
4808 const attributeName = attribute.nodeName.toLowerCase();
4809 if (allowedAttributeList.includes(attributeName)) {
4810 if (uriAttributes.has(attributeName)) {
4811 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue));
4816 // Check if a regular expression validates the attribute.
4817 return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));
4819 function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
4820 if (!unsafeHtml.length) {
4823 if (sanitizeFunction && typeof sanitizeFunction === 'function') {
4824 return sanitizeFunction(unsafeHtml);
4826 const domParser = new window.DOMParser();
4827 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
4828 const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
4829 for (const element of elements) {
4830 const elementName = element.nodeName.toLowerCase();
4831 if (!Object.keys(allowList).includes(elementName)) {
4835 const attributeList = [].concat(...element.attributes);
4836 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
4837 for (const attribute of attributeList) {
4838 if (!allowedAttribute(attribute, allowedAttributes)) {
4839 element.removeAttribute(attribute.nodeName);
4843 return createdDocument.body.innerHTML;
4847 * --------------------------------------------------------------------------
4848 * Bootstrap util/template-factory.js
4849 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4850 * --------------------------------------------------------------------------
4858 const NAME$5 = 'TemplateFactory';
4860 allowList: DefaultAllowlist,
4862 // { selector : text , selector2 : text2 , }
4867 template: '<div></div>'
4869 const DefaultType$4 = {
4870 allowList: 'object',
4872 extraClass: '(string|function)',
4874 sanitize: 'boolean',
4875 sanitizeFn: '(null|function)',
4878 const DefaultContentType = {
4879 entry: '(string|element|function|null)',
4880 selector: '(string|element)'
4887 class TemplateFactory extends Config {
4888 constructor(config) {
4890 this._config = this._getConfig(config);
4894 static get Default() {
4897 static get DefaultType() {
4898 return DefaultType$4;
4906 return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);
4909 return this.getContent().length > 0;
4911 changeContent(content) {
4912 this._checkContent(content);
4913 this._config.content = {
4914 ...this._config.content,
4920 const templateWrapper = document.createElement('div');
4921 templateWrapper.innerHTML = this._maybeSanitize(this._config.template);
4922 for (const [selector, text] of Object.entries(this._config.content)) {
4923 this._setContent(templateWrapper, text, selector);
4925 const template = templateWrapper.children[0];
4926 const extraClass = this._resolvePossibleFunction(this._config.extraClass);
4928 template.classList.add(...extraClass.split(' '));
4934 _typeCheckConfig(config) {
4935 super._typeCheckConfig(config);
4936 this._checkContent(config.content);
4938 _checkContent(arg) {
4939 for (const [selector, content] of Object.entries(arg)) {
4940 super._typeCheckConfig({
4943 }, DefaultContentType);
4946 _setContent(template, content, selector) {
4947 const templateElement = SelectorEngine.findOne(selector, template);
4948 if (!templateElement) {
4951 content = this._resolvePossibleFunction(content);
4953 templateElement.remove();
4956 if (isElement$1(content)) {
4957 this._putElementInTemplate(getElement(content), templateElement);
4960 if (this._config.html) {
4961 templateElement.innerHTML = this._maybeSanitize(content);
4964 templateElement.textContent = content;
4966 _maybeSanitize(arg) {
4967 return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;
4969 _resolvePossibleFunction(arg) {
4970 return execute(arg, [this]);
4972 _putElementInTemplate(element, templateElement) {
4973 if (this._config.html) {
4974 templateElement.innerHTML = '';
4975 templateElement.append(element);
4978 templateElement.textContent = element.textContent;
4983 * --------------------------------------------------------------------------
4984 * Bootstrap tooltip.js
4985 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4986 * --------------------------------------------------------------------------
4994 const NAME$4 = 'tooltip';
4995 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
4996 const CLASS_NAME_FADE$2 = 'fade';
4997 const CLASS_NAME_MODAL = 'modal';
4998 const CLASS_NAME_SHOW$2 = 'show';
4999 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
5000 const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
5001 const EVENT_MODAL_HIDE = 'hide.bs.modal';
5002 const TRIGGER_HOVER = 'hover';
5003 const TRIGGER_FOCUS = 'focus';
5004 const TRIGGER_CLICK = 'click';
5005 const TRIGGER_MANUAL = 'manual';
5006 const EVENT_HIDE$2 = 'hide';
5007 const EVENT_HIDDEN$2 = 'hidden';
5008 const EVENT_SHOW$2 = 'show';
5009 const EVENT_SHOWN$2 = 'shown';
5010 const EVENT_INSERTED = 'inserted';
5011 const EVENT_CLICK$1 = 'click';
5012 const EVENT_FOCUSIN$1 = 'focusin';
5013 const EVENT_FOCUSOUT$1 = 'focusout';
5014 const EVENT_MOUSEENTER = 'mouseenter';
5015 const EVENT_MOUSELEAVE = 'mouseleave';
5016 const AttachmentMap = {
5019 RIGHT: isRTL() ? 'left' : 'right',
5021 LEFT: isRTL() ? 'right' : 'left'
5024 allowList: DefaultAllowlist,
5026 boundary: 'clippingParents',
5030 fallbackPlacements: ['top', 'right', 'bottom', 'left'],
5038 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
5040 trigger: 'hover focus'
5042 const DefaultType$3 = {
5043 allowList: 'object',
5044 animation: 'boolean',
5045 boundary: '(string|element)',
5046 container: '(string|element|boolean)',
5047 customClass: '(string|function)',
5048 delay: '(number|object)',
5049 fallbackPlacements: 'array',
5051 offset: '(array|string|function)',
5052 placement: '(string|function)',
5053 popperConfig: '(null|object|function)',
5054 sanitize: 'boolean',
5055 sanitizeFn: '(null|function)',
5056 selector: '(string|boolean)',
5058 title: '(string|element|function)',
5066 class Tooltip extends BaseComponent {
5067 constructor(element, config) {
5068 if (typeof Popper === 'undefined') {
5069 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
5071 super(element, config);
5074 this._isEnabled = true;
5076 this._isHovered = null;
5077 this._activeTrigger = {};
5078 this._popper = null;
5079 this._templateFactory = null;
5080 this._newContent = null;
5084 this._setListeners();
5085 if (!this._config.selector) {
5091 static get Default() {
5094 static get DefaultType() {
5095 return DefaultType$3;
5103 this._isEnabled = true;
5106 this._isEnabled = false;
5109 this._isEnabled = !this._isEnabled;
5112 if (!this._isEnabled) {
5115 this._activeTrigger.click = !this._activeTrigger.click;
5116 if (this._isShown()) {
5123 clearTimeout(this._timeout);
5124 EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
5125 if (this._element.getAttribute('data-bs-original-title')) {
5126 this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));
5128 this._disposePopper();
5132 if (this._element.style.display === 'none') {
5133 throw new Error('Please use show on visible elements');
5135 if (!(this._isWithContent() && this._isEnabled)) {
5138 const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));
5139 const shadowRoot = findShadowRoot(this._element);
5140 const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);
5141 if (showEvent.defaultPrevented || !isInTheDom) {
5145 // TODO: v6 remove this or make it optional
5146 this._disposePopper();
5147 const tip = this._getTipElement();
5148 this._element.setAttribute('aria-describedby', tip.getAttribute('id'));
5152 if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
5153 container.append(tip);
5154 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));
5156 this._popper = this._createPopper(tip);
5157 tip.classList.add(CLASS_NAME_SHOW$2);
5159 // If this is a touch-enabled device we add extra
5160 // empty mouseover listeners to the body's immediate children;
5161 // only needed because of broken event delegation on iOS
5162 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
5163 if ('ontouchstart' in document.documentElement) {
5164 for (const element of [].concat(...document.body.children)) {
5165 EventHandler.on(element, 'mouseover', noop);
5168 const complete = () => {
5169 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));
5170 if (this._isHovered === false) {
5173 this._isHovered = false;
5175 this._queueCallback(complete, this.tip, this._isAnimated());
5178 if (!this._isShown()) {
5181 const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));
5182 if (hideEvent.defaultPrevented) {
5185 const tip = this._getTipElement();
5186 tip.classList.remove(CLASS_NAME_SHOW$2);
5188 // If this is a touch-enabled device we remove the extra
5189 // empty mouseover listeners we added for iOS support
5190 if ('ontouchstart' in document.documentElement) {
5191 for (const element of [].concat(...document.body.children)) {
5192 EventHandler.off(element, 'mouseover', noop);
5195 this._activeTrigger[TRIGGER_CLICK] = false;
5196 this._activeTrigger[TRIGGER_FOCUS] = false;
5197 this._activeTrigger[TRIGGER_HOVER] = false;
5198 this._isHovered = null; // it is a trick to support manual triggering
5200 const complete = () => {
5201 if (this._isWithActiveTrigger()) {
5204 if (!this._isHovered) {
5205 this._disposePopper();
5207 this._element.removeAttribute('aria-describedby');
5208 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));
5210 this._queueCallback(complete, this.tip, this._isAnimated());
5214 this._popper.update();
5220 return Boolean(this._getTitle());
5224 this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());
5228 _createTipElement(content) {
5229 const tip = this._getTemplateFactory(content).toHtml();
5231 // TODO: remove this check in v6
5235 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2);
5236 // TODO: v6 the following can be achieved with CSS only
5237 tip.classList.add(`bs-${this.constructor.NAME}-auto`);
5238 const tipId = getUID(this.constructor.NAME).toString();
5239 tip.setAttribute('id', tipId);
5240 if (this._isAnimated()) {
5241 tip.classList.add(CLASS_NAME_FADE$2);
5245 setContent(content) {
5246 this._newContent = content;
5247 if (this._isShown()) {
5248 this._disposePopper();
5252 _getTemplateFactory(content) {
5253 if (this._templateFactory) {
5254 this._templateFactory.changeContent(content);
5256 this._templateFactory = new TemplateFactory({
5258 // the `content` var has to be after `this._config`
5259 // to override config.content in case of popover
5261 extraClass: this._resolvePossibleFunction(this._config.customClass)
5264 return this._templateFactory;
5266 _getContentForTemplate() {
5268 [SELECTOR_TOOLTIP_INNER]: this._getTitle()
5272 return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');
5276 _initializeOnDelegatedTarget(event) {
5277 return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());
5280 return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);
5283 return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);
5285 _createPopper(tip) {
5286 const placement = execute(this._config.placement, [this, tip, this._element]);
5287 const attachment = AttachmentMap[placement.toUpperCase()];
5288 return createPopper(this._element, tip, this._getPopperConfig(attachment));
5294 if (typeof offset === 'string') {
5295 return offset.split(',').map(value => Number.parseInt(value, 10));
5297 if (typeof offset === 'function') {
5298 return popperData => offset(popperData, this._element);
5302 _resolvePossibleFunction(arg) {
5303 return execute(arg, [this._element]);
5305 _getPopperConfig(attachment) {
5306 const defaultBsPopperConfig = {
5307 placement: attachment,
5311 fallbackPlacements: this._config.fallbackPlacements
5316 offset: this._getOffset()
5319 name: 'preventOverflow',
5321 boundary: this._config.boundary
5326 element: `.${this.constructor.NAME}-arrow`
5329 name: 'preSetPlacement',
5331 phase: 'beforeMain',
5333 // Pre-set Popper's placement attribute in order to read the arrow sizes properly.
5334 // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement
5335 this._getTipElement().setAttribute('data-popper-placement', data.state.placement);
5340 ...defaultBsPopperConfig,
5341 ...execute(this._config.popperConfig, [defaultBsPopperConfig])
5345 const triggers = this._config.trigger.split(' ');
5346 for (const trigger of triggers) {
5347 if (trigger === 'click') {
5348 EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
5349 const context = this._initializeOnDelegatedTarget(event);
5352 } else if (trigger !== TRIGGER_MANUAL) {
5353 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);
5354 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);
5355 EventHandler.on(this._element, eventIn, this._config.selector, event => {
5356 const context = this._initializeOnDelegatedTarget(event);
5357 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
5360 EventHandler.on(this._element, eventOut, this._config.selector, event => {
5361 const context = this._initializeOnDelegatedTarget(event);
5362 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);
5367 this._hideModalHandler = () => {
5368 if (this._element) {
5372 EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
5375 const title = this._element.getAttribute('title');
5379 if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {
5380 this._element.setAttribute('aria-label', title);
5382 this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility
5383 this._element.removeAttribute('title');
5386 if (this._isShown() || this._isHovered) {
5387 this._isHovered = true;
5390 this._isHovered = true;
5391 this._setTimeout(() => {
5392 if (this._isHovered) {
5395 }, this._config.delay.show);
5398 if (this._isWithActiveTrigger()) {
5401 this._isHovered = false;
5402 this._setTimeout(() => {
5403 if (!this._isHovered) {
5406 }, this._config.delay.hide);
5408 _setTimeout(handler, timeout) {
5409 clearTimeout(this._timeout);
5410 this._timeout = setTimeout(handler, timeout);
5412 _isWithActiveTrigger() {
5413 return Object.values(this._activeTrigger).includes(true);
5415 _getConfig(config) {
5416 const dataAttributes = Manipulator.getDataAttributes(this._element);
5417 for (const dataAttribute of Object.keys(dataAttributes)) {
5418 if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {
5419 delete dataAttributes[dataAttribute];
5424 ...(typeof config === 'object' && config ? config : {})
5426 config = this._mergeConfigObj(config);
5427 config = this._configAfterMerge(config);
5428 this._typeCheckConfig(config);
5431 _configAfterMerge(config) {
5432 config.container = config.container === false ? document.body : getElement(config.container);
5433 if (typeof config.delay === 'number') {
5439 if (typeof config.title === 'number') {
5440 config.title = config.title.toString();
5442 if (typeof config.content === 'number') {
5443 config.content = config.content.toString();
5447 _getDelegateConfig() {
5449 for (const [key, value] of Object.entries(this._config)) {
5450 if (this.constructor.Default[key] !== value) {
5451 config[key] = value;
5454 config.selector = false;
5455 config.trigger = 'manual';
5457 // In the future can be replaced with:
5458 // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
5459 // `Object.fromEntries(keysWithDifferentValues)`
5464 this._popper.destroy();
5465 this._popper = null;
5474 static jQueryInterface(config) {
5475 return this.each(function () {
5476 const data = Tooltip.getOrCreateInstance(this, config);
5477 if (typeof config !== 'string') {
5480 if (typeof data[config] === 'undefined') {
5481 throw new TypeError(`No method named "${config}"`);
5492 defineJQueryPlugin(Tooltip);
5495 * --------------------------------------------------------------------------
5496 * Bootstrap popover.js
5497 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5498 * --------------------------------------------------------------------------
5506 const NAME$3 = 'popover';
5507 const SELECTOR_TITLE = '.popover-header';
5508 const SELECTOR_CONTENT = '.popover-body';
5514 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>',
5517 const DefaultType$2 = {
5518 ...Tooltip.DefaultType,
5519 content: '(null|string|element|function)'
5526 class Popover extends Tooltip {
5528 static get Default() {
5531 static get DefaultType() {
5532 return DefaultType$2;
5540 return this._getTitle() || this._getContent();
5544 _getContentForTemplate() {
5546 [SELECTOR_TITLE]: this._getTitle(),
5547 [SELECTOR_CONTENT]: this._getContent()
5551 return this._resolvePossibleFunction(this._config.content);
5555 static jQueryInterface(config) {
5556 return this.each(function () {
5557 const data = Popover.getOrCreateInstance(this, config);
5558 if (typeof config !== 'string') {
5561 if (typeof data[config] === 'undefined') {
5562 throw new TypeError(`No method named "${config}"`);
5573 defineJQueryPlugin(Popover);
5576 * --------------------------------------------------------------------------
5577 * Bootstrap scrollspy.js
5578 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5579 * --------------------------------------------------------------------------
5587 const NAME$2 = 'scrollspy';
5588 const DATA_KEY$2 = 'bs.scrollspy';
5589 const EVENT_KEY$2 = `.${DATA_KEY$2}`;
5590 const DATA_API_KEY = '.data-api';
5591 const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;
5592 const EVENT_CLICK = `click${EVENT_KEY$2}`;
5593 const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;
5594 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
5595 const CLASS_NAME_ACTIVE$1 = 'active';
5596 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
5597 const SELECTOR_TARGET_LINKS = '[href]';
5598 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
5599 const SELECTOR_NAV_LINKS = '.nav-link';
5600 const SELECTOR_NAV_ITEMS = '.nav-item';
5601 const SELECTOR_LIST_ITEMS = '.list-group-item';
5602 const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
5603 const SELECTOR_DROPDOWN = '.dropdown';
5604 const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
5607 // TODO: v6 @deprecated, keep it for backwards compatibility reasons
5608 rootMargin: '0px 0px -25%',
5609 smoothScroll: false,
5611 threshold: [0.1, 0.5, 1]
5613 const DefaultType$1 = {
5614 offset: '(number|null)',
5615 // TODO v6 @deprecated, keep it for backwards compatibility reasons
5616 rootMargin: 'string',
5617 smoothScroll: 'boolean',
5626 class ScrollSpy extends BaseComponent {
5627 constructor(element, config) {
5628 super(element, config);
5630 // this._element is the observablesContainer and config.target the menu links wrapper
5631 this._targetLinks = new Map();
5632 this._observableSections = new Map();
5633 this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
5634 this._activeTarget = null;
5635 this._observer = null;
5636 this._previousScrollData = {
5640 this.refresh(); // initialize
5644 static get Default() {
5647 static get DefaultType() {
5648 return DefaultType$1;
5656 this._initializeTargetsAndObservables();
5657 this._maybeEnableSmoothScroll();
5658 if (this._observer) {
5659 this._observer.disconnect();
5661 this._observer = this._getNewObserver();
5663 for (const section of this._observableSections.values()) {
5664 this._observer.observe(section);
5668 this._observer.disconnect();
5673 _configAfterMerge(config) {
5674 // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
5675 config.target = getElement(config.target) || document.body;
5677 // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
5678 config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
5679 if (typeof config.threshold === 'string') {
5680 config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
5684 _maybeEnableSmoothScroll() {
5685 if (!this._config.smoothScroll) {
5689 // unregister any previous listeners
5690 EventHandler.off(this._config.target, EVENT_CLICK);
5691 EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
5692 const observableSection = this._observableSections.get(event.target.hash);
5693 if (observableSection) {
5694 event.preventDefault();
5695 const root = this._rootElement || window;
5696 const height = observableSection.offsetTop - this._element.offsetTop;
5697 if (root.scrollTo) {
5705 // Chrome 60 doesn't support `scrollTo`
5706 root.scrollTop = height;
5712 root: this._rootElement,
5713 threshold: this._config.threshold,
5714 rootMargin: this._config.rootMargin
5716 return new IntersectionObserver(entries => this._observerCallback(entries), options);
5719 // The logic of selection
5720 _observerCallback(entries) {
5721 const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
5722 const activate = entry => {
5723 this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
5724 this._process(targetElement(entry));
5726 const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
5727 const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
5728 this._previousScrollData.parentScrollTop = parentScrollTop;
5729 for (const entry of entries) {
5730 if (!entry.isIntersecting) {
5731 this._activeTarget = null;
5732 this._clearActiveClass(targetElement(entry));
5735 const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop;
5736 // if we are scrolling down, pick the bigger offsetTop
5737 if (userScrollsDown && entryIsLowerThanPrevious) {
5739 // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
5740 if (!parentScrollTop) {
5746 // if we are scrolling up, pick the smallest offsetTop
5747 if (!userScrollsDown && !entryIsLowerThanPrevious) {
5752 _initializeTargetsAndObservables() {
5753 this._targetLinks = new Map();
5754 this._observableSections = new Map();
5755 const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);
5756 for (const anchor of targetLinks) {
5757 // ensure that the anchor has an id and is not disabled
5758 if (!anchor.hash || isDisabled(anchor)) {
5761 const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element);
5763 // ensure that the observableSection exists & is visible
5764 if (isVisible(observableSection)) {
5765 this._targetLinks.set(decodeURI(anchor.hash), anchor);
5766 this._observableSections.set(anchor.hash, observableSection);
5771 if (this._activeTarget === target) {
5774 this._clearActiveClass(this._config.target);
5775 this._activeTarget = target;
5776 target.classList.add(CLASS_NAME_ACTIVE$1);
5777 this._activateParents(target);
5778 EventHandler.trigger(this._element, EVENT_ACTIVATE, {
5779 relatedTarget: target
5782 _activateParents(target) {
5783 // Activate dropdown parents
5784 if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
5785 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);
5788 for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {
5789 // Set triggered links parents as active
5790 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
5791 for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {
5792 item.classList.add(CLASS_NAME_ACTIVE$1);
5796 _clearActiveClass(parent) {
5797 parent.classList.remove(CLASS_NAME_ACTIVE$1);
5798 const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent);
5799 for (const node of activeNodes) {
5800 node.classList.remove(CLASS_NAME_ACTIVE$1);
5805 static jQueryInterface(config) {
5806 return this.each(function () {
5807 const data = ScrollSpy.getOrCreateInstance(this, config);
5808 if (typeof config !== 'string') {
5811 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
5812 throw new TypeError(`No method named "${config}"`);
5820 * Data API implementation
5823 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => {
5824 for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {
5825 ScrollSpy.getOrCreateInstance(spy);
5833 defineJQueryPlugin(ScrollSpy);
5836 * --------------------------------------------------------------------------
5838 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5839 * --------------------------------------------------------------------------
5847 const NAME$1 = 'tab';
5848 const DATA_KEY$1 = 'bs.tab';
5849 const EVENT_KEY$1 = `.${DATA_KEY$1}`;
5850 const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;
5851 const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;
5852 const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;
5853 const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;
5854 const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`;
5855 const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`;
5856 const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`;
5857 const ARROW_LEFT_KEY = 'ArrowLeft';
5858 const ARROW_RIGHT_KEY = 'ArrowRight';
5859 const ARROW_UP_KEY = 'ArrowUp';
5860 const ARROW_DOWN_KEY = 'ArrowDown';
5861 const HOME_KEY = 'Home';
5862 const END_KEY = 'End';
5863 const CLASS_NAME_ACTIVE = 'active';
5864 const CLASS_NAME_FADE$1 = 'fade';
5865 const CLASS_NAME_SHOW$1 = 'show';
5866 const CLASS_DROPDOWN = 'dropdown';
5867 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
5868 const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
5869 const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`;
5870 const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
5871 const SELECTOR_OUTER = '.nav-item, .list-group-item';
5872 const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
5873 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6
5874 const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
5875 const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`;
5881 class Tab extends BaseComponent {
5882 constructor(element) {
5884 this._parent = this._element.closest(SELECTOR_TAB_PANEL);
5885 if (!this._parent) {
5887 // TODO: should throw exception in v6
5888 // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
5891 // Set up initial aria attributes
5892 this._setInitialAttributes(this._parent, this._getChildren());
5893 EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
5903 // Shows this elem and deactivate the active sibling if exists
5904 const innerElem = this._element;
5905 if (this._elemIsActive(innerElem)) {
5909 // Search for active tab on same parent to deactivate it
5910 const active = this._getActiveElem();
5911 const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, {
5912 relatedTarget: innerElem
5914 const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, {
5915 relatedTarget: active
5917 if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
5920 this._deactivate(active, innerElem);
5921 this._activate(innerElem, active);
5925 _activate(element, relatedElem) {
5929 element.classList.add(CLASS_NAME_ACTIVE);
5930 this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section
5932 const complete = () => {
5933 if (element.getAttribute('role') !== 'tab') {
5934 element.classList.add(CLASS_NAME_SHOW$1);
5937 element.removeAttribute('tabindex');
5938 element.setAttribute('aria-selected', true);
5939 this._toggleDropDown(element, true);
5940 EventHandler.trigger(element, EVENT_SHOWN$1, {
5941 relatedTarget: relatedElem
5944 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));
5946 _deactivate(element, relatedElem) {
5950 element.classList.remove(CLASS_NAME_ACTIVE);
5952 this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too
5954 const complete = () => {
5955 if (element.getAttribute('role') !== 'tab') {
5956 element.classList.remove(CLASS_NAME_SHOW$1);
5959 element.setAttribute('aria-selected', false);
5960 element.setAttribute('tabindex', '-1');
5961 this._toggleDropDown(element, false);
5962 EventHandler.trigger(element, EVENT_HIDDEN$1, {
5963 relatedTarget: relatedElem
5966 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));
5969 if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) {
5972 event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
5973 event.preventDefault();
5974 const children = this._getChildren().filter(element => !isDisabled(element));
5975 let nextActiveElement;
5976 if ([HOME_KEY, END_KEY].includes(event.key)) {
5977 nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1];
5979 const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
5980 nextActiveElement = getNextActiveElement(children, event.target, isNext, true);
5982 if (nextActiveElement) {
5983 nextActiveElement.focus({
5986 Tab.getOrCreateInstance(nextActiveElement).show();
5990 // collection of inner elements
5991 return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
5994 return this._getChildren().find(child => this._elemIsActive(child)) || null;
5996 _setInitialAttributes(parent, children) {
5997 this._setAttributeIfNotExists(parent, 'role', 'tablist');
5998 for (const child of children) {
5999 this._setInitialAttributesOnChild(child);
6002 _setInitialAttributesOnChild(child) {
6003 child = this._getInnerElement(child);
6004 const isActive = this._elemIsActive(child);
6005 const outerElem = this._getOuterElement(child);
6006 child.setAttribute('aria-selected', isActive);
6007 if (outerElem !== child) {
6008 this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
6011 child.setAttribute('tabindex', '-1');
6013 this._setAttributeIfNotExists(child, 'role', 'tab');
6015 // set attributes to the related panel too
6016 this._setInitialAttributesOnTargetPanel(child);
6018 _setInitialAttributesOnTargetPanel(child) {
6019 const target = SelectorEngine.getElementFromSelector(child);
6023 this._setAttributeIfNotExists(target, 'role', 'tabpanel');
6025 this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`);
6028 _toggleDropDown(element, open) {
6029 const outerElem = this._getOuterElement(element);
6030 if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
6033 const toggle = (selector, className) => {
6034 const element = SelectorEngine.findOne(selector, outerElem);
6036 element.classList.toggle(className, open);
6039 toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
6040 toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1);
6041 outerElem.setAttribute('aria-expanded', open);
6043 _setAttributeIfNotExists(element, attribute, value) {
6044 if (!element.hasAttribute(attribute)) {
6045 element.setAttribute(attribute, value);
6048 _elemIsActive(elem) {
6049 return elem.classList.contains(CLASS_NAME_ACTIVE);
6052 // Try to get the inner element (usually the .nav-link)
6053 _getInnerElement(elem) {
6054 return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
6057 // Try to get the outer element (usually the .nav-item)
6058 _getOuterElement(elem) {
6059 return elem.closest(SELECTOR_OUTER) || elem;
6063 static jQueryInterface(config) {
6064 return this.each(function () {
6065 const data = Tab.getOrCreateInstance(this);
6066 if (typeof config !== 'string') {
6069 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
6070 throw new TypeError(`No method named "${config}"`);
6078 * Data API implementation
6081 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
6082 if (['A', 'AREA'].includes(this.tagName)) {
6083 event.preventDefault();
6085 if (isDisabled(this)) {
6088 Tab.getOrCreateInstance(this).show();
6092 * Initialize on focus
6094 EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
6095 for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
6096 Tab.getOrCreateInstance(element);
6103 defineJQueryPlugin(Tab);
6106 * --------------------------------------------------------------------------
6107 * Bootstrap toast.js
6108 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6109 * --------------------------------------------------------------------------
6117 const NAME = 'toast';
6118 const DATA_KEY = 'bs.toast';
6119 const EVENT_KEY = `.${DATA_KEY}`;
6120 const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;
6121 const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;
6122 const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
6123 const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;
6124 const EVENT_HIDE = `hide${EVENT_KEY}`;
6125 const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
6126 const EVENT_SHOW = `show${EVENT_KEY}`;
6127 const EVENT_SHOWN = `shown${EVENT_KEY}`;
6128 const CLASS_NAME_FADE = 'fade';
6129 const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
6130 const CLASS_NAME_SHOW = 'show';
6131 const CLASS_NAME_SHOWING = 'showing';
6132 const DefaultType = {
6133 animation: 'boolean',
6134 autohide: 'boolean',
6147 class Toast extends BaseComponent {
6148 constructor(element, config) {
6149 super(element, config);
6150 this._timeout = null;
6151 this._hasMouseInteraction = false;
6152 this._hasKeyboardInteraction = false;
6153 this._setListeners();
6157 static get Default() {
6160 static get DefaultType() {
6169 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);
6170 if (showEvent.defaultPrevented) {
6173 this._clearTimeout();
6174 if (this._config.animation) {
6175 this._element.classList.add(CLASS_NAME_FADE);
6177 const complete = () => {
6178 this._element.classList.remove(CLASS_NAME_SHOWING);
6179 EventHandler.trigger(this._element, EVENT_SHOWN);
6180 this._maybeScheduleHide();
6182 this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
6183 reflow(this._element);
6184 this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING);
6185 this._queueCallback(complete, this._element, this._config.animation);
6188 if (!this.isShown()) {
6191 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
6192 if (hideEvent.defaultPrevented) {
6195 const complete = () => {
6196 this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
6197 this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW);
6198 EventHandler.trigger(this._element, EVENT_HIDDEN);
6200 this._element.classList.add(CLASS_NAME_SHOWING);
6201 this._queueCallback(complete, this._element, this._config.animation);
6204 this._clearTimeout();
6205 if (this.isShown()) {
6206 this._element.classList.remove(CLASS_NAME_SHOW);
6211 return this._element.classList.contains(CLASS_NAME_SHOW);
6216 _maybeScheduleHide() {
6217 if (!this._config.autohide) {
6220 if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
6223 this._timeout = setTimeout(() => {
6225 }, this._config.delay);
6227 _onInteraction(event, isInteracting) {
6228 switch (event.type) {
6232 this._hasMouseInteraction = isInteracting;
6238 this._hasKeyboardInteraction = isInteracting;
6242 if (isInteracting) {
6243 this._clearTimeout();
6246 const nextElement = event.relatedTarget;
6247 if (this._element === nextElement || this._element.contains(nextElement)) {
6250 this._maybeScheduleHide();
6253 EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));
6254 EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));
6255 EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));
6256 EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));
6259 clearTimeout(this._timeout);
6260 this._timeout = null;
6264 static jQueryInterface(config) {
6265 return this.each(function () {
6266 const data = Toast.getOrCreateInstance(this, config);
6267 if (typeof config === 'string') {
6268 if (typeof data[config] === 'undefined') {
6269 throw new TypeError(`No method named "${config}"`);
6278 * Data API implementation
6281 enableDismissTrigger(Toast);
6287 defineJQueryPlugin(Toast);
6290 * --------------------------------------------------------------------------
6291 * Bootstrap index.umd.js
6292 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
6293 * --------------------------------------------------------------------------
6314//# sourceMappingURL=bootstrap.js.map