PluginProbe
UpdraftCentral Dashboard / trunk
UpdraftCentral Dashboard vtrunk
0.8.33 0.7.2 0.7.3 0.7.4 0.8.0 0.8.1 0.8.10 0.8.11 0.8.12 0.8.13 0.8.14 0.8.15 0.8.16 0.8.17 0.8.18 0.8.19 0.8.2 0.8.20 0.8.21 0.8.22 0.8.23 0.8.24 0.8.25 0.8.26 0.8.27 All 51 releases
updraftcentral / js / bootstrap / bootstrap.js

bootstrap.js in UpdraftCentral Dashboard trunk, at js/bootstrap/bootstrap.js

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