Subversion Repositories oidplus

Rev

Rev 1339 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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