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