프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / ConvertService / ServiceBase / UploadFonts / Scripts / bootstrap.js @ 8acc4862

이력 | 보기 | 이력해설 | 다운로드 (142 KB)

1
/*!
2
  * Bootstrap v5.2.3 (https://getbootstrap.com/)
3
  * Copyright 2011-2022 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
4
  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
  */
6
(function (global, factory) {
7
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('@popperjs/core')) :
8
  typeof define === 'function' && define.amd ? define(['@popperjs/core'], factory) :
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory(global.Popper));
10
})(this, (function (Popper) { 'use strict';
11

    
12
  function _interopNamespace(e) {
13
    if (e && e.__esModule) return e;
14
    const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } });
15
    if (e) {
16
      for (const k in e) {
17
        if (k !== 'default') {
18
          const d = Object.getOwnPropertyDescriptor(e, k);
19
          Object.defineProperty(n, k, d.get ? d : {
20
            enumerable: true,
21
            get: () => e[k]
22
          });
23
        }
24
      }
25
    }
26
    n.default = e;
27
    return Object.freeze(n);
28
  }
29

    
30
  const Popper__namespace = /*#__PURE__*/_interopNamespace(Popper);
31

    
32
  /**
33
   * --------------------------------------------------------------------------
34
   * Bootstrap (v5.2.3): util/index.js
35
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
36
   * --------------------------------------------------------------------------
37
   */
38
  const MAX_UID = 1000000;
39
  const MILLISECONDS_MULTIPLIER = 1000;
40
  const TRANSITION_END = 'transitionend'; // Shout-out Angus Croll (https://goo.gl/pxwQGp)
41

    
42
  const toType = object => {
43
    if (object === null || object === undefined) {
44
      return `${object}`;
45
    }
46

    
47
    return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase();
48
  };
49
  /**
50
   * Public Util API
51
   */
52

    
53

    
54
  const getUID = prefix => {
55
    do {
56
      prefix += Math.floor(Math.random() * MAX_UID);
57
    } while (document.getElementById(prefix));
58

    
59
    return prefix;
60
  };
61

    
62
  const getSelector = element => {
63
    let selector = element.getAttribute('data-bs-target');
64

    
65
    if (!selector || selector === '#') {
66
      let hrefAttribute = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
67
      // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
68
      // `document.querySelector` will rightfully complain it is invalid.
69
      // See https://github.com/twbs/bootstrap/issues/32273
70

    
71
      if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) {
72
        return null;
73
      } // Just in case some CMS puts out a full URL with the anchor appended
74

    
75

    
76
      if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) {
77
        hrefAttribute = `#${hrefAttribute.split('#')[1]}`;
78
      }
79

    
80
      selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null;
81
    }
82

    
83
    return selector;
84
  };
85

    
86
  const getSelectorFromElement = element => {
87
    const selector = getSelector(element);
88

    
89
    if (selector) {
90
      return document.querySelector(selector) ? selector : null;
91
    }
92

    
93
    return null;
94
  };
95

    
96
  const getElementFromSelector = element => {
97
    const selector = getSelector(element);
98
    return selector ? document.querySelector(selector) : null;
99
  };
100

    
101
  const getTransitionDurationFromElement = element => {
102
    if (!element) {
103
      return 0;
104
    } // Get transition-duration of the element
105

    
106

    
107
    let {
108
      transitionDuration,
109
      transitionDelay
110
    } = window.getComputedStyle(element);
111
    const floatTransitionDuration = Number.parseFloat(transitionDuration);
112
    const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
113

    
114
    if (!floatTransitionDuration && !floatTransitionDelay) {
115
      return 0;
116
    } // If multiple durations are defined, take the first
117

    
118

    
119
    transitionDuration = transitionDuration.split(',')[0];
120
    transitionDelay = transitionDelay.split(',')[0];
121
    return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
122
  };
123

    
124
  const triggerTransitionEnd = element => {
125
    element.dispatchEvent(new Event(TRANSITION_END));
126
  };
127

    
128
  const isElement = object => {
129
    if (!object || typeof object !== 'object') {
130
      return false;
131
    }
132

    
133
    if (typeof object.jquery !== 'undefined') {
134
      object = object[0];
135
    }
136

    
137
    return typeof object.nodeType !== 'undefined';
138
  };
139

    
140
  const getElement = object => {
141
    // it's a jQuery object or a node element
142
    if (isElement(object)) {
143
      return object.jquery ? object[0] : object;
144
    }
145

    
146
    if (typeof object === 'string' && object.length > 0) {
147
      return document.querySelector(object);
148
    }
149

    
150
    return null;
151
  };
152

    
153
  const isVisible = element => {
154
    if (!isElement(element) || element.getClientRects().length === 0) {
155
      return false;
156
    }
157

    
158
    const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; // Handle `details` element as its content may falsie appear visible when it is closed
159

    
160
    const closedDetails = element.closest('details:not([open])');
161

    
162
    if (!closedDetails) {
163
      return elementIsVisible;
164
    }
165

    
166
    if (closedDetails !== element) {
167
      const summary = element.closest('summary');
168

    
169
      if (summary && summary.parentNode !== closedDetails) {
170
        return false;
171
      }
172

    
173
      if (summary === null) {
174
        return false;
175
      }
176
    }
177

    
178
    return elementIsVisible;
179
  };
180

    
181
  const isDisabled = element => {
182
    if (!element || element.nodeType !== Node.ELEMENT_NODE) {
183
      return true;
184
    }
185

    
186
    if (element.classList.contains('disabled')) {
187
      return true;
188
    }
189

    
190
    if (typeof element.disabled !== 'undefined') {
191
      return element.disabled;
192
    }
193

    
194
    return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
195
  };
196

    
197
  const findShadowRoot = element => {
198
    if (!document.documentElement.attachShadow) {
199
      return null;
200
    } // Can find the shadow root otherwise it'll return the document
201

    
202

    
203
    if (typeof element.getRootNode === 'function') {
204
      const root = element.getRootNode();
205
      return root instanceof ShadowRoot ? root : null;
206
    }
207

    
208
    if (element instanceof ShadowRoot) {
209
      return element;
210
    } // when we don't find a shadow root
211

    
212

    
213
    if (!element.parentNode) {
214
      return null;
215
    }
216

    
217
    return findShadowRoot(element.parentNode);
218
  };
219

    
220
  const noop = () => {};
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

    
230

    
231
  const reflow = element => {
232
    element.offsetHeight; // eslint-disable-line no-unused-expressions
233
  };
234

    
235
  const getjQuery = () => {
236
    if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
237
      return window.jQuery;
238
    }
239

    
240
    return null;
241
  };
242

    
243
  const DOMContentLoadedCallbacks = [];
244

    
245
  const onDOMContentLoaded = callback => {
246
    if (document.readyState === 'loading') {
247
      // add listener on the first call when the document is in loading state
248
      if (!DOMContentLoadedCallbacks.length) {
249
        document.addEventListener('DOMContentLoaded', () => {
250
          for (const callback of DOMContentLoadedCallbacks) {
251
            callback();
252
          }
253
        });
254
      }
255

    
256
      DOMContentLoadedCallbacks.push(callback);
257
    } else {
258
      callback();
259
    }
260
  };
261

    
262
  const isRTL = () => document.documentElement.dir === 'rtl';
263

    
264
  const defineJQueryPlugin = plugin => {
265
    onDOMContentLoaded(() => {
266
      const $ = getjQuery();
267
      /* istanbul ignore if */
268

    
269
      if ($) {
270
        const name = plugin.NAME;
271
        const JQUERY_NO_CONFLICT = $.fn[name];
272
        $.fn[name] = plugin.jQueryInterface;
273
        $.fn[name].Constructor = plugin;
274

    
275
        $.fn[name].noConflict = () => {
276
          $.fn[name] = JQUERY_NO_CONFLICT;
277
          return plugin.jQueryInterface;
278
        };
279
      }
280
    });
281
  };
282

    
283
  const execute = callback => {
284
    if (typeof callback === 'function') {
285
      callback();
286
    }
287
  };
288

    
289
  const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
290
    if (!waitForTransition) {
291
      execute(callback);
292
      return;
293
    }
294

    
295
    const durationPadding = 5;
296
    const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
297
    let called = false;
298

    
299
    const handler = ({
300
      target
301
    }) => {
302
      if (target !== transitionElement) {
303
        return;
304
      }
305

    
306
      called = true;
307
      transitionElement.removeEventListener(TRANSITION_END, handler);
308
      execute(callback);
309
    };
310

    
311
    transitionElement.addEventListener(TRANSITION_END, handler);
312
    setTimeout(() => {
313
      if (!called) {
314
        triggerTransitionEnd(transitionElement);
315
      }
316
    }, emulatedDuration);
317
  };
318
  /**
319
   * Return the previous/next element of a list.
320
   *
321
   * @param {array} list    The list of elements
322
   * @param activeElement   The active element
323
   * @param shouldGetNext   Choose to get next or previous element
324
   * @param isCycleAllowed
325
   * @return {Element|elem} The proper element
326
   */
327

    
328

    
329
  const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => {
330
    const listLength = list.length;
331
    let index = list.indexOf(activeElement); // if the element does not exist in the list return an element
332
    // depending on the direction and if cycle is allowed
333

    
334
    if (index === -1) {
335
      return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0];
336
    }
337

    
338
    index += shouldGetNext ? 1 : -1;
339

    
340
    if (isCycleAllowed) {
341
      index = (index + listLength) % listLength;
342
    }
343

    
344
    return list[Math.max(0, Math.min(index, listLength - 1))];
345
  };
346

    
347
  /**
348
   * --------------------------------------------------------------------------
349
   * Bootstrap (v5.2.3): dom/event-handler.js
350
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
351
   * --------------------------------------------------------------------------
352
   */
353
  /**
354
   * Constants
355
   */
356

    
357
  const namespaceRegex = /[^.]*(?=\..*)\.|.*/;
358
  const stripNameRegex = /\..*/;
359
  const stripUidRegex = /::\d+$/;
360
  const eventRegistry = {}; // Events storage
361

    
362
  let uidEvent = 1;
363
  const customEvents = {
364
    mouseenter: 'mouseover',
365
    mouseleave: 'mouseout'
366
  };
367
  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']);
368
  /**
369
   * Private methods
370
   */
371

    
372
  function makeEventUid(element, uid) {
373
    return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++;
374
  }
375

    
376
  function getElementEvents(element) {
377
    const uid = makeEventUid(element);
378
    element.uidEvent = uid;
379
    eventRegistry[uid] = eventRegistry[uid] || {};
380
    return eventRegistry[uid];
381
  }
382

    
383
  function bootstrapHandler(element, fn) {
384
    return function handler(event) {
385
      hydrateObj(event, {
386
        delegateTarget: element
387
      });
388

    
389
      if (handler.oneOff) {
390
        EventHandler.off(element, event.type, fn);
391
      }
392

    
393
      return fn.apply(element, [event]);
394
    };
395
  }
396

    
397
  function bootstrapDelegationHandler(element, selector, fn) {
398
    return function handler(event) {
399
      const domElements = element.querySelectorAll(selector);
400

    
401
      for (let {
402
        target
403
      } = event; target && target !== this; target = target.parentNode) {
404
        for (const domElement of domElements) {
405
          if (domElement !== target) {
406
            continue;
407
          }
408

    
409
          hydrateObj(event, {
410
            delegateTarget: target
411
          });
412

    
413
          if (handler.oneOff) {
414
            EventHandler.off(element, event.type, selector, fn);
415
          }
416

    
417
          return fn.apply(target, [event]);
418
        }
419
      }
420
    };
421
  }
422

    
423
  function findHandler(events, callable, delegationSelector = null) {
424
    return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector);
425
  }
426

    
427
  function normalizeParameters(originalTypeEvent, handler, delegationFunction) {
428
    const isDelegated = typeof handler === 'string'; // todo: tooltip passes `false` instead of selector, so we need to check
429

    
430
    const callable = isDelegated ? delegationFunction : handler || delegationFunction;
431
    let typeEvent = getTypeEvent(originalTypeEvent);
432

    
433
    if (!nativeEvents.has(typeEvent)) {
434
      typeEvent = originalTypeEvent;
435
    }
436

    
437
    return [isDelegated, callable, typeEvent];
438
  }
439

    
440
  function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) {
441
    if (typeof originalTypeEvent !== 'string' || !element) {
442
      return;
443
    }
444

    
445
    let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position
446
    // this prevents the handler from being dispatched the same way as mouseover or mouseout does
447

    
448
    if (originalTypeEvent in customEvents) {
449
      const wrapFunction = fn => {
450
        return function (event) {
451
          if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) {
452
            return fn.call(this, event);
453
          }
454
        };
455
      };
456

    
457
      callable = wrapFunction(callable);
458
    }
459

    
460
    const events = getElementEvents(element);
461
    const handlers = events[typeEvent] || (events[typeEvent] = {});
462
    const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null);
463

    
464
    if (previousFunction) {
465
      previousFunction.oneOff = previousFunction.oneOff && oneOff;
466
      return;
467
    }
468

    
469
    const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, ''));
470
    const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable);
471
    fn.delegationSelector = isDelegated ? handler : null;
472
    fn.callable = callable;
473
    fn.oneOff = oneOff;
474
    fn.uidEvent = uid;
475
    handlers[uid] = fn;
476
    element.addEventListener(typeEvent, fn, isDelegated);
477
  }
478

    
479
  function removeHandler(element, events, typeEvent, handler, delegationSelector) {
480
    const fn = findHandler(events[typeEvent], handler, delegationSelector);
481

    
482
    if (!fn) {
483
      return;
484
    }
485

    
486
    element.removeEventListener(typeEvent, fn, Boolean(delegationSelector));
487
    delete events[typeEvent][fn.uidEvent];
488
  }
489

    
490
  function removeNamespacedHandlers(element, events, typeEvent, namespace) {
491
    const storeElementEvent = events[typeEvent] || {};
492

    
493
    for (const handlerKey of Object.keys(storeElementEvent)) {
494
      if (handlerKey.includes(namespace)) {
495
        const event = storeElementEvent[handlerKey];
496
        removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
497
      }
498
    }
499
  }
500

    
501
  function getTypeEvent(event) {
502
    // allow to get the native events from namespaced events ('click.bs.button' --> 'click')
503
    event = event.replace(stripNameRegex, '');
504
    return customEvents[event] || event;
505
  }
506

    
507
  const EventHandler = {
508
    on(element, event, handler, delegationFunction) {
509
      addHandler(element, event, handler, delegationFunction, false);
510
    },
511

    
512
    one(element, event, handler, delegationFunction) {
513
      addHandler(element, event, handler, delegationFunction, true);
514
    },
515

    
516
    off(element, originalTypeEvent, handler, delegationFunction) {
517
      if (typeof originalTypeEvent !== 'string' || !element) {
518
        return;
519
      }
520

    
521
      const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction);
522
      const inNamespace = typeEvent !== originalTypeEvent;
523
      const events = getElementEvents(element);
524
      const storeElementEvent = events[typeEvent] || {};
525
      const isNamespace = originalTypeEvent.startsWith('.');
526

    
527
      if (typeof callable !== 'undefined') {
528
        // Simplest case: handler is passed, remove that listener ONLY.
529
        if (!Object.keys(storeElementEvent).length) {
530
          return;
531
        }
532

    
533
        removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null);
534
        return;
535
      }
536

    
537
      if (isNamespace) {
538
        for (const elementEvent of Object.keys(events)) {
539
          removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1));
540
        }
541
      }
542

    
543
      for (const keyHandlers of Object.keys(storeElementEvent)) {
544
        const handlerKey = keyHandlers.replace(stripUidRegex, '');
545

    
546
        if (!inNamespace || originalTypeEvent.includes(handlerKey)) {
547
          const event = storeElementEvent[keyHandlers];
548
          removeHandler(element, events, typeEvent, event.callable, event.delegationSelector);
549
        }
550
      }
551
    },
552

    
553
    trigger(element, event, args) {
554
      if (typeof event !== 'string' || !element) {
555
        return null;
556
      }
557

    
558
      const $ = getjQuery();
559
      const typeEvent = getTypeEvent(event);
560
      const inNamespace = event !== typeEvent;
561
      let jQueryEvent = null;
562
      let bubbles = true;
563
      let nativeDispatch = true;
564
      let defaultPrevented = false;
565

    
566
      if (inNamespace && $) {
567
        jQueryEvent = $.Event(event, args);
568
        $(element).trigger(jQueryEvent);
569
        bubbles = !jQueryEvent.isPropagationStopped();
570
        nativeDispatch = !jQueryEvent.isImmediatePropagationStopped();
571
        defaultPrevented = jQueryEvent.isDefaultPrevented();
572
      }
573

    
574
      let evt = new Event(event, {
575
        bubbles,
576
        cancelable: true
577
      });
578
      evt = hydrateObj(evt, args);
579

    
580
      if (defaultPrevented) {
581
        evt.preventDefault();
582
      }
583

    
584
      if (nativeDispatch) {
585
        element.dispatchEvent(evt);
586
      }
587

    
588
      if (evt.defaultPrevented && jQueryEvent) {
589
        jQueryEvent.preventDefault();
590
      }
591

    
592
      return evt;
593
    }
594

    
595
  };
596

    
597
  function hydrateObj(obj, meta) {
598
    for (const [key, value] of Object.entries(meta || {})) {
599
      try {
600
        obj[key] = value;
601
      } catch (_unused) {
602
        Object.defineProperty(obj, key, {
603
          configurable: true,
604

    
605
          get() {
606
            return value;
607
          }
608

    
609
        });
610
      }
611
    }
612

    
613
    return obj;
614
  }
615

    
616
  /**
617
   * --------------------------------------------------------------------------
618
   * Bootstrap (v5.2.3): dom/data.js
619
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
620
   * --------------------------------------------------------------------------
621
   */
622

    
623
  /**
624
   * Constants
625
   */
626
  const elementMap = new Map();
627
  const Data = {
628
    set(element, key, instance) {
629
      if (!elementMap.has(element)) {
630
        elementMap.set(element, new Map());
631
      }
632

    
633
      const instanceMap = elementMap.get(element); // make it clear we only want one instance per element
634
      // can be removed later when multiple key/instances are fine to be used
635

    
636
      if (!instanceMap.has(key) && instanceMap.size !== 0) {
637
        // eslint-disable-next-line no-console
638
        console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`);
639
        return;
640
      }
641

642
      instanceMap.set(key, instance);
643
    },
644

645
    get(element, key) {
646
      if (elementMap.has(element)) {
647
        return elementMap.get(element).get(key) || null;
648
      }
649

650
      return null;
651
    },
652

653
    remove(element, key) {
654
      if (!elementMap.has(element)) {
655
        return;
656
      }
657

658
      const instanceMap = elementMap.get(element);
659
      instanceMap.delete(key); // free up element references if there are no instances left for an element
660

661
      if (instanceMap.size === 0) {
662
        elementMap.delete(element);
663
      }
664
    }
665

666
  };
667

668
  /**
669
   * --------------------------------------------------------------------------
670
   * Bootstrap (v5.2.3): dom/manipulator.js
671
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
672
   * --------------------------------------------------------------------------
673
   */
674
  function normalizeData(value) {
675
    if (value === 'true') {
676
      return true;
677
    }
678

679
    if (value === 'false') {
680
      return false;
681
    }
682

683
    if (value === Number(value).toString()) {
684
      return Number(value);
685
    }
686

687
    if (value === '' || value === 'null') {
688
      return null;
689
    }
690

691
    if (typeof value !== 'string') {
692
      return value;
693
    }
694

695
    try {
696
      return JSON.parse(decodeURIComponent(value));
697
    } catch (_unused) {
698
      return value;
699
    }
700
  }
701

702
  function normalizeDataKey(key) {
703
    return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`);
704
  }
705

706
  const Manipulator = {
707
    setDataAttribute(element, key, value) {
708
      element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value);
709
    },
710

711
    removeDataAttribute(element, key) {
712
      element.removeAttribute(`data-bs-${normalizeDataKey(key)}`);
713
    },
714

715
    getDataAttributes(element) {
716
      if (!element) {
717
        return {};
718
      }
719

720
      const attributes = {};
721
      const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig'));
722

723
      for (const key of bsKeys) {
724
        let pureKey = key.replace(/^bs/, '');
725
        pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length);
726
        attributes[pureKey] = normalizeData(element.dataset[key]);
727
      }
728

729
      return attributes;
730
    },
731

732
    getDataAttribute(element, key) {
733
      return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`));
734
    }
735

736
  };
737

738
  /**
739
   * --------------------------------------------------------------------------
740
   * Bootstrap (v5.2.3): util/config.js
741
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
742
   * --------------------------------------------------------------------------
743
   */
744
  /**
745
   * Class definition
746
   */
747

748
  class Config {
749
    // Getters
750
    static get Default() {
751
      return {};
752
    }
753

754
    static get DefaultType() {
755
      return {};
756
    }
757

758
    static get NAME() {
759
      throw new Error('You have to implement the static method "NAME", for each component!');
760
    }
761

762
    _getConfig(config) {
763
      config = this._mergeConfigObj(config);
764
      config = this._configAfterMerge(config);
765

766
      this._typeCheckConfig(config);
767

768
      return config;
769
    }
770

771
    _configAfterMerge(config) {
772
      return config;
773
    }
774

775
    _mergeConfigObj(config, element) {
776
      const jsonConfig = isElement(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse
777

778
      return { ...this.constructor.Default,
779
        ...(typeof jsonConfig === 'object' ? jsonConfig : {}),
780
        ...(isElement(element) ? Manipulator.getDataAttributes(element) : {}),
781
        ...(typeof config === 'object' ? config : {})
782
      };
783
    }
784

785
    _typeCheckConfig(config, configTypes = this.constructor.DefaultType) {
786
      for (const property of Object.keys(configTypes)) {
787
        const expectedTypes = configTypes[property];
788
        const value = config[property];
789
        const valueType = isElement(value) ? 'element' : toType(value);
790

791
        if (!new RegExp(expectedTypes).test(valueType)) {
792
          throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
793
        }
794
      }
795
    }
796

797
  }
798

799
  /**
800
   * --------------------------------------------------------------------------
801
   * Bootstrap (v5.2.3): base-component.js
802
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
803
   * --------------------------------------------------------------------------
804
   */
805
  /**
806
   * Constants
807
   */
808

809
  const VERSION = '5.2.3';
810
  /**
811
   * Class definition
812
   */
813

814
  class BaseComponent extends Config {
815
    constructor(element, config) {
816
      super();
817
      element = getElement(element);
818

819
      if (!element) {
820
        return;
821
      }
822

823
      this._element = element;
824
      this._config = this._getConfig(config);
825
      Data.set(this._element, this.constructor.DATA_KEY, this);
826
    } // Public
827

828

829
    dispose() {
830
      Data.remove(this._element, this.constructor.DATA_KEY);
831
      EventHandler.off(this._element, this.constructor.EVENT_KEY);
832

833
      for (const propertyName of Object.getOwnPropertyNames(this)) {
834
        this[propertyName] = null;
835
      }
836
    }
837

838
    _queueCallback(callback, element, isAnimated = true) {
839
      executeAfterTransition(callback, element, isAnimated);
840
    }
841

842
    _getConfig(config) {
843
      config = this._mergeConfigObj(config, this._element);
844
      config = this._configAfterMerge(config);
845

846
      this._typeCheckConfig(config);
847

848
      return config;
849
    } // Static
850

851

852
    static getInstance(element) {
853
      return Data.get(getElement(element), this.DATA_KEY);
854
    }
855

856
    static getOrCreateInstance(element, config = {}) {
857
      return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null);
858
    }
859

860
    static get VERSION() {
861
      return VERSION;
862
    }
863

864
    static get DATA_KEY() {
865
      return `bs.${this.NAME}`;
866
    }
867

868
    static get EVENT_KEY() {
869
      return `.${this.DATA_KEY}`;
870
    }
871

872
    static eventName(name) {
873
      return `${name}${this.EVENT_KEY}`;
874
    }
875

876
  }
877

878
  /**
879
   * --------------------------------------------------------------------------
880
   * Bootstrap (v5.2.3): util/component-functions.js
881
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
882
   * --------------------------------------------------------------------------
883
   */
884

885
  const enableDismissTrigger = (component, method = 'hide') => {
886
    const clickEvent = `click.dismiss${component.EVENT_KEY}`;
887
    const name = component.NAME;
888
    EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) {
889
      if (['A', 'AREA'].includes(this.tagName)) {
890
        event.preventDefault();
891
      }
892

893
      if (isDisabled(this)) {
894
        return;
895
      }
896

897
      const target = getElementFromSelector(this) || this.closest(`.${name}`);
898
      const instance = component.getOrCreateInstance(target); // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method
899

    
900
      instance[method]();
901
    });
902
  };
903

    
904
  /**
905
   * --------------------------------------------------------------------------
906
   * Bootstrap (v5.2.3): alert.js
907
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
908
   * --------------------------------------------------------------------------
909
   */
910
  /**
911
   * Constants
912
   */
913

    
914
  const NAME$f = 'alert';
915
  const DATA_KEY$a = 'bs.alert';
916
  const EVENT_KEY$b = `.${DATA_KEY$a}`;
917
  const EVENT_CLOSE = `close${EVENT_KEY$b}`;
918
  const EVENT_CLOSED = `closed${EVENT_KEY$b}`;
919
  const CLASS_NAME_FADE$5 = 'fade';
920
  const CLASS_NAME_SHOW$8 = 'show';
921
  /**
922
   * Class definition
923
   */
924

    
925
  class Alert extends BaseComponent {
926
    // Getters
927
    static get NAME() {
928
      return NAME$f;
929
    } // Public
930

    
931

    
932
    close() {
933
      const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE);
934

    
935
      if (closeEvent.defaultPrevented) {
936
        return;
937
      }
938

    
939
      this._element.classList.remove(CLASS_NAME_SHOW$8);
940

    
941
      const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5);
942

    
943
      this._queueCallback(() => this._destroyElement(), this._element, isAnimated);
944
    } // Private
945

    
946

    
947
    _destroyElement() {
948
      this._element.remove();
949

    
950
      EventHandler.trigger(this._element, EVENT_CLOSED);
951
      this.dispose();
952
    } // Static
953

    
954

    
955
    static jQueryInterface(config) {
956
      return this.each(function () {
957
        const data = Alert.getOrCreateInstance(this);
958

    
959
        if (typeof config !== 'string') {
960
          return;
961
        }
962

    
963
        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
964
          throw new TypeError(`No method named "${config}"`);
965
        }
966

    
967
        data[config](this);
968
      });
969
    }
970

    
971
  }
972
  /**
973
   * Data API implementation
974
   */
975

    
976

    
977
  enableDismissTrigger(Alert, 'close');
978
  /**
979
   * jQuery
980
   */
981

    
982
  defineJQueryPlugin(Alert);
983

    
984
  /**
985
   * --------------------------------------------------------------------------
986
   * Bootstrap (v5.2.3): button.js
987
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
988
   * --------------------------------------------------------------------------
989
   */
990
  /**
991
   * Constants
992
   */
993

    
994
  const NAME$e = 'button';
995
  const DATA_KEY$9 = 'bs.button';
996
  const EVENT_KEY$a = `.${DATA_KEY$9}`;
997
  const DATA_API_KEY$6 = '.data-api';
998
  const CLASS_NAME_ACTIVE$3 = 'active';
999
  const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]';
1000
  const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`;
1001
  /**
1002
   * Class definition
1003
   */
1004

    
1005
  class Button extends BaseComponent {
1006
    // Getters
1007
    static get NAME() {
1008
      return NAME$e;
1009
    } // Public
1010

    
1011

    
1012
    toggle() {
1013
      // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method
1014
      this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3));
1015
    } // Static
1016

    
1017

    
1018
    static jQueryInterface(config) {
1019
      return this.each(function () {
1020
        const data = Button.getOrCreateInstance(this);
1021

    
1022
        if (config === 'toggle') {
1023
          data[config]();
1024
        }
1025
      });
1026
    }
1027

    
1028
  }
1029
  /**
1030
   * Data API implementation
1031
   */
1032

    
1033

    
1034
  EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => {
1035
    event.preventDefault();
1036
    const button = event.target.closest(SELECTOR_DATA_TOGGLE$5);
1037
    const data = Button.getOrCreateInstance(button);
1038
    data.toggle();
1039
  });
1040
  /**
1041
   * jQuery
1042
   */
1043

    
1044
  defineJQueryPlugin(Button);
1045

    
1046
  /**
1047
   * --------------------------------------------------------------------------
1048
   * Bootstrap (v5.2.3): dom/selector-engine.js
1049
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1050
   * --------------------------------------------------------------------------
1051
   */
1052
  /**
1053
   * Constants
1054
   */
1055

    
1056
  const SelectorEngine = {
1057
    find(selector, element = document.documentElement) {
1058
      return [].concat(...Element.prototype.querySelectorAll.call(element, selector));
1059
    },
1060

    
1061
    findOne(selector, element = document.documentElement) {
1062
      return Element.prototype.querySelector.call(element, selector);
1063
    },
1064

    
1065
    children(element, selector) {
1066
      return [].concat(...element.children).filter(child => child.matches(selector));
1067
    },
1068

    
1069
    parents(element, selector) {
1070
      const parents = [];
1071
      let ancestor = element.parentNode.closest(selector);
1072

    
1073
      while (ancestor) {
1074
        parents.push(ancestor);
1075
        ancestor = ancestor.parentNode.closest(selector);
1076
      }
1077

    
1078
      return parents;
1079
    },
1080

    
1081
    prev(element, selector) {
1082
      let previous = element.previousElementSibling;
1083

    
1084
      while (previous) {
1085
        if (previous.matches(selector)) {
1086
          return [previous];
1087
        }
1088

    
1089
        previous = previous.previousElementSibling;
1090
      }
1091

    
1092
      return [];
1093
    },
1094

    
1095
    // TODO: this is now unused; remove later along with prev()
1096
    next(element, selector) {
1097
      let next = element.nextElementSibling;
1098

    
1099
      while (next) {
1100
        if (next.matches(selector)) {
1101
          return [next];
1102
        }
1103

    
1104
        next = next.nextElementSibling;
1105
      }
1106

    
1107
      return [];
1108
    },
1109

    
1110
    focusableChildren(element) {
1111
      const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(',');
1112
      return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el));
1113
    }
1114

    
1115
  };
1116

    
1117
  /**
1118
   * --------------------------------------------------------------------------
1119
   * Bootstrap (v5.2.3): util/swipe.js
1120
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1121
   * --------------------------------------------------------------------------
1122
   */
1123
  /**
1124
   * Constants
1125
   */
1126

    
1127
  const NAME$d = 'swipe';
1128
  const EVENT_KEY$9 = '.bs.swipe';
1129
  const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`;
1130
  const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`;
1131
  const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`;
1132
  const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`;
1133
  const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`;
1134
  const POINTER_TYPE_TOUCH = 'touch';
1135
  const POINTER_TYPE_PEN = 'pen';
1136
  const CLASS_NAME_POINTER_EVENT = 'pointer-event';
1137
  const SWIPE_THRESHOLD = 40;
1138
  const Default$c = {
1139
    endCallback: null,
1140
    leftCallback: null,
1141
    rightCallback: null
1142
  };
1143
  const DefaultType$c = {
1144
    endCallback: '(function|null)',
1145
    leftCallback: '(function|null)',
1146
    rightCallback: '(function|null)'
1147
  };
1148
  /**
1149
   * Class definition
1150
   */
1151

    
1152
  class Swipe extends Config {
1153
    constructor(element, config) {
1154
      super();
1155
      this._element = element;
1156

    
1157
      if (!element || !Swipe.isSupported()) {
1158
        return;
1159
      }
1160

    
1161
      this._config = this._getConfig(config);
1162
      this._deltaX = 0;
1163
      this._supportPointerEvents = Boolean(window.PointerEvent);
1164

    
1165
      this._initEvents();
1166
    } // Getters
1167

    
1168

    
1169
    static get Default() {
1170
      return Default$c;
1171
    }
1172

    
1173
    static get DefaultType() {
1174
      return DefaultType$c;
1175
    }
1176

    
1177
    static get NAME() {
1178
      return NAME$d;
1179
    } // Public
1180

    
1181

    
1182
    dispose() {
1183
      EventHandler.off(this._element, EVENT_KEY$9);
1184
    } // Private
1185

    
1186

    
1187
    _start(event) {
1188
      if (!this._supportPointerEvents) {
1189
        this._deltaX = event.touches[0].clientX;
1190
        return;
1191
      }
1192

    
1193
      if (this._eventIsPointerPenTouch(event)) {
1194
        this._deltaX = event.clientX;
1195
      }
1196
    }
1197

    
1198
    _end(event) {
1199
      if (this._eventIsPointerPenTouch(event)) {
1200
        this._deltaX = event.clientX - this._deltaX;
1201
      }
1202

    
1203
      this._handleSwipe();
1204

    
1205
      execute(this._config.endCallback);
1206
    }
1207

    
1208
    _move(event) {
1209
      this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX;
1210
    }
1211

    
1212
    _handleSwipe() {
1213
      const absDeltaX = Math.abs(this._deltaX);
1214

    
1215
      if (absDeltaX <= SWIPE_THRESHOLD) {
1216
        return;
1217
      }
1218

    
1219
      const direction = absDeltaX / this._deltaX;
1220
      this._deltaX = 0;
1221

    
1222
      if (!direction) {
1223
        return;
1224
      }
1225

    
1226
      execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback);
1227
    }
1228

    
1229
    _initEvents() {
1230
      if (this._supportPointerEvents) {
1231
        EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event));
1232
        EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event));
1233

    
1234
        this._element.classList.add(CLASS_NAME_POINTER_EVENT);
1235
      } else {
1236
        EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event));
1237
        EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event));
1238
        EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event));
1239
      }
1240
    }
1241

    
1242
    _eventIsPointerPenTouch(event) {
1243
      return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH);
1244
    } // Static
1245

    
1246

    
1247
    static isSupported() {
1248
      return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
1249
    }
1250

    
1251
  }
1252

    
1253
  /**
1254
   * --------------------------------------------------------------------------
1255
   * Bootstrap (v5.2.3): carousel.js
1256
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1257
   * --------------------------------------------------------------------------
1258
   */
1259
  /**
1260
   * Constants
1261
   */
1262

    
1263
  const NAME$c = 'carousel';
1264
  const DATA_KEY$8 = 'bs.carousel';
1265
  const EVENT_KEY$8 = `.${DATA_KEY$8}`;
1266
  const DATA_API_KEY$5 = '.data-api';
1267
  const ARROW_LEFT_KEY$1 = 'ArrowLeft';
1268
  const ARROW_RIGHT_KEY$1 = 'ArrowRight';
1269
  const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
1270

    
1271
  const ORDER_NEXT = 'next';
1272
  const ORDER_PREV = 'prev';
1273
  const DIRECTION_LEFT = 'left';
1274
  const DIRECTION_RIGHT = 'right';
1275
  const EVENT_SLIDE = `slide${EVENT_KEY$8}`;
1276
  const EVENT_SLID = `slid${EVENT_KEY$8}`;
1277
  const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`;
1278
  const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`;
1279
  const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`;
1280
  const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`;
1281
  const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`;
1282
  const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`;
1283
  const CLASS_NAME_CAROUSEL = 'carousel';
1284
  const CLASS_NAME_ACTIVE$2 = 'active';
1285
  const CLASS_NAME_SLIDE = 'slide';
1286
  const CLASS_NAME_END = 'carousel-item-end';
1287
  const CLASS_NAME_START = 'carousel-item-start';
1288
  const CLASS_NAME_NEXT = 'carousel-item-next';
1289
  const CLASS_NAME_PREV = 'carousel-item-prev';
1290
  const SELECTOR_ACTIVE = '.active';
1291
  const SELECTOR_ITEM = '.carousel-item';
1292
  const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM;
1293
  const SELECTOR_ITEM_IMG = '.carousel-item img';
1294
  const SELECTOR_INDICATORS = '.carousel-indicators';
1295
  const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]';
1296
  const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]';
1297
  const KEY_TO_DIRECTION = {
1298
    [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT,
1299
    [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT
1300
  };
1301
  const Default$b = {
1302
    interval: 5000,
1303
    keyboard: true,
1304
    pause: 'hover',
1305
    ride: false,
1306
    touch: true,
1307
    wrap: true
1308
  };
1309
  const DefaultType$b = {
1310
    interval: '(number|boolean)',
1311
    // TODO:v6 remove boolean support
1312
    keyboard: 'boolean',
1313
    pause: '(string|boolean)',
1314
    ride: '(boolean|string)',
1315
    touch: 'boolean',
1316
    wrap: 'boolean'
1317
  };
1318
  /**
1319
   * Class definition
1320
   */
1321

    
1322
  class Carousel extends BaseComponent {
1323
    constructor(element, config) {
1324
      super(element, config);
1325
      this._interval = null;
1326
      this._activeElement = null;
1327
      this._isSliding = false;
1328
      this.touchTimeout = null;
1329
      this._swipeHelper = null;
1330
      this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element);
1331

    
1332
      this._addEventListeners();
1333

    
1334
      if (this._config.ride === CLASS_NAME_CAROUSEL) {
1335
        this.cycle();
1336
      }
1337
    } // Getters
1338

    
1339

    
1340
    static get Default() {
1341
      return Default$b;
1342
    }
1343

    
1344
    static get DefaultType() {
1345
      return DefaultType$b;
1346
    }
1347

    
1348
    static get NAME() {
1349
      return NAME$c;
1350
    } // Public
1351

    
1352

    
1353
    next() {
1354
      this._slide(ORDER_NEXT);
1355
    }
1356

    
1357
    nextWhenVisible() {
1358
      // FIXME TODO use `document.visibilityState`
1359
      // Don't call next when the page isn't visible
1360
      // or the carousel or its parent isn't visible
1361
      if (!document.hidden && isVisible(this._element)) {
1362
        this.next();
1363
      }
1364
    }
1365

    
1366
    prev() {
1367
      this._slide(ORDER_PREV);
1368
    }
1369

    
1370
    pause() {
1371
      if (this._isSliding) {
1372
        triggerTransitionEnd(this._element);
1373
      }
1374

    
1375
      this._clearInterval();
1376
    }
1377

    
1378
    cycle() {
1379
      this._clearInterval();
1380

    
1381
      this._updateInterval();
1382

    
1383
      this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval);
1384
    }
1385

    
1386
    _maybeEnableCycle() {
1387
      if (!this._config.ride) {
1388
        return;
1389
      }
1390

    
1391
      if (this._isSliding) {
1392
        EventHandler.one(this._element, EVENT_SLID, () => this.cycle());
1393
        return;
1394
      }
1395

    
1396
      this.cycle();
1397
    }
1398

    
1399
    to(index) {
1400
      const items = this._getItems();
1401

    
1402
      if (index > items.length - 1 || index < 0) {
1403
        return;
1404
      }
1405

    
1406
      if (this._isSliding) {
1407
        EventHandler.one(this._element, EVENT_SLID, () => this.to(index));
1408
        return;
1409
      }
1410

    
1411
      const activeIndex = this._getItemIndex(this._getActive());
1412

    
1413
      if (activeIndex === index) {
1414
        return;
1415
      }
1416

    
1417
      const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV;
1418

    
1419
      this._slide(order, items[index]);
1420
    }
1421

    
1422
    dispose() {
1423
      if (this._swipeHelper) {
1424
        this._swipeHelper.dispose();
1425
      }
1426

    
1427
      super.dispose();
1428
    } // Private
1429

    
1430

    
1431
    _configAfterMerge(config) {
1432
      config.defaultInterval = config.interval;
1433
      return config;
1434
    }
1435

    
1436
    _addEventListeners() {
1437
      if (this._config.keyboard) {
1438
        EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event));
1439
      }
1440

    
1441
      if (this._config.pause === 'hover') {
1442
        EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause());
1443
        EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle());
1444
      }
1445

    
1446
      if (this._config.touch && Swipe.isSupported()) {
1447
        this._addTouchEventListeners();
1448
      }
1449
    }
1450

    
1451
    _addTouchEventListeners() {
1452
      for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) {
1453
        EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault());
1454
      }
1455

    
1456
      const endCallBack = () => {
1457
        if (this._config.pause !== 'hover') {
1458
          return;
1459
        } // If it's a touch-enabled device, mouseenter/leave are fired as
1460
        // part of the mouse compatibility events on first tap - the carousel
1461
        // would stop cycling until user tapped out of it;
1462
        // here, we listen for touchend, explicitly pause the carousel
1463
        // (as if it's the second time we tap on it, mouseenter compat event
1464
        // is NOT fired) and after a timeout (to allow for mouse compatibility
1465
        // events to fire) we explicitly restart cycling
1466

    
1467

    
1468
        this.pause();
1469

    
1470
        if (this.touchTimeout) {
1471
          clearTimeout(this.touchTimeout);
1472
        }
1473

    
1474
        this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval);
1475
      };
1476

    
1477
      const swipeConfig = {
1478
        leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)),
1479
        rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)),
1480
        endCallback: endCallBack
1481
      };
1482
      this._swipeHelper = new Swipe(this._element, swipeConfig);
1483
    }
1484

    
1485
    _keydown(event) {
1486
      if (/input|textarea/i.test(event.target.tagName)) {
1487
        return;
1488
      }
1489

    
1490
      const direction = KEY_TO_DIRECTION[event.key];
1491

    
1492
      if (direction) {
1493
        event.preventDefault();
1494

    
1495
        this._slide(this._directionToOrder(direction));
1496
      }
1497
    }
1498

    
1499
    _getItemIndex(element) {
1500
      return this._getItems().indexOf(element);
1501
    }
1502

    
1503
    _setActiveIndicatorElement(index) {
1504
      if (!this._indicatorsElement) {
1505
        return;
1506
      }
1507

    
1508
      const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement);
1509
      activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2);
1510
      activeIndicator.removeAttribute('aria-current');
1511
      const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement);
1512

    
1513
      if (newActiveIndicator) {
1514
        newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2);
1515
        newActiveIndicator.setAttribute('aria-current', 'true');
1516
      }
1517
    }
1518

    
1519
    _updateInterval() {
1520
      const element = this._activeElement || this._getActive();
1521

    
1522
      if (!element) {
1523
        return;
1524
      }
1525

    
1526
      const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10);
1527
      this._config.interval = elementInterval || this._config.defaultInterval;
1528
    }
1529

    
1530
    _slide(order, element = null) {
1531
      if (this._isSliding) {
1532
        return;
1533
      }
1534

    
1535
      const activeElement = this._getActive();
1536

    
1537
      const isNext = order === ORDER_NEXT;
1538
      const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap);
1539

    
1540
      if (nextElement === activeElement) {
1541
        return;
1542
      }
1543

    
1544
      const nextElementIndex = this._getItemIndex(nextElement);
1545

    
1546
      const triggerEvent = eventName => {
1547
        return EventHandler.trigger(this._element, eventName, {
1548
          relatedTarget: nextElement,
1549
          direction: this._orderToDirection(order),
1550
          from: this._getItemIndex(activeElement),
1551
          to: nextElementIndex
1552
        });
1553
      };
1554

    
1555
      const slideEvent = triggerEvent(EVENT_SLIDE);
1556

    
1557
      if (slideEvent.defaultPrevented) {
1558
        return;
1559
      }
1560

    
1561
      if (!activeElement || !nextElement) {
1562
        // Some weirdness is happening, so we bail
1563
        // todo: change tests that use empty divs to avoid this check
1564
        return;
1565
      }
1566

    
1567
      const isCycling = Boolean(this._interval);
1568
      this.pause();
1569
      this._isSliding = true;
1570

    
1571
      this._setActiveIndicatorElement(nextElementIndex);
1572

    
1573
      this._activeElement = nextElement;
1574
      const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END;
1575
      const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV;
1576
      nextElement.classList.add(orderClassName);
1577
      reflow(nextElement);
1578
      activeElement.classList.add(directionalClassName);
1579
      nextElement.classList.add(directionalClassName);
1580

    
1581
      const completeCallBack = () => {
1582
        nextElement.classList.remove(directionalClassName, orderClassName);
1583
        nextElement.classList.add(CLASS_NAME_ACTIVE$2);
1584
        activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName);
1585
        this._isSliding = false;
1586
        triggerEvent(EVENT_SLID);
1587
      };
1588

    
1589
      this._queueCallback(completeCallBack, activeElement, this._isAnimated());
1590

    
1591
      if (isCycling) {
1592
        this.cycle();
1593
      }
1594
    }
1595

    
1596
    _isAnimated() {
1597
      return this._element.classList.contains(CLASS_NAME_SLIDE);
1598
    }
1599

    
1600
    _getActive() {
1601
      return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element);
1602
    }
1603

    
1604
    _getItems() {
1605
      return SelectorEngine.find(SELECTOR_ITEM, this._element);
1606
    }
1607

    
1608
    _clearInterval() {
1609
      if (this._interval) {
1610
        clearInterval(this._interval);
1611
        this._interval = null;
1612
      }
1613
    }
1614

    
1615
    _directionToOrder(direction) {
1616
      if (isRTL()) {
1617
        return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT;
1618
      }
1619

    
1620
      return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV;
1621
    }
1622

    
1623
    _orderToDirection(order) {
1624
      if (isRTL()) {
1625
        return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT;
1626
      }
1627

    
1628
      return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT;
1629
    } // Static
1630

    
1631

    
1632
    static jQueryInterface(config) {
1633
      return this.each(function () {
1634
        const data = Carousel.getOrCreateInstance(this, config);
1635

    
1636
        if (typeof config === 'number') {
1637
          data.to(config);
1638
          return;
1639
        }
1640

    
1641
        if (typeof config === 'string') {
1642
          if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
1643
            throw new TypeError(`No method named "${config}"`);
1644
          }
1645

    
1646
          data[config]();
1647
        }
1648
      });
1649
    }
1650

    
1651
  }
1652
  /**
1653
   * Data API implementation
1654
   */
1655

    
1656

    
1657
  EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) {
1658
    const target = getElementFromSelector(this);
1659

    
1660
    if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) {
1661
      return;
1662
    }
1663

    
1664
    event.preventDefault();
1665
    const carousel = Carousel.getOrCreateInstance(target);
1666
    const slideIndex = this.getAttribute('data-bs-slide-to');
1667

    
1668
    if (slideIndex) {
1669
      carousel.to(slideIndex);
1670

    
1671
      carousel._maybeEnableCycle();
1672

    
1673
      return;
1674
    }
1675

    
1676
    if (Manipulator.getDataAttribute(this, 'slide') === 'next') {
1677
      carousel.next();
1678

    
1679
      carousel._maybeEnableCycle();
1680

    
1681
      return;
1682
    }
1683

    
1684
    carousel.prev();
1685

    
1686
    carousel._maybeEnableCycle();
1687
  });
1688
  EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => {
1689
    const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE);
1690

    
1691
    for (const carousel of carousels) {
1692
      Carousel.getOrCreateInstance(carousel);
1693
    }
1694
  });
1695
  /**
1696
   * jQuery
1697
   */
1698

    
1699
  defineJQueryPlugin(Carousel);
1700

    
1701
  /**
1702
   * --------------------------------------------------------------------------
1703
   * Bootstrap (v5.2.3): collapse.js
1704
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1705
   * --------------------------------------------------------------------------
1706
   */
1707
  /**
1708
   * Constants
1709
   */
1710

    
1711
  const NAME$b = 'collapse';
1712
  const DATA_KEY$7 = 'bs.collapse';
1713
  const EVENT_KEY$7 = `.${DATA_KEY$7}`;
1714
  const DATA_API_KEY$4 = '.data-api';
1715
  const EVENT_SHOW$6 = `show${EVENT_KEY$7}`;
1716
  const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`;
1717
  const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`;
1718
  const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`;
1719
  const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`;
1720
  const CLASS_NAME_SHOW$7 = 'show';
1721
  const CLASS_NAME_COLLAPSE = 'collapse';
1722
  const CLASS_NAME_COLLAPSING = 'collapsing';
1723
  const CLASS_NAME_COLLAPSED = 'collapsed';
1724
  const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`;
1725
  const CLASS_NAME_HORIZONTAL = 'collapse-horizontal';
1726
  const WIDTH = 'width';
1727
  const HEIGHT = 'height';
1728
  const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing';
1729
  const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]';
1730
  const Default$a = {
1731
    parent: null,
1732
    toggle: true
1733
  };
1734
  const DefaultType$a = {
1735
    parent: '(null|element)',
1736
    toggle: 'boolean'
1737
  };
1738
  /**
1739
   * Class definition
1740
   */
1741

    
1742
  class Collapse extends BaseComponent {
1743
    constructor(element, config) {
1744
      super(element, config);
1745
      this._isTransitioning = false;
1746
      this._triggerArray = [];
1747
      const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4);
1748

    
1749
      for (const elem of toggleList) {
1750
        const selector = getSelectorFromElement(elem);
1751
        const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element);
1752

    
1753
        if (selector !== null && filterElement.length) {
1754
          this._triggerArray.push(elem);
1755
        }
1756
      }
1757

    
1758
      this._initializeChildren();
1759

    
1760
      if (!this._config.parent) {
1761
        this._addAriaAndCollapsedClass(this._triggerArray, this._isShown());
1762
      }
1763

    
1764
      if (this._config.toggle) {
1765
        this.toggle();
1766
      }
1767
    } // Getters
1768

    
1769

    
1770
    static get Default() {
1771
      return Default$a;
1772
    }
1773

    
1774
    static get DefaultType() {
1775
      return DefaultType$a;
1776
    }
1777

    
1778
    static get NAME() {
1779
      return NAME$b;
1780
    } // Public
1781

    
1782

    
1783
    toggle() {
1784
      if (this._isShown()) {
1785
        this.hide();
1786
      } else {
1787
        this.show();
1788
      }
1789
    }
1790

    
1791
    show() {
1792
      if (this._isTransitioning || this._isShown()) {
1793
        return;
1794
      }
1795

    
1796
      let activeChildren = []; // find active children
1797

    
1798
      if (this._config.parent) {
1799
        activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, {
1800
          toggle: false
1801
        }));
1802
      }
1803

    
1804
      if (activeChildren.length && activeChildren[0]._isTransitioning) {
1805
        return;
1806
      }
1807

    
1808
      const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6);
1809

    
1810
      if (startEvent.defaultPrevented) {
1811
        return;
1812
      }
1813

    
1814
      for (const activeInstance of activeChildren) {
1815
        activeInstance.hide();
1816
      }
1817

    
1818
      const dimension = this._getDimension();
1819

    
1820
      this._element.classList.remove(CLASS_NAME_COLLAPSE);
1821

    
1822
      this._element.classList.add(CLASS_NAME_COLLAPSING);
1823

    
1824
      this._element.style[dimension] = 0;
1825

    
1826
      this._addAriaAndCollapsedClass(this._triggerArray, true);
1827

    
1828
      this._isTransitioning = true;
1829

    
1830
      const complete = () => {
1831
        this._isTransitioning = false;
1832

    
1833
        this._element.classList.remove(CLASS_NAME_COLLAPSING);
1834

    
1835
        this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1836

    
1837
        this._element.style[dimension] = '';
1838
        EventHandler.trigger(this._element, EVENT_SHOWN$6);
1839
      };
1840

    
1841
      const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
1842
      const scrollSize = `scroll${capitalizedDimension}`;
1843

    
1844
      this._queueCallback(complete, this._element, true);
1845

    
1846
      this._element.style[dimension] = `${this._element[scrollSize]}px`;
1847
    }
1848

    
1849
    hide() {
1850
      if (this._isTransitioning || !this._isShown()) {
1851
        return;
1852
      }
1853

    
1854
      const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6);
1855

    
1856
      if (startEvent.defaultPrevented) {
1857
        return;
1858
      }
1859

    
1860
      const dimension = this._getDimension();
1861

    
1862
      this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`;
1863
      reflow(this._element);
1864

    
1865
      this._element.classList.add(CLASS_NAME_COLLAPSING);
1866

    
1867
      this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7);
1868

    
1869
      for (const trigger of this._triggerArray) {
1870
        const element = getElementFromSelector(trigger);
1871

    
1872
        if (element && !this._isShown(element)) {
1873
          this._addAriaAndCollapsedClass([trigger], false);
1874
        }
1875
      }
1876

    
1877
      this._isTransitioning = true;
1878

    
1879
      const complete = () => {
1880
        this._isTransitioning = false;
1881

    
1882
        this._element.classList.remove(CLASS_NAME_COLLAPSING);
1883

    
1884
        this._element.classList.add(CLASS_NAME_COLLAPSE);
1885

    
1886
        EventHandler.trigger(this._element, EVENT_HIDDEN$6);
1887
      };
1888

    
1889
      this._element.style[dimension] = '';
1890

    
1891
      this._queueCallback(complete, this._element, true);
1892
    }
1893

    
1894
    _isShown(element = this._element) {
1895
      return element.classList.contains(CLASS_NAME_SHOW$7);
1896
    } // Private
1897

    
1898

    
1899
    _configAfterMerge(config) {
1900
      config.toggle = Boolean(config.toggle); // Coerce string values
1901

    
1902
      config.parent = getElement(config.parent);
1903
      return config;
1904
    }
1905

    
1906
    _getDimension() {
1907
      return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT;
1908
    }
1909

    
1910
    _initializeChildren() {
1911
      if (!this._config.parent) {
1912
        return;
1913
      }
1914

    
1915
      const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4);
1916

    
1917
      for (const element of children) {
1918
        const selected = getElementFromSelector(element);
1919

    
1920
        if (selected) {
1921
          this._addAriaAndCollapsedClass([element], this._isShown(selected));
1922
        }
1923
      }
1924
    }
1925

    
1926
    _getFirstLevelChildren(selector) {
1927
      const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); // remove children if greater depth
1928

    
1929
      return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element));
1930
    }
1931

    
1932
    _addAriaAndCollapsedClass(triggerArray, isOpen) {
1933
      if (!triggerArray.length) {
1934
        return;
1935
      }
1936

    
1937
      for (const element of triggerArray) {
1938
        element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen);
1939
        element.setAttribute('aria-expanded', isOpen);
1940
      }
1941
    } // Static
1942

    
1943

    
1944
    static jQueryInterface(config) {
1945
      const _config = {};
1946

    
1947
      if (typeof config === 'string' && /show|hide/.test(config)) {
1948
        _config.toggle = false;
1949
      }
1950

    
1951
      return this.each(function () {
1952
        const data = Collapse.getOrCreateInstance(this, _config);
1953

    
1954
        if (typeof config === 'string') {
1955
          if (typeof data[config] === 'undefined') {
1956
            throw new TypeError(`No method named "${config}"`);
1957
          }
1958

    
1959
          data[config]();
1960
        }
1961
      });
1962
    }
1963

    
1964
  }
1965
  /**
1966
   * Data API implementation
1967
   */
1968

    
1969

    
1970
  EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) {
1971
    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
1972
    if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') {
1973
      event.preventDefault();
1974
    }
1975

    
1976
    const selector = getSelectorFromElement(this);
1977
    const selectorElements = SelectorEngine.find(selector);
1978

    
1979
    for (const element of selectorElements) {
1980
      Collapse.getOrCreateInstance(element, {
1981
        toggle: false
1982
      }).toggle();
1983
    }
1984
  });
1985
  /**
1986
   * jQuery
1987
   */
1988

    
1989
  defineJQueryPlugin(Collapse);
1990

    
1991
  /**
1992
   * --------------------------------------------------------------------------
1993
   * Bootstrap (v5.2.3): dropdown.js
1994
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
1995
   * --------------------------------------------------------------------------
1996
   */
1997
  /**
1998
   * Constants
1999
   */
2000

    
2001
  const NAME$a = 'dropdown';
2002
  const DATA_KEY$6 = 'bs.dropdown';
2003
  const EVENT_KEY$6 = `.${DATA_KEY$6}`;
2004
  const DATA_API_KEY$3 = '.data-api';
2005
  const ESCAPE_KEY$2 = 'Escape';
2006
  const TAB_KEY$1 = 'Tab';
2007
  const ARROW_UP_KEY$1 = 'ArrowUp';
2008
  const ARROW_DOWN_KEY$1 = 'ArrowDown';
2009
  const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button
2010

    
2011
  const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`;
2012
  const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`;
2013
  const EVENT_SHOW$5 = `show${EVENT_KEY$6}`;
2014
  const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`;
2015
  const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`;
2016
  const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`;
2017
  const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`;
2018
  const CLASS_NAME_SHOW$6 = 'show';
2019
  const CLASS_NAME_DROPUP = 'dropup';
2020
  const CLASS_NAME_DROPEND = 'dropend';
2021
  const CLASS_NAME_DROPSTART = 'dropstart';
2022
  const CLASS_NAME_DROPUP_CENTER = 'dropup-center';
2023
  const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center';
2024
  const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)';
2025
  const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`;
2026
  const SELECTOR_MENU = '.dropdown-menu';
2027
  const SELECTOR_NAVBAR = '.navbar';
2028
  const SELECTOR_NAVBAR_NAV = '.navbar-nav';
2029
  const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
2030
  const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start';
2031
  const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end';
2032
  const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start';
2033
  const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end';
2034
  const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start';
2035
  const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start';
2036
  const PLACEMENT_TOPCENTER = 'top';
2037
  const PLACEMENT_BOTTOMCENTER = 'bottom';
2038
  const Default$9 = {
2039
    autoClose: true,
2040
    boundary: 'clippingParents',
2041
    display: 'dynamic',
2042
    offset: [0, 2],
2043
    popperConfig: null,
2044
    reference: 'toggle'
2045
  };
2046
  const DefaultType$9 = {
2047
    autoClose: '(boolean|string)',
2048
    boundary: '(string|element)',
2049
    display: 'string',
2050
    offset: '(array|string|function)',
2051
    popperConfig: '(null|object|function)',
2052
    reference: '(string|element|object)'
2053
  };
2054
  /**
2055
   * Class definition
2056
   */
2057

    
2058
  class Dropdown extends BaseComponent {
2059
    constructor(element, config) {
2060
      super(element, config);
2061
      this._popper = null;
2062
      this._parent = this._element.parentNode; // dropdown wrapper
2063
      // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/
2064

    
2065
      this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent);
2066
      this._inNavbar = this._detectNavbar();
2067
    } // Getters
2068

    
2069

    
2070
    static get Default() {
2071
      return Default$9;
2072
    }
2073

    
2074
    static get DefaultType() {
2075
      return DefaultType$9;
2076
    }
2077

    
2078
    static get NAME() {
2079
      return NAME$a;
2080
    } // Public
2081

    
2082

    
2083
    toggle() {
2084
      return this._isShown() ? this.hide() : this.show();
2085
    }
2086

    
2087
    show() {
2088
      if (isDisabled(this._element) || this._isShown()) {
2089
        return;
2090
      }
2091

    
2092
      const relatedTarget = {
2093
        relatedTarget: this._element
2094
      };
2095
      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget);
2096

    
2097
      if (showEvent.defaultPrevented) {
2098
        return;
2099
      }
2100

    
2101
      this._createPopper(); // If this is a touch-enabled device we add extra
2102
      // empty mouseover listeners to the body's immediate children;
2103
      // only needed because of broken event delegation on iOS
2104
      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
2105

    
2106

    
2107
      if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) {
2108
        for (const element of [].concat(...document.body.children)) {
2109
          EventHandler.on(element, 'mouseover', noop);
2110
        }
2111
      }
2112

    
2113
      this._element.focus();
2114

    
2115
      this._element.setAttribute('aria-expanded', true);
2116

    
2117
      this._menu.classList.add(CLASS_NAME_SHOW$6);
2118

    
2119
      this._element.classList.add(CLASS_NAME_SHOW$6);
2120

    
2121
      EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget);
2122
    }
2123

    
2124
    hide() {
2125
      if (isDisabled(this._element) || !this._isShown()) {
2126
        return;
2127
      }
2128

    
2129
      const relatedTarget = {
2130
        relatedTarget: this._element
2131
      };
2132

    
2133
      this._completeHide(relatedTarget);
2134
    }
2135

    
2136
    dispose() {
2137
      if (this._popper) {
2138
        this._popper.destroy();
2139
      }
2140

    
2141
      super.dispose();
2142
    }
2143

    
2144
    update() {
2145
      this._inNavbar = this._detectNavbar();
2146

    
2147
      if (this._popper) {
2148
        this._popper.update();
2149
      }
2150
    } // Private
2151

    
2152

    
2153
    _completeHide(relatedTarget) {
2154
      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget);
2155

    
2156
      if (hideEvent.defaultPrevented) {
2157
        return;
2158
      } // If this is a touch-enabled device we remove the extra
2159
      // empty mouseover listeners we added for iOS support
2160

    
2161

    
2162
      if ('ontouchstart' in document.documentElement) {
2163
        for (const element of [].concat(...document.body.children)) {
2164
          EventHandler.off(element, 'mouseover', noop);
2165
        }
2166
      }
2167

    
2168
      if (this._popper) {
2169
        this._popper.destroy();
2170
      }
2171

    
2172
      this._menu.classList.remove(CLASS_NAME_SHOW$6);
2173

    
2174
      this._element.classList.remove(CLASS_NAME_SHOW$6);
2175

    
2176
      this._element.setAttribute('aria-expanded', 'false');
2177

    
2178
      Manipulator.removeDataAttribute(this._menu, 'popper');
2179
      EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget);
2180
    }
2181

    
2182
    _getConfig(config) {
2183
      config = super._getConfig(config);
2184

    
2185
      if (typeof config.reference === 'object' && !isElement(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') {
2186
        // Popper virtual elements require a getBoundingClientRect method
2187
        throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`);
2188
      }
2189

    
2190
      return config;
2191
    }
2192

    
2193
    _createPopper() {
2194
      if (typeof Popper__namespace === 'undefined') {
2195
        throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
2196
      }
2197

    
2198
      let referenceElement = this._element;
2199

    
2200
      if (this._config.reference === 'parent') {
2201
        referenceElement = this._parent;
2202
      } else if (isElement(this._config.reference)) {
2203
        referenceElement = getElement(this._config.reference);
2204
      } else if (typeof this._config.reference === 'object') {
2205
        referenceElement = this._config.reference;
2206
      }
2207

    
2208
      const popperConfig = this._getPopperConfig();
2209

    
2210
      this._popper = Popper__namespace.createPopper(referenceElement, this._menu, popperConfig);
2211
    }
2212

    
2213
    _isShown() {
2214
      return this._menu.classList.contains(CLASS_NAME_SHOW$6);
2215
    }
2216

    
2217
    _getPlacement() {
2218
      const parentDropdown = this._parent;
2219

    
2220
      if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) {
2221
        return PLACEMENT_RIGHT;
2222
      }
2223

    
2224
      if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) {
2225
        return PLACEMENT_LEFT;
2226
      }
2227

    
2228
      if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) {
2229
        return PLACEMENT_TOPCENTER;
2230
      }
2231

    
2232
      if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) {
2233
        return PLACEMENT_BOTTOMCENTER;
2234
      } // We need to trim the value because custom properties can also include spaces
2235

    
2236

    
2237
      const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end';
2238

    
2239
      if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) {
2240
        return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP;
2241
      }
2242

    
2243
      return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM;
2244
    }
2245

    
2246
    _detectNavbar() {
2247
      return this._element.closest(SELECTOR_NAVBAR) !== null;
2248
    }
2249

    
2250
    _getOffset() {
2251
      const {
2252
        offset
2253
      } = this._config;
2254

    
2255
      if (typeof offset === 'string') {
2256
        return offset.split(',').map(value => Number.parseInt(value, 10));
2257
      }
2258

    
2259
      if (typeof offset === 'function') {
2260
        return popperData => offset(popperData, this._element);
2261
      }
2262

    
2263
      return offset;
2264
    }
2265

    
2266
    _getPopperConfig() {
2267
      const defaultBsPopperConfig = {
2268
        placement: this._getPlacement(),
2269
        modifiers: [{
2270
          name: 'preventOverflow',
2271
          options: {
2272
            boundary: this._config.boundary
2273
          }
2274
        }, {
2275
          name: 'offset',
2276
          options: {
2277
            offset: this._getOffset()
2278
          }
2279
        }]
2280
      }; // Disable Popper if we have a static display or Dropdown is in Navbar
2281

    
2282
      if (this._inNavbar || this._config.display === 'static') {
2283
        Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // todo:v6 remove
2284

    
2285
        defaultBsPopperConfig.modifiers = [{
2286
          name: 'applyStyles',
2287
          enabled: false
2288
        }];
2289
      }
2290

    
2291
      return { ...defaultBsPopperConfig,
2292
        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
2293
      };
2294
    }
2295

    
2296
    _selectMenuItem({
2297
      key,
2298
      target
2299
    }) {
2300
      const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element));
2301

    
2302
      if (!items.length) {
2303
        return;
2304
      } // if target isn't included in items (e.g. when expanding the dropdown)
2305
      // allow cycling to get the last item in case key equals ARROW_UP_KEY
2306

    
2307

    
2308
      getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus();
2309
    } // Static
2310

    
2311

    
2312
    static jQueryInterface(config) {
2313
      return this.each(function () {
2314
        const data = Dropdown.getOrCreateInstance(this, config);
2315

    
2316
        if (typeof config !== 'string') {
2317
          return;
2318
        }
2319

    
2320
        if (typeof data[config] === 'undefined') {
2321
          throw new TypeError(`No method named "${config}"`);
2322
        }
2323

    
2324
        data[config]();
2325
      });
2326
    }
2327

    
2328
    static clearMenus(event) {
2329
      if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) {
2330
        return;
2331
      }
2332

    
2333
      const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN);
2334

    
2335
      for (const toggle of openToggles) {
2336
        const context = Dropdown.getInstance(toggle);
2337

    
2338
        if (!context || context._config.autoClose === false) {
2339
          continue;
2340
        }
2341

    
2342
        const composedPath = event.composedPath();
2343
        const isMenuTarget = composedPath.includes(context._menu);
2344

    
2345
        if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) {
2346
          continue;
2347
        } // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu
2348

    
2349

    
2350
        if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) {
2351
          continue;
2352
        }
2353

    
2354
        const relatedTarget = {
2355
          relatedTarget: context._element
2356
        };
2357

    
2358
        if (event.type === 'click') {
2359
          relatedTarget.clickEvent = event;
2360
        }
2361

    
2362
        context._completeHide(relatedTarget);
2363
      }
2364
    }
2365

    
2366
    static dataApiKeydownHandler(event) {
2367
      // If not an UP | DOWN | ESCAPE key => not a dropdown command
2368
      // If input/textarea && if key is other than ESCAPE => not a dropdown command
2369
      const isInput = /input|textarea/i.test(event.target.tagName);
2370
      const isEscapeEvent = event.key === ESCAPE_KEY$2;
2371
      const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key);
2372

    
2373
      if (!isUpOrDownEvent && !isEscapeEvent) {
2374
        return;
2375
      }
2376

    
2377
      if (isInput && !isEscapeEvent) {
2378
        return;
2379
      }
2380

    
2381
      event.preventDefault(); // todo: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.2/forms/input-group/
2382

    
2383
      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);
2384
      const instance = Dropdown.getOrCreateInstance(getToggleButton);
2385

    
2386
      if (isUpOrDownEvent) {
2387
        event.stopPropagation();
2388
        instance.show();
2389

    
2390
        instance._selectMenuItem(event);
2391

    
2392
        return;
2393
      }
2394

    
2395
      if (instance._isShown()) {
2396
        // else is escape and we check if it is shown
2397
        event.stopPropagation();
2398
        instance.hide();
2399
        getToggleButton.focus();
2400
      }
2401
    }
2402

    
2403
  }
2404
  /**
2405
   * Data API implementation
2406
   */
2407

    
2408

    
2409
  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler);
2410
  EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler);
2411
  EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus);
2412
  EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus);
2413
  EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) {
2414
    event.preventDefault();
2415
    Dropdown.getOrCreateInstance(this).toggle();
2416
  });
2417
  /**
2418
   * jQuery
2419
   */
2420

    
2421
  defineJQueryPlugin(Dropdown);
2422

    
2423
  /**
2424
   * --------------------------------------------------------------------------
2425
   * Bootstrap (v5.2.3): util/scrollBar.js
2426
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2427
   * --------------------------------------------------------------------------
2428
   */
2429
  /**
2430
   * Constants
2431
   */
2432

    
2433
  const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
2434
  const SELECTOR_STICKY_CONTENT = '.sticky-top';
2435
  const PROPERTY_PADDING = 'padding-right';
2436
  const PROPERTY_MARGIN = 'margin-right';
2437
  /**
2438
   * Class definition
2439
   */
2440

    
2441
  class ScrollBarHelper {
2442
    constructor() {
2443
      this._element = document.body;
2444
    } // Public
2445

    
2446

    
2447
    getWidth() {
2448
      // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
2449
      const documentWidth = document.documentElement.clientWidth;
2450
      return Math.abs(window.innerWidth - documentWidth);
2451
    }
2452

    
2453
    hide() {
2454
      const width = this.getWidth();
2455

    
2456
      this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
2457

    
2458

    
2459
      this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
2460

    
2461

    
2462
      this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width);
2463

    
2464
      this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width);
2465
    }
2466

    
2467
    reset() {
2468
      this._resetElementAttributes(this._element, 'overflow');
2469

    
2470
      this._resetElementAttributes(this._element, PROPERTY_PADDING);
2471

    
2472
      this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING);
2473

    
2474
      this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN);
2475
    }
2476

    
2477
    isOverflowing() {
2478
      return this.getWidth() > 0;
2479
    } // Private
2480

    
2481

    
2482
    _disableOverFlow() {
2483
      this._saveInitialAttribute(this._element, 'overflow');
2484

    
2485
      this._element.style.overflow = 'hidden';
2486
    }
2487

    
2488
    _setElementAttributes(selector, styleProperty, callback) {
2489
      const scrollbarWidth = this.getWidth();
2490

    
2491
      const manipulationCallBack = element => {
2492
        if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
2493
          return;
2494
        }
2495

    
2496
        this._saveInitialAttribute(element, styleProperty);
2497

    
2498
        const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty);
2499
        element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`);
2500
      };
2501

    
2502
      this._applyManipulationCallback(selector, manipulationCallBack);
2503
    }
2504

    
2505
    _saveInitialAttribute(element, styleProperty) {
2506
      const actualValue = element.style.getPropertyValue(styleProperty);
2507

    
2508
      if (actualValue) {
2509
        Manipulator.setDataAttribute(element, styleProperty, actualValue);
2510
      }
2511
    }
2512

    
2513
    _resetElementAttributes(selector, styleProperty) {
2514
      const manipulationCallBack = element => {
2515
        const value = Manipulator.getDataAttribute(element, styleProperty); // We only want to remove the property if the value is `null`; the value can also be zero
2516

    
2517
        if (value === null) {
2518
          element.style.removeProperty(styleProperty);
2519
          return;
2520
        }
2521

    
2522
        Manipulator.removeDataAttribute(element, styleProperty);
2523
        element.style.setProperty(styleProperty, value);
2524
      };
2525

    
2526
      this._applyManipulationCallback(selector, manipulationCallBack);
2527
    }
2528

    
2529
    _applyManipulationCallback(selector, callBack) {
2530
      if (isElement(selector)) {
2531
        callBack(selector);
2532
        return;
2533
      }
2534

    
2535
      for (const sel of SelectorEngine.find(selector, this._element)) {
2536
        callBack(sel);
2537
      }
2538
    }
2539

    
2540
  }
2541

    
2542
  /**
2543
   * --------------------------------------------------------------------------
2544
   * Bootstrap (v5.2.3): util/backdrop.js
2545
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2546
   * --------------------------------------------------------------------------
2547
   */
2548
  /**
2549
   * Constants
2550
   */
2551

    
2552
  const NAME$9 = 'backdrop';
2553
  const CLASS_NAME_FADE$4 = 'fade';
2554
  const CLASS_NAME_SHOW$5 = 'show';
2555
  const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`;
2556
  const Default$8 = {
2557
    className: 'modal-backdrop',
2558
    clickCallback: null,
2559
    isAnimated: false,
2560
    isVisible: true,
2561
    // if false, we use the backdrop helper without adding any element to the dom
2562
    rootElement: 'body' // give the choice to place backdrop under different elements
2563

    
2564
  };
2565
  const DefaultType$8 = {
2566
    className: 'string',
2567
    clickCallback: '(function|null)',
2568
    isAnimated: 'boolean',
2569
    isVisible: 'boolean',
2570
    rootElement: '(element|string)'
2571
  };
2572
  /**
2573
   * Class definition
2574
   */
2575

    
2576
  class Backdrop extends Config {
2577
    constructor(config) {
2578
      super();
2579
      this._config = this._getConfig(config);
2580
      this._isAppended = false;
2581
      this._element = null;
2582
    } // Getters
2583

    
2584

    
2585
    static get Default() {
2586
      return Default$8;
2587
    }
2588

    
2589
    static get DefaultType() {
2590
      return DefaultType$8;
2591
    }
2592

    
2593
    static get NAME() {
2594
      return NAME$9;
2595
    } // Public
2596

    
2597

    
2598
    show(callback) {
2599
      if (!this._config.isVisible) {
2600
        execute(callback);
2601
        return;
2602
      }
2603

    
2604
      this._append();
2605

    
2606
      const element = this._getElement();
2607

    
2608
      if (this._config.isAnimated) {
2609
        reflow(element);
2610
      }
2611

    
2612
      element.classList.add(CLASS_NAME_SHOW$5);
2613

    
2614
      this._emulateAnimation(() => {
2615
        execute(callback);
2616
      });
2617
    }
2618

    
2619
    hide(callback) {
2620
      if (!this._config.isVisible) {
2621
        execute(callback);
2622
        return;
2623
      }
2624

    
2625
      this._getElement().classList.remove(CLASS_NAME_SHOW$5);
2626

    
2627
      this._emulateAnimation(() => {
2628
        this.dispose();
2629
        execute(callback);
2630
      });
2631
    }
2632

    
2633
    dispose() {
2634
      if (!this._isAppended) {
2635
        return;
2636
      }
2637

    
2638
      EventHandler.off(this._element, EVENT_MOUSEDOWN);
2639

    
2640
      this._element.remove();
2641

    
2642
      this._isAppended = false;
2643
    } // Private
2644

    
2645

    
2646
    _getElement() {
2647
      if (!this._element) {
2648
        const backdrop = document.createElement('div');
2649
        backdrop.className = this._config.className;
2650

    
2651
        if (this._config.isAnimated) {
2652
          backdrop.classList.add(CLASS_NAME_FADE$4);
2653
        }
2654

    
2655
        this._element = backdrop;
2656
      }
2657

    
2658
      return this._element;
2659
    }
2660

    
2661
    _configAfterMerge(config) {
2662
      // use getElement() with the default "body" to get a fresh Element on each instantiation
2663
      config.rootElement = getElement(config.rootElement);
2664
      return config;
2665
    }
2666

    
2667
    _append() {
2668
      if (this._isAppended) {
2669
        return;
2670
      }
2671

    
2672
      const element = this._getElement();
2673

    
2674
      this._config.rootElement.append(element);
2675

    
2676
      EventHandler.on(element, EVENT_MOUSEDOWN, () => {
2677
        execute(this._config.clickCallback);
2678
      });
2679
      this._isAppended = true;
2680
    }
2681

    
2682
    _emulateAnimation(callback) {
2683
      executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
2684
    }
2685

    
2686
  }
2687

    
2688
  /**
2689
   * --------------------------------------------------------------------------
2690
   * Bootstrap (v5.2.3): util/focustrap.js
2691
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2692
   * --------------------------------------------------------------------------
2693
   */
2694
  /**
2695
   * Constants
2696
   */
2697

    
2698
  const NAME$8 = 'focustrap';
2699
  const DATA_KEY$5 = 'bs.focustrap';
2700
  const EVENT_KEY$5 = `.${DATA_KEY$5}`;
2701
  const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`;
2702
  const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`;
2703
  const TAB_KEY = 'Tab';
2704
  const TAB_NAV_FORWARD = 'forward';
2705
  const TAB_NAV_BACKWARD = 'backward';
2706
  const Default$7 = {
2707
    autofocus: true,
2708
    trapElement: null // The element to trap focus inside of
2709

    
2710
  };
2711
  const DefaultType$7 = {
2712
    autofocus: 'boolean',
2713
    trapElement: 'element'
2714
  };
2715
  /**
2716
   * Class definition
2717
   */
2718

    
2719
  class FocusTrap extends Config {
2720
    constructor(config) {
2721
      super();
2722
      this._config = this._getConfig(config);
2723
      this._isActive = false;
2724
      this._lastTabNavDirection = null;
2725
    } // Getters
2726

    
2727

    
2728
    static get Default() {
2729
      return Default$7;
2730
    }
2731

    
2732
    static get DefaultType() {
2733
      return DefaultType$7;
2734
    }
2735

    
2736
    static get NAME() {
2737
      return NAME$8;
2738
    } // Public
2739

    
2740

    
2741
    activate() {
2742
      if (this._isActive) {
2743
        return;
2744
      }
2745

    
2746
      if (this._config.autofocus) {
2747
        this._config.trapElement.focus();
2748
      }
2749

    
2750
      EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop
2751

    
2752
      EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event));
2753
      EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
2754
      this._isActive = true;
2755
    }
2756

    
2757
    deactivate() {
2758
      if (!this._isActive) {
2759
        return;
2760
      }
2761

    
2762
      this._isActive = false;
2763
      EventHandler.off(document, EVENT_KEY$5);
2764
    } // Private
2765

    
2766

    
2767
    _handleFocusin(event) {
2768
      const {
2769
        trapElement
2770
      } = this._config;
2771

    
2772
      if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {
2773
        return;
2774
      }
2775

    
2776
      const elements = SelectorEngine.focusableChildren(trapElement);
2777

    
2778
      if (elements.length === 0) {
2779
        trapElement.focus();
2780
      } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
2781
        elements[elements.length - 1].focus();
2782
      } else {
2783
        elements[0].focus();
2784
      }
2785
    }
2786

    
2787
    _handleKeydown(event) {
2788
      if (event.key !== TAB_KEY) {
2789
        return;
2790
      }
2791

    
2792
      this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
2793
    }
2794

    
2795
  }
2796

    
2797
  /**
2798
   * --------------------------------------------------------------------------
2799
   * Bootstrap (v5.2.3): modal.js
2800
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
2801
   * --------------------------------------------------------------------------
2802
   */
2803
  /**
2804
   * Constants
2805
   */
2806

    
2807
  const NAME$7 = 'modal';
2808
  const DATA_KEY$4 = 'bs.modal';
2809
  const EVENT_KEY$4 = `.${DATA_KEY$4}`;
2810
  const DATA_API_KEY$2 = '.data-api';
2811
  const ESCAPE_KEY$1 = 'Escape';
2812
  const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`;
2813
  const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`;
2814
  const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`;
2815
  const EVENT_SHOW$4 = `show${EVENT_KEY$4}`;
2816
  const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`;
2817
  const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`;
2818
  const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`;
2819
  const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`;
2820
  const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`;
2821
  const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`;
2822
  const CLASS_NAME_OPEN = 'modal-open';
2823
  const CLASS_NAME_FADE$3 = 'fade';
2824
  const CLASS_NAME_SHOW$4 = 'show';
2825
  const CLASS_NAME_STATIC = 'modal-static';
2826
  const OPEN_SELECTOR$1 = '.modal.show';
2827
  const SELECTOR_DIALOG = '.modal-dialog';
2828
  const SELECTOR_MODAL_BODY = '.modal-body';
2829
  const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]';
2830
  const Default$6 = {
2831
    backdrop: true,
2832
    focus: true,
2833
    keyboard: true
2834
  };
2835
  const DefaultType$6 = {
2836
    backdrop: '(boolean|string)',
2837
    focus: 'boolean',
2838
    keyboard: 'boolean'
2839
  };
2840
  /**
2841
   * Class definition
2842
   */
2843

    
2844
  class Modal extends BaseComponent {
2845
    constructor(element, config) {
2846
      super(element, config);
2847
      this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element);
2848
      this._backdrop = this._initializeBackDrop();
2849
      this._focustrap = this._initializeFocusTrap();
2850
      this._isShown = false;
2851
      this._isTransitioning = false;
2852
      this._scrollBar = new ScrollBarHelper();
2853

    
2854
      this._addEventListeners();
2855
    } // Getters
2856

    
2857

    
2858
    static get Default() {
2859
      return Default$6;
2860
    }
2861

    
2862
    static get DefaultType() {
2863
      return DefaultType$6;
2864
    }
2865

    
2866
    static get NAME() {
2867
      return NAME$7;
2868
    } // Public
2869

    
2870

    
2871
    toggle(relatedTarget) {
2872
      return this._isShown ? this.hide() : this.show(relatedTarget);
2873
    }
2874

    
2875
    show(relatedTarget) {
2876
      if (this._isShown || this._isTransitioning) {
2877
        return;
2878
      }
2879

    
2880
      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, {
2881
        relatedTarget
2882
      });
2883

    
2884
      if (showEvent.defaultPrevented) {
2885
        return;
2886
      }
2887

    
2888
      this._isShown = true;
2889
      this._isTransitioning = true;
2890

    
2891
      this._scrollBar.hide();
2892

    
2893
      document.body.classList.add(CLASS_NAME_OPEN);
2894

    
2895
      this._adjustDialog();
2896

    
2897
      this._backdrop.show(() => this._showElement(relatedTarget));
2898
    }
2899

    
2900
    hide() {
2901
      if (!this._isShown || this._isTransitioning) {
2902
        return;
2903
      }
2904

    
2905
      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4);
2906

    
2907
      if (hideEvent.defaultPrevented) {
2908
        return;
2909
      }
2910

    
2911
      this._isShown = false;
2912
      this._isTransitioning = true;
2913

    
2914
      this._focustrap.deactivate();
2915

    
2916
      this._element.classList.remove(CLASS_NAME_SHOW$4);
2917

    
2918
      this._queueCallback(() => this._hideModal(), this._element, this._isAnimated());
2919
    }
2920

    
2921
    dispose() {
2922
      for (const htmlElement of [window, this._dialog]) {
2923
        EventHandler.off(htmlElement, EVENT_KEY$4);
2924
      }
2925

    
2926
      this._backdrop.dispose();
2927

    
2928
      this._focustrap.deactivate();
2929

    
2930
      super.dispose();
2931
    }
2932

    
2933
    handleUpdate() {
2934
      this._adjustDialog();
2935
    } // Private
2936

    
2937

    
2938
    _initializeBackDrop() {
2939
      return new Backdrop({
2940
        isVisible: Boolean(this._config.backdrop),
2941
        // 'static' option will be translated to true, and booleans will keep their value,
2942
        isAnimated: this._isAnimated()
2943
      });
2944
    }
2945

    
2946
    _initializeFocusTrap() {
2947
      return new FocusTrap({
2948
        trapElement: this._element
2949
      });
2950
    }
2951

    
2952
    _showElement(relatedTarget) {
2953
      // try to append dynamic modal
2954
      if (!document.body.contains(this._element)) {
2955
        document.body.append(this._element);
2956
      }
2957

    
2958
      this._element.style.display = 'block';
2959

    
2960
      this._element.removeAttribute('aria-hidden');
2961

    
2962
      this._element.setAttribute('aria-modal', true);
2963

    
2964
      this._element.setAttribute('role', 'dialog');
2965

    
2966
      this._element.scrollTop = 0;
2967
      const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog);
2968

    
2969
      if (modalBody) {
2970
        modalBody.scrollTop = 0;
2971
      }
2972

    
2973
      reflow(this._element);
2974

    
2975
      this._element.classList.add(CLASS_NAME_SHOW$4);
2976

    
2977
      const transitionComplete = () => {
2978
        if (this._config.focus) {
2979
          this._focustrap.activate();
2980
        }
2981

    
2982
        this._isTransitioning = false;
2983
        EventHandler.trigger(this._element, EVENT_SHOWN$4, {
2984
          relatedTarget
2985
        });
2986
      };
2987

    
2988
      this._queueCallback(transitionComplete, this._dialog, this._isAnimated());
2989
    }
2990

    
2991
    _addEventListeners() {
2992
      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => {
2993
        if (event.key !== ESCAPE_KEY$1) {
2994
          return;
2995
        }
2996

    
2997
        if (this._config.keyboard) {
2998
          event.preventDefault();
2999
          this.hide();
3000
          return;
3001
        }
3002

    
3003
        this._triggerBackdropTransition();
3004
      });
3005
      EventHandler.on(window, EVENT_RESIZE$1, () => {
3006
        if (this._isShown && !this._isTransitioning) {
3007
          this._adjustDialog();
3008
        }
3009
      });
3010
      EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => {
3011
        // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks
3012
        EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => {
3013
          if (this._element !== event.target || this._element !== event2.target) {
3014
            return;
3015
          }
3016

    
3017
          if (this._config.backdrop === 'static') {
3018
            this._triggerBackdropTransition();
3019

    
3020
            return;
3021
          }
3022

    
3023
          if (this._config.backdrop) {
3024
            this.hide();
3025
          }
3026
        });
3027
      });
3028
    }
3029

    
3030
    _hideModal() {
3031
      this._element.style.display = 'none';
3032

    
3033
      this._element.setAttribute('aria-hidden', true);
3034

    
3035
      this._element.removeAttribute('aria-modal');
3036

    
3037
      this._element.removeAttribute('role');
3038

    
3039
      this._isTransitioning = false;
3040

    
3041
      this._backdrop.hide(() => {
3042
        document.body.classList.remove(CLASS_NAME_OPEN);
3043

    
3044
        this._resetAdjustments();
3045

    
3046
        this._scrollBar.reset();
3047

    
3048
        EventHandler.trigger(this._element, EVENT_HIDDEN$4);
3049
      });
3050
    }
3051

    
3052
    _isAnimated() {
3053
      return this._element.classList.contains(CLASS_NAME_FADE$3);
3054
    }
3055

    
3056
    _triggerBackdropTransition() {
3057
      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1);
3058

    
3059
      if (hideEvent.defaultPrevented) {
3060
        return;
3061
      }
3062

    
3063
      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
3064
      const initialOverflowY = this._element.style.overflowY; // return if the following background transition hasn't yet completed
3065

    
3066
      if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) {
3067
        return;
3068
      }
3069

    
3070
      if (!isModalOverflowing) {
3071
        this._element.style.overflowY = 'hidden';
3072
      }
3073

    
3074
      this._element.classList.add(CLASS_NAME_STATIC);
3075

    
3076
      this._queueCallback(() => {
3077
        this._element.classList.remove(CLASS_NAME_STATIC);
3078

    
3079
        this._queueCallback(() => {
3080
          this._element.style.overflowY = initialOverflowY;
3081
        }, this._dialog);
3082
      }, this._dialog);
3083

    
3084
      this._element.focus();
3085
    }
3086
    /**
3087
     * The following methods are used to handle overflowing modals
3088
     */
3089

    
3090

    
3091
    _adjustDialog() {
3092
      const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
3093

    
3094
      const scrollbarWidth = this._scrollBar.getWidth();
3095

    
3096
      const isBodyOverflowing = scrollbarWidth > 0;
3097

    
3098
      if (isBodyOverflowing && !isModalOverflowing) {
3099
        const property = isRTL() ? 'paddingLeft' : 'paddingRight';
3100
        this._element.style[property] = `${scrollbarWidth}px`;
3101
      }
3102

    
3103
      if (!isBodyOverflowing && isModalOverflowing) {
3104
        const property = isRTL() ? 'paddingRight' : 'paddingLeft';
3105
        this._element.style[property] = `${scrollbarWidth}px`;
3106
      }
3107
    }
3108

    
3109
    _resetAdjustments() {
3110
      this._element.style.paddingLeft = '';
3111
      this._element.style.paddingRight = '';
3112
    } // Static
3113

    
3114

    
3115
    static jQueryInterface(config, relatedTarget) {
3116
      return this.each(function () {
3117
        const data = Modal.getOrCreateInstance(this, config);
3118

    
3119
        if (typeof config !== 'string') {
3120
          return;
3121
        }
3122

    
3123
        if (typeof data[config] === 'undefined') {
3124
          throw new TypeError(`No method named "${config}"`);
3125
        }
3126

    
3127
        data[config](relatedTarget);
3128
      });
3129
    }
3130

    
3131
  }
3132
  /**
3133
   * Data API implementation
3134
   */
3135

    
3136

    
3137
  EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) {
3138
    const target = getElementFromSelector(this);
3139

    
3140
    if (['A', 'AREA'].includes(this.tagName)) {
3141
      event.preventDefault();
3142
    }
3143

    
3144
    EventHandler.one(target, EVENT_SHOW$4, showEvent => {
3145
      if (showEvent.defaultPrevented) {
3146
        // only register focus restorer if modal will actually get shown
3147
        return;
3148
      }
3149

    
3150
      EventHandler.one(target, EVENT_HIDDEN$4, () => {
3151
        if (isVisible(this)) {
3152
          this.focus();
3153
        }
3154
      });
3155
    }); // avoid conflict when clicking modal toggler while another one is open
3156

    
3157
    const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1);
3158

    
3159
    if (alreadyOpen) {
3160
      Modal.getInstance(alreadyOpen).hide();
3161
    }
3162

    
3163
    const data = Modal.getOrCreateInstance(target);
3164
    data.toggle(this);
3165
  });
3166
  enableDismissTrigger(Modal);
3167
  /**
3168
   * jQuery
3169
   */
3170

    
3171
  defineJQueryPlugin(Modal);
3172

    
3173
  /**
3174
   * --------------------------------------------------------------------------
3175
   * Bootstrap (v5.2.3): offcanvas.js
3176
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3177
   * --------------------------------------------------------------------------
3178
   */
3179
  /**
3180
   * Constants
3181
   */
3182

    
3183
  const NAME$6 = 'offcanvas';
3184
  const DATA_KEY$3 = 'bs.offcanvas';
3185
  const EVENT_KEY$3 = `.${DATA_KEY$3}`;
3186
  const DATA_API_KEY$1 = '.data-api';
3187
  const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`;
3188
  const ESCAPE_KEY = 'Escape';
3189
  const CLASS_NAME_SHOW$3 = 'show';
3190
  const CLASS_NAME_SHOWING$1 = 'showing';
3191
  const CLASS_NAME_HIDING = 'hiding';
3192
  const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
3193
  const OPEN_SELECTOR = '.offcanvas.show';
3194
  const EVENT_SHOW$3 = `show${EVENT_KEY$3}`;
3195
  const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`;
3196
  const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`;
3197
  const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`;
3198
  const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`;
3199
  const EVENT_RESIZE = `resize${EVENT_KEY$3}`;
3200
  const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`;
3201
  const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`;
3202
  const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]';
3203
  const Default$5 = {
3204
    backdrop: true,
3205
    keyboard: true,
3206
    scroll: false
3207
  };
3208
  const DefaultType$5 = {
3209
    backdrop: '(boolean|string)',
3210
    keyboard: 'boolean',
3211
    scroll: 'boolean'
3212
  };
3213
  /**
3214
   * Class definition
3215
   */
3216

    
3217
  class Offcanvas extends BaseComponent {
3218
    constructor(element, config) {
3219
      super(element, config);
3220
      this._isShown = false;
3221
      this._backdrop = this._initializeBackDrop();
3222
      this._focustrap = this._initializeFocusTrap();
3223

    
3224
      this._addEventListeners();
3225
    } // Getters
3226

    
3227

    
3228
    static get Default() {
3229
      return Default$5;
3230
    }
3231

    
3232
    static get DefaultType() {
3233
      return DefaultType$5;
3234
    }
3235

    
3236
    static get NAME() {
3237
      return NAME$6;
3238
    } // Public
3239

    
3240

    
3241
    toggle(relatedTarget) {
3242
      return this._isShown ? this.hide() : this.show(relatedTarget);
3243
    }
3244

    
3245
    show(relatedTarget) {
3246
      if (this._isShown) {
3247
        return;
3248
      }
3249

    
3250
      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, {
3251
        relatedTarget
3252
      });
3253

    
3254
      if (showEvent.defaultPrevented) {
3255
        return;
3256
      }
3257

    
3258
      this._isShown = true;
3259

    
3260
      this._backdrop.show();
3261

    
3262
      if (!this._config.scroll) {
3263
        new ScrollBarHelper().hide();
3264
      }
3265

    
3266
      this._element.setAttribute('aria-modal', true);
3267

    
3268
      this._element.setAttribute('role', 'dialog');
3269

    
3270
      this._element.classList.add(CLASS_NAME_SHOWING$1);
3271

    
3272
      const completeCallBack = () => {
3273
        if (!this._config.scroll || this._config.backdrop) {
3274
          this._focustrap.activate();
3275
        }
3276

    
3277
        this._element.classList.add(CLASS_NAME_SHOW$3);
3278

    
3279
        this._element.classList.remove(CLASS_NAME_SHOWING$1);
3280

    
3281
        EventHandler.trigger(this._element, EVENT_SHOWN$3, {
3282
          relatedTarget
3283
        });
3284
      };
3285

    
3286
      this._queueCallback(completeCallBack, this._element, true);
3287
    }
3288

    
3289
    hide() {
3290
      if (!this._isShown) {
3291
        return;
3292
      }
3293

    
3294
      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3);
3295

    
3296
      if (hideEvent.defaultPrevented) {
3297
        return;
3298
      }
3299

    
3300
      this._focustrap.deactivate();
3301

    
3302
      this._element.blur();
3303

    
3304
      this._isShown = false;
3305

    
3306
      this._element.classList.add(CLASS_NAME_HIDING);
3307

    
3308
      this._backdrop.hide();
3309

    
3310
      const completeCallback = () => {
3311
        this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING);
3312

    
3313
        this._element.removeAttribute('aria-modal');
3314

    
3315
        this._element.removeAttribute('role');
3316

    
3317
        if (!this._config.scroll) {
3318
          new ScrollBarHelper().reset();
3319
        }
3320

    
3321
        EventHandler.trigger(this._element, EVENT_HIDDEN$3);
3322
      };
3323

    
3324
      this._queueCallback(completeCallback, this._element, true);
3325
    }
3326

    
3327
    dispose() {
3328
      this._backdrop.dispose();
3329

    
3330
      this._focustrap.deactivate();
3331

    
3332
      super.dispose();
3333
    } // Private
3334

    
3335

    
3336
    _initializeBackDrop() {
3337
      const clickCallback = () => {
3338
        if (this._config.backdrop === 'static') {
3339
          EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
3340
          return;
3341
        }
3342

    
3343
        this.hide();
3344
      }; // 'static' option will be translated to true, and booleans will keep their value
3345

    
3346

    
3347
      const isVisible = Boolean(this._config.backdrop);
3348
      return new Backdrop({
3349
        className: CLASS_NAME_BACKDROP,
3350
        isVisible,
3351
        isAnimated: true,
3352
        rootElement: this._element.parentNode,
3353
        clickCallback: isVisible ? clickCallback : null
3354
      });
3355
    }
3356

    
3357
    _initializeFocusTrap() {
3358
      return new FocusTrap({
3359
        trapElement: this._element
3360
      });
3361
    }
3362

    
3363
    _addEventListeners() {
3364
      EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => {
3365
        if (event.key !== ESCAPE_KEY) {
3366
          return;
3367
        }
3368

    
3369
        if (!this._config.keyboard) {
3370
          EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED);
3371
          return;
3372
        }
3373

    
3374
        this.hide();
3375
      });
3376
    } // Static
3377

    
3378

    
3379
    static jQueryInterface(config) {
3380
      return this.each(function () {
3381
        const data = Offcanvas.getOrCreateInstance(this, config);
3382

    
3383
        if (typeof config !== 'string') {
3384
          return;
3385
        }
3386

    
3387
        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
3388
          throw new TypeError(`No method named "${config}"`);
3389
        }
3390

    
3391
        data[config](this);
3392
      });
3393
    }
3394

    
3395
  }
3396
  /**
3397
   * Data API implementation
3398
   */
3399

    
3400

    
3401
  EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) {
3402
    const target = getElementFromSelector(this);
3403

    
3404
    if (['A', 'AREA'].includes(this.tagName)) {
3405
      event.preventDefault();
3406
    }
3407

    
3408
    if (isDisabled(this)) {
3409
      return;
3410
    }
3411

    
3412
    EventHandler.one(target, EVENT_HIDDEN$3, () => {
3413
      // focus on trigger when it is closed
3414
      if (isVisible(this)) {
3415
        this.focus();
3416
      }
3417
    }); // avoid conflict when clicking a toggler of an offcanvas, while another is open
3418

    
3419
    const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR);
3420

    
3421
    if (alreadyOpen && alreadyOpen !== target) {
3422
      Offcanvas.getInstance(alreadyOpen).hide();
3423
    }
3424

    
3425
    const data = Offcanvas.getOrCreateInstance(target);
3426
    data.toggle(this);
3427
  });
3428
  EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => {
3429
    for (const selector of SelectorEngine.find(OPEN_SELECTOR)) {
3430
      Offcanvas.getOrCreateInstance(selector).show();
3431
    }
3432
  });
3433
  EventHandler.on(window, EVENT_RESIZE, () => {
3434
    for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) {
3435
      if (getComputedStyle(element).position !== 'fixed') {
3436
        Offcanvas.getOrCreateInstance(element).hide();
3437
      }
3438
    }
3439
  });
3440
  enableDismissTrigger(Offcanvas);
3441
  /**
3442
   * jQuery
3443
   */
3444

    
3445
  defineJQueryPlugin(Offcanvas);
3446

    
3447
  /**
3448
   * --------------------------------------------------------------------------
3449
   * Bootstrap (v5.2.3): util/sanitizer.js
3450
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3451
   * --------------------------------------------------------------------------
3452
   */
3453
  const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']);
3454
  const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
3455
  /**
3456
   * A pattern that recognizes a commonly useful subset of URLs that are safe.
3457
   *
3458
   * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
3459
   */
3460

    
3461
  const SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i;
3462
  /**
3463
   * A pattern that matches safe data URLs. Only matches image, video and audio types.
3464
   *
3465
   * Shout-out to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts
3466
   */
3467

    
3468
  const DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
3469

    
3470
  const allowedAttribute = (attribute, allowedAttributeList) => {
3471
    const attributeName = attribute.nodeName.toLowerCase();
3472

    
3473
    if (allowedAttributeList.includes(attributeName)) {
3474
      if (uriAttributes.has(attributeName)) {
3475
        return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue) || DATA_URL_PATTERN.test(attribute.nodeValue));
3476
      }
3477

    
3478
      return true;
3479
    } // Check if a regular expression validates the attribute.
3480

    
3481

    
3482
    return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName));
3483
  };
3484

    
3485
  const DefaultAllowlist = {
3486
    // Global attributes allowed on any supplied element below.
3487
    '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
3488
    a: ['target', 'href', 'title', 'rel'],
3489
    area: [],
3490
    b: [],
3491
    br: [],
3492
    col: [],
3493
    code: [],
3494
    div: [],
3495
    em: [],
3496
    hr: [],
3497
    h1: [],
3498
    h2: [],
3499
    h3: [],
3500
    h4: [],
3501
    h5: [],
3502
    h6: [],
3503
    i: [],
3504
    img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
3505
    li: [],
3506
    ol: [],
3507
    p: [],
3508
    pre: [],
3509
    s: [],
3510
    small: [],
3511
    span: [],
3512
    sub: [],
3513
    sup: [],
3514
    strong: [],
3515
    u: [],
3516
    ul: []
3517
  };
3518
  function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) {
3519
    if (!unsafeHtml.length) {
3520
      return unsafeHtml;
3521
    }
3522

    
3523
    if (sanitizeFunction && typeof sanitizeFunction === 'function') {
3524
      return sanitizeFunction(unsafeHtml);
3525
    }
3526

    
3527
    const domParser = new window.DOMParser();
3528
    const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
3529
    const elements = [].concat(...createdDocument.body.querySelectorAll('*'));
3530

    
3531
    for (const element of elements) {
3532
      const elementName = element.nodeName.toLowerCase();
3533

    
3534
      if (!Object.keys(allowList).includes(elementName)) {
3535
        element.remove();
3536
        continue;
3537
      }
3538

    
3539
      const attributeList = [].concat(...element.attributes);
3540
      const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []);
3541

    
3542
      for (const attribute of attributeList) {
3543
        if (!allowedAttribute(attribute, allowedAttributes)) {
3544
          element.removeAttribute(attribute.nodeName);
3545
        }
3546
      }
3547
    }
3548

    
3549
    return createdDocument.body.innerHTML;
3550
  }
3551

    
3552
  /**
3553
   * --------------------------------------------------------------------------
3554
   * Bootstrap (v5.2.3): util/template-factory.js
3555
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3556
   * --------------------------------------------------------------------------
3557
   */
3558
  /**
3559
   * Constants
3560
   */
3561

    
3562
  const NAME$5 = 'TemplateFactory';
3563
  const Default$4 = {
3564
    allowList: DefaultAllowlist,
3565
    content: {},
3566
    // { selector : text ,  selector2 : text2 , }
3567
    extraClass: '',
3568
    html: false,
3569
    sanitize: true,
3570
    sanitizeFn: null,
3571
    template: '<div></div>'
3572
  };
3573
  const DefaultType$4 = {
3574
    allowList: 'object',
3575
    content: 'object',
3576
    extraClass: '(string|function)',
3577
    html: 'boolean',
3578
    sanitize: 'boolean',
3579
    sanitizeFn: '(null|function)',
3580
    template: 'string'
3581
  };
3582
  const DefaultContentType = {
3583
    entry: '(string|element|function|null)',
3584
    selector: '(string|element)'
3585
  };
3586
  /**
3587
   * Class definition
3588
   */
3589

    
3590
  class TemplateFactory extends Config {
3591
    constructor(config) {
3592
      super();
3593
      this._config = this._getConfig(config);
3594
    } // Getters
3595

    
3596

    
3597
    static get Default() {
3598
      return Default$4;
3599
    }
3600

    
3601
    static get DefaultType() {
3602
      return DefaultType$4;
3603
    }
3604

    
3605
    static get NAME() {
3606
      return NAME$5;
3607
    } // Public
3608

    
3609

    
3610
    getContent() {
3611
      return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean);
3612
    }
3613

    
3614
    hasContent() {
3615
      return this.getContent().length > 0;
3616
    }
3617

    
3618
    changeContent(content) {
3619
      this._checkContent(content);
3620

    
3621
      this._config.content = { ...this._config.content,
3622
        ...content
3623
      };
3624
      return this;
3625
    }
3626

    
3627
    toHtml() {
3628
      const templateWrapper = document.createElement('div');
3629
      templateWrapper.innerHTML = this._maybeSanitize(this._config.template);
3630

    
3631
      for (const [selector, text] of Object.entries(this._config.content)) {
3632
        this._setContent(templateWrapper, text, selector);
3633
      }
3634

    
3635
      const template = templateWrapper.children[0];
3636

    
3637
      const extraClass = this._resolvePossibleFunction(this._config.extraClass);
3638

    
3639
      if (extraClass) {
3640
        template.classList.add(...extraClass.split(' '));
3641
      }
3642

    
3643
      return template;
3644
    } // Private
3645

    
3646

    
3647
    _typeCheckConfig(config) {
3648
      super._typeCheckConfig(config);
3649

    
3650
      this._checkContent(config.content);
3651
    }
3652

    
3653
    _checkContent(arg) {
3654
      for (const [selector, content] of Object.entries(arg)) {
3655
        super._typeCheckConfig({
3656
          selector,
3657
          entry: content
3658
        }, DefaultContentType);
3659
      }
3660
    }
3661

    
3662
    _setContent(template, content, selector) {
3663
      const templateElement = SelectorEngine.findOne(selector, template);
3664

    
3665
      if (!templateElement) {
3666
        return;
3667
      }
3668

    
3669
      content = this._resolvePossibleFunction(content);
3670

    
3671
      if (!content) {
3672
        templateElement.remove();
3673
        return;
3674
      }
3675

    
3676
      if (isElement(content)) {
3677
        this._putElementInTemplate(getElement(content), templateElement);
3678

    
3679
        return;
3680
      }
3681

    
3682
      if (this._config.html) {
3683
        templateElement.innerHTML = this._maybeSanitize(content);
3684
        return;
3685
      }
3686

    
3687
      templateElement.textContent = content;
3688
    }
3689

    
3690
    _maybeSanitize(arg) {
3691
      return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg;
3692
    }
3693

    
3694
    _resolvePossibleFunction(arg) {
3695
      return typeof arg === 'function' ? arg(this) : arg;
3696
    }
3697

    
3698
    _putElementInTemplate(element, templateElement) {
3699
      if (this._config.html) {
3700
        templateElement.innerHTML = '';
3701
        templateElement.append(element);
3702
        return;
3703
      }
3704

    
3705
      templateElement.textContent = element.textContent;
3706
    }
3707

    
3708
  }
3709

    
3710
  /**
3711
   * --------------------------------------------------------------------------
3712
   * Bootstrap (v5.2.3): tooltip.js
3713
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
3714
   * --------------------------------------------------------------------------
3715
   */
3716
  /**
3717
   * Constants
3718
   */
3719

    
3720
  const NAME$4 = 'tooltip';
3721
  const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']);
3722
  const CLASS_NAME_FADE$2 = 'fade';
3723
  const CLASS_NAME_MODAL = 'modal';
3724
  const CLASS_NAME_SHOW$2 = 'show';
3725
  const SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
3726
  const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`;
3727
  const EVENT_MODAL_HIDE = 'hide.bs.modal';
3728
  const TRIGGER_HOVER = 'hover';
3729
  const TRIGGER_FOCUS = 'focus';
3730
  const TRIGGER_CLICK = 'click';
3731
  const TRIGGER_MANUAL = 'manual';
3732
  const EVENT_HIDE$2 = 'hide';
3733
  const EVENT_HIDDEN$2 = 'hidden';
3734
  const EVENT_SHOW$2 = 'show';
3735
  const EVENT_SHOWN$2 = 'shown';
3736
  const EVENT_INSERTED = 'inserted';
3737
  const EVENT_CLICK$1 = 'click';
3738
  const EVENT_FOCUSIN$1 = 'focusin';
3739
  const EVENT_FOCUSOUT$1 = 'focusout';
3740
  const EVENT_MOUSEENTER = 'mouseenter';
3741
  const EVENT_MOUSELEAVE = 'mouseleave';
3742
  const AttachmentMap = {
3743
    AUTO: 'auto',
3744
    TOP: 'top',
3745
    RIGHT: isRTL() ? 'left' : 'right',
3746
    BOTTOM: 'bottom',
3747
    LEFT: isRTL() ? 'right' : 'left'
3748
  };
3749
  const Default$3 = {
3750
    allowList: DefaultAllowlist,
3751
    animation: true,
3752
    boundary: 'clippingParents',
3753
    container: false,
3754
    customClass: '',
3755
    delay: 0,
3756
    fallbackPlacements: ['top', 'right', 'bottom', 'left'],
3757
    html: false,
3758
    offset: [0, 0],
3759
    placement: 'top',
3760
    popperConfig: null,
3761
    sanitize: true,
3762
    sanitizeFn: null,
3763
    selector: false,
3764
    template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>',
3765
    title: '',
3766
    trigger: 'hover focus'
3767
  };
3768
  const DefaultType$3 = {
3769
    allowList: 'object',
3770
    animation: 'boolean',
3771
    boundary: '(string|element)',
3772
    container: '(string|element|boolean)',
3773
    customClass: '(string|function)',
3774
    delay: '(number|object)',
3775
    fallbackPlacements: 'array',
3776
    html: 'boolean',
3777
    offset: '(array|string|function)',
3778
    placement: '(string|function)',
3779
    popperConfig: '(null|object|function)',
3780
    sanitize: 'boolean',
3781
    sanitizeFn: '(null|function)',
3782
    selector: '(string|boolean)',
3783
    template: 'string',
3784
    title: '(string|element|function)',
3785
    trigger: 'string'
3786
  };
3787
  /**
3788
   * Class definition
3789
   */
3790

    
3791
  class Tooltip extends BaseComponent {
3792
    constructor(element, config) {
3793
      if (typeof Popper__namespace === 'undefined') {
3794
        throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
3795
      }
3796

    
3797
      super(element, config); // Private
3798

    
3799
      this._isEnabled = true;
3800
      this._timeout = 0;
3801
      this._isHovered = null;
3802
      this._activeTrigger = {};
3803
      this._popper = null;
3804
      this._templateFactory = null;
3805
      this._newContent = null; // Protected
3806

    
3807
      this.tip = null;
3808

    
3809
      this._setListeners();
3810

    
3811
      if (!this._config.selector) {
3812
        this._fixTitle();
3813
      }
3814
    } // Getters
3815

    
3816

    
3817
    static get Default() {
3818
      return Default$3;
3819
    }
3820

    
3821
    static get DefaultType() {
3822
      return DefaultType$3;
3823
    }
3824

    
3825
    static get NAME() {
3826
      return NAME$4;
3827
    } // Public
3828

    
3829

    
3830
    enable() {
3831
      this._isEnabled = true;
3832
    }
3833

    
3834
    disable() {
3835
      this._isEnabled = false;
3836
    }
3837

    
3838
    toggleEnabled() {
3839
      this._isEnabled = !this._isEnabled;
3840
    }
3841

    
3842
    toggle() {
3843
      if (!this._isEnabled) {
3844
        return;
3845
      }
3846

    
3847
      this._activeTrigger.click = !this._activeTrigger.click;
3848

    
3849
      if (this._isShown()) {
3850
        this._leave();
3851

    
3852
        return;
3853
      }
3854

    
3855
      this._enter();
3856
    }
3857

    
3858
    dispose() {
3859
      clearTimeout(this._timeout);
3860
      EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
3861

    
3862
      if (this._element.getAttribute('data-bs-original-title')) {
3863
        this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title'));
3864
      }
3865

    
3866
      this._disposePopper();
3867

    
3868
      super.dispose();
3869
    }
3870

    
3871
    show() {
3872
      if (this._element.style.display === 'none') {
3873
        throw new Error('Please use show on visible elements');
3874
      }
3875

    
3876
      if (!(this._isWithContent() && this._isEnabled)) {
3877
        return;
3878
      }
3879

    
3880
      const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2));
3881
      const shadowRoot = findShadowRoot(this._element);
3882

    
3883
      const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element);
3884

    
3885
      if (showEvent.defaultPrevented || !isInTheDom) {
3886
        return;
3887
      } // todo v6 remove this OR make it optional
3888

    
3889

    
3890
      this._disposePopper();
3891

    
3892
      const tip = this._getTipElement();
3893

    
3894
      this._element.setAttribute('aria-describedby', tip.getAttribute('id'));
3895

    
3896
      const {
3897
        container
3898
      } = this._config;
3899

    
3900
      if (!this._element.ownerDocument.documentElement.contains(this.tip)) {
3901
        container.append(tip);
3902
        EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED));
3903
      }
3904

    
3905
      this._popper = this._createPopper(tip);
3906
      tip.classList.add(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we add extra
3907
      // empty mouseover listeners to the body's immediate children;
3908
      // only needed because of broken event delegation on iOS
3909
      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
3910

    
3911
      if ('ontouchstart' in document.documentElement) {
3912
        for (const element of [].concat(...document.body.children)) {
3913
          EventHandler.on(element, 'mouseover', noop);
3914
        }
3915
      }
3916

    
3917
      const complete = () => {
3918
        EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2));
3919

    
3920
        if (this._isHovered === false) {
3921
          this._leave();
3922
        }
3923

    
3924
        this._isHovered = false;
3925
      };
3926

    
3927
      this._queueCallback(complete, this.tip, this._isAnimated());
3928
    }
3929

    
3930
    hide() {
3931
      if (!this._isShown()) {
3932
        return;
3933
      }
3934

    
3935
      const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2));
3936

    
3937
      if (hideEvent.defaultPrevented) {
3938
        return;
3939
      }
3940

    
3941
      const tip = this._getTipElement();
3942

    
3943
      tip.classList.remove(CLASS_NAME_SHOW$2); // If this is a touch-enabled device we remove the extra
3944
      // empty mouseover listeners we added for iOS support
3945

    
3946
      if ('ontouchstart' in document.documentElement) {
3947
        for (const element of [].concat(...document.body.children)) {
3948
          EventHandler.off(element, 'mouseover', noop);
3949
        }
3950
      }
3951

    
3952
      this._activeTrigger[TRIGGER_CLICK] = false;
3953
      this._activeTrigger[TRIGGER_FOCUS] = false;
3954
      this._activeTrigger[TRIGGER_HOVER] = false;
3955
      this._isHovered = null; // it is a trick to support manual triggering
3956

    
3957
      const complete = () => {
3958
        if (this._isWithActiveTrigger()) {
3959
          return;
3960
        }
3961

    
3962
        if (!this._isHovered) {
3963
          this._disposePopper();
3964
        }
3965

    
3966
        this._element.removeAttribute('aria-describedby');
3967

    
3968
        EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2));
3969
      };
3970

    
3971
      this._queueCallback(complete, this.tip, this._isAnimated());
3972
    }
3973

    
3974
    update() {
3975
      if (this._popper) {
3976
        this._popper.update();
3977
      }
3978
    } // Protected
3979

    
3980

    
3981
    _isWithContent() {
3982
      return Boolean(this._getTitle());
3983
    }
3984

    
3985
    _getTipElement() {
3986
      if (!this.tip) {
3987
        this.tip = this._createTipElement(this._newContent || this._getContentForTemplate());
3988
      }
3989

    
3990
      return this.tip;
3991
    }
3992

    
3993
    _createTipElement(content) {
3994
      const tip = this._getTemplateFactory(content).toHtml(); // todo: remove this check on v6
3995

    
3996

    
3997
      if (!tip) {
3998
        return null;
3999
      }
4000

    
4001
      tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); // todo: on v6 the following can be achieved with CSS only
4002

    
4003
      tip.classList.add(`bs-${this.constructor.NAME}-auto`);
4004
      const tipId = getUID(this.constructor.NAME).toString();
4005
      tip.setAttribute('id', tipId);
4006

    
4007
      if (this._isAnimated()) {
4008
        tip.classList.add(CLASS_NAME_FADE$2);
4009
      }
4010

    
4011
      return tip;
4012
    }
4013

    
4014
    setContent(content) {
4015
      this._newContent = content;
4016

    
4017
      if (this._isShown()) {
4018
        this._disposePopper();
4019

    
4020
        this.show();
4021
      }
4022
    }
4023

    
4024
    _getTemplateFactory(content) {
4025
      if (this._templateFactory) {
4026
        this._templateFactory.changeContent(content);
4027
      } else {
4028
        this._templateFactory = new TemplateFactory({ ...this._config,
4029
          // the `content` var has to be after `this._config`
4030
          // to override config.content in case of popover
4031
          content,
4032
          extraClass: this._resolvePossibleFunction(this._config.customClass)
4033
        });
4034
      }
4035

    
4036
      return this._templateFactory;
4037
    }
4038

    
4039
    _getContentForTemplate() {
4040
      return {
4041
        [SELECTOR_TOOLTIP_INNER]: this._getTitle()
4042
      };
4043
    }
4044

    
4045
    _getTitle() {
4046
      return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title');
4047
    } // Private
4048

    
4049

    
4050
    _initializeOnDelegatedTarget(event) {
4051
      return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig());
4052
    }
4053

    
4054
    _isAnimated() {
4055
      return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2);
4056
    }
4057

    
4058
    _isShown() {
4059
      return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2);
4060
    }
4061

    
4062
    _createPopper(tip) {
4063
      const placement = typeof this._config.placement === 'function' ? this._config.placement.call(this, tip, this._element) : this._config.placement;
4064
      const attachment = AttachmentMap[placement.toUpperCase()];
4065
      return Popper__namespace.createPopper(this._element, tip, this._getPopperConfig(attachment));
4066
    }
4067

    
4068
    _getOffset() {
4069
      const {
4070
        offset
4071
      } = this._config;
4072

    
4073
      if (typeof offset === 'string') {
4074
        return offset.split(',').map(value => Number.parseInt(value, 10));
4075
      }
4076

    
4077
      if (typeof offset === 'function') {
4078
        return popperData => offset(popperData, this._element);
4079
      }
4080

    
4081
      return offset;
4082
    }
4083

    
4084
    _resolvePossibleFunction(arg) {
4085
      return typeof arg === 'function' ? arg.call(this._element) : arg;
4086
    }
4087

    
4088
    _getPopperConfig(attachment) {
4089
      const defaultBsPopperConfig = {
4090
        placement: attachment,
4091
        modifiers: [{
4092
          name: 'flip',
4093
          options: {
4094
            fallbackPlacements: this._config.fallbackPlacements
4095
          }
4096
        }, {
4097
          name: 'offset',
4098
          options: {
4099
            offset: this._getOffset()
4100
          }
4101
        }, {
4102
          name: 'preventOverflow',
4103
          options: {
4104
            boundary: this._config.boundary
4105
          }
4106
        }, {
4107
          name: 'arrow',
4108
          options: {
4109
            element: `.${this.constructor.NAME}-arrow`
4110
          }
4111
        }, {
4112
          name: 'preSetPlacement',
4113
          enabled: true,
4114
          phase: 'beforeMain',
4115
          fn: data => {
4116
            // Pre-set Popper's placement attribute in order to read the arrow sizes properly.
4117
            // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement
4118
            this._getTipElement().setAttribute('data-popper-placement', data.state.placement);
4119
          }
4120
        }]
4121
      };
4122
      return { ...defaultBsPopperConfig,
4123
        ...(typeof this._config.popperConfig === 'function' ? this._config.popperConfig(defaultBsPopperConfig) : this._config.popperConfig)
4124
      };
4125
    }
4126

    
4127
    _setListeners() {
4128
      const triggers = this._config.trigger.split(' ');
4129

    
4130
      for (const trigger of triggers) {
4131
        if (trigger === 'click') {
4132
          EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => {
4133
            const context = this._initializeOnDelegatedTarget(event);
4134

    
4135
            context.toggle();
4136
          });
4137
        } else if (trigger !== TRIGGER_MANUAL) {
4138
          const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1);
4139
          const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1);
4140
          EventHandler.on(this._element, eventIn, this._config.selector, event => {
4141
            const context = this._initializeOnDelegatedTarget(event);
4142

    
4143
            context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
4144

    
4145
            context._enter();
4146
          });
4147
          EventHandler.on(this._element, eventOut, this._config.selector, event => {
4148
            const context = this._initializeOnDelegatedTarget(event);
4149

    
4150
            context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget);
4151

    
4152
            context._leave();
4153
          });
4154
        }
4155
      }
4156

    
4157
      this._hideModalHandler = () => {
4158
        if (this._element) {
4159
          this.hide();
4160
        }
4161
      };
4162

    
4163
      EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler);
4164
    }
4165

    
4166
    _fixTitle() {
4167
      const title = this._element.getAttribute('title');
4168

    
4169
      if (!title) {
4170
        return;
4171
      }
4172

    
4173
      if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) {
4174
        this._element.setAttribute('aria-label', title);
4175
      }
4176

    
4177
      this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility
4178

    
4179

    
4180
      this._element.removeAttribute('title');
4181
    }
4182

    
4183
    _enter() {
4184
      if (this._isShown() || this._isHovered) {
4185
        this._isHovered = true;
4186
        return;
4187
      }
4188

    
4189
      this._isHovered = true;
4190

    
4191
      this._setTimeout(() => {
4192
        if (this._isHovered) {
4193
          this.show();
4194
        }
4195
      }, this._config.delay.show);
4196
    }
4197

    
4198
    _leave() {
4199
      if (this._isWithActiveTrigger()) {
4200
        return;
4201
      }
4202

    
4203
      this._isHovered = false;
4204

    
4205
      this._setTimeout(() => {
4206
        if (!this._isHovered) {
4207
          this.hide();
4208
        }
4209
      }, this._config.delay.hide);
4210
    }
4211

    
4212
    _setTimeout(handler, timeout) {
4213
      clearTimeout(this._timeout);
4214
      this._timeout = setTimeout(handler, timeout);
4215
    }
4216

    
4217
    _isWithActiveTrigger() {
4218
      return Object.values(this._activeTrigger).includes(true);
4219
    }
4220

    
4221
    _getConfig(config) {
4222
      const dataAttributes = Manipulator.getDataAttributes(this._element);
4223

    
4224
      for (const dataAttribute of Object.keys(dataAttributes)) {
4225
        if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) {
4226
          delete dataAttributes[dataAttribute];
4227
        }
4228
      }
4229

    
4230
      config = { ...dataAttributes,
4231
        ...(typeof config === 'object' && config ? config : {})
4232
      };
4233
      config = this._mergeConfigObj(config);
4234
      config = this._configAfterMerge(config);
4235

    
4236
      this._typeCheckConfig(config);
4237

    
4238
      return config;
4239
    }
4240

    
4241
    _configAfterMerge(config) {
4242
      config.container = config.container === false ? document.body : getElement(config.container);
4243

    
4244
      if (typeof config.delay === 'number') {
4245
        config.delay = {
4246
          show: config.delay,
4247
          hide: config.delay
4248
        };
4249
      }
4250

    
4251
      if (typeof config.title === 'number') {
4252
        config.title = config.title.toString();
4253
      }
4254

    
4255
      if (typeof config.content === 'number') {
4256
        config.content = config.content.toString();
4257
      }
4258

    
4259
      return config;
4260
    }
4261

    
4262
    _getDelegateConfig() {
4263
      const config = {};
4264

    
4265
      for (const key in this._config) {
4266
        if (this.constructor.Default[key] !== this._config[key]) {
4267
          config[key] = this._config[key];
4268
        }
4269
      }
4270

    
4271
      config.selector = false;
4272
      config.trigger = 'manual'; // In the future can be replaced with:
4273
      // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]])
4274
      // `Object.fromEntries(keysWithDifferentValues)`
4275

    
4276
      return config;
4277
    }
4278

    
4279
    _disposePopper() {
4280
      if (this._popper) {
4281
        this._popper.destroy();
4282

    
4283
        this._popper = null;
4284
      }
4285

    
4286
      if (this.tip) {
4287
        this.tip.remove();
4288
        this.tip = null;
4289
      }
4290
    } // Static
4291

    
4292

    
4293
    static jQueryInterface(config) {
4294
      return this.each(function () {
4295
        const data = Tooltip.getOrCreateInstance(this, config);
4296

    
4297
        if (typeof config !== 'string') {
4298
          return;
4299
        }
4300

    
4301
        if (typeof data[config] === 'undefined') {
4302
          throw new TypeError(`No method named "${config}"`);
4303
        }
4304

    
4305
        data[config]();
4306
      });
4307
    }
4308

    
4309
  }
4310
  /**
4311
   * jQuery
4312
   */
4313

    
4314

    
4315
  defineJQueryPlugin(Tooltip);
4316

    
4317
  /**
4318
   * --------------------------------------------------------------------------
4319
   * Bootstrap (v5.2.3): popover.js
4320
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4321
   * --------------------------------------------------------------------------
4322
   */
4323
  /**
4324
   * Constants
4325
   */
4326

    
4327
  const NAME$3 = 'popover';
4328
  const SELECTOR_TITLE = '.popover-header';
4329
  const SELECTOR_CONTENT = '.popover-body';
4330
  const Default$2 = { ...Tooltip.Default,
4331
    content: '',
4332
    offset: [0, 8],
4333
    placement: 'right',
4334
    template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>',
4335
    trigger: 'click'
4336
  };
4337
  const DefaultType$2 = { ...Tooltip.DefaultType,
4338
    content: '(null|string|element|function)'
4339
  };
4340
  /**
4341
   * Class definition
4342
   */
4343

    
4344
  class Popover extends Tooltip {
4345
    // Getters
4346
    static get Default() {
4347
      return Default$2;
4348
    }
4349

    
4350
    static get DefaultType() {
4351
      return DefaultType$2;
4352
    }
4353

    
4354
    static get NAME() {
4355
      return NAME$3;
4356
    } // Overrides
4357

    
4358

    
4359
    _isWithContent() {
4360
      return this._getTitle() || this._getContent();
4361
    } // Private
4362

    
4363

    
4364
    _getContentForTemplate() {
4365
      return {
4366
        [SELECTOR_TITLE]: this._getTitle(),
4367
        [SELECTOR_CONTENT]: this._getContent()
4368
      };
4369
    }
4370

    
4371
    _getContent() {
4372
      return this._resolvePossibleFunction(this._config.content);
4373
    } // Static
4374

    
4375

    
4376
    static jQueryInterface(config) {
4377
      return this.each(function () {
4378
        const data = Popover.getOrCreateInstance(this, config);
4379

    
4380
        if (typeof config !== 'string') {
4381
          return;
4382
        }
4383

    
4384
        if (typeof data[config] === 'undefined') {
4385
          throw new TypeError(`No method named "${config}"`);
4386
        }
4387

    
4388
        data[config]();
4389
      });
4390
    }
4391

    
4392
  }
4393
  /**
4394
   * jQuery
4395
   */
4396

    
4397

    
4398
  defineJQueryPlugin(Popover);
4399

    
4400
  /**
4401
   * --------------------------------------------------------------------------
4402
   * Bootstrap (v5.2.3): scrollspy.js
4403
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4404
   * --------------------------------------------------------------------------
4405
   */
4406
  /**
4407
   * Constants
4408
   */
4409

    
4410
  const NAME$2 = 'scrollspy';
4411
  const DATA_KEY$2 = 'bs.scrollspy';
4412
  const EVENT_KEY$2 = `.${DATA_KEY$2}`;
4413
  const DATA_API_KEY = '.data-api';
4414
  const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`;
4415
  const EVENT_CLICK = `click${EVENT_KEY$2}`;
4416
  const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`;
4417
  const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
4418
  const CLASS_NAME_ACTIVE$1 = 'active';
4419
  const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]';
4420
  const SELECTOR_TARGET_LINKS = '[href]';
4421
  const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
4422
  const SELECTOR_NAV_LINKS = '.nav-link';
4423
  const SELECTOR_NAV_ITEMS = '.nav-item';
4424
  const SELECTOR_LIST_ITEMS = '.list-group-item';
4425
  const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`;
4426
  const SELECTOR_DROPDOWN = '.dropdown';
4427
  const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
4428
  const Default$1 = {
4429
    offset: null,
4430
    // TODO: v6 @deprecated, keep it for backwards compatibility reasons
4431
    rootMargin: '0px 0px -25%',
4432
    smoothScroll: false,
4433
    target: null,
4434
    threshold: [0.1, 0.5, 1]
4435
  };
4436
  const DefaultType$1 = {
4437
    offset: '(number|null)',
4438
    // TODO v6 @deprecated, keep it for backwards compatibility reasons
4439
    rootMargin: 'string',
4440
    smoothScroll: 'boolean',
4441
    target: 'element',
4442
    threshold: 'array'
4443
  };
4444
  /**
4445
   * Class definition
4446
   */
4447

    
4448
  class ScrollSpy extends BaseComponent {
4449
    constructor(element, config) {
4450
      super(element, config); // this._element is the observablesContainer and config.target the menu links wrapper
4451

    
4452
      this._targetLinks = new Map();
4453
      this._observableSections = new Map();
4454
      this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element;
4455
      this._activeTarget = null;
4456
      this._observer = null;
4457
      this._previousScrollData = {
4458
        visibleEntryTop: 0,
4459
        parentScrollTop: 0
4460
      };
4461
      this.refresh(); // initialize
4462
    } // Getters
4463

    
4464

    
4465
    static get Default() {
4466
      return Default$1;
4467
    }
4468

    
4469
    static get DefaultType() {
4470
      return DefaultType$1;
4471
    }
4472

    
4473
    static get NAME() {
4474
      return NAME$2;
4475
    } // Public
4476

    
4477

    
4478
    refresh() {
4479
      this._initializeTargetsAndObservables();
4480

    
4481
      this._maybeEnableSmoothScroll();
4482

    
4483
      if (this._observer) {
4484
        this._observer.disconnect();
4485
      } else {
4486
        this._observer = this._getNewObserver();
4487
      }
4488

    
4489
      for (const section of this._observableSections.values()) {
4490
        this._observer.observe(section);
4491
      }
4492
    }
4493

    
4494
    dispose() {
4495
      this._observer.disconnect();
4496

    
4497
      super.dispose();
4498
    } // Private
4499

    
4500

    
4501
    _configAfterMerge(config) {
4502
      // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case
4503
      config.target = getElement(config.target) || document.body; // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only
4504

    
4505
      config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin;
4506

    
4507
      if (typeof config.threshold === 'string') {
4508
        config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value));
4509
      }
4510

    
4511
      return config;
4512
    }
4513

    
4514
    _maybeEnableSmoothScroll() {
4515
      if (!this._config.smoothScroll) {
4516
        return;
4517
      } // unregister any previous listeners
4518

    
4519

    
4520
      EventHandler.off(this._config.target, EVENT_CLICK);
4521
      EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => {
4522
        const observableSection = this._observableSections.get(event.target.hash);
4523

    
4524
        if (observableSection) {
4525
          event.preventDefault();
4526
          const root = this._rootElement || window;
4527
          const height = observableSection.offsetTop - this._element.offsetTop;
4528

    
4529
          if (root.scrollTo) {
4530
            root.scrollTo({
4531
              top: height,
4532
              behavior: 'smooth'
4533
            });
4534
            return;
4535
          } // Chrome 60 doesn't support `scrollTo`
4536

    
4537

    
4538
          root.scrollTop = height;
4539
        }
4540
      });
4541
    }
4542

    
4543
    _getNewObserver() {
4544
      const options = {
4545
        root: this._rootElement,
4546
        threshold: this._config.threshold,
4547
        rootMargin: this._config.rootMargin
4548
      };
4549
      return new IntersectionObserver(entries => this._observerCallback(entries), options);
4550
    } // The logic of selection
4551

    
4552

    
4553
    _observerCallback(entries) {
4554
      const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`);
4555

    
4556
      const activate = entry => {
4557
        this._previousScrollData.visibleEntryTop = entry.target.offsetTop;
4558

    
4559
        this._process(targetElement(entry));
4560
      };
4561

    
4562
      const parentScrollTop = (this._rootElement || document.documentElement).scrollTop;
4563
      const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop;
4564
      this._previousScrollData.parentScrollTop = parentScrollTop;
4565

    
4566
      for (const entry of entries) {
4567
        if (!entry.isIntersecting) {
4568
          this._activeTarget = null;
4569

    
4570
          this._clearActiveClass(targetElement(entry));
4571

    
4572
          continue;
4573
        }
4574

    
4575
        const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; // if we are scrolling down, pick the bigger offsetTop
4576

    
4577
        if (userScrollsDown && entryIsLowerThanPrevious) {
4578
          activate(entry); // if parent isn't scrolled, let's keep the first visible item, breaking the iteration
4579

    
4580
          if (!parentScrollTop) {
4581
            return;
4582
          }
4583

    
4584
          continue;
4585
        } // if we are scrolling up, pick the smallest offsetTop
4586

    
4587

    
4588
        if (!userScrollsDown && !entryIsLowerThanPrevious) {
4589
          activate(entry);
4590
        }
4591
      }
4592
    }
4593

    
4594
    _initializeTargetsAndObservables() {
4595
      this._targetLinks = new Map();
4596
      this._observableSections = new Map();
4597
      const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target);
4598

    
4599
      for (const anchor of targetLinks) {
4600
        // ensure that the anchor has an id and is not disabled
4601
        if (!anchor.hash || isDisabled(anchor)) {
4602
          continue;
4603
        }
4604

    
4605
        const observableSection = SelectorEngine.findOne(anchor.hash, this._element); // ensure that the observableSection exists & is visible
4606

    
4607
        if (isVisible(observableSection)) {
4608
          this._targetLinks.set(anchor.hash, anchor);
4609

    
4610
          this._observableSections.set(anchor.hash, observableSection);
4611
        }
4612
      }
4613
    }
4614

    
4615
    _process(target) {
4616
      if (this._activeTarget === target) {
4617
        return;
4618
      }
4619

    
4620
      this._clearActiveClass(this._config.target);
4621

    
4622
      this._activeTarget = target;
4623
      target.classList.add(CLASS_NAME_ACTIVE$1);
4624

    
4625
      this._activateParents(target);
4626

    
4627
      EventHandler.trigger(this._element, EVENT_ACTIVATE, {
4628
        relatedTarget: target
4629
      });
4630
    }
4631

    
4632
    _activateParents(target) {
4633
      // Activate dropdown parents
4634
      if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) {
4635
        SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1);
4636
        return;
4637
      }
4638

    
4639
      for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) {
4640
        // Set triggered links parents as active
4641
        // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
4642
        for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) {
4643
          item.classList.add(CLASS_NAME_ACTIVE$1);
4644
        }
4645
      }
4646
    }
4647

    
4648
    _clearActiveClass(parent) {
4649
      parent.classList.remove(CLASS_NAME_ACTIVE$1);
4650
      const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent);
4651

    
4652
      for (const node of activeNodes) {
4653
        node.classList.remove(CLASS_NAME_ACTIVE$1);
4654
      }
4655
    } // Static
4656

    
4657

    
4658
    static jQueryInterface(config) {
4659
      return this.each(function () {
4660
        const data = ScrollSpy.getOrCreateInstance(this, config);
4661

    
4662
        if (typeof config !== 'string') {
4663
          return;
4664
        }
4665

    
4666
        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
4667
          throw new TypeError(`No method named "${config}"`);
4668
        }
4669

    
4670
        data[config]();
4671
      });
4672
    }
4673

    
4674
  }
4675
  /**
4676
   * Data API implementation
4677
   */
4678

    
4679

    
4680
  EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => {
4681
    for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) {
4682
      ScrollSpy.getOrCreateInstance(spy);
4683
    }
4684
  });
4685
  /**
4686
   * jQuery
4687
   */
4688

    
4689
  defineJQueryPlugin(ScrollSpy);
4690

    
4691
  /**
4692
   * --------------------------------------------------------------------------
4693
   * Bootstrap (v5.2.3): tab.js
4694
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
4695
   * --------------------------------------------------------------------------
4696
   */
4697
  /**
4698
   * Constants
4699
   */
4700

    
4701
  const NAME$1 = 'tab';
4702
  const DATA_KEY$1 = 'bs.tab';
4703
  const EVENT_KEY$1 = `.${DATA_KEY$1}`;
4704
  const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`;
4705
  const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`;
4706
  const EVENT_SHOW$1 = `show${EVENT_KEY$1}`;
4707
  const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`;
4708
  const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`;
4709
  const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`;
4710
  const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`;
4711
  const ARROW_LEFT_KEY = 'ArrowLeft';
4712
  const ARROW_RIGHT_KEY = 'ArrowRight';
4713
  const ARROW_UP_KEY = 'ArrowUp';
4714
  const ARROW_DOWN_KEY = 'ArrowDown';
4715
  const CLASS_NAME_ACTIVE = 'active';
4716
  const CLASS_NAME_FADE$1 = 'fade';
4717
  const CLASS_NAME_SHOW$1 = 'show';
4718
  const CLASS_DROPDOWN = 'dropdown';
4719
  const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
4720
  const SELECTOR_DROPDOWN_MENU = '.dropdown-menu';
4721
  const NOT_SELECTOR_DROPDOWN_TOGGLE = ':not(.dropdown-toggle)';
4722
  const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]';
4723
  const SELECTOR_OUTER = '.nav-item, .list-group-item';
4724
  const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`;
4725
  const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // todo:v6: could be only `tab`
4726

    
4727
  const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`;
4728
  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"]`;
4729
  /**
4730
   * Class definition
4731
   */
4732

    
4733
  class Tab extends BaseComponent {
4734
    constructor(element) {
4735
      super(element);
4736
      this._parent = this._element.closest(SELECTOR_TAB_PANEL);
4737

    
4738
      if (!this._parent) {
4739
        return; // todo: should Throw exception on v6
4740
        // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`)
4741
      } // Set up initial aria attributes
4742

    
4743

    
4744
      this._setInitialAttributes(this._parent, this._getChildren());
4745

    
4746
      EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event));
4747
    } // Getters
4748

    
4749

    
4750
    static get NAME() {
4751
      return NAME$1;
4752
    } // Public
4753

    
4754

    
4755
    show() {
4756
      // Shows this elem and deactivate the active sibling if exists
4757
      const innerElem = this._element;
4758

    
4759
      if (this._elemIsActive(innerElem)) {
4760
        return;
4761
      } // Search for active tab on same parent to deactivate it
4762

    
4763

    
4764
      const active = this._getActiveElem();
4765

    
4766
      const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, {
4767
        relatedTarget: innerElem
4768
      }) : null;
4769
      const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, {
4770
        relatedTarget: active
4771
      });
4772

    
4773
      if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) {
4774
        return;
4775
      }
4776

    
4777
      this._deactivate(active, innerElem);
4778

    
4779
      this._activate(innerElem, active);
4780
    } // Private
4781

    
4782

    
4783
    _activate(element, relatedElem) {
4784
      if (!element) {
4785
        return;
4786
      }
4787

    
4788
      element.classList.add(CLASS_NAME_ACTIVE);
4789

    
4790
      this._activate(getElementFromSelector(element)); // Search and activate/show the proper section
4791

    
4792

    
4793
      const complete = () => {
4794
        if (element.getAttribute('role') !== 'tab') {
4795
          element.classList.add(CLASS_NAME_SHOW$1);
4796
          return;
4797
        }
4798

    
4799
        element.removeAttribute('tabindex');
4800
        element.setAttribute('aria-selected', true);
4801

    
4802
        this._toggleDropDown(element, true);
4803

    
4804
        EventHandler.trigger(element, EVENT_SHOWN$1, {
4805
          relatedTarget: relatedElem
4806
        });
4807
      };
4808

    
4809
      this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));
4810
    }
4811

    
4812
    _deactivate(element, relatedElem) {
4813
      if (!element) {
4814
        return;
4815
      }
4816

    
4817
      element.classList.remove(CLASS_NAME_ACTIVE);
4818
      element.blur();
4819

    
4820
      this._deactivate(getElementFromSelector(element)); // Search and deactivate the shown section too
4821

    
4822

    
4823
      const complete = () => {
4824
        if (element.getAttribute('role') !== 'tab') {
4825
          element.classList.remove(CLASS_NAME_SHOW$1);
4826
          return;
4827
        }
4828

    
4829
        element.setAttribute('aria-selected', false);
4830
        element.setAttribute('tabindex', '-1');
4831

    
4832
        this._toggleDropDown(element, false);
4833

    
4834
        EventHandler.trigger(element, EVENT_HIDDEN$1, {
4835
          relatedTarget: relatedElem
4836
        });
4837
      };
4838

    
4839
      this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1));
4840
    }
4841

    
4842
    _keydown(event) {
4843
      if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY].includes(event.key)) {
4844
        return;
4845
      }
4846

    
4847
      event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page
4848

    
4849
      event.preventDefault();
4850
      const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key);
4851
      const nextActiveElement = getNextActiveElement(this._getChildren().filter(element => !isDisabled(element)), event.target, isNext, true);
4852

    
4853
      if (nextActiveElement) {
4854
        nextActiveElement.focus({
4855
          preventScroll: true
4856
        });
4857
        Tab.getOrCreateInstance(nextActiveElement).show();
4858
      }
4859
    }
4860

    
4861
    _getChildren() {
4862
      // collection of inner elements
4863
      return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent);
4864
    }
4865

    
4866
    _getActiveElem() {
4867
      return this._getChildren().find(child => this._elemIsActive(child)) || null;
4868
    }
4869

    
4870
    _setInitialAttributes(parent, children) {
4871
      this._setAttributeIfNotExists(parent, 'role', 'tablist');
4872

    
4873
      for (const child of children) {
4874
        this._setInitialAttributesOnChild(child);
4875
      }
4876
    }
4877

    
4878
    _setInitialAttributesOnChild(child) {
4879
      child = this._getInnerElement(child);
4880

    
4881
      const isActive = this._elemIsActive(child);
4882

    
4883
      const outerElem = this._getOuterElement(child);
4884

    
4885
      child.setAttribute('aria-selected', isActive);
4886

    
4887
      if (outerElem !== child) {
4888
        this._setAttributeIfNotExists(outerElem, 'role', 'presentation');
4889
      }
4890

    
4891
      if (!isActive) {
4892
        child.setAttribute('tabindex', '-1');
4893
      }
4894

    
4895
      this._setAttributeIfNotExists(child, 'role', 'tab'); // set attributes to the related panel too
4896

    
4897

    
4898
      this._setInitialAttributesOnTargetPanel(child);
4899
    }
4900

    
4901
    _setInitialAttributesOnTargetPanel(child) {
4902
      const target = getElementFromSelector(child);
4903

    
4904
      if (!target) {
4905
        return;
4906
      }
4907

    
4908
      this._setAttributeIfNotExists(target, 'role', 'tabpanel');
4909

    
4910
      if (child.id) {
4911
        this._setAttributeIfNotExists(target, 'aria-labelledby', `#${child.id}`);
4912
      }
4913
    }
4914

    
4915
    _toggleDropDown(element, open) {
4916
      const outerElem = this._getOuterElement(element);
4917

    
4918
      if (!outerElem.classList.contains(CLASS_DROPDOWN)) {
4919
        return;
4920
      }
4921

    
4922
      const toggle = (selector, className) => {
4923
        const element = SelectorEngine.findOne(selector, outerElem);
4924

    
4925
        if (element) {
4926
          element.classList.toggle(className, open);
4927
        }
4928
      };
4929

    
4930
      toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE);
4931
      toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1);
4932
      outerElem.setAttribute('aria-expanded', open);
4933
    }
4934

    
4935
    _setAttributeIfNotExists(element, attribute, value) {
4936
      if (!element.hasAttribute(attribute)) {
4937
        element.setAttribute(attribute, value);
4938
      }
4939
    }
4940

    
4941
    _elemIsActive(elem) {
4942
      return elem.classList.contains(CLASS_NAME_ACTIVE);
4943
    } // Try to get the inner element (usually the .nav-link)
4944

    
4945

    
4946
    _getInnerElement(elem) {
4947
      return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem);
4948
    } // Try to get the outer element (usually the .nav-item)
4949

    
4950

    
4951
    _getOuterElement(elem) {
4952
      return elem.closest(SELECTOR_OUTER) || elem;
4953
    } // Static
4954

    
4955

    
4956
    static jQueryInterface(config) {
4957
      return this.each(function () {
4958
        const data = Tab.getOrCreateInstance(this);
4959

    
4960
        if (typeof config !== 'string') {
4961
          return;
4962
        }
4963

    
4964
        if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
4965
          throw new TypeError(`No method named "${config}"`);
4966
        }
4967

    
4968
        data[config]();
4969
      });
4970
    }
4971

    
4972
  }
4973
  /**
4974
   * Data API implementation
4975
   */
4976

    
4977

    
4978
  EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
4979
    if (['A', 'AREA'].includes(this.tagName)) {
4980
      event.preventDefault();
4981
    }
4982

    
4983
    if (isDisabled(this)) {
4984
      return;
4985
    }
4986

    
4987
    Tab.getOrCreateInstance(this).show();
4988
  });
4989
  /**
4990
   * Initialize on focus
4991
   */
4992

    
4993
  EventHandler.on(window, EVENT_LOAD_DATA_API, () => {
4994
    for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) {
4995
      Tab.getOrCreateInstance(element);
4996
    }
4997
  });
4998
  /**
4999
   * jQuery
5000
   */
5001

    
5002
  defineJQueryPlugin(Tab);
5003

    
5004
  /**
5005
   * --------------------------------------------------------------------------
5006
   * Bootstrap (v5.2.3): toast.js
5007
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5008
   * --------------------------------------------------------------------------
5009
   */
5010
  /**
5011
   * Constants
5012
   */
5013

    
5014
  const NAME = 'toast';
5015
  const DATA_KEY = 'bs.toast';
5016
  const EVENT_KEY = `.${DATA_KEY}`;
5017
  const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`;
5018
  const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`;
5019
  const EVENT_FOCUSIN = `focusin${EVENT_KEY}`;
5020
  const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`;
5021
  const EVENT_HIDE = `hide${EVENT_KEY}`;
5022
  const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
5023
  const EVENT_SHOW = `show${EVENT_KEY}`;
5024
  const EVENT_SHOWN = `shown${EVENT_KEY}`;
5025
  const CLASS_NAME_FADE = 'fade';
5026
  const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility
5027

    
5028
  const CLASS_NAME_SHOW = 'show';
5029
  const CLASS_NAME_SHOWING = 'showing';
5030
  const DefaultType = {
5031
    animation: 'boolean',
5032
    autohide: 'boolean',
5033
    delay: 'number'
5034
  };
5035
  const Default = {
5036
    animation: true,
5037
    autohide: true,
5038
    delay: 5000
5039
  };
5040
  /**
5041
   * Class definition
5042
   */
5043

    
5044
  class Toast extends BaseComponent {
5045
    constructor(element, config) {
5046
      super(element, config);
5047
      this._timeout = null;
5048
      this._hasMouseInteraction = false;
5049
      this._hasKeyboardInteraction = false;
5050

    
5051
      this._setListeners();
5052
    } // Getters
5053

    
5054

    
5055
    static get Default() {
5056
      return Default;
5057
    }
5058

    
5059
    static get DefaultType() {
5060
      return DefaultType;
5061
    }
5062

    
5063
    static get NAME() {
5064
      return NAME;
5065
    } // Public
5066

    
5067

    
5068
    show() {
5069
      const showEvent = EventHandler.trigger(this._element, EVENT_SHOW);
5070

    
5071
      if (showEvent.defaultPrevented) {
5072
        return;
5073
      }
5074

    
5075
      this._clearTimeout();
5076

    
5077
      if (this._config.animation) {
5078
        this._element.classList.add(CLASS_NAME_FADE);
5079
      }
5080

    
5081
      const complete = () => {
5082
        this._element.classList.remove(CLASS_NAME_SHOWING);
5083

    
5084
        EventHandler.trigger(this._element, EVENT_SHOWN);
5085

    
5086
        this._maybeScheduleHide();
5087
      };
5088

    
5089
      this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated
5090

    
5091

    
5092
      reflow(this._element);
5093

    
5094
      this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING);
5095

    
5096
      this._queueCallback(complete, this._element, this._config.animation);
5097
    }
5098

    
5099
    hide() {
5100
      if (!this.isShown()) {
5101
        return;
5102
      }
5103

    
5104
      const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE);
5105

    
5106
      if (hideEvent.defaultPrevented) {
5107
        return;
5108
      }
5109

    
5110
      const complete = () => {
5111
        this._element.classList.add(CLASS_NAME_HIDE); // @deprecated
5112

    
5113

    
5114
        this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW);
5115

    
5116
        EventHandler.trigger(this._element, EVENT_HIDDEN);
5117
      };
5118

    
5119
      this._element.classList.add(CLASS_NAME_SHOWING);
5120

    
5121
      this._queueCallback(complete, this._element, this._config.animation);
5122
    }
5123

    
5124
    dispose() {
5125
      this._clearTimeout();
5126

    
5127
      if (this.isShown()) {
5128
        this._element.classList.remove(CLASS_NAME_SHOW);
5129
      }
5130

    
5131
      super.dispose();
5132
    }
5133

    
5134
    isShown() {
5135
      return this._element.classList.contains(CLASS_NAME_SHOW);
5136
    } // Private
5137

    
5138

    
5139
    _maybeScheduleHide() {
5140
      if (!this._config.autohide) {
5141
        return;
5142
      }
5143

    
5144
      if (this._hasMouseInteraction || this._hasKeyboardInteraction) {
5145
        return;
5146
      }
5147

    
5148
      this._timeout = setTimeout(() => {
5149
        this.hide();
5150
      }, this._config.delay);
5151
    }
5152

    
5153
    _onInteraction(event, isInteracting) {
5154
      switch (event.type) {
5155
        case 'mouseover':
5156
        case 'mouseout':
5157
          {
5158
            this._hasMouseInteraction = isInteracting;
5159
            break;
5160
          }
5161

    
5162
        case 'focusin':
5163
        case 'focusout':
5164
          {
5165
            this._hasKeyboardInteraction = isInteracting;
5166
            break;
5167
          }
5168
      }
5169

    
5170
      if (isInteracting) {
5171
        this._clearTimeout();
5172

    
5173
        return;
5174
      }
5175

    
5176
      const nextElement = event.relatedTarget;
5177

    
5178
      if (this._element === nextElement || this._element.contains(nextElement)) {
5179
        return;
5180
      }
5181

    
5182
      this._maybeScheduleHide();
5183
    }
5184

    
5185
    _setListeners() {
5186
      EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true));
5187
      EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false));
5188
      EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true));
5189
      EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false));
5190
    }
5191

    
5192
    _clearTimeout() {
5193
      clearTimeout(this._timeout);
5194
      this._timeout = null;
5195
    } // Static
5196

    
5197

    
5198
    static jQueryInterface(config) {
5199
      return this.each(function () {
5200
        const data = Toast.getOrCreateInstance(this, config);
5201

    
5202
        if (typeof config === 'string') {
5203
          if (typeof data[config] === 'undefined') {
5204
            throw new TypeError(`No method named "${config}"`);
5205
          }
5206

    
5207
          data[config](this);
5208
        }
5209
      });
5210
    }
5211

    
5212
  }
5213
  /**
5214
   * Data API implementation
5215
   */
5216

    
5217

    
5218
  enableDismissTrigger(Toast);
5219
  /**
5220
   * jQuery
5221
   */
5222

    
5223
  defineJQueryPlugin(Toast);
5224

    
5225
  /**
5226
   * --------------------------------------------------------------------------
5227
   * Bootstrap (v5.2.3): index.umd.js
5228
   * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5229
   * --------------------------------------------------------------------------
5230
   */
5231
  const index_umd = {
5232
    Alert,
5233
    Button,
5234
    Carousel,
5235
    Collapse,
5236
    Dropdown,
5237
    Modal,
5238
    Offcanvas,
5239
    Popover,
5240
    ScrollSpy,
5241
    Tab,
5242
    Toast,
5243
    Tooltip
5244
  };
5245

    
5246
  return index_umd;
5247

    
5248
}));
5249
//# sourceMappingURL=bootstrap.js.map
클립보드 이미지 추가 (최대 크기: 500 MB)