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