Subversion Repositories oidplus

Rev

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

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