bootstrap.bundle.js (207819B)
1 /*! 2 * Bootstrap v5.3.3 (https://getbootstrap.com/) 3 * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) 4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5 */ 6 (function (global, factory) { 7 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 8 typeof define === 'function' && define.amd ? define(factory) : 9 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrap = factory()); 10 })(this, (function () { 'use strict'; 11 12 /** 13 * -------------------------------------------------------------------------- 14 * Bootstrap dom/data.js 15 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 16 * -------------------------------------------------------------------------- 17 */ 18 19 /** 20 * Constants 21 */ 22 23 const elementMap = new Map(); 24 const Data = { 25 set(element, key, instance) { 26 if (!elementMap.has(element)) { 27 elementMap.set(element, new Map()); 28 } 29 const instanceMap = elementMap.get(element); 30 31 // make it clear we only want one instance per element 32 // can be removed later when multiple key/instances are fine to be used 33 if (!instanceMap.has(key) && instanceMap.size !== 0) { 34 // eslint-disable-next-line no-console 35 console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(instanceMap.keys())[0]}.`); 36 return; 37 } 38 instanceMap.set(key, instance); 39 }, 40 get(element, key) { 41 if (elementMap.has(element)) { 42 return elementMap.get(element).get(key) || null; 43 } 44 return null; 45 }, 46 remove(element, key) { 47 if (!elementMap.has(element)) { 48 return; 49 } 50 const instanceMap = elementMap.get(element); 51 instanceMap.delete(key); 52 53 // free up element references if there are no instances left for an element 54 if (instanceMap.size === 0) { 55 elementMap.delete(element); 56 } 57 } 58 }; 59 60 /** 61 * -------------------------------------------------------------------------- 62 * Bootstrap util/index.js 63 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 64 * -------------------------------------------------------------------------- 65 */ 66 67 const MAX_UID = 1000000; 68 const MILLISECONDS_MULTIPLIER = 1000; 69 const TRANSITION_END = 'transitionend'; 70 71 /** 72 * Properly escape IDs selectors to handle weird IDs 73 * @param {string} selector 74 * @returns {string} 75 */ 76 const parseSelector = selector => { 77 if (selector && window.CSS && window.CSS.escape) { 78 // document.querySelector needs escaping to handle IDs (html5+) containing for instance / 79 selector = selector.replace(/#([^\s"#']+)/g, (match, id) => `#${CSS.escape(id)}`); 80 } 81 return selector; 82 }; 83 84 // Shout-out Angus Croll (https://goo.gl/pxwQGp) 85 const toType = object => { 86 if (object === null || object === undefined) { 87 return `${object}`; 88 } 89 return Object.prototype.toString.call(object).match(/\s([a-z]+)/i)[1].toLowerCase(); 90 }; 91 92 /** 93 * Public Util API 94 */ 95 96 const getUID = prefix => { 97 do { 98 prefix += Math.floor(Math.random() * MAX_UID); 99 } while (document.getElementById(prefix)); 100 return prefix; 101 }; 102 const getTransitionDurationFromElement = element => { 103 if (!element) { 104 return 0; 105 } 106 107 // Get transition-duration of the element 108 let { 109 transitionDuration, 110 transitionDelay 111 } = window.getComputedStyle(element); 112 const floatTransitionDuration = Number.parseFloat(transitionDuration); 113 const floatTransitionDelay = Number.parseFloat(transitionDelay); 114 115 // Return 0 if element or transition duration is not found 116 if (!floatTransitionDuration && !floatTransitionDelay) { 117 return 0; 118 } 119 120 // If multiple durations are defined, take the first 121 transitionDuration = transitionDuration.split(',')[0]; 122 transitionDelay = transitionDelay.split(',')[0]; 123 return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; 124 }; 125 const triggerTransitionEnd = element => { 126 element.dispatchEvent(new Event(TRANSITION_END)); 127 }; 128 const isElement$1 = object => { 129 if (!object || typeof object !== 'object') { 130 return false; 131 } 132 if (typeof object.jquery !== 'undefined') { 133 object = object[0]; 134 } 135 return typeof object.nodeType !== 'undefined'; 136 }; 137 const getElement = object => { 138 // it's a jQuery object or a node element 139 if (isElement$1(object)) { 140 return object.jquery ? object[0] : object; 141 } 142 if (typeof object === 'string' && object.length > 0) { 143 return document.querySelector(parseSelector(object)); 144 } 145 return null; 146 }; 147 const isVisible = element => { 148 if (!isElement$1(element) || element.getClientRects().length === 0) { 149 return false; 150 } 151 const elementIsVisible = getComputedStyle(element).getPropertyValue('visibility') === 'visible'; 152 // Handle `details` element as its content may falsie appear visible when it is closed 153 const closedDetails = element.closest('details:not([open])'); 154 if (!closedDetails) { 155 return elementIsVisible; 156 } 157 if (closedDetails !== element) { 158 const summary = element.closest('summary'); 159 if (summary && summary.parentNode !== closedDetails) { 160 return false; 161 } 162 if (summary === null) { 163 return false; 164 } 165 } 166 return elementIsVisible; 167 }; 168 const isDisabled = element => { 169 if (!element || element.nodeType !== Node.ELEMENT_NODE) { 170 return true; 171 } 172 if (element.classList.contains('disabled')) { 173 return true; 174 } 175 if (typeof element.disabled !== 'undefined') { 176 return element.disabled; 177 } 178 return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false'; 179 }; 180 const findShadowRoot = element => { 181 if (!document.documentElement.attachShadow) { 182 return null; 183 } 184 185 // Can find the shadow root otherwise it'll return the document 186 if (typeof element.getRootNode === 'function') { 187 const root = element.getRootNode(); 188 return root instanceof ShadowRoot ? root : null; 189 } 190 if (element instanceof ShadowRoot) { 191 return element; 192 } 193 194 // when we don't find a shadow root 195 if (!element.parentNode) { 196 return null; 197 } 198 return findShadowRoot(element.parentNode); 199 }; 200 const noop = () => {}; 201 202 /** 203 * Trick to restart an element's animation 204 * 205 * @param {HTMLElement} element 206 * @return void 207 * 208 * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation 209 */ 210 const reflow = element => { 211 element.offsetHeight; // eslint-disable-line no-unused-expressions 212 }; 213 const getjQuery = () => { 214 if (window.jQuery && !document.body.hasAttribute('data-bs-no-jquery')) { 215 return window.jQuery; 216 } 217 return null; 218 }; 219 const DOMContentLoadedCallbacks = []; 220 const onDOMContentLoaded = callback => { 221 if (document.readyState === 'loading') { 222 // add listener on the first call when the document is in loading state 223 if (!DOMContentLoadedCallbacks.length) { 224 document.addEventListener('DOMContentLoaded', () => { 225 for (const callback of DOMContentLoadedCallbacks) { 226 callback(); 227 } 228 }); 229 } 230 DOMContentLoadedCallbacks.push(callback); 231 } else { 232 callback(); 233 } 234 }; 235 const isRTL = () => document.documentElement.dir === 'rtl'; 236 const defineJQueryPlugin = plugin => { 237 onDOMContentLoaded(() => { 238 const $ = getjQuery(); 239 /* istanbul ignore if */ 240 if ($) { 241 const name = plugin.NAME; 242 const JQUERY_NO_CONFLICT = $.fn[name]; 243 $.fn[name] = plugin.jQueryInterface; 244 $.fn[name].Constructor = plugin; 245 $.fn[name].noConflict = () => { 246 $.fn[name] = JQUERY_NO_CONFLICT; 247 return plugin.jQueryInterface; 248 }; 249 } 250 }); 251 }; 252 const execute = (possibleCallback, args = [], defaultValue = possibleCallback) => { 253 return typeof possibleCallback === 'function' ? possibleCallback(...args) : defaultValue; 254 }; 255 const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => { 256 if (!waitForTransition) { 257 execute(callback); 258 return; 259 } 260 const durationPadding = 5; 261 const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding; 262 let called = false; 263 const handler = ({ 264 target 265 }) => { 266 if (target !== transitionElement) { 267 return; 268 } 269 called = true; 270 transitionElement.removeEventListener(TRANSITION_END, handler); 271 execute(callback); 272 }; 273 transitionElement.addEventListener(TRANSITION_END, handler); 274 setTimeout(() => { 275 if (!called) { 276 triggerTransitionEnd(transitionElement); 277 } 278 }, emulatedDuration); 279 }; 280 281 /** 282 * Return the previous/next element of a list. 283 * 284 * @param {array} list The list of elements 285 * @param activeElement The active element 286 * @param shouldGetNext Choose to get next or previous element 287 * @param isCycleAllowed 288 * @return {Element|elem} The proper element 289 */ 290 const getNextActiveElement = (list, activeElement, shouldGetNext, isCycleAllowed) => { 291 const listLength = list.length; 292 let index = list.indexOf(activeElement); 293 294 // if the element does not exist in the list return an element 295 // depending on the direction and if cycle is allowed 296 if (index === -1) { 297 return !shouldGetNext && isCycleAllowed ? list[listLength - 1] : list[0]; 298 } 299 index += shouldGetNext ? 1 : -1; 300 if (isCycleAllowed) { 301 index = (index + listLength) % listLength; 302 } 303 return list[Math.max(0, Math.min(index, listLength - 1))]; 304 }; 305 306 /** 307 * -------------------------------------------------------------------------- 308 * Bootstrap dom/event-handler.js 309 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 310 * -------------------------------------------------------------------------- 311 */ 312 313 314 /** 315 * Constants 316 */ 317 318 const namespaceRegex = /[^.]*(?=\..*)\.|.*/; 319 const stripNameRegex = /\..*/; 320 const stripUidRegex = /::\d+$/; 321 const eventRegistry = {}; // Events storage 322 let uidEvent = 1; 323 const customEvents = { 324 mouseenter: 'mouseover', 325 mouseleave: 'mouseout' 326 }; 327 const nativeEvents = new Set(['click', 'dblclick', 'mouseup', 'mousedown', 'contextmenu', 'mousewheel', 'DOMMouseScroll', 'mouseover', 'mouseout', 'mousemove', 'selectstart', 'selectend', 'keydown', 'keypress', 'keyup', 'orientationchange', 'touchstart', 'touchmove', 'touchend', 'touchcancel', 'pointerdown', 'pointermove', 'pointerup', 'pointerleave', 'pointercancel', 'gesturestart', 'gesturechange', 'gestureend', 'focus', 'blur', 'change', 'reset', 'select', 'submit', 'focusin', 'focusout', 'load', 'unload', 'beforeunload', 'resize', 'move', 'DOMContentLoaded', 'readystatechange', 'error', 'abort', 'scroll']); 328 329 /** 330 * Private methods 331 */ 332 333 function makeEventUid(element, uid) { 334 return uid && `${uid}::${uidEvent++}` || element.uidEvent || uidEvent++; 335 } 336 function getElementEvents(element) { 337 const uid = makeEventUid(element); 338 element.uidEvent = uid; 339 eventRegistry[uid] = eventRegistry[uid] || {}; 340 return eventRegistry[uid]; 341 } 342 function bootstrapHandler(element, fn) { 343 return function handler(event) { 344 hydrateObj(event, { 345 delegateTarget: element 346 }); 347 if (handler.oneOff) { 348 EventHandler.off(element, event.type, fn); 349 } 350 return fn.apply(element, [event]); 351 }; 352 } 353 function bootstrapDelegationHandler(element, selector, fn) { 354 return function handler(event) { 355 const domElements = element.querySelectorAll(selector); 356 for (let { 357 target 358 } = event; target && target !== this; target = target.parentNode) { 359 for (const domElement of domElements) { 360 if (domElement !== target) { 361 continue; 362 } 363 hydrateObj(event, { 364 delegateTarget: target 365 }); 366 if (handler.oneOff) { 367 EventHandler.off(element, event.type, selector, fn); 368 } 369 return fn.apply(target, [event]); 370 } 371 } 372 }; 373 } 374 function findHandler(events, callable, delegationSelector = null) { 375 return Object.values(events).find(event => event.callable === callable && event.delegationSelector === delegationSelector); 376 } 377 function normalizeParameters(originalTypeEvent, handler, delegationFunction) { 378 const isDelegated = typeof handler === 'string'; 379 // TODO: tooltip passes `false` instead of selector, so we need to check 380 const callable = isDelegated ? delegationFunction : handler || delegationFunction; 381 let typeEvent = getTypeEvent(originalTypeEvent); 382 if (!nativeEvents.has(typeEvent)) { 383 typeEvent = originalTypeEvent; 384 } 385 return [isDelegated, callable, typeEvent]; 386 } 387 function addHandler(element, originalTypeEvent, handler, delegationFunction, oneOff) { 388 if (typeof originalTypeEvent !== 'string' || !element) { 389 return; 390 } 391 let [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 392 393 // in case of mouseenter or mouseleave wrap the handler within a function that checks for its DOM position 394 // this prevents the handler from being dispatched the same way as mouseover or mouseout does 395 if (originalTypeEvent in customEvents) { 396 const wrapFunction = fn => { 397 return function (event) { 398 if (!event.relatedTarget || event.relatedTarget !== event.delegateTarget && !event.delegateTarget.contains(event.relatedTarget)) { 399 return fn.call(this, event); 400 } 401 }; 402 }; 403 callable = wrapFunction(callable); 404 } 405 const events = getElementEvents(element); 406 const handlers = events[typeEvent] || (events[typeEvent] = {}); 407 const previousFunction = findHandler(handlers, callable, isDelegated ? handler : null); 408 if (previousFunction) { 409 previousFunction.oneOff = previousFunction.oneOff && oneOff; 410 return; 411 } 412 const uid = makeEventUid(callable, originalTypeEvent.replace(namespaceRegex, '')); 413 const fn = isDelegated ? bootstrapDelegationHandler(element, handler, callable) : bootstrapHandler(element, callable); 414 fn.delegationSelector = isDelegated ? handler : null; 415 fn.callable = callable; 416 fn.oneOff = oneOff; 417 fn.uidEvent = uid; 418 handlers[uid] = fn; 419 element.addEventListener(typeEvent, fn, isDelegated); 420 } 421 function removeHandler(element, events, typeEvent, handler, delegationSelector) { 422 const fn = findHandler(events[typeEvent], handler, delegationSelector); 423 if (!fn) { 424 return; 425 } 426 element.removeEventListener(typeEvent, fn, Boolean(delegationSelector)); 427 delete events[typeEvent][fn.uidEvent]; 428 } 429 function removeNamespacedHandlers(element, events, typeEvent, namespace) { 430 const storeElementEvent = events[typeEvent] || {}; 431 for (const [handlerKey, event] of Object.entries(storeElementEvent)) { 432 if (handlerKey.includes(namespace)) { 433 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 434 } 435 } 436 } 437 function getTypeEvent(event) { 438 // allow to get the native events from namespaced events ('click.bs.button' --> 'click') 439 event = event.replace(stripNameRegex, ''); 440 return customEvents[event] || event; 441 } 442 const EventHandler = { 443 on(element, event, handler, delegationFunction) { 444 addHandler(element, event, handler, delegationFunction, false); 445 }, 446 one(element, event, handler, delegationFunction) { 447 addHandler(element, event, handler, delegationFunction, true); 448 }, 449 off(element, originalTypeEvent, handler, delegationFunction) { 450 if (typeof originalTypeEvent !== 'string' || !element) { 451 return; 452 } 453 const [isDelegated, callable, typeEvent] = normalizeParameters(originalTypeEvent, handler, delegationFunction); 454 const inNamespace = typeEvent !== originalTypeEvent; 455 const events = getElementEvents(element); 456 const storeElementEvent = events[typeEvent] || {}; 457 const isNamespace = originalTypeEvent.startsWith('.'); 458 if (typeof callable !== 'undefined') { 459 // Simplest case: handler is passed, remove that listener ONLY. 460 if (!Object.keys(storeElementEvent).length) { 461 return; 462 } 463 removeHandler(element, events, typeEvent, callable, isDelegated ? handler : null); 464 return; 465 } 466 if (isNamespace) { 467 for (const elementEvent of Object.keys(events)) { 468 removeNamespacedHandlers(element, events, elementEvent, originalTypeEvent.slice(1)); 469 } 470 } 471 for (const [keyHandlers, event] of Object.entries(storeElementEvent)) { 472 const handlerKey = keyHandlers.replace(stripUidRegex, ''); 473 if (!inNamespace || originalTypeEvent.includes(handlerKey)) { 474 removeHandler(element, events, typeEvent, event.callable, event.delegationSelector); 475 } 476 } 477 }, 478 trigger(element, event, args) { 479 if (typeof event !== 'string' || !element) { 480 return null; 481 } 482 const $ = getjQuery(); 483 const typeEvent = getTypeEvent(event); 484 const inNamespace = event !== typeEvent; 485 let jQueryEvent = null; 486 let bubbles = true; 487 let nativeDispatch = true; 488 let defaultPrevented = false; 489 if (inNamespace && $) { 490 jQueryEvent = $.Event(event, args); 491 $(element).trigger(jQueryEvent); 492 bubbles = !jQueryEvent.isPropagationStopped(); 493 nativeDispatch = !jQueryEvent.isImmediatePropagationStopped(); 494 defaultPrevented = jQueryEvent.isDefaultPrevented(); 495 } 496 const evt = hydrateObj(new Event(event, { 497 bubbles, 498 cancelable: true 499 }), args); 500 if (defaultPrevented) { 501 evt.preventDefault(); 502 } 503 if (nativeDispatch) { 504 element.dispatchEvent(evt); 505 } 506 if (evt.defaultPrevented && jQueryEvent) { 507 jQueryEvent.preventDefault(); 508 } 509 return evt; 510 } 511 }; 512 function hydrateObj(obj, meta = {}) { 513 for (const [key, value] of Object.entries(meta)) { 514 try { 515 obj[key] = value; 516 } catch (_unused) { 517 Object.defineProperty(obj, key, { 518 configurable: true, 519 get() { 520 return value; 521 } 522 }); 523 } 524 } 525 return obj; 526 } 527 528 /** 529 * -------------------------------------------------------------------------- 530 * Bootstrap dom/manipulator.js 531 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 532 * -------------------------------------------------------------------------- 533 */ 534 535 function normalizeData(value) { 536 if (value === 'true') { 537 return true; 538 } 539 if (value === 'false') { 540 return false; 541 } 542 if (value === Number(value).toString()) { 543 return Number(value); 544 } 545 if (value === '' || value === 'null') { 546 return null; 547 } 548 if (typeof value !== 'string') { 549 return value; 550 } 551 try { 552 return JSON.parse(decodeURIComponent(value)); 553 } catch (_unused) { 554 return value; 555 } 556 } 557 function normalizeDataKey(key) { 558 return key.replace(/[A-Z]/g, chr => `-${chr.toLowerCase()}`); 559 } 560 const Manipulator = { 561 setDataAttribute(element, key, value) { 562 element.setAttribute(`data-bs-${normalizeDataKey(key)}`, value); 563 }, 564 removeDataAttribute(element, key) { 565 element.removeAttribute(`data-bs-${normalizeDataKey(key)}`); 566 }, 567 getDataAttributes(element) { 568 if (!element) { 569 return {}; 570 } 571 const attributes = {}; 572 const bsKeys = Object.keys(element.dataset).filter(key => key.startsWith('bs') && !key.startsWith('bsConfig')); 573 for (const key of bsKeys) { 574 let pureKey = key.replace(/^bs/, ''); 575 pureKey = pureKey.charAt(0).toLowerCase() + pureKey.slice(1, pureKey.length); 576 attributes[pureKey] = normalizeData(element.dataset[key]); 577 } 578 return attributes; 579 }, 580 getDataAttribute(element, key) { 581 return normalizeData(element.getAttribute(`data-bs-${normalizeDataKey(key)}`)); 582 } 583 }; 584 585 /** 586 * -------------------------------------------------------------------------- 587 * Bootstrap util/config.js 588 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 589 * -------------------------------------------------------------------------- 590 */ 591 592 593 /** 594 * Class definition 595 */ 596 597 class Config { 598 // Getters 599 static get Default() { 600 return {}; 601 } 602 static get DefaultType() { 603 return {}; 604 } 605 static get NAME() { 606 throw new Error('You have to implement the static method "NAME", for each component!'); 607 } 608 _getConfig(config) { 609 config = this._mergeConfigObj(config); 610 config = this._configAfterMerge(config); 611 this._typeCheckConfig(config); 612 return config; 613 } 614 _configAfterMerge(config) { 615 return config; 616 } 617 _mergeConfigObj(config, element) { 618 const jsonConfig = isElement$1(element) ? Manipulator.getDataAttribute(element, 'config') : {}; // try to parse 619 620 return { 621 ...this.constructor.Default, 622 ...(typeof jsonConfig === 'object' ? jsonConfig : {}), 623 ...(isElement$1(element) ? Manipulator.getDataAttributes(element) : {}), 624 ...(typeof config === 'object' ? config : {}) 625 }; 626 } 627 _typeCheckConfig(config, configTypes = this.constructor.DefaultType) { 628 for (const [property, expectedTypes] of Object.entries(configTypes)) { 629 const value = config[property]; 630 const valueType = isElement$1(value) ? 'element' : toType(value); 631 if (!new RegExp(expectedTypes).test(valueType)) { 632 throw new TypeError(`${this.constructor.NAME.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`); 633 } 634 } 635 } 636 } 637 638 /** 639 * -------------------------------------------------------------------------- 640 * Bootstrap base-component.js 641 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 642 * -------------------------------------------------------------------------- 643 */ 644 645 646 /** 647 * Constants 648 */ 649 650 const VERSION = '5.3.3'; 651 652 /** 653 * Class definition 654 */ 655 656 class BaseComponent extends Config { 657 constructor(element, config) { 658 super(); 659 element = getElement(element); 660 if (!element) { 661 return; 662 } 663 this._element = element; 664 this._config = this._getConfig(config); 665 Data.set(this._element, this.constructor.DATA_KEY, this); 666 } 667 668 // Public 669 dispose() { 670 Data.remove(this._element, this.constructor.DATA_KEY); 671 EventHandler.off(this._element, this.constructor.EVENT_KEY); 672 for (const propertyName of Object.getOwnPropertyNames(this)) { 673 this[propertyName] = null; 674 } 675 } 676 _queueCallback(callback, element, isAnimated = true) { 677 executeAfterTransition(callback, element, isAnimated); 678 } 679 _getConfig(config) { 680 config = this._mergeConfigObj(config, this._element); 681 config = this._configAfterMerge(config); 682 this._typeCheckConfig(config); 683 return config; 684 } 685 686 // Static 687 static getInstance(element) { 688 return Data.get(getElement(element), this.DATA_KEY); 689 } 690 static getOrCreateInstance(element, config = {}) { 691 return this.getInstance(element) || new this(element, typeof config === 'object' ? config : null); 692 } 693 static get VERSION() { 694 return VERSION; 695 } 696 static get DATA_KEY() { 697 return `bs.${this.NAME}`; 698 } 699 static get EVENT_KEY() { 700 return `.${this.DATA_KEY}`; 701 } 702 static eventName(name) { 703 return `${name}${this.EVENT_KEY}`; 704 } 705 } 706 707 /** 708 * -------------------------------------------------------------------------- 709 * Bootstrap dom/selector-engine.js 710 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 711 * -------------------------------------------------------------------------- 712 */ 713 714 const getSelector = element => { 715 let selector = element.getAttribute('data-bs-target'); 716 if (!selector || selector === '#') { 717 let hrefAttribute = element.getAttribute('href'); 718 719 // The only valid content that could double as a selector are IDs or classes, 720 // so everything starting with `#` or `.`. If a "real" URL is used as the selector, 721 // `document.querySelector` will rightfully complain it is invalid. 722 // See https://github.com/twbs/bootstrap/issues/32273 723 if (!hrefAttribute || !hrefAttribute.includes('#') && !hrefAttribute.startsWith('.')) { 724 return null; 725 } 726 727 // Just in case some CMS puts out a full URL with the anchor appended 728 if (hrefAttribute.includes('#') && !hrefAttribute.startsWith('#')) { 729 hrefAttribute = `#${hrefAttribute.split('#')[1]}`; 730 } 731 selector = hrefAttribute && hrefAttribute !== '#' ? hrefAttribute.trim() : null; 732 } 733 return selector ? selector.split(',').map(sel => parseSelector(sel)).join(',') : null; 734 }; 735 const SelectorEngine = { 736 find(selector, element = document.documentElement) { 737 return [].concat(...Element.prototype.querySelectorAll.call(element, selector)); 738 }, 739 findOne(selector, element = document.documentElement) { 740 return Element.prototype.querySelector.call(element, selector); 741 }, 742 children(element, selector) { 743 return [].concat(...element.children).filter(child => child.matches(selector)); 744 }, 745 parents(element, selector) { 746 const parents = []; 747 let ancestor = element.parentNode.closest(selector); 748 while (ancestor) { 749 parents.push(ancestor); 750 ancestor = ancestor.parentNode.closest(selector); 751 } 752 return parents; 753 }, 754 prev(element, selector) { 755 let previous = element.previousElementSibling; 756 while (previous) { 757 if (previous.matches(selector)) { 758 return [previous]; 759 } 760 previous = previous.previousElementSibling; 761 } 762 return []; 763 }, 764 // TODO: this is now unused; remove later along with prev() 765 next(element, selector) { 766 let next = element.nextElementSibling; 767 while (next) { 768 if (next.matches(selector)) { 769 return [next]; 770 } 771 next = next.nextElementSibling; 772 } 773 return []; 774 }, 775 focusableChildren(element) { 776 const focusables = ['a', 'button', 'input', 'textarea', 'select', 'details', '[tabindex]', '[contenteditable="true"]'].map(selector => `${selector}:not([tabindex^="-"])`).join(','); 777 return this.find(focusables, element).filter(el => !isDisabled(el) && isVisible(el)); 778 }, 779 getSelectorFromElement(element) { 780 const selector = getSelector(element); 781 if (selector) { 782 return SelectorEngine.findOne(selector) ? selector : null; 783 } 784 return null; 785 }, 786 getElementFromSelector(element) { 787 const selector = getSelector(element); 788 return selector ? SelectorEngine.findOne(selector) : null; 789 }, 790 getMultipleElementsFromSelector(element) { 791 const selector = getSelector(element); 792 return selector ? SelectorEngine.find(selector) : []; 793 } 794 }; 795 796 /** 797 * -------------------------------------------------------------------------- 798 * Bootstrap util/component-functions.js 799 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 800 * -------------------------------------------------------------------------- 801 */ 802 803 const enableDismissTrigger = (component, method = 'hide') => { 804 const clickEvent = `click.dismiss${component.EVENT_KEY}`; 805 const name = component.NAME; 806 EventHandler.on(document, clickEvent, `[data-bs-dismiss="${name}"]`, function (event) { 807 if (['A', 'AREA'].includes(this.tagName)) { 808 event.preventDefault(); 809 } 810 if (isDisabled(this)) { 811 return; 812 } 813 const target = SelectorEngine.getElementFromSelector(this) || this.closest(`.${name}`); 814 const instance = component.getOrCreateInstance(target); 815 816 // Method argument is left, for Alert and only, as it doesn't implement the 'hide' method 817 instance[method](); 818 }); 819 }; 820 821 /** 822 * -------------------------------------------------------------------------- 823 * Bootstrap alert.js 824 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 825 * -------------------------------------------------------------------------- 826 */ 827 828 829 /** 830 * Constants 831 */ 832 833 const NAME$f = 'alert'; 834 const DATA_KEY$a = 'bs.alert'; 835 const EVENT_KEY$b = `.${DATA_KEY$a}`; 836 const EVENT_CLOSE = `close${EVENT_KEY$b}`; 837 const EVENT_CLOSED = `closed${EVENT_KEY$b}`; 838 const CLASS_NAME_FADE$5 = 'fade'; 839 const CLASS_NAME_SHOW$8 = 'show'; 840 841 /** 842 * Class definition 843 */ 844 845 class Alert extends BaseComponent { 846 // Getters 847 static get NAME() { 848 return NAME$f; 849 } 850 851 // Public 852 close() { 853 const closeEvent = EventHandler.trigger(this._element, EVENT_CLOSE); 854 if (closeEvent.defaultPrevented) { 855 return; 856 } 857 this._element.classList.remove(CLASS_NAME_SHOW$8); 858 const isAnimated = this._element.classList.contains(CLASS_NAME_FADE$5); 859 this._queueCallback(() => this._destroyElement(), this._element, isAnimated); 860 } 861 862 // Private 863 _destroyElement() { 864 this._element.remove(); 865 EventHandler.trigger(this._element, EVENT_CLOSED); 866 this.dispose(); 867 } 868 869 // Static 870 static jQueryInterface(config) { 871 return this.each(function () { 872 const data = Alert.getOrCreateInstance(this); 873 if (typeof config !== 'string') { 874 return; 875 } 876 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 877 throw new TypeError(`No method named "${config}"`); 878 } 879 data[config](this); 880 }); 881 } 882 } 883 884 /** 885 * Data API implementation 886 */ 887 888 enableDismissTrigger(Alert, 'close'); 889 890 /** 891 * jQuery 892 */ 893 894 defineJQueryPlugin(Alert); 895 896 /** 897 * -------------------------------------------------------------------------- 898 * Bootstrap button.js 899 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 900 * -------------------------------------------------------------------------- 901 */ 902 903 904 /** 905 * Constants 906 */ 907 908 const NAME$e = 'button'; 909 const DATA_KEY$9 = 'bs.button'; 910 const EVENT_KEY$a = `.${DATA_KEY$9}`; 911 const DATA_API_KEY$6 = '.data-api'; 912 const CLASS_NAME_ACTIVE$3 = 'active'; 913 const SELECTOR_DATA_TOGGLE$5 = '[data-bs-toggle="button"]'; 914 const EVENT_CLICK_DATA_API$6 = `click${EVENT_KEY$a}${DATA_API_KEY$6}`; 915 916 /** 917 * Class definition 918 */ 919 920 class Button extends BaseComponent { 921 // Getters 922 static get NAME() { 923 return NAME$e; 924 } 925 926 // Public 927 toggle() { 928 // Toggle class and sync the `aria-pressed` attribute with the return value of the `.toggle()` method 929 this._element.setAttribute('aria-pressed', this._element.classList.toggle(CLASS_NAME_ACTIVE$3)); 930 } 931 932 // Static 933 static jQueryInterface(config) { 934 return this.each(function () { 935 const data = Button.getOrCreateInstance(this); 936 if (config === 'toggle') { 937 data[config](); 938 } 939 }); 940 } 941 } 942 943 /** 944 * Data API implementation 945 */ 946 947 EventHandler.on(document, EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$5, event => { 948 event.preventDefault(); 949 const button = event.target.closest(SELECTOR_DATA_TOGGLE$5); 950 const data = Button.getOrCreateInstance(button); 951 data.toggle(); 952 }); 953 954 /** 955 * jQuery 956 */ 957 958 defineJQueryPlugin(Button); 959 960 /** 961 * -------------------------------------------------------------------------- 962 * Bootstrap util/swipe.js 963 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 964 * -------------------------------------------------------------------------- 965 */ 966 967 968 /** 969 * Constants 970 */ 971 972 const NAME$d = 'swipe'; 973 const EVENT_KEY$9 = '.bs.swipe'; 974 const EVENT_TOUCHSTART = `touchstart${EVENT_KEY$9}`; 975 const EVENT_TOUCHMOVE = `touchmove${EVENT_KEY$9}`; 976 const EVENT_TOUCHEND = `touchend${EVENT_KEY$9}`; 977 const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY$9}`; 978 const EVENT_POINTERUP = `pointerup${EVENT_KEY$9}`; 979 const POINTER_TYPE_TOUCH = 'touch'; 980 const POINTER_TYPE_PEN = 'pen'; 981 const CLASS_NAME_POINTER_EVENT = 'pointer-event'; 982 const SWIPE_THRESHOLD = 40; 983 const Default$c = { 984 endCallback: null, 985 leftCallback: null, 986 rightCallback: null 987 }; 988 const DefaultType$c = { 989 endCallback: '(function|null)', 990 leftCallback: '(function|null)', 991 rightCallback: '(function|null)' 992 }; 993 994 /** 995 * Class definition 996 */ 997 998 class Swipe extends Config { 999 constructor(element, config) { 1000 super(); 1001 this._element = element; 1002 if (!element || !Swipe.isSupported()) { 1003 return; 1004 } 1005 this._config = this._getConfig(config); 1006 this._deltaX = 0; 1007 this._supportPointerEvents = Boolean(window.PointerEvent); 1008 this._initEvents(); 1009 } 1010 1011 // Getters 1012 static get Default() { 1013 return Default$c; 1014 } 1015 static get DefaultType() { 1016 return DefaultType$c; 1017 } 1018 static get NAME() { 1019 return NAME$d; 1020 } 1021 1022 // Public 1023 dispose() { 1024 EventHandler.off(this._element, EVENT_KEY$9); 1025 } 1026 1027 // Private 1028 _start(event) { 1029 if (!this._supportPointerEvents) { 1030 this._deltaX = event.touches[0].clientX; 1031 return; 1032 } 1033 if (this._eventIsPointerPenTouch(event)) { 1034 this._deltaX = event.clientX; 1035 } 1036 } 1037 _end(event) { 1038 if (this._eventIsPointerPenTouch(event)) { 1039 this._deltaX = event.clientX - this._deltaX; 1040 } 1041 this._handleSwipe(); 1042 execute(this._config.endCallback); 1043 } 1044 _move(event) { 1045 this._deltaX = event.touches && event.touches.length > 1 ? 0 : event.touches[0].clientX - this._deltaX; 1046 } 1047 _handleSwipe() { 1048 const absDeltaX = Math.abs(this._deltaX); 1049 if (absDeltaX <= SWIPE_THRESHOLD) { 1050 return; 1051 } 1052 const direction = absDeltaX / this._deltaX; 1053 this._deltaX = 0; 1054 if (!direction) { 1055 return; 1056 } 1057 execute(direction > 0 ? this._config.rightCallback : this._config.leftCallback); 1058 } 1059 _initEvents() { 1060 if (this._supportPointerEvents) { 1061 EventHandler.on(this._element, EVENT_POINTERDOWN, event => this._start(event)); 1062 EventHandler.on(this._element, EVENT_POINTERUP, event => this._end(event)); 1063 this._element.classList.add(CLASS_NAME_POINTER_EVENT); 1064 } else { 1065 EventHandler.on(this._element, EVENT_TOUCHSTART, event => this._start(event)); 1066 EventHandler.on(this._element, EVENT_TOUCHMOVE, event => this._move(event)); 1067 EventHandler.on(this._element, EVENT_TOUCHEND, event => this._end(event)); 1068 } 1069 } 1070 _eventIsPointerPenTouch(event) { 1071 return this._supportPointerEvents && (event.pointerType === POINTER_TYPE_PEN || event.pointerType === POINTER_TYPE_TOUCH); 1072 } 1073 1074 // Static 1075 static isSupported() { 1076 return 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; 1077 } 1078 } 1079 1080 /** 1081 * -------------------------------------------------------------------------- 1082 * Bootstrap carousel.js 1083 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1084 * -------------------------------------------------------------------------- 1085 */ 1086 1087 1088 /** 1089 * Constants 1090 */ 1091 1092 const NAME$c = 'carousel'; 1093 const DATA_KEY$8 = 'bs.carousel'; 1094 const EVENT_KEY$8 = `.${DATA_KEY$8}`; 1095 const DATA_API_KEY$5 = '.data-api'; 1096 const ARROW_LEFT_KEY$1 = 'ArrowLeft'; 1097 const ARROW_RIGHT_KEY$1 = 'ArrowRight'; 1098 const TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch 1099 1100 const ORDER_NEXT = 'next'; 1101 const ORDER_PREV = 'prev'; 1102 const DIRECTION_LEFT = 'left'; 1103 const DIRECTION_RIGHT = 'right'; 1104 const EVENT_SLIDE = `slide${EVENT_KEY$8}`; 1105 const EVENT_SLID = `slid${EVENT_KEY$8}`; 1106 const EVENT_KEYDOWN$1 = `keydown${EVENT_KEY$8}`; 1107 const EVENT_MOUSEENTER$1 = `mouseenter${EVENT_KEY$8}`; 1108 const EVENT_MOUSELEAVE$1 = `mouseleave${EVENT_KEY$8}`; 1109 const EVENT_DRAG_START = `dragstart${EVENT_KEY$8}`; 1110 const EVENT_LOAD_DATA_API$3 = `load${EVENT_KEY$8}${DATA_API_KEY$5}`; 1111 const EVENT_CLICK_DATA_API$5 = `click${EVENT_KEY$8}${DATA_API_KEY$5}`; 1112 const CLASS_NAME_CAROUSEL = 'carousel'; 1113 const CLASS_NAME_ACTIVE$2 = 'active'; 1114 const CLASS_NAME_SLIDE = 'slide'; 1115 const CLASS_NAME_END = 'carousel-item-end'; 1116 const CLASS_NAME_START = 'carousel-item-start'; 1117 const CLASS_NAME_NEXT = 'carousel-item-next'; 1118 const CLASS_NAME_PREV = 'carousel-item-prev'; 1119 const SELECTOR_ACTIVE = '.active'; 1120 const SELECTOR_ITEM = '.carousel-item'; 1121 const SELECTOR_ACTIVE_ITEM = SELECTOR_ACTIVE + SELECTOR_ITEM; 1122 const SELECTOR_ITEM_IMG = '.carousel-item img'; 1123 const SELECTOR_INDICATORS = '.carousel-indicators'; 1124 const SELECTOR_DATA_SLIDE = '[data-bs-slide], [data-bs-slide-to]'; 1125 const SELECTOR_DATA_RIDE = '[data-bs-ride="carousel"]'; 1126 const KEY_TO_DIRECTION = { 1127 [ARROW_LEFT_KEY$1]: DIRECTION_RIGHT, 1128 [ARROW_RIGHT_KEY$1]: DIRECTION_LEFT 1129 }; 1130 const Default$b = { 1131 interval: 5000, 1132 keyboard: true, 1133 pause: 'hover', 1134 ride: false, 1135 touch: true, 1136 wrap: true 1137 }; 1138 const DefaultType$b = { 1139 interval: '(number|boolean)', 1140 // TODO:v6 remove boolean support 1141 keyboard: 'boolean', 1142 pause: '(string|boolean)', 1143 ride: '(boolean|string)', 1144 touch: 'boolean', 1145 wrap: 'boolean' 1146 }; 1147 1148 /** 1149 * Class definition 1150 */ 1151 1152 class Carousel extends BaseComponent { 1153 constructor(element, config) { 1154 super(element, config); 1155 this._interval = null; 1156 this._activeElement = null; 1157 this._isSliding = false; 1158 this.touchTimeout = null; 1159 this._swipeHelper = null; 1160 this._indicatorsElement = SelectorEngine.findOne(SELECTOR_INDICATORS, this._element); 1161 this._addEventListeners(); 1162 if (this._config.ride === CLASS_NAME_CAROUSEL) { 1163 this.cycle(); 1164 } 1165 } 1166 1167 // Getters 1168 static get Default() { 1169 return Default$b; 1170 } 1171 static get DefaultType() { 1172 return DefaultType$b; 1173 } 1174 static get NAME() { 1175 return NAME$c; 1176 } 1177 1178 // Public 1179 next() { 1180 this._slide(ORDER_NEXT); 1181 } 1182 nextWhenVisible() { 1183 // FIXME TODO use `document.visibilityState` 1184 // Don't call next when the page isn't visible 1185 // or the carousel or its parent isn't visible 1186 if (!document.hidden && isVisible(this._element)) { 1187 this.next(); 1188 } 1189 } 1190 prev() { 1191 this._slide(ORDER_PREV); 1192 } 1193 pause() { 1194 if (this._isSliding) { 1195 triggerTransitionEnd(this._element); 1196 } 1197 this._clearInterval(); 1198 } 1199 cycle() { 1200 this._clearInterval(); 1201 this._updateInterval(); 1202 this._interval = setInterval(() => this.nextWhenVisible(), this._config.interval); 1203 } 1204 _maybeEnableCycle() { 1205 if (!this._config.ride) { 1206 return; 1207 } 1208 if (this._isSliding) { 1209 EventHandler.one(this._element, EVENT_SLID, () => this.cycle()); 1210 return; 1211 } 1212 this.cycle(); 1213 } 1214 to(index) { 1215 const items = this._getItems(); 1216 if (index > items.length - 1 || index < 0) { 1217 return; 1218 } 1219 if (this._isSliding) { 1220 EventHandler.one(this._element, EVENT_SLID, () => this.to(index)); 1221 return; 1222 } 1223 const activeIndex = this._getItemIndex(this._getActive()); 1224 if (activeIndex === index) { 1225 return; 1226 } 1227 const order = index > activeIndex ? ORDER_NEXT : ORDER_PREV; 1228 this._slide(order, items[index]); 1229 } 1230 dispose() { 1231 if (this._swipeHelper) { 1232 this._swipeHelper.dispose(); 1233 } 1234 super.dispose(); 1235 } 1236 1237 // Private 1238 _configAfterMerge(config) { 1239 config.defaultInterval = config.interval; 1240 return config; 1241 } 1242 _addEventListeners() { 1243 if (this._config.keyboard) { 1244 EventHandler.on(this._element, EVENT_KEYDOWN$1, event => this._keydown(event)); 1245 } 1246 if (this._config.pause === 'hover') { 1247 EventHandler.on(this._element, EVENT_MOUSEENTER$1, () => this.pause()); 1248 EventHandler.on(this._element, EVENT_MOUSELEAVE$1, () => this._maybeEnableCycle()); 1249 } 1250 if (this._config.touch && Swipe.isSupported()) { 1251 this._addTouchEventListeners(); 1252 } 1253 } 1254 _addTouchEventListeners() { 1255 for (const img of SelectorEngine.find(SELECTOR_ITEM_IMG, this._element)) { 1256 EventHandler.on(img, EVENT_DRAG_START, event => event.preventDefault()); 1257 } 1258 const endCallBack = () => { 1259 if (this._config.pause !== 'hover') { 1260 return; 1261 } 1262 1263 // If it's a touch-enabled device, mouseenter/leave are fired as 1264 // part of the mouse compatibility events on first tap - the carousel 1265 // would stop cycling until user tapped out of it; 1266 // here, we listen for touchend, explicitly pause the carousel 1267 // (as if it's the second time we tap on it, mouseenter compat event 1268 // is NOT fired) and after a timeout (to allow for mouse compatibility 1269 // events to fire) we explicitly restart cycling 1270 1271 this.pause(); 1272 if (this.touchTimeout) { 1273 clearTimeout(this.touchTimeout); 1274 } 1275 this.touchTimeout = setTimeout(() => this._maybeEnableCycle(), TOUCHEVENT_COMPAT_WAIT + this._config.interval); 1276 }; 1277 const swipeConfig = { 1278 leftCallback: () => this._slide(this._directionToOrder(DIRECTION_LEFT)), 1279 rightCallback: () => this._slide(this._directionToOrder(DIRECTION_RIGHT)), 1280 endCallback: endCallBack 1281 }; 1282 this._swipeHelper = new Swipe(this._element, swipeConfig); 1283 } 1284 _keydown(event) { 1285 if (/input|textarea/i.test(event.target.tagName)) { 1286 return; 1287 } 1288 const direction = KEY_TO_DIRECTION[event.key]; 1289 if (direction) { 1290 event.preventDefault(); 1291 this._slide(this._directionToOrder(direction)); 1292 } 1293 } 1294 _getItemIndex(element) { 1295 return this._getItems().indexOf(element); 1296 } 1297 _setActiveIndicatorElement(index) { 1298 if (!this._indicatorsElement) { 1299 return; 1300 } 1301 const activeIndicator = SelectorEngine.findOne(SELECTOR_ACTIVE, this._indicatorsElement); 1302 activeIndicator.classList.remove(CLASS_NAME_ACTIVE$2); 1303 activeIndicator.removeAttribute('aria-current'); 1304 const newActiveIndicator = SelectorEngine.findOne(`[data-bs-slide-to="${index}"]`, this._indicatorsElement); 1305 if (newActiveIndicator) { 1306 newActiveIndicator.classList.add(CLASS_NAME_ACTIVE$2); 1307 newActiveIndicator.setAttribute('aria-current', 'true'); 1308 } 1309 } 1310 _updateInterval() { 1311 const element = this._activeElement || this._getActive(); 1312 if (!element) { 1313 return; 1314 } 1315 const elementInterval = Number.parseInt(element.getAttribute('data-bs-interval'), 10); 1316 this._config.interval = elementInterval || this._config.defaultInterval; 1317 } 1318 _slide(order, element = null) { 1319 if (this._isSliding) { 1320 return; 1321 } 1322 const activeElement = this._getActive(); 1323 const isNext = order === ORDER_NEXT; 1324 const nextElement = element || getNextActiveElement(this._getItems(), activeElement, isNext, this._config.wrap); 1325 if (nextElement === activeElement) { 1326 return; 1327 } 1328 const nextElementIndex = this._getItemIndex(nextElement); 1329 const triggerEvent = eventName => { 1330 return EventHandler.trigger(this._element, eventName, { 1331 relatedTarget: nextElement, 1332 direction: this._orderToDirection(order), 1333 from: this._getItemIndex(activeElement), 1334 to: nextElementIndex 1335 }); 1336 }; 1337 const slideEvent = triggerEvent(EVENT_SLIDE); 1338 if (slideEvent.defaultPrevented) { 1339 return; 1340 } 1341 if (!activeElement || !nextElement) { 1342 // Some weirdness is happening, so we bail 1343 // TODO: change tests that use empty divs to avoid this check 1344 return; 1345 } 1346 const isCycling = Boolean(this._interval); 1347 this.pause(); 1348 this._isSliding = true; 1349 this._setActiveIndicatorElement(nextElementIndex); 1350 this._activeElement = nextElement; 1351 const directionalClassName = isNext ? CLASS_NAME_START : CLASS_NAME_END; 1352 const orderClassName = isNext ? CLASS_NAME_NEXT : CLASS_NAME_PREV; 1353 nextElement.classList.add(orderClassName); 1354 reflow(nextElement); 1355 activeElement.classList.add(directionalClassName); 1356 nextElement.classList.add(directionalClassName); 1357 const completeCallBack = () => { 1358 nextElement.classList.remove(directionalClassName, orderClassName); 1359 nextElement.classList.add(CLASS_NAME_ACTIVE$2); 1360 activeElement.classList.remove(CLASS_NAME_ACTIVE$2, orderClassName, directionalClassName); 1361 this._isSliding = false; 1362 triggerEvent(EVENT_SLID); 1363 }; 1364 this._queueCallback(completeCallBack, activeElement, this._isAnimated()); 1365 if (isCycling) { 1366 this.cycle(); 1367 } 1368 } 1369 _isAnimated() { 1370 return this._element.classList.contains(CLASS_NAME_SLIDE); 1371 } 1372 _getActive() { 1373 return SelectorEngine.findOne(SELECTOR_ACTIVE_ITEM, this._element); 1374 } 1375 _getItems() { 1376 return SelectorEngine.find(SELECTOR_ITEM, this._element); 1377 } 1378 _clearInterval() { 1379 if (this._interval) { 1380 clearInterval(this._interval); 1381 this._interval = null; 1382 } 1383 } 1384 _directionToOrder(direction) { 1385 if (isRTL()) { 1386 return direction === DIRECTION_LEFT ? ORDER_PREV : ORDER_NEXT; 1387 } 1388 return direction === DIRECTION_LEFT ? ORDER_NEXT : ORDER_PREV; 1389 } 1390 _orderToDirection(order) { 1391 if (isRTL()) { 1392 return order === ORDER_PREV ? DIRECTION_LEFT : DIRECTION_RIGHT; 1393 } 1394 return order === ORDER_PREV ? DIRECTION_RIGHT : DIRECTION_LEFT; 1395 } 1396 1397 // Static 1398 static jQueryInterface(config) { 1399 return this.each(function () { 1400 const data = Carousel.getOrCreateInstance(this, config); 1401 if (typeof config === 'number') { 1402 data.to(config); 1403 return; 1404 } 1405 if (typeof config === 'string') { 1406 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 1407 throw new TypeError(`No method named "${config}"`); 1408 } 1409 data[config](); 1410 } 1411 }); 1412 } 1413 } 1414 1415 /** 1416 * Data API implementation 1417 */ 1418 1419 EventHandler.on(document, EVENT_CLICK_DATA_API$5, SELECTOR_DATA_SLIDE, function (event) { 1420 const target = SelectorEngine.getElementFromSelector(this); 1421 if (!target || !target.classList.contains(CLASS_NAME_CAROUSEL)) { 1422 return; 1423 } 1424 event.preventDefault(); 1425 const carousel = Carousel.getOrCreateInstance(target); 1426 const slideIndex = this.getAttribute('data-bs-slide-to'); 1427 if (slideIndex) { 1428 carousel.to(slideIndex); 1429 carousel._maybeEnableCycle(); 1430 return; 1431 } 1432 if (Manipulator.getDataAttribute(this, 'slide') === 'next') { 1433 carousel.next(); 1434 carousel._maybeEnableCycle(); 1435 return; 1436 } 1437 carousel.prev(); 1438 carousel._maybeEnableCycle(); 1439 }); 1440 EventHandler.on(window, EVENT_LOAD_DATA_API$3, () => { 1441 const carousels = SelectorEngine.find(SELECTOR_DATA_RIDE); 1442 for (const carousel of carousels) { 1443 Carousel.getOrCreateInstance(carousel); 1444 } 1445 }); 1446 1447 /** 1448 * jQuery 1449 */ 1450 1451 defineJQueryPlugin(Carousel); 1452 1453 /** 1454 * -------------------------------------------------------------------------- 1455 * Bootstrap collapse.js 1456 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 1457 * -------------------------------------------------------------------------- 1458 */ 1459 1460 1461 /** 1462 * Constants 1463 */ 1464 1465 const NAME$b = 'collapse'; 1466 const DATA_KEY$7 = 'bs.collapse'; 1467 const EVENT_KEY$7 = `.${DATA_KEY$7}`; 1468 const DATA_API_KEY$4 = '.data-api'; 1469 const EVENT_SHOW$6 = `show${EVENT_KEY$7}`; 1470 const EVENT_SHOWN$6 = `shown${EVENT_KEY$7}`; 1471 const EVENT_HIDE$6 = `hide${EVENT_KEY$7}`; 1472 const EVENT_HIDDEN$6 = `hidden${EVENT_KEY$7}`; 1473 const EVENT_CLICK_DATA_API$4 = `click${EVENT_KEY$7}${DATA_API_KEY$4}`; 1474 const CLASS_NAME_SHOW$7 = 'show'; 1475 const CLASS_NAME_COLLAPSE = 'collapse'; 1476 const CLASS_NAME_COLLAPSING = 'collapsing'; 1477 const CLASS_NAME_COLLAPSED = 'collapsed'; 1478 const CLASS_NAME_DEEPER_CHILDREN = `:scope .${CLASS_NAME_COLLAPSE} .${CLASS_NAME_COLLAPSE}`; 1479 const CLASS_NAME_HORIZONTAL = 'collapse-horizontal'; 1480 const WIDTH = 'width'; 1481 const HEIGHT = 'height'; 1482 const SELECTOR_ACTIVES = '.collapse.show, .collapse.collapsing'; 1483 const SELECTOR_DATA_TOGGLE$4 = '[data-bs-toggle="collapse"]'; 1484 const Default$a = { 1485 parent: null, 1486 toggle: true 1487 }; 1488 const DefaultType$a = { 1489 parent: '(null|element)', 1490 toggle: 'boolean' 1491 }; 1492 1493 /** 1494 * Class definition 1495 */ 1496 1497 class Collapse extends BaseComponent { 1498 constructor(element, config) { 1499 super(element, config); 1500 this._isTransitioning = false; 1501 this._triggerArray = []; 1502 const toggleList = SelectorEngine.find(SELECTOR_DATA_TOGGLE$4); 1503 for (const elem of toggleList) { 1504 const selector = SelectorEngine.getSelectorFromElement(elem); 1505 const filterElement = SelectorEngine.find(selector).filter(foundElement => foundElement === this._element); 1506 if (selector !== null && filterElement.length) { 1507 this._triggerArray.push(elem); 1508 } 1509 } 1510 this._initializeChildren(); 1511 if (!this._config.parent) { 1512 this._addAriaAndCollapsedClass(this._triggerArray, this._isShown()); 1513 } 1514 if (this._config.toggle) { 1515 this.toggle(); 1516 } 1517 } 1518 1519 // Getters 1520 static get Default() { 1521 return Default$a; 1522 } 1523 static get DefaultType() { 1524 return DefaultType$a; 1525 } 1526 static get NAME() { 1527 return NAME$b; 1528 } 1529 1530 // Public 1531 toggle() { 1532 if (this._isShown()) { 1533 this.hide(); 1534 } else { 1535 this.show(); 1536 } 1537 } 1538 show() { 1539 if (this._isTransitioning || this._isShown()) { 1540 return; 1541 } 1542 let activeChildren = []; 1543 1544 // find active children 1545 if (this._config.parent) { 1546 activeChildren = this._getFirstLevelChildren(SELECTOR_ACTIVES).filter(element => element !== this._element).map(element => Collapse.getOrCreateInstance(element, { 1547 toggle: false 1548 })); 1549 } 1550 if (activeChildren.length && activeChildren[0]._isTransitioning) { 1551 return; 1552 } 1553 const startEvent = EventHandler.trigger(this._element, EVENT_SHOW$6); 1554 if (startEvent.defaultPrevented) { 1555 return; 1556 } 1557 for (const activeInstance of activeChildren) { 1558 activeInstance.hide(); 1559 } 1560 const dimension = this._getDimension(); 1561 this._element.classList.remove(CLASS_NAME_COLLAPSE); 1562 this._element.classList.add(CLASS_NAME_COLLAPSING); 1563 this._element.style[dimension] = 0; 1564 this._addAriaAndCollapsedClass(this._triggerArray, true); 1565 this._isTransitioning = true; 1566 const complete = () => { 1567 this._isTransitioning = false; 1568 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1569 this._element.classList.add(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1570 this._element.style[dimension] = ''; 1571 EventHandler.trigger(this._element, EVENT_SHOWN$6); 1572 }; 1573 const capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); 1574 const scrollSize = `scroll${capitalizedDimension}`; 1575 this._queueCallback(complete, this._element, true); 1576 this._element.style[dimension] = `${this._element[scrollSize]}px`; 1577 } 1578 hide() { 1579 if (this._isTransitioning || !this._isShown()) { 1580 return; 1581 } 1582 const startEvent = EventHandler.trigger(this._element, EVENT_HIDE$6); 1583 if (startEvent.defaultPrevented) { 1584 return; 1585 } 1586 const dimension = this._getDimension(); 1587 this._element.style[dimension] = `${this._element.getBoundingClientRect()[dimension]}px`; 1588 reflow(this._element); 1589 this._element.classList.add(CLASS_NAME_COLLAPSING); 1590 this._element.classList.remove(CLASS_NAME_COLLAPSE, CLASS_NAME_SHOW$7); 1591 for (const trigger of this._triggerArray) { 1592 const element = SelectorEngine.getElementFromSelector(trigger); 1593 if (element && !this._isShown(element)) { 1594 this._addAriaAndCollapsedClass([trigger], false); 1595 } 1596 } 1597 this._isTransitioning = true; 1598 const complete = () => { 1599 this._isTransitioning = false; 1600 this._element.classList.remove(CLASS_NAME_COLLAPSING); 1601 this._element.classList.add(CLASS_NAME_COLLAPSE); 1602 EventHandler.trigger(this._element, EVENT_HIDDEN$6); 1603 }; 1604 this._element.style[dimension] = ''; 1605 this._queueCallback(complete, this._element, true); 1606 } 1607 _isShown(element = this._element) { 1608 return element.classList.contains(CLASS_NAME_SHOW$7); 1609 } 1610 1611 // Private 1612 _configAfterMerge(config) { 1613 config.toggle = Boolean(config.toggle); // Coerce string values 1614 config.parent = getElement(config.parent); 1615 return config; 1616 } 1617 _getDimension() { 1618 return this._element.classList.contains(CLASS_NAME_HORIZONTAL) ? WIDTH : HEIGHT; 1619 } 1620 _initializeChildren() { 1621 if (!this._config.parent) { 1622 return; 1623 } 1624 const children = this._getFirstLevelChildren(SELECTOR_DATA_TOGGLE$4); 1625 for (const element of children) { 1626 const selected = SelectorEngine.getElementFromSelector(element); 1627 if (selected) { 1628 this._addAriaAndCollapsedClass([element], this._isShown(selected)); 1629 } 1630 } 1631 } 1632 _getFirstLevelChildren(selector) { 1633 const children = SelectorEngine.find(CLASS_NAME_DEEPER_CHILDREN, this._config.parent); 1634 // remove children if greater depth 1635 return SelectorEngine.find(selector, this._config.parent).filter(element => !children.includes(element)); 1636 } 1637 _addAriaAndCollapsedClass(triggerArray, isOpen) { 1638 if (!triggerArray.length) { 1639 return; 1640 } 1641 for (const element of triggerArray) { 1642 element.classList.toggle(CLASS_NAME_COLLAPSED, !isOpen); 1643 element.setAttribute('aria-expanded', isOpen); 1644 } 1645 } 1646 1647 // Static 1648 static jQueryInterface(config) { 1649 const _config = {}; 1650 if (typeof config === 'string' && /show|hide/.test(config)) { 1651 _config.toggle = false; 1652 } 1653 return this.each(function () { 1654 const data = Collapse.getOrCreateInstance(this, _config); 1655 if (typeof config === 'string') { 1656 if (typeof data[config] === 'undefined') { 1657 throw new TypeError(`No method named "${config}"`); 1658 } 1659 data[config](); 1660 } 1661 }); 1662 } 1663 } 1664 1665 /** 1666 * Data API implementation 1667 */ 1668 1669 EventHandler.on(document, EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$4, function (event) { 1670 // preventDefault only for <a> elements (which change the URL) not inside the collapsible element 1671 if (event.target.tagName === 'A' || event.delegateTarget && event.delegateTarget.tagName === 'A') { 1672 event.preventDefault(); 1673 } 1674 for (const element of SelectorEngine.getMultipleElementsFromSelector(this)) { 1675 Collapse.getOrCreateInstance(element, { 1676 toggle: false 1677 }).toggle(); 1678 } 1679 }); 1680 1681 /** 1682 * jQuery 1683 */ 1684 1685 defineJQueryPlugin(Collapse); 1686 1687 var top = 'top'; 1688 var bottom = 'bottom'; 1689 var right = 'right'; 1690 var left = 'left'; 1691 var auto = 'auto'; 1692 var basePlacements = [top, bottom, right, left]; 1693 var start = 'start'; 1694 var end = 'end'; 1695 var clippingParents = 'clippingParents'; 1696 var viewport = 'viewport'; 1697 var popper = 'popper'; 1698 var reference = 'reference'; 1699 var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) { 1700 return acc.concat([placement + "-" + start, placement + "-" + end]); 1701 }, []); 1702 var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) { 1703 return acc.concat([placement, placement + "-" + start, placement + "-" + end]); 1704 }, []); // modifiers that need to read the DOM 1705 1706 var beforeRead = 'beforeRead'; 1707 var read = 'read'; 1708 var afterRead = 'afterRead'; // pure-logic modifiers 1709 1710 var beforeMain = 'beforeMain'; 1711 var main = 'main'; 1712 var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state) 1713 1714 var beforeWrite = 'beforeWrite'; 1715 var write = 'write'; 1716 var afterWrite = 'afterWrite'; 1717 var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite]; 1718 1719 function getNodeName(element) { 1720 return element ? (element.nodeName || '').toLowerCase() : null; 1721 } 1722 1723 function getWindow(node) { 1724 if (node == null) { 1725 return window; 1726 } 1727 1728 if (node.toString() !== '[object Window]') { 1729 var ownerDocument = node.ownerDocument; 1730 return ownerDocument ? ownerDocument.defaultView || window : window; 1731 } 1732 1733 return node; 1734 } 1735 1736 function isElement(node) { 1737 var OwnElement = getWindow(node).Element; 1738 return node instanceof OwnElement || node instanceof Element; 1739 } 1740 1741 function isHTMLElement(node) { 1742 var OwnElement = getWindow(node).HTMLElement; 1743 return node instanceof OwnElement || node instanceof HTMLElement; 1744 } 1745 1746 function isShadowRoot(node) { 1747 // IE 11 has no ShadowRoot 1748 if (typeof ShadowRoot === 'undefined') { 1749 return false; 1750 } 1751 1752 var OwnElement = getWindow(node).ShadowRoot; 1753 return node instanceof OwnElement || node instanceof ShadowRoot; 1754 } 1755 1756 // and applies them to the HTMLElements such as popper and arrow 1757 1758 function applyStyles(_ref) { 1759 var state = _ref.state; 1760 Object.keys(state.elements).forEach(function (name) { 1761 var style = state.styles[name] || {}; 1762 var attributes = state.attributes[name] || {}; 1763 var element = state.elements[name]; // arrow is optional + virtual elements 1764 1765 if (!isHTMLElement(element) || !getNodeName(element)) { 1766 return; 1767 } // Flow doesn't support to extend this property, but it's the most 1768 // effective way to apply styles to an HTMLElement 1769 // $FlowFixMe[cannot-write] 1770 1771 1772 Object.assign(element.style, style); 1773 Object.keys(attributes).forEach(function (name) { 1774 var value = attributes[name]; 1775 1776 if (value === false) { 1777 element.removeAttribute(name); 1778 } else { 1779 element.setAttribute(name, value === true ? '' : value); 1780 } 1781 }); 1782 }); 1783 } 1784 1785 function effect$2(_ref2) { 1786 var state = _ref2.state; 1787 var initialStyles = { 1788 popper: { 1789 position: state.options.strategy, 1790 left: '0', 1791 top: '0', 1792 margin: '0' 1793 }, 1794 arrow: { 1795 position: 'absolute' 1796 }, 1797 reference: {} 1798 }; 1799 Object.assign(state.elements.popper.style, initialStyles.popper); 1800 state.styles = initialStyles; 1801 1802 if (state.elements.arrow) { 1803 Object.assign(state.elements.arrow.style, initialStyles.arrow); 1804 } 1805 1806 return function () { 1807 Object.keys(state.elements).forEach(function (name) { 1808 var element = state.elements[name]; 1809 var attributes = state.attributes[name] || {}; 1810 var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them 1811 1812 var style = styleProperties.reduce(function (style, property) { 1813 style[property] = ''; 1814 return style; 1815 }, {}); // arrow is optional + virtual elements 1816 1817 if (!isHTMLElement(element) || !getNodeName(element)) { 1818 return; 1819 } 1820 1821 Object.assign(element.style, style); 1822 Object.keys(attributes).forEach(function (attribute) { 1823 element.removeAttribute(attribute); 1824 }); 1825 }); 1826 }; 1827 } // eslint-disable-next-line import/no-unused-modules 1828 1829 1830 const applyStyles$1 = { 1831 name: 'applyStyles', 1832 enabled: true, 1833 phase: 'write', 1834 fn: applyStyles, 1835 effect: effect$2, 1836 requires: ['computeStyles'] 1837 }; 1838 1839 function getBasePlacement(placement) { 1840 return placement.split('-')[0]; 1841 } 1842 1843 var max = Math.max; 1844 var min = Math.min; 1845 var round = Math.round; 1846 1847 function getUAString() { 1848 var uaData = navigator.userAgentData; 1849 1850 if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) { 1851 return uaData.brands.map(function (item) { 1852 return item.brand + "/" + item.version; 1853 }).join(' '); 1854 } 1855 1856 return navigator.userAgent; 1857 } 1858 1859 function isLayoutViewport() { 1860 return !/^((?!chrome|android).)*safari/i.test(getUAString()); 1861 } 1862 1863 function getBoundingClientRect(element, includeScale, isFixedStrategy) { 1864 if (includeScale === void 0) { 1865 includeScale = false; 1866 } 1867 1868 if (isFixedStrategy === void 0) { 1869 isFixedStrategy = false; 1870 } 1871 1872 var clientRect = element.getBoundingClientRect(); 1873 var scaleX = 1; 1874 var scaleY = 1; 1875 1876 if (includeScale && isHTMLElement(element)) { 1877 scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1; 1878 scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1; 1879 } 1880 1881 var _ref = isElement(element) ? getWindow(element) : window, 1882 visualViewport = _ref.visualViewport; 1883 1884 var addVisualOffsets = !isLayoutViewport() && isFixedStrategy; 1885 var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX; 1886 var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY; 1887 var width = clientRect.width / scaleX; 1888 var height = clientRect.height / scaleY; 1889 return { 1890 width: width, 1891 height: height, 1892 top: y, 1893 right: x + width, 1894 bottom: y + height, 1895 left: x, 1896 x: x, 1897 y: y 1898 }; 1899 } 1900 1901 // means it doesn't take into account transforms. 1902 1903 function getLayoutRect(element) { 1904 var clientRect = getBoundingClientRect(element); // Use the clientRect sizes if it's not been transformed. 1905 // Fixes https://github.com/popperjs/popper-core/issues/1223 1906 1907 var width = element.offsetWidth; 1908 var height = element.offsetHeight; 1909 1910 if (Math.abs(clientRect.width - width) <= 1) { 1911 width = clientRect.width; 1912 } 1913 1914 if (Math.abs(clientRect.height - height) <= 1) { 1915 height = clientRect.height; 1916 } 1917 1918 return { 1919 x: element.offsetLeft, 1920 y: element.offsetTop, 1921 width: width, 1922 height: height 1923 }; 1924 } 1925 1926 function contains(parent, child) { 1927 var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method 1928 1929 if (parent.contains(child)) { 1930 return true; 1931 } // then fallback to custom implementation with Shadow DOM support 1932 else if (rootNode && isShadowRoot(rootNode)) { 1933 var next = child; 1934 1935 do { 1936 if (next && parent.isSameNode(next)) { 1937 return true; 1938 } // $FlowFixMe[prop-missing]: need a better way to handle this... 1939 1940 1941 next = next.parentNode || next.host; 1942 } while (next); 1943 } // Give up, the result is false 1944 1945 1946 return false; 1947 } 1948 1949 function getComputedStyle$1(element) { 1950 return getWindow(element).getComputedStyle(element); 1951 } 1952 1953 function isTableElement(element) { 1954 return ['table', 'td', 'th'].indexOf(getNodeName(element)) >= 0; 1955 } 1956 1957 function getDocumentElement(element) { 1958 // $FlowFixMe[incompatible-return]: assume body is always available 1959 return ((isElement(element) ? element.ownerDocument : // $FlowFixMe[prop-missing] 1960 element.document) || window.document).documentElement; 1961 } 1962 1963 function getParentNode(element) { 1964 if (getNodeName(element) === 'html') { 1965 return element; 1966 } 1967 1968 return (// this is a quicker (but less type safe) way to save quite some bytes from the bundle 1969 // $FlowFixMe[incompatible-return] 1970 // $FlowFixMe[prop-missing] 1971 element.assignedSlot || // step into the shadow DOM of the parent of a slotted node 1972 element.parentNode || ( // DOM Element detected 1973 isShadowRoot(element) ? element.host : null) || // ShadowRoot detected 1974 // $FlowFixMe[incompatible-call]: HTMLElement is a Node 1975 getDocumentElement(element) // fallback 1976 1977 ); 1978 } 1979 1980 function getTrueOffsetParent(element) { 1981 if (!isHTMLElement(element) || // https://github.com/popperjs/popper-core/issues/837 1982 getComputedStyle$1(element).position === 'fixed') { 1983 return null; 1984 } 1985 1986 return element.offsetParent; 1987 } // `.offsetParent` reports `null` for fixed elements, while absolute elements 1988 // return the containing block 1989 1990 1991 function getContainingBlock(element) { 1992 var isFirefox = /firefox/i.test(getUAString()); 1993 var isIE = /Trident/i.test(getUAString()); 1994 1995 if (isIE && isHTMLElement(element)) { 1996 // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport 1997 var elementCss = getComputedStyle$1(element); 1998 1999 if (elementCss.position === 'fixed') { 2000 return null; 2001 } 2002 } 2003 2004 var currentNode = getParentNode(element); 2005 2006 if (isShadowRoot(currentNode)) { 2007 currentNode = currentNode.host; 2008 } 2009 2010 while (isHTMLElement(currentNode) && ['html', 'body'].indexOf(getNodeName(currentNode)) < 0) { 2011 var css = getComputedStyle$1(currentNode); // This is non-exhaustive but covers the most common CSS properties that 2012 // create a containing block. 2013 // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block 2014 2015 if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') { 2016 return currentNode; 2017 } else { 2018 currentNode = currentNode.parentNode; 2019 } 2020 } 2021 2022 return null; 2023 } // Gets the closest ancestor positioned element. Handles some edge cases, 2024 // such as table ancestors and cross browser bugs. 2025 2026 2027 function getOffsetParent(element) { 2028 var window = getWindow(element); 2029 var offsetParent = getTrueOffsetParent(element); 2030 2031 while (offsetParent && isTableElement(offsetParent) && getComputedStyle$1(offsetParent).position === 'static') { 2032 offsetParent = getTrueOffsetParent(offsetParent); 2033 } 2034 2035 if (offsetParent && (getNodeName(offsetParent) === 'html' || getNodeName(offsetParent) === 'body' && getComputedStyle$1(offsetParent).position === 'static')) { 2036 return window; 2037 } 2038 2039 return offsetParent || getContainingBlock(element) || window; 2040 } 2041 2042 function getMainAxisFromPlacement(placement) { 2043 return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y'; 2044 } 2045 2046 function within(min$1, value, max$1) { 2047 return max(min$1, min(value, max$1)); 2048 } 2049 function withinMaxClamp(min, value, max) { 2050 var v = within(min, value, max); 2051 return v > max ? max : v; 2052 } 2053 2054 function getFreshSideObject() { 2055 return { 2056 top: 0, 2057 right: 0, 2058 bottom: 0, 2059 left: 0 2060 }; 2061 } 2062 2063 function mergePaddingObject(paddingObject) { 2064 return Object.assign({}, getFreshSideObject(), paddingObject); 2065 } 2066 2067 function expandToHashMap(value, keys) { 2068 return keys.reduce(function (hashMap, key) { 2069 hashMap[key] = value; 2070 return hashMap; 2071 }, {}); 2072 } 2073 2074 var toPaddingObject = function toPaddingObject(padding, state) { 2075 padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, { 2076 placement: state.placement 2077 })) : padding; 2078 return mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); 2079 }; 2080 2081 function arrow(_ref) { 2082 var _state$modifiersData$; 2083 2084 var state = _ref.state, 2085 name = _ref.name, 2086 options = _ref.options; 2087 var arrowElement = state.elements.arrow; 2088 var popperOffsets = state.modifiersData.popperOffsets; 2089 var basePlacement = getBasePlacement(state.placement); 2090 var axis = getMainAxisFromPlacement(basePlacement); 2091 var isVertical = [left, right].indexOf(basePlacement) >= 0; 2092 var len = isVertical ? 'height' : 'width'; 2093 2094 if (!arrowElement || !popperOffsets) { 2095 return; 2096 } 2097 2098 var paddingObject = toPaddingObject(options.padding, state); 2099 var arrowRect = getLayoutRect(arrowElement); 2100 var minProp = axis === 'y' ? top : left; 2101 var maxProp = axis === 'y' ? bottom : right; 2102 var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len]; 2103 var startDiff = popperOffsets[axis] - state.rects.reference[axis]; 2104 var arrowOffsetParent = getOffsetParent(arrowElement); 2105 var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0; 2106 var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is 2107 // outside of the popper bounds 2108 2109 var min = paddingObject[minProp]; 2110 var max = clientSize - arrowRect[len] - paddingObject[maxProp]; 2111 var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference; 2112 var offset = within(min, center, max); // Prevents breaking syntax highlighting... 2113 2114 var axisProp = axis; 2115 state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$); 2116 } 2117 2118 function effect$1(_ref2) { 2119 var state = _ref2.state, 2120 options = _ref2.options; 2121 var _options$element = options.element, 2122 arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element; 2123 2124 if (arrowElement == null) { 2125 return; 2126 } // CSS selector 2127 2128 2129 if (typeof arrowElement === 'string') { 2130 arrowElement = state.elements.popper.querySelector(arrowElement); 2131 2132 if (!arrowElement) { 2133 return; 2134 } 2135 } 2136 2137 if (!contains(state.elements.popper, arrowElement)) { 2138 return; 2139 } 2140 2141 state.elements.arrow = arrowElement; 2142 } // eslint-disable-next-line import/no-unused-modules 2143 2144 2145 const arrow$1 = { 2146 name: 'arrow', 2147 enabled: true, 2148 phase: 'main', 2149 fn: arrow, 2150 effect: effect$1, 2151 requires: ['popperOffsets'], 2152 requiresIfExists: ['preventOverflow'] 2153 }; 2154 2155 function getVariation(placement) { 2156 return placement.split('-')[1]; 2157 } 2158 2159 var unsetSides = { 2160 top: 'auto', 2161 right: 'auto', 2162 bottom: 'auto', 2163 left: 'auto' 2164 }; // Round the offsets to the nearest suitable subpixel based on the DPR. 2165 // Zooming can change the DPR, but it seems to report a value that will 2166 // cleanly divide the values into the appropriate subpixels. 2167 2168 function roundOffsetsByDPR(_ref, win) { 2169 var x = _ref.x, 2170 y = _ref.y; 2171 var dpr = win.devicePixelRatio || 1; 2172 return { 2173 x: round(x * dpr) / dpr || 0, 2174 y: round(y * dpr) / dpr || 0 2175 }; 2176 } 2177 2178 function mapToStyles(_ref2) { 2179 var _Object$assign2; 2180 2181 var popper = _ref2.popper, 2182 popperRect = _ref2.popperRect, 2183 placement = _ref2.placement, 2184 variation = _ref2.variation, 2185 offsets = _ref2.offsets, 2186 position = _ref2.position, 2187 gpuAcceleration = _ref2.gpuAcceleration, 2188 adaptive = _ref2.adaptive, 2189 roundOffsets = _ref2.roundOffsets, 2190 isFixed = _ref2.isFixed; 2191 var _offsets$x = offsets.x, 2192 x = _offsets$x === void 0 ? 0 : _offsets$x, 2193 _offsets$y = offsets.y, 2194 y = _offsets$y === void 0 ? 0 : _offsets$y; 2195 2196 var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({ 2197 x: x, 2198 y: y 2199 }) : { 2200 x: x, 2201 y: y 2202 }; 2203 2204 x = _ref3.x; 2205 y = _ref3.y; 2206 var hasX = offsets.hasOwnProperty('x'); 2207 var hasY = offsets.hasOwnProperty('y'); 2208 var sideX = left; 2209 var sideY = top; 2210 var win = window; 2211 2212 if (adaptive) { 2213 var offsetParent = getOffsetParent(popper); 2214 var heightProp = 'clientHeight'; 2215 var widthProp = 'clientWidth'; 2216 2217 if (offsetParent === getWindow(popper)) { 2218 offsetParent = getDocumentElement(popper); 2219 2220 if (getComputedStyle$1(offsetParent).position !== 'static' && position === 'absolute') { 2221 heightProp = 'scrollHeight'; 2222 widthProp = 'scrollWidth'; 2223 } 2224 } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it 2225 2226 2227 offsetParent = offsetParent; 2228 2229 if (placement === top || (placement === left || placement === right) && variation === end) { 2230 sideY = bottom; 2231 var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : // $FlowFixMe[prop-missing] 2232 offsetParent[heightProp]; 2233 y -= offsetY - popperRect.height; 2234 y *= gpuAcceleration ? 1 : -1; 2235 } 2236 2237 if (placement === left || (placement === top || placement === bottom) && variation === end) { 2238 sideX = right; 2239 var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : // $FlowFixMe[prop-missing] 2240 offsetParent[widthProp]; 2241 x -= offsetX - popperRect.width; 2242 x *= gpuAcceleration ? 1 : -1; 2243 } 2244 } 2245 2246 var commonStyles = Object.assign({ 2247 position: position 2248 }, adaptive && unsetSides); 2249 2250 var _ref4 = roundOffsets === true ? roundOffsetsByDPR({ 2251 x: x, 2252 y: y 2253 }, getWindow(popper)) : { 2254 x: x, 2255 y: y 2256 }; 2257 2258 x = _ref4.x; 2259 y = _ref4.y; 2260 2261 if (gpuAcceleration) { 2262 var _Object$assign; 2263 2264 return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign)); 2265 } 2266 2267 return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2)); 2268 } 2269 2270 function computeStyles(_ref5) { 2271 var state = _ref5.state, 2272 options = _ref5.options; 2273 var _options$gpuAccelerat = options.gpuAcceleration, 2274 gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, 2275 _options$adaptive = options.adaptive, 2276 adaptive = _options$adaptive === void 0 ? true : _options$adaptive, 2277 _options$roundOffsets = options.roundOffsets, 2278 roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets; 2279 var commonStyles = { 2280 placement: getBasePlacement(state.placement), 2281 variation: getVariation(state.placement), 2282 popper: state.elements.popper, 2283 popperRect: state.rects.popper, 2284 gpuAcceleration: gpuAcceleration, 2285 isFixed: state.options.strategy === 'fixed' 2286 }; 2287 2288 if (state.modifiersData.popperOffsets != null) { 2289 state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, { 2290 offsets: state.modifiersData.popperOffsets, 2291 position: state.options.strategy, 2292 adaptive: adaptive, 2293 roundOffsets: roundOffsets 2294 }))); 2295 } 2296 2297 if (state.modifiersData.arrow != null) { 2298 state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, { 2299 offsets: state.modifiersData.arrow, 2300 position: 'absolute', 2301 adaptive: false, 2302 roundOffsets: roundOffsets 2303 }))); 2304 } 2305 2306 state.attributes.popper = Object.assign({}, state.attributes.popper, { 2307 'data-popper-placement': state.placement 2308 }); 2309 } // eslint-disable-next-line import/no-unused-modules 2310 2311 2312 const computeStyles$1 = { 2313 name: 'computeStyles', 2314 enabled: true, 2315 phase: 'beforeWrite', 2316 fn: computeStyles, 2317 data: {} 2318 }; 2319 2320 var passive = { 2321 passive: true 2322 }; 2323 2324 function effect(_ref) { 2325 var state = _ref.state, 2326 instance = _ref.instance, 2327 options = _ref.options; 2328 var _options$scroll = options.scroll, 2329 scroll = _options$scroll === void 0 ? true : _options$scroll, 2330 _options$resize = options.resize, 2331 resize = _options$resize === void 0 ? true : _options$resize; 2332 var window = getWindow(state.elements.popper); 2333 var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper); 2334 2335 if (scroll) { 2336 scrollParents.forEach(function (scrollParent) { 2337 scrollParent.addEventListener('scroll', instance.update, passive); 2338 }); 2339 } 2340 2341 if (resize) { 2342 window.addEventListener('resize', instance.update, passive); 2343 } 2344 2345 return function () { 2346 if (scroll) { 2347 scrollParents.forEach(function (scrollParent) { 2348 scrollParent.removeEventListener('scroll', instance.update, passive); 2349 }); 2350 } 2351 2352 if (resize) { 2353 window.removeEventListener('resize', instance.update, passive); 2354 } 2355 }; 2356 } // eslint-disable-next-line import/no-unused-modules 2357 2358 2359 const eventListeners = { 2360 name: 'eventListeners', 2361 enabled: true, 2362 phase: 'write', 2363 fn: function fn() {}, 2364 effect: effect, 2365 data: {} 2366 }; 2367 2368 var hash$1 = { 2369 left: 'right', 2370 right: 'left', 2371 bottom: 'top', 2372 top: 'bottom' 2373 }; 2374 function getOppositePlacement(placement) { 2375 return placement.replace(/left|right|bottom|top/g, function (matched) { 2376 return hash$1[matched]; 2377 }); 2378 } 2379 2380 var hash = { 2381 start: 'end', 2382 end: 'start' 2383 }; 2384 function getOppositeVariationPlacement(placement) { 2385 return placement.replace(/start|end/g, function (matched) { 2386 return hash[matched]; 2387 }); 2388 } 2389 2390 function getWindowScroll(node) { 2391 var win = getWindow(node); 2392 var scrollLeft = win.pageXOffset; 2393 var scrollTop = win.pageYOffset; 2394 return { 2395 scrollLeft: scrollLeft, 2396 scrollTop: scrollTop 2397 }; 2398 } 2399 2400 function getWindowScrollBarX(element) { 2401 // If <html> has a CSS width greater than the viewport, then this will be 2402 // incorrect for RTL. 2403 // Popper 1 is broken in this case and never had a bug report so let's assume 2404 // it's not an issue. I don't think anyone ever specifies width on <html> 2405 // anyway. 2406 // Browsers where the left scrollbar doesn't cause an issue report `0` for 2407 // this (e.g. Edge 2019, IE11, Safari) 2408 return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft; 2409 } 2410 2411 function getViewportRect(element, strategy) { 2412 var win = getWindow(element); 2413 var html = getDocumentElement(element); 2414 var visualViewport = win.visualViewport; 2415 var width = html.clientWidth; 2416 var height = html.clientHeight; 2417 var x = 0; 2418 var y = 0; 2419 2420 if (visualViewport) { 2421 width = visualViewport.width; 2422 height = visualViewport.height; 2423 var layoutViewport = isLayoutViewport(); 2424 2425 if (layoutViewport || !layoutViewport && strategy === 'fixed') { 2426 x = visualViewport.offsetLeft; 2427 y = visualViewport.offsetTop; 2428 } 2429 } 2430 2431 return { 2432 width: width, 2433 height: height, 2434 x: x + getWindowScrollBarX(element), 2435 y: y 2436 }; 2437 } 2438 2439 // of the `<html>` and `<body>` rect bounds if horizontally scrollable 2440 2441 function getDocumentRect(element) { 2442 var _element$ownerDocumen; 2443 2444 var html = getDocumentElement(element); 2445 var winScroll = getWindowScroll(element); 2446 var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body; 2447 var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0); 2448 var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0); 2449 var x = -winScroll.scrollLeft + getWindowScrollBarX(element); 2450 var y = -winScroll.scrollTop; 2451 2452 if (getComputedStyle$1(body || html).direction === 'rtl') { 2453 x += max(html.clientWidth, body ? body.clientWidth : 0) - width; 2454 } 2455 2456 return { 2457 width: width, 2458 height: height, 2459 x: x, 2460 y: y 2461 }; 2462 } 2463 2464 function isScrollParent(element) { 2465 // Firefox wants us to check `-x` and `-y` variations as well 2466 var _getComputedStyle = getComputedStyle$1(element), 2467 overflow = _getComputedStyle.overflow, 2468 overflowX = _getComputedStyle.overflowX, 2469 overflowY = _getComputedStyle.overflowY; 2470 2471 return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX); 2472 } 2473 2474 function getScrollParent(node) { 2475 if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { 2476 // $FlowFixMe[incompatible-return]: assume body is always available 2477 return node.ownerDocument.body; 2478 } 2479 2480 if (isHTMLElement(node) && isScrollParent(node)) { 2481 return node; 2482 } 2483 2484 return getScrollParent(getParentNode(node)); 2485 } 2486 2487 /* 2488 given a DOM element, return the list of all scroll parents, up the list of ancesors 2489 until we get to the top window object. This list is what we attach scroll listeners 2490 to, because if any of these parent elements scroll, we'll need to re-calculate the 2491 reference element's position. 2492 */ 2493 2494 function listScrollParents(element, list) { 2495 var _element$ownerDocumen; 2496 2497 if (list === void 0) { 2498 list = []; 2499 } 2500 2501 var scrollParent = getScrollParent(element); 2502 var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body); 2503 var win = getWindow(scrollParent); 2504 var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent; 2505 var updatedList = list.concat(target); 2506 return isBody ? updatedList : // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here 2507 updatedList.concat(listScrollParents(getParentNode(target))); 2508 } 2509 2510 function rectToClientRect(rect) { 2511 return Object.assign({}, rect, { 2512 left: rect.x, 2513 top: rect.y, 2514 right: rect.x + rect.width, 2515 bottom: rect.y + rect.height 2516 }); 2517 } 2518 2519 function getInnerBoundingClientRect(element, strategy) { 2520 var rect = getBoundingClientRect(element, false, strategy === 'fixed'); 2521 rect.top = rect.top + element.clientTop; 2522 rect.left = rect.left + element.clientLeft; 2523 rect.bottom = rect.top + element.clientHeight; 2524 rect.right = rect.left + element.clientWidth; 2525 rect.width = element.clientWidth; 2526 rect.height = element.clientHeight; 2527 rect.x = rect.left; 2528 rect.y = rect.top; 2529 return rect; 2530 } 2531 2532 function getClientRectFromMixedType(element, clippingParent, strategy) { 2533 return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element))); 2534 } // A "clipping parent" is an overflowable container with the characteristic of 2535 // clipping (or hiding) overflowing elements with a position different from 2536 // `initial` 2537 2538 2539 function getClippingParents(element) { 2540 var clippingParents = listScrollParents(getParentNode(element)); 2541 var canEscapeClipping = ['absolute', 'fixed'].indexOf(getComputedStyle$1(element).position) >= 0; 2542 var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element; 2543 2544 if (!isElement(clipperElement)) { 2545 return []; 2546 } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414 2547 2548 2549 return clippingParents.filter(function (clippingParent) { 2550 return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== 'body'; 2551 }); 2552 } // Gets the maximum area that the element is visible in due to any number of 2553 // clipping parents 2554 2555 2556 function getClippingRect(element, boundary, rootBoundary, strategy) { 2557 var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary); 2558 var clippingParents = [].concat(mainClippingParents, [rootBoundary]); 2559 var firstClippingParent = clippingParents[0]; 2560 var clippingRect = clippingParents.reduce(function (accRect, clippingParent) { 2561 var rect = getClientRectFromMixedType(element, clippingParent, strategy); 2562 accRect.top = max(rect.top, accRect.top); 2563 accRect.right = min(rect.right, accRect.right); 2564 accRect.bottom = min(rect.bottom, accRect.bottom); 2565 accRect.left = max(rect.left, accRect.left); 2566 return accRect; 2567 }, getClientRectFromMixedType(element, firstClippingParent, strategy)); 2568 clippingRect.width = clippingRect.right - clippingRect.left; 2569 clippingRect.height = clippingRect.bottom - clippingRect.top; 2570 clippingRect.x = clippingRect.left; 2571 clippingRect.y = clippingRect.top; 2572 return clippingRect; 2573 } 2574 2575 function computeOffsets(_ref) { 2576 var reference = _ref.reference, 2577 element = _ref.element, 2578 placement = _ref.placement; 2579 var basePlacement = placement ? getBasePlacement(placement) : null; 2580 var variation = placement ? getVariation(placement) : null; 2581 var commonX = reference.x + reference.width / 2 - element.width / 2; 2582 var commonY = reference.y + reference.height / 2 - element.height / 2; 2583 var offsets; 2584 2585 switch (basePlacement) { 2586 case top: 2587 offsets = { 2588 x: commonX, 2589 y: reference.y - element.height 2590 }; 2591 break; 2592 2593 case bottom: 2594 offsets = { 2595 x: commonX, 2596 y: reference.y + reference.height 2597 }; 2598 break; 2599 2600 case right: 2601 offsets = { 2602 x: reference.x + reference.width, 2603 y: commonY 2604 }; 2605 break; 2606 2607 case left: 2608 offsets = { 2609 x: reference.x - element.width, 2610 y: commonY 2611 }; 2612 break; 2613 2614 default: 2615 offsets = { 2616 x: reference.x, 2617 y: reference.y 2618 }; 2619 } 2620 2621 var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null; 2622 2623 if (mainAxis != null) { 2624 var len = mainAxis === 'y' ? 'height' : 'width'; 2625 2626 switch (variation) { 2627 case start: 2628 offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2); 2629 break; 2630 2631 case end: 2632 offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2); 2633 break; 2634 } 2635 } 2636 2637 return offsets; 2638 } 2639 2640 function detectOverflow(state, options) { 2641 if (options === void 0) { 2642 options = {}; 2643 } 2644 2645 var _options = options, 2646 _options$placement = _options.placement, 2647 placement = _options$placement === void 0 ? state.placement : _options$placement, 2648 _options$strategy = _options.strategy, 2649 strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, 2650 _options$boundary = _options.boundary, 2651 boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, 2652 _options$rootBoundary = _options.rootBoundary, 2653 rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, 2654 _options$elementConte = _options.elementContext, 2655 elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, 2656 _options$altBoundary = _options.altBoundary, 2657 altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, 2658 _options$padding = _options.padding, 2659 padding = _options$padding === void 0 ? 0 : _options$padding; 2660 var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements)); 2661 var altContext = elementContext === popper ? reference : popper; 2662 var popperRect = state.rects.popper; 2663 var element = state.elements[altBoundary ? altContext : elementContext]; 2664 var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy); 2665 var referenceClientRect = getBoundingClientRect(state.elements.reference); 2666 var popperOffsets = computeOffsets({ 2667 reference: referenceClientRect, 2668 element: popperRect, 2669 strategy: 'absolute', 2670 placement: placement 2671 }); 2672 var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets)); 2673 var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect 2674 // 0 or negative = within the clipping rect 2675 2676 var overflowOffsets = { 2677 top: clippingClientRect.top - elementClientRect.top + paddingObject.top, 2678 bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom, 2679 left: clippingClientRect.left - elementClientRect.left + paddingObject.left, 2680 right: elementClientRect.right - clippingClientRect.right + paddingObject.right 2681 }; 2682 var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element 2683 2684 if (elementContext === popper && offsetData) { 2685 var offset = offsetData[placement]; 2686 Object.keys(overflowOffsets).forEach(function (key) { 2687 var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1; 2688 var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x'; 2689 overflowOffsets[key] += offset[axis] * multiply; 2690 }); 2691 } 2692 2693 return overflowOffsets; 2694 } 2695 2696 function computeAutoPlacement(state, options) { 2697 if (options === void 0) { 2698 options = {}; 2699 } 2700 2701 var _options = options, 2702 placement = _options.placement, 2703 boundary = _options.boundary, 2704 rootBoundary = _options.rootBoundary, 2705 padding = _options.padding, 2706 flipVariations = _options.flipVariations, 2707 _options$allowedAutoP = _options.allowedAutoPlacements, 2708 allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP; 2709 var variation = getVariation(placement); 2710 var placements$1 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function (placement) { 2711 return getVariation(placement) === variation; 2712 }) : basePlacements; 2713 var allowedPlacements = placements$1.filter(function (placement) { 2714 return allowedAutoPlacements.indexOf(placement) >= 0; 2715 }); 2716 2717 if (allowedPlacements.length === 0) { 2718 allowedPlacements = placements$1; 2719 } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions... 2720 2721 2722 var overflows = allowedPlacements.reduce(function (acc, placement) { 2723 acc[placement] = detectOverflow(state, { 2724 placement: placement, 2725 boundary: boundary, 2726 rootBoundary: rootBoundary, 2727 padding: padding 2728 })[getBasePlacement(placement)]; 2729 return acc; 2730 }, {}); 2731 return Object.keys(overflows).sort(function (a, b) { 2732 return overflows[a] - overflows[b]; 2733 }); 2734 } 2735 2736 function getExpandedFallbackPlacements(placement) { 2737 if (getBasePlacement(placement) === auto) { 2738 return []; 2739 } 2740 2741 var oppositePlacement = getOppositePlacement(placement); 2742 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)]; 2743 } 2744 2745 function flip(_ref) { 2746 var state = _ref.state, 2747 options = _ref.options, 2748 name = _ref.name; 2749 2750 if (state.modifiersData[name]._skip) { 2751 return; 2752 } 2753 2754 var _options$mainAxis = options.mainAxis, 2755 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, 2756 _options$altAxis = options.altAxis, 2757 checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, 2758 specifiedFallbackPlacements = options.fallbackPlacements, 2759 padding = options.padding, 2760 boundary = options.boundary, 2761 rootBoundary = options.rootBoundary, 2762 altBoundary = options.altBoundary, 2763 _options$flipVariatio = options.flipVariations, 2764 flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, 2765 allowedAutoPlacements = options.allowedAutoPlacements; 2766 var preferredPlacement = state.options.placement; 2767 var basePlacement = getBasePlacement(preferredPlacement); 2768 var isBasePlacement = basePlacement === preferredPlacement; 2769 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement)); 2770 var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) { 2771 return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, { 2772 placement: placement, 2773 boundary: boundary, 2774 rootBoundary: rootBoundary, 2775 padding: padding, 2776 flipVariations: flipVariations, 2777 allowedAutoPlacements: allowedAutoPlacements 2778 }) : placement); 2779 }, []); 2780 var referenceRect = state.rects.reference; 2781 var popperRect = state.rects.popper; 2782 var checksMap = new Map(); 2783 var makeFallbackChecks = true; 2784 var firstFittingPlacement = placements[0]; 2785 2786 for (var i = 0; i < placements.length; i++) { 2787 var placement = placements[i]; 2788 2789 var _basePlacement = getBasePlacement(placement); 2790 2791 var isStartVariation = getVariation(placement) === start; 2792 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0; 2793 var len = isVertical ? 'width' : 'height'; 2794 var overflow = detectOverflow(state, { 2795 placement: placement, 2796 boundary: boundary, 2797 rootBoundary: rootBoundary, 2798 altBoundary: altBoundary, 2799 padding: padding 2800 }); 2801 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top; 2802 2803 if (referenceRect[len] > popperRect[len]) { 2804 mainVariationSide = getOppositePlacement(mainVariationSide); 2805 } 2806 2807 var altVariationSide = getOppositePlacement(mainVariationSide); 2808 var checks = []; 2809 2810 if (checkMainAxis) { 2811 checks.push(overflow[_basePlacement] <= 0); 2812 } 2813 2814 if (checkAltAxis) { 2815 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0); 2816 } 2817 2818 if (checks.every(function (check) { 2819 return check; 2820 })) { 2821 firstFittingPlacement = placement; 2822 makeFallbackChecks = false; 2823 break; 2824 } 2825 2826 checksMap.set(placement, checks); 2827 } 2828 2829 if (makeFallbackChecks) { 2830 // `2` may be desired in some cases – research later 2831 var numberOfChecks = flipVariations ? 3 : 1; 2832 2833 var _loop = function _loop(_i) { 2834 var fittingPlacement = placements.find(function (placement) { 2835 var checks = checksMap.get(placement); 2836 2837 if (checks) { 2838 return checks.slice(0, _i).every(function (check) { 2839 return check; 2840 }); 2841 } 2842 }); 2843 2844 if (fittingPlacement) { 2845 firstFittingPlacement = fittingPlacement; 2846 return "break"; 2847 } 2848 }; 2849 2850 for (var _i = numberOfChecks; _i > 0; _i--) { 2851 var _ret = _loop(_i); 2852 2853 if (_ret === "break") break; 2854 } 2855 } 2856 2857 if (state.placement !== firstFittingPlacement) { 2858 state.modifiersData[name]._skip = true; 2859 state.placement = firstFittingPlacement; 2860 state.reset = true; 2861 } 2862 } // eslint-disable-next-line import/no-unused-modules 2863 2864 2865 const flip$1 = { 2866 name: 'flip', 2867 enabled: true, 2868 phase: 'main', 2869 fn: flip, 2870 requiresIfExists: ['offset'], 2871 data: { 2872 _skip: false 2873 } 2874 }; 2875 2876 function getSideOffsets(overflow, rect, preventedOffsets) { 2877 if (preventedOffsets === void 0) { 2878 preventedOffsets = { 2879 x: 0, 2880 y: 0 2881 }; 2882 } 2883 2884 return { 2885 top: overflow.top - rect.height - preventedOffsets.y, 2886 right: overflow.right - rect.width + preventedOffsets.x, 2887 bottom: overflow.bottom - rect.height + preventedOffsets.y, 2888 left: overflow.left - rect.width - preventedOffsets.x 2889 }; 2890 } 2891 2892 function isAnySideFullyClipped(overflow) { 2893 return [top, right, bottom, left].some(function (side) { 2894 return overflow[side] >= 0; 2895 }); 2896 } 2897 2898 function hide(_ref) { 2899 var state = _ref.state, 2900 name = _ref.name; 2901 var referenceRect = state.rects.reference; 2902 var popperRect = state.rects.popper; 2903 var preventedOffsets = state.modifiersData.preventOverflow; 2904 var referenceOverflow = detectOverflow(state, { 2905 elementContext: 'reference' 2906 }); 2907 var popperAltOverflow = detectOverflow(state, { 2908 altBoundary: true 2909 }); 2910 var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect); 2911 var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets); 2912 var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets); 2913 var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets); 2914 state.modifiersData[name] = { 2915 referenceClippingOffsets: referenceClippingOffsets, 2916 popperEscapeOffsets: popperEscapeOffsets, 2917 isReferenceHidden: isReferenceHidden, 2918 hasPopperEscaped: hasPopperEscaped 2919 }; 2920 state.attributes.popper = Object.assign({}, state.attributes.popper, { 2921 'data-popper-reference-hidden': isReferenceHidden, 2922 'data-popper-escaped': hasPopperEscaped 2923 }); 2924 } // eslint-disable-next-line import/no-unused-modules 2925 2926 2927 const hide$1 = { 2928 name: 'hide', 2929 enabled: true, 2930 phase: 'main', 2931 requiresIfExists: ['preventOverflow'], 2932 fn: hide 2933 }; 2934 2935 function distanceAndSkiddingToXY(placement, rects, offset) { 2936 var basePlacement = getBasePlacement(placement); 2937 var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1; 2938 2939 var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, { 2940 placement: placement 2941 })) : offset, 2942 skidding = _ref[0], 2943 distance = _ref[1]; 2944 2945 skidding = skidding || 0; 2946 distance = (distance || 0) * invertDistance; 2947 return [left, right].indexOf(basePlacement) >= 0 ? { 2948 x: distance, 2949 y: skidding 2950 } : { 2951 x: skidding, 2952 y: distance 2953 }; 2954 } 2955 2956 function offset(_ref2) { 2957 var state = _ref2.state, 2958 options = _ref2.options, 2959 name = _ref2.name; 2960 var _options$offset = options.offset, 2961 offset = _options$offset === void 0 ? [0, 0] : _options$offset; 2962 var data = placements.reduce(function (acc, placement) { 2963 acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset); 2964 return acc; 2965 }, {}); 2966 var _data$state$placement = data[state.placement], 2967 x = _data$state$placement.x, 2968 y = _data$state$placement.y; 2969 2970 if (state.modifiersData.popperOffsets != null) { 2971 state.modifiersData.popperOffsets.x += x; 2972 state.modifiersData.popperOffsets.y += y; 2973 } 2974 2975 state.modifiersData[name] = data; 2976 } // eslint-disable-next-line import/no-unused-modules 2977 2978 2979 const offset$1 = { 2980 name: 'offset', 2981 enabled: true, 2982 phase: 'main', 2983 requires: ['popperOffsets'], 2984 fn: offset 2985 }; 2986 2987 function popperOffsets(_ref) { 2988 var state = _ref.state, 2989 name = _ref.name; 2990 // Offsets are the actual position the popper needs to have to be 2991 // properly positioned near its reference element 2992 // This is the most basic placement, and will be adjusted by 2993 // the modifiers in the next step 2994 state.modifiersData[name] = computeOffsets({ 2995 reference: state.rects.reference, 2996 element: state.rects.popper, 2997 strategy: 'absolute', 2998 placement: state.placement 2999 }); 3000 } // eslint-disable-next-line import/no-unused-modules 3001 3002 3003 const popperOffsets$1 = { 3004 name: 'popperOffsets', 3005 enabled: true, 3006 phase: 'read', 3007 fn: popperOffsets, 3008 data: {} 3009 }; 3010 3011 function getAltAxis(axis) { 3012 return axis === 'x' ? 'y' : 'x'; 3013 } 3014 3015 function preventOverflow(_ref) { 3016 var state = _ref.state, 3017 options = _ref.options, 3018 name = _ref.name; 3019 var _options$mainAxis = options.mainAxis, 3020 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, 3021 _options$altAxis = options.altAxis, 3022 checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, 3023 boundary = options.boundary, 3024 rootBoundary = options.rootBoundary, 3025 altBoundary = options.altBoundary, 3026 padding = options.padding, 3027 _options$tether = options.tether, 3028 tether = _options$tether === void 0 ? true : _options$tether, 3029 _options$tetherOffset = options.tetherOffset, 3030 tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset; 3031 var overflow = detectOverflow(state, { 3032 boundary: boundary, 3033 rootBoundary: rootBoundary, 3034 padding: padding, 3035 altBoundary: altBoundary 3036 }); 3037 var basePlacement = getBasePlacement(state.placement); 3038 var variation = getVariation(state.placement); 3039 var isBasePlacement = !variation; 3040 var mainAxis = getMainAxisFromPlacement(basePlacement); 3041 var altAxis = getAltAxis(mainAxis); 3042 var popperOffsets = state.modifiersData.popperOffsets; 3043 var referenceRect = state.rects.reference; 3044 var popperRect = state.rects.popper; 3045 var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, { 3046 placement: state.placement 3047 })) : tetherOffset; 3048 var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? { 3049 mainAxis: tetherOffsetValue, 3050 altAxis: tetherOffsetValue 3051 } : Object.assign({ 3052 mainAxis: 0, 3053 altAxis: 0 3054 }, tetherOffsetValue); 3055 var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null; 3056 var data = { 3057 x: 0, 3058 y: 0 3059 }; 3060 3061 if (!popperOffsets) { 3062 return; 3063 } 3064 3065 if (checkMainAxis) { 3066 var _offsetModifierState$; 3067 3068 var mainSide = mainAxis === 'y' ? top : left; 3069 var altSide = mainAxis === 'y' ? bottom : right; 3070 var len = mainAxis === 'y' ? 'height' : 'width'; 3071 var offset = popperOffsets[mainAxis]; 3072 var min$1 = offset + overflow[mainSide]; 3073 var max$1 = offset - overflow[altSide]; 3074 var additive = tether ? -popperRect[len] / 2 : 0; 3075 var minLen = variation === start ? referenceRect[len] : popperRect[len]; 3076 var maxLen = variation === start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go 3077 // outside the reference bounds 3078 3079 var arrowElement = state.elements.arrow; 3080 var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : { 3081 width: 0, 3082 height: 0 3083 }; 3084 var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : getFreshSideObject(); 3085 var arrowPaddingMin = arrowPaddingObject[mainSide]; 3086 var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want 3087 // to include its full size in the calculation. If the reference is small 3088 // and near the edge of a boundary, the popper can overflow even if the 3089 // reference is not overflowing as well (e.g. virtual elements with no 3090 // width or height) 3091 3092 var arrowLen = within(0, referenceRect[len], arrowRect[len]); 3093 var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis; 3094 var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis; 3095 var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow); 3096 var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0; 3097 var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0; 3098 var tetherMin = offset + minOffset - offsetModifierValue - clientOffset; 3099 var tetherMax = offset + maxOffset - offsetModifierValue; 3100 var preventedOffset = within(tether ? min(min$1, tetherMin) : min$1, offset, tether ? max(max$1, tetherMax) : max$1); 3101 popperOffsets[mainAxis] = preventedOffset; 3102 data[mainAxis] = preventedOffset - offset; 3103 } 3104 3105 if (checkAltAxis) { 3106 var _offsetModifierState$2; 3107 3108 var _mainSide = mainAxis === 'x' ? top : left; 3109 3110 var _altSide = mainAxis === 'x' ? bottom : right; 3111 3112 var _offset = popperOffsets[altAxis]; 3113 3114 var _len = altAxis === 'y' ? 'height' : 'width'; 3115 3116 var _min = _offset + overflow[_mainSide]; 3117 3118 var _max = _offset - overflow[_altSide]; 3119 3120 var isOriginSide = [top, left].indexOf(basePlacement) !== -1; 3121 3122 var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0; 3123 3124 var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis; 3125 3126 var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max; 3127 3128 var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max); 3129 3130 popperOffsets[altAxis] = _preventedOffset; 3131 data[altAxis] = _preventedOffset - _offset; 3132 } 3133 3134 state.modifiersData[name] = data; 3135 } // eslint-disable-next-line import/no-unused-modules 3136 3137 3138 const preventOverflow$1 = { 3139 name: 'preventOverflow', 3140 enabled: true, 3141 phase: 'main', 3142 fn: preventOverflow, 3143 requiresIfExists: ['offset'] 3144 }; 3145 3146 function getHTMLElementScroll(element) { 3147 return { 3148 scrollLeft: element.scrollLeft, 3149 scrollTop: element.scrollTop 3150 }; 3151 } 3152 3153 function getNodeScroll(node) { 3154 if (node === getWindow(node) || !isHTMLElement(node)) { 3155 return getWindowScroll(node); 3156 } else { 3157 return getHTMLElementScroll(node); 3158 } 3159 } 3160 3161 function isElementScaled(element) { 3162 var rect = element.getBoundingClientRect(); 3163 var scaleX = round(rect.width) / element.offsetWidth || 1; 3164 var scaleY = round(rect.height) / element.offsetHeight || 1; 3165 return scaleX !== 1 || scaleY !== 1; 3166 } // Returns the composite rect of an element relative to its offsetParent. 3167 // Composite means it takes into account transforms as well as layout. 3168 3169 3170 function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) { 3171 if (isFixed === void 0) { 3172 isFixed = false; 3173 } 3174 3175 var isOffsetParentAnElement = isHTMLElement(offsetParent); 3176 var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent); 3177 var documentElement = getDocumentElement(offsetParent); 3178 var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed); 3179 var scroll = { 3180 scrollLeft: 0, 3181 scrollTop: 0 3182 }; 3183 var offsets = { 3184 x: 0, 3185 y: 0 3186 }; 3187 3188 if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) { 3189 if (getNodeName(offsetParent) !== 'body' || // https://github.com/popperjs/popper-core/issues/1078 3190 isScrollParent(documentElement)) { 3191 scroll = getNodeScroll(offsetParent); 3192 } 3193 3194 if (isHTMLElement(offsetParent)) { 3195 offsets = getBoundingClientRect(offsetParent, true); 3196 offsets.x += offsetParent.clientLeft; 3197 offsets.y += offsetParent.clientTop; 3198 } else if (documentElement) { 3199 offsets.x = getWindowScrollBarX(documentElement); 3200 } 3201 } 3202 3203 return { 3204 x: rect.left + scroll.scrollLeft - offsets.x, 3205 y: rect.top + scroll.scrollTop - offsets.y, 3206 width: rect.width, 3207 height: rect.height 3208 }; 3209 } 3210 3211 function order(modifiers) { 3212 var map = new Map(); 3213 var visited = new Set(); 3214 var result = []; 3215 modifiers.forEach(function (modifier) { 3216 map.set(modifier.name, modifier); 3217 }); // On visiting object, check for its dependencies and visit them recursively 3218 3219 function sort(modifier) { 3220 visited.add(modifier.name); 3221 var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []); 3222 requires.forEach(function (dep) { 3223 if (!visited.has(dep)) { 3224 var depModifier = map.get(dep); 3225 3226 if (depModifier) { 3227 sort(depModifier); 3228 } 3229 } 3230 }); 3231 result.push(modifier); 3232 } 3233 3234 modifiers.forEach(function (modifier) { 3235 if (!visited.has(modifier.name)) { 3236 // check for visited object 3237 sort(modifier); 3238 } 3239 }); 3240 return result; 3241 } 3242 3243 function orderModifiers(modifiers) { 3244 // order based on dependencies 3245 var orderedModifiers = order(modifiers); // order based on phase 3246 3247 return modifierPhases.reduce(function (acc, phase) { 3248 return acc.concat(orderedModifiers.filter(function (modifier) { 3249 return modifier.phase === phase; 3250 })); 3251 }, []); 3252 } 3253 3254 function debounce(fn) { 3255 var pending; 3256 return function () { 3257 if (!pending) { 3258 pending = new Promise(function (resolve) { 3259 Promise.resolve().then(function () { 3260 pending = undefined; 3261 resolve(fn()); 3262 }); 3263 }); 3264 } 3265 3266 return pending; 3267 }; 3268 } 3269 3270 function mergeByName(modifiers) { 3271 var merged = modifiers.reduce(function (merged, current) { 3272 var existing = merged[current.name]; 3273 merged[current.name] = existing ? Object.assign({}, existing, current, { 3274 options: Object.assign({}, existing.options, current.options), 3275 data: Object.assign({}, existing.data, current.data) 3276 }) : current; 3277 return merged; 3278 }, {}); // IE11 does not support Object.values 3279 3280 return Object.keys(merged).map(function (key) { 3281 return merged[key]; 3282 }); 3283 } 3284 3285 var DEFAULT_OPTIONS = { 3286 placement: 'bottom', 3287 modifiers: [], 3288 strategy: 'absolute' 3289 }; 3290 3291 function areValidElements() { 3292 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 3293 args[_key] = arguments[_key]; 3294 } 3295 3296 return !args.some(function (element) { 3297 return !(element && typeof element.getBoundingClientRect === 'function'); 3298 }); 3299 } 3300 3301 function popperGenerator(generatorOptions) { 3302 if (generatorOptions === void 0) { 3303 generatorOptions = {}; 3304 } 3305 3306 var _generatorOptions = generatorOptions, 3307 _generatorOptions$def = _generatorOptions.defaultModifiers, 3308 defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, 3309 _generatorOptions$def2 = _generatorOptions.defaultOptions, 3310 defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2; 3311 return function createPopper(reference, popper, options) { 3312 if (options === void 0) { 3313 options = defaultOptions; 3314 } 3315 3316 var state = { 3317 placement: 'bottom', 3318 orderedModifiers: [], 3319 options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions), 3320 modifiersData: {}, 3321 elements: { 3322 reference: reference, 3323 popper: popper 3324 }, 3325 attributes: {}, 3326 styles: {} 3327 }; 3328 var effectCleanupFns = []; 3329 var isDestroyed = false; 3330 var instance = { 3331 state: state, 3332 setOptions: function setOptions(setOptionsAction) { 3333 var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction; 3334 cleanupModifierEffects(); 3335 state.options = Object.assign({}, defaultOptions, state.options, options); 3336 state.scrollParents = { 3337 reference: isElement(reference) ? listScrollParents(reference) : reference.contextElement ? listScrollParents(reference.contextElement) : [], 3338 popper: listScrollParents(popper) 3339 }; // Orders the modifiers based on their dependencies and `phase` 3340 // properties 3341 3342 var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers 3343 3344 state.orderedModifiers = orderedModifiers.filter(function (m) { 3345 return m.enabled; 3346 }); 3347 runModifierEffects(); 3348 return instance.update(); 3349 }, 3350 // Sync update – it will always be executed, even if not necessary. This 3351 // is useful for low frequency updates where sync behavior simplifies the 3352 // logic. 3353 // For high frequency updates (e.g. `resize` and `scroll` events), always 3354 // prefer the async Popper#update method 3355 forceUpdate: function forceUpdate() { 3356 if (isDestroyed) { 3357 return; 3358 } 3359 3360 var _state$elements = state.elements, 3361 reference = _state$elements.reference, 3362 popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements 3363 // anymore 3364 3365 if (!areValidElements(reference, popper)) { 3366 return; 3367 } // Store the reference and popper rects to be read by modifiers 3368 3369 3370 state.rects = { 3371 reference: getCompositeRect(reference, getOffsetParent(popper), state.options.strategy === 'fixed'), 3372 popper: getLayoutRect(popper) 3373 }; // Modifiers have the ability to reset the current update cycle. The 3374 // most common use case for this is the `flip` modifier changing the 3375 // placement, which then needs to re-run all the modifiers, because the 3376 // logic was previously ran for the previous placement and is therefore 3377 // stale/incorrect 3378 3379 state.reset = false; 3380 state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier 3381 // is filled with the initial data specified by the modifier. This means 3382 // it doesn't persist and is fresh on each update. 3383 // To ensure persistent data, use `${name}#persistent` 3384 3385 state.orderedModifiers.forEach(function (modifier) { 3386 return state.modifiersData[modifier.name] = Object.assign({}, modifier.data); 3387 }); 3388 3389 for (var index = 0; index < state.orderedModifiers.length; index++) { 3390 if (state.reset === true) { 3391 state.reset = false; 3392 index = -1; 3393 continue; 3394 } 3395 3396 var _state$orderedModifie = state.orderedModifiers[index], 3397 fn = _state$orderedModifie.fn, 3398 _state$orderedModifie2 = _state$orderedModifie.options, 3399 _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, 3400 name = _state$orderedModifie.name; 3401 3402 if (typeof fn === 'function') { 3403 state = fn({ 3404 state: state, 3405 options: _options, 3406 name: name, 3407 instance: instance 3408 }) || state; 3409 } 3410 } 3411 }, 3412 // Async and optimistically optimized update – it will not be executed if 3413 // not necessary (debounced to run at most once-per-tick) 3414 update: debounce(function () { 3415 return new Promise(function (resolve) { 3416 instance.forceUpdate(); 3417 resolve(state); 3418 }); 3419 }), 3420 destroy: function destroy() { 3421 cleanupModifierEffects(); 3422 isDestroyed = true; 3423 } 3424 }; 3425 3426 if (!areValidElements(reference, popper)) { 3427 return instance; 3428 } 3429 3430 instance.setOptions(options).then(function (state) { 3431 if (!isDestroyed && options.onFirstUpdate) { 3432 options.onFirstUpdate(state); 3433 } 3434 }); // Modifiers have the ability to execute arbitrary code before the first 3435 // update cycle runs. They will be executed in the same order as the update 3436 // cycle. This is useful when a modifier adds some persistent data that 3437 // other modifiers need to use, but the modifier is run after the dependent 3438 // one. 3439 3440 function runModifierEffects() { 3441 state.orderedModifiers.forEach(function (_ref) { 3442 var name = _ref.name, 3443 _ref$options = _ref.options, 3444 options = _ref$options === void 0 ? {} : _ref$options, 3445 effect = _ref.effect; 3446 3447 if (typeof effect === 'function') { 3448 var cleanupFn = effect({ 3449 state: state, 3450 name: name, 3451 instance: instance, 3452 options: options 3453 }); 3454 3455 var noopFn = function noopFn() {}; 3456 3457 effectCleanupFns.push(cleanupFn || noopFn); 3458 } 3459 }); 3460 } 3461 3462 function cleanupModifierEffects() { 3463 effectCleanupFns.forEach(function (fn) { 3464 return fn(); 3465 }); 3466 effectCleanupFns = []; 3467 } 3468 3469 return instance; 3470 }; 3471 } 3472 var createPopper$2 = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules 3473 3474 var defaultModifiers$1 = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1]; 3475 var createPopper$1 = /*#__PURE__*/popperGenerator({ 3476 defaultModifiers: defaultModifiers$1 3477 }); // eslint-disable-next-line import/no-unused-modules 3478 3479 var defaultModifiers = [eventListeners, popperOffsets$1, computeStyles$1, applyStyles$1, offset$1, flip$1, preventOverflow$1, arrow$1, hide$1]; 3480 var createPopper = /*#__PURE__*/popperGenerator({ 3481 defaultModifiers: defaultModifiers 3482 }); // eslint-disable-next-line import/no-unused-modules 3483 3484 const Popper = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({ 3485 __proto__: null, 3486 afterMain, 3487 afterRead, 3488 afterWrite, 3489 applyStyles: applyStyles$1, 3490 arrow: arrow$1, 3491 auto, 3492 basePlacements, 3493 beforeMain, 3494 beforeRead, 3495 beforeWrite, 3496 bottom, 3497 clippingParents, 3498 computeStyles: computeStyles$1, 3499 createPopper, 3500 createPopperBase: createPopper$2, 3501 createPopperLite: createPopper$1, 3502 detectOverflow, 3503 end, 3504 eventListeners, 3505 flip: flip$1, 3506 hide: hide$1, 3507 left, 3508 main, 3509 modifierPhases, 3510 offset: offset$1, 3511 placements, 3512 popper, 3513 popperGenerator, 3514 popperOffsets: popperOffsets$1, 3515 preventOverflow: preventOverflow$1, 3516 read, 3517 reference, 3518 right, 3519 start, 3520 top, 3521 variationPlacements, 3522 viewport, 3523 write 3524 }, Symbol.toStringTag, { value: 'Module' })); 3525 3526 /** 3527 * -------------------------------------------------------------------------- 3528 * Bootstrap dropdown.js 3529 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3530 * -------------------------------------------------------------------------- 3531 */ 3532 3533 3534 /** 3535 * Constants 3536 */ 3537 3538 const NAME$a = 'dropdown'; 3539 const DATA_KEY$6 = 'bs.dropdown'; 3540 const EVENT_KEY$6 = `.${DATA_KEY$6}`; 3541 const DATA_API_KEY$3 = '.data-api'; 3542 const ESCAPE_KEY$2 = 'Escape'; 3543 const TAB_KEY$1 = 'Tab'; 3544 const ARROW_UP_KEY$1 = 'ArrowUp'; 3545 const ARROW_DOWN_KEY$1 = 'ArrowDown'; 3546 const RIGHT_MOUSE_BUTTON = 2; // MouseEvent.button value for the secondary button, usually the right button 3547 3548 const EVENT_HIDE$5 = `hide${EVENT_KEY$6}`; 3549 const EVENT_HIDDEN$5 = `hidden${EVENT_KEY$6}`; 3550 const EVENT_SHOW$5 = `show${EVENT_KEY$6}`; 3551 const EVENT_SHOWN$5 = `shown${EVENT_KEY$6}`; 3552 const EVENT_CLICK_DATA_API$3 = `click${EVENT_KEY$6}${DATA_API_KEY$3}`; 3553 const EVENT_KEYDOWN_DATA_API = `keydown${EVENT_KEY$6}${DATA_API_KEY$3}`; 3554 const EVENT_KEYUP_DATA_API = `keyup${EVENT_KEY$6}${DATA_API_KEY$3}`; 3555 const CLASS_NAME_SHOW$6 = 'show'; 3556 const CLASS_NAME_DROPUP = 'dropup'; 3557 const CLASS_NAME_DROPEND = 'dropend'; 3558 const CLASS_NAME_DROPSTART = 'dropstart'; 3559 const CLASS_NAME_DROPUP_CENTER = 'dropup-center'; 3560 const CLASS_NAME_DROPDOWN_CENTER = 'dropdown-center'; 3561 const SELECTOR_DATA_TOGGLE$3 = '[data-bs-toggle="dropdown"]:not(.disabled):not(:disabled)'; 3562 const SELECTOR_DATA_TOGGLE_SHOWN = `${SELECTOR_DATA_TOGGLE$3}.${CLASS_NAME_SHOW$6}`; 3563 const SELECTOR_MENU = '.dropdown-menu'; 3564 const SELECTOR_NAVBAR = '.navbar'; 3565 const SELECTOR_NAVBAR_NAV = '.navbar-nav'; 3566 const SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; 3567 const PLACEMENT_TOP = isRTL() ? 'top-end' : 'top-start'; 3568 const PLACEMENT_TOPEND = isRTL() ? 'top-start' : 'top-end'; 3569 const PLACEMENT_BOTTOM = isRTL() ? 'bottom-end' : 'bottom-start'; 3570 const PLACEMENT_BOTTOMEND = isRTL() ? 'bottom-start' : 'bottom-end'; 3571 const PLACEMENT_RIGHT = isRTL() ? 'left-start' : 'right-start'; 3572 const PLACEMENT_LEFT = isRTL() ? 'right-start' : 'left-start'; 3573 const PLACEMENT_TOPCENTER = 'top'; 3574 const PLACEMENT_BOTTOMCENTER = 'bottom'; 3575 const Default$9 = { 3576 autoClose: true, 3577 boundary: 'clippingParents', 3578 display: 'dynamic', 3579 offset: [0, 2], 3580 popperConfig: null, 3581 reference: 'toggle' 3582 }; 3583 const DefaultType$9 = { 3584 autoClose: '(boolean|string)', 3585 boundary: '(string|element)', 3586 display: 'string', 3587 offset: '(array|string|function)', 3588 popperConfig: '(null|object|function)', 3589 reference: '(string|element|object)' 3590 }; 3591 3592 /** 3593 * Class definition 3594 */ 3595 3596 class Dropdown extends BaseComponent { 3597 constructor(element, config) { 3598 super(element, config); 3599 this._popper = null; 3600 this._parent = this._element.parentNode; // dropdown wrapper 3601 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 3602 this._menu = SelectorEngine.next(this._element, SELECTOR_MENU)[0] || SelectorEngine.prev(this._element, SELECTOR_MENU)[0] || SelectorEngine.findOne(SELECTOR_MENU, this._parent); 3603 this._inNavbar = this._detectNavbar(); 3604 } 3605 3606 // Getters 3607 static get Default() { 3608 return Default$9; 3609 } 3610 static get DefaultType() { 3611 return DefaultType$9; 3612 } 3613 static get NAME() { 3614 return NAME$a; 3615 } 3616 3617 // Public 3618 toggle() { 3619 return this._isShown() ? this.hide() : this.show(); 3620 } 3621 show() { 3622 if (isDisabled(this._element) || this._isShown()) { 3623 return; 3624 } 3625 const relatedTarget = { 3626 relatedTarget: this._element 3627 }; 3628 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$5, relatedTarget); 3629 if (showEvent.defaultPrevented) { 3630 return; 3631 } 3632 this._createPopper(); 3633 3634 // If this is a touch-enabled device we add extra 3635 // empty mouseover listeners to the body's immediate children; 3636 // only needed because of broken event delegation on iOS 3637 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 3638 if ('ontouchstart' in document.documentElement && !this._parent.closest(SELECTOR_NAVBAR_NAV)) { 3639 for (const element of [].concat(...document.body.children)) { 3640 EventHandler.on(element, 'mouseover', noop); 3641 } 3642 } 3643 this._element.focus(); 3644 this._element.setAttribute('aria-expanded', true); 3645 this._menu.classList.add(CLASS_NAME_SHOW$6); 3646 this._element.classList.add(CLASS_NAME_SHOW$6); 3647 EventHandler.trigger(this._element, EVENT_SHOWN$5, relatedTarget); 3648 } 3649 hide() { 3650 if (isDisabled(this._element) || !this._isShown()) { 3651 return; 3652 } 3653 const relatedTarget = { 3654 relatedTarget: this._element 3655 }; 3656 this._completeHide(relatedTarget); 3657 } 3658 dispose() { 3659 if (this._popper) { 3660 this._popper.destroy(); 3661 } 3662 super.dispose(); 3663 } 3664 update() { 3665 this._inNavbar = this._detectNavbar(); 3666 if (this._popper) { 3667 this._popper.update(); 3668 } 3669 } 3670 3671 // Private 3672 _completeHide(relatedTarget) { 3673 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$5, relatedTarget); 3674 if (hideEvent.defaultPrevented) { 3675 return; 3676 } 3677 3678 // If this is a touch-enabled device we remove the extra 3679 // empty mouseover listeners we added for iOS support 3680 if ('ontouchstart' in document.documentElement) { 3681 for (const element of [].concat(...document.body.children)) { 3682 EventHandler.off(element, 'mouseover', noop); 3683 } 3684 } 3685 if (this._popper) { 3686 this._popper.destroy(); 3687 } 3688 this._menu.classList.remove(CLASS_NAME_SHOW$6); 3689 this._element.classList.remove(CLASS_NAME_SHOW$6); 3690 this._element.setAttribute('aria-expanded', 'false'); 3691 Manipulator.removeDataAttribute(this._menu, 'popper'); 3692 EventHandler.trigger(this._element, EVENT_HIDDEN$5, relatedTarget); 3693 } 3694 _getConfig(config) { 3695 config = super._getConfig(config); 3696 if (typeof config.reference === 'object' && !isElement$1(config.reference) && typeof config.reference.getBoundingClientRect !== 'function') { 3697 // Popper virtual elements require a getBoundingClientRect method 3698 throw new TypeError(`${NAME$a.toUpperCase()}: Option "reference" provided type "object" without a required "getBoundingClientRect" method.`); 3699 } 3700 return config; 3701 } 3702 _createPopper() { 3703 if (typeof Popper === 'undefined') { 3704 throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)'); 3705 } 3706 let referenceElement = this._element; 3707 if (this._config.reference === 'parent') { 3708 referenceElement = this._parent; 3709 } else if (isElement$1(this._config.reference)) { 3710 referenceElement = getElement(this._config.reference); 3711 } else if (typeof this._config.reference === 'object') { 3712 referenceElement = this._config.reference; 3713 } 3714 const popperConfig = this._getPopperConfig(); 3715 this._popper = createPopper(referenceElement, this._menu, popperConfig); 3716 } 3717 _isShown() { 3718 return this._menu.classList.contains(CLASS_NAME_SHOW$6); 3719 } 3720 _getPlacement() { 3721 const parentDropdown = this._parent; 3722 if (parentDropdown.classList.contains(CLASS_NAME_DROPEND)) { 3723 return PLACEMENT_RIGHT; 3724 } 3725 if (parentDropdown.classList.contains(CLASS_NAME_DROPSTART)) { 3726 return PLACEMENT_LEFT; 3727 } 3728 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP_CENTER)) { 3729 return PLACEMENT_TOPCENTER; 3730 } 3731 if (parentDropdown.classList.contains(CLASS_NAME_DROPDOWN_CENTER)) { 3732 return PLACEMENT_BOTTOMCENTER; 3733 } 3734 3735 // We need to trim the value because custom properties can also include spaces 3736 const isEnd = getComputedStyle(this._menu).getPropertyValue('--bs-position').trim() === 'end'; 3737 if (parentDropdown.classList.contains(CLASS_NAME_DROPUP)) { 3738 return isEnd ? PLACEMENT_TOPEND : PLACEMENT_TOP; 3739 } 3740 return isEnd ? PLACEMENT_BOTTOMEND : PLACEMENT_BOTTOM; 3741 } 3742 _detectNavbar() { 3743 return this._element.closest(SELECTOR_NAVBAR) !== null; 3744 } 3745 _getOffset() { 3746 const { 3747 offset 3748 } = this._config; 3749 if (typeof offset === 'string') { 3750 return offset.split(',').map(value => Number.parseInt(value, 10)); 3751 } 3752 if (typeof offset === 'function') { 3753 return popperData => offset(popperData, this._element); 3754 } 3755 return offset; 3756 } 3757 _getPopperConfig() { 3758 const defaultBsPopperConfig = { 3759 placement: this._getPlacement(), 3760 modifiers: [{ 3761 name: 'preventOverflow', 3762 options: { 3763 boundary: this._config.boundary 3764 } 3765 }, { 3766 name: 'offset', 3767 options: { 3768 offset: this._getOffset() 3769 } 3770 }] 3771 }; 3772 3773 // Disable Popper if we have a static display or Dropdown is in Navbar 3774 if (this._inNavbar || this._config.display === 'static') { 3775 Manipulator.setDataAttribute(this._menu, 'popper', 'static'); // TODO: v6 remove 3776 defaultBsPopperConfig.modifiers = [{ 3777 name: 'applyStyles', 3778 enabled: false 3779 }]; 3780 } 3781 return { 3782 ...defaultBsPopperConfig, 3783 ...execute(this._config.popperConfig, [defaultBsPopperConfig]) 3784 }; 3785 } 3786 _selectMenuItem({ 3787 key, 3788 target 3789 }) { 3790 const items = SelectorEngine.find(SELECTOR_VISIBLE_ITEMS, this._menu).filter(element => isVisible(element)); 3791 if (!items.length) { 3792 return; 3793 } 3794 3795 // if target isn't included in items (e.g. when expanding the dropdown) 3796 // allow cycling to get the last item in case key equals ARROW_UP_KEY 3797 getNextActiveElement(items, target, key === ARROW_DOWN_KEY$1, !items.includes(target)).focus(); 3798 } 3799 3800 // Static 3801 static jQueryInterface(config) { 3802 return this.each(function () { 3803 const data = Dropdown.getOrCreateInstance(this, config); 3804 if (typeof config !== 'string') { 3805 return; 3806 } 3807 if (typeof data[config] === 'undefined') { 3808 throw new TypeError(`No method named "${config}"`); 3809 } 3810 data[config](); 3811 }); 3812 } 3813 static clearMenus(event) { 3814 if (event.button === RIGHT_MOUSE_BUTTON || event.type === 'keyup' && event.key !== TAB_KEY$1) { 3815 return; 3816 } 3817 const openToggles = SelectorEngine.find(SELECTOR_DATA_TOGGLE_SHOWN); 3818 for (const toggle of openToggles) { 3819 const context = Dropdown.getInstance(toggle); 3820 if (!context || context._config.autoClose === false) { 3821 continue; 3822 } 3823 const composedPath = event.composedPath(); 3824 const isMenuTarget = composedPath.includes(context._menu); 3825 if (composedPath.includes(context._element) || context._config.autoClose === 'inside' && !isMenuTarget || context._config.autoClose === 'outside' && isMenuTarget) { 3826 continue; 3827 } 3828 3829 // Tab navigation through the dropdown menu or events from contained inputs shouldn't close the menu 3830 if (context._menu.contains(event.target) && (event.type === 'keyup' && event.key === TAB_KEY$1 || /input|select|option|textarea|form/i.test(event.target.tagName))) { 3831 continue; 3832 } 3833 const relatedTarget = { 3834 relatedTarget: context._element 3835 }; 3836 if (event.type === 'click') { 3837 relatedTarget.clickEvent = event; 3838 } 3839 context._completeHide(relatedTarget); 3840 } 3841 } 3842 static dataApiKeydownHandler(event) { 3843 // If not an UP | DOWN | ESCAPE key => not a dropdown command 3844 // If input/textarea && if key is other than ESCAPE => not a dropdown command 3845 3846 const isInput = /input|textarea/i.test(event.target.tagName); 3847 const isEscapeEvent = event.key === ESCAPE_KEY$2; 3848 const isUpOrDownEvent = [ARROW_UP_KEY$1, ARROW_DOWN_KEY$1].includes(event.key); 3849 if (!isUpOrDownEvent && !isEscapeEvent) { 3850 return; 3851 } 3852 if (isInput && !isEscapeEvent) { 3853 return; 3854 } 3855 event.preventDefault(); 3856 3857 // TODO: v6 revert #37011 & change markup https://getbootstrap.com/docs/5.3/forms/input-group/ 3858 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); 3859 const instance = Dropdown.getOrCreateInstance(getToggleButton); 3860 if (isUpOrDownEvent) { 3861 event.stopPropagation(); 3862 instance.show(); 3863 instance._selectMenuItem(event); 3864 return; 3865 } 3866 if (instance._isShown()) { 3867 // else is escape and we check if it is shown 3868 event.stopPropagation(); 3869 instance.hide(); 3870 getToggleButton.focus(); 3871 } 3872 } 3873 } 3874 3875 /** 3876 * Data API implementation 3877 */ 3878 3879 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$3, Dropdown.dataApiKeydownHandler); 3880 EventHandler.on(document, EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown.dataApiKeydownHandler); 3881 EventHandler.on(document, EVENT_CLICK_DATA_API$3, Dropdown.clearMenus); 3882 EventHandler.on(document, EVENT_KEYUP_DATA_API, Dropdown.clearMenus); 3883 EventHandler.on(document, EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) { 3884 event.preventDefault(); 3885 Dropdown.getOrCreateInstance(this).toggle(); 3886 }); 3887 3888 /** 3889 * jQuery 3890 */ 3891 3892 defineJQueryPlugin(Dropdown); 3893 3894 /** 3895 * -------------------------------------------------------------------------- 3896 * Bootstrap util/backdrop.js 3897 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 3898 * -------------------------------------------------------------------------- 3899 */ 3900 3901 3902 /** 3903 * Constants 3904 */ 3905 3906 const NAME$9 = 'backdrop'; 3907 const CLASS_NAME_FADE$4 = 'fade'; 3908 const CLASS_NAME_SHOW$5 = 'show'; 3909 const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$9}`; 3910 const Default$8 = { 3911 className: 'modal-backdrop', 3912 clickCallback: null, 3913 isAnimated: false, 3914 isVisible: true, 3915 // if false, we use the backdrop helper without adding any element to the dom 3916 rootElement: 'body' // give the choice to place backdrop under different elements 3917 }; 3918 const DefaultType$8 = { 3919 className: 'string', 3920 clickCallback: '(function|null)', 3921 isAnimated: 'boolean', 3922 isVisible: 'boolean', 3923 rootElement: '(element|string)' 3924 }; 3925 3926 /** 3927 * Class definition 3928 */ 3929 3930 class Backdrop extends Config { 3931 constructor(config) { 3932 super(); 3933 this._config = this._getConfig(config); 3934 this._isAppended = false; 3935 this._element = null; 3936 } 3937 3938 // Getters 3939 static get Default() { 3940 return Default$8; 3941 } 3942 static get DefaultType() { 3943 return DefaultType$8; 3944 } 3945 static get NAME() { 3946 return NAME$9; 3947 } 3948 3949 // Public 3950 show(callback) { 3951 if (!this._config.isVisible) { 3952 execute(callback); 3953 return; 3954 } 3955 this._append(); 3956 const element = this._getElement(); 3957 if (this._config.isAnimated) { 3958 reflow(element); 3959 } 3960 element.classList.add(CLASS_NAME_SHOW$5); 3961 this._emulateAnimation(() => { 3962 execute(callback); 3963 }); 3964 } 3965 hide(callback) { 3966 if (!this._config.isVisible) { 3967 execute(callback); 3968 return; 3969 } 3970 this._getElement().classList.remove(CLASS_NAME_SHOW$5); 3971 this._emulateAnimation(() => { 3972 this.dispose(); 3973 execute(callback); 3974 }); 3975 } 3976 dispose() { 3977 if (!this._isAppended) { 3978 return; 3979 } 3980 EventHandler.off(this._element, EVENT_MOUSEDOWN); 3981 this._element.remove(); 3982 this._isAppended = false; 3983 } 3984 3985 // Private 3986 _getElement() { 3987 if (!this._element) { 3988 const backdrop = document.createElement('div'); 3989 backdrop.className = this._config.className; 3990 if (this._config.isAnimated) { 3991 backdrop.classList.add(CLASS_NAME_FADE$4); 3992 } 3993 this._element = backdrop; 3994 } 3995 return this._element; 3996 } 3997 _configAfterMerge(config) { 3998 // use getElement() with the default "body" to get a fresh Element on each instantiation 3999 config.rootElement = getElement(config.rootElement); 4000 return config; 4001 } 4002 _append() { 4003 if (this._isAppended) { 4004 return; 4005 } 4006 const element = this._getElement(); 4007 this._config.rootElement.append(element); 4008 EventHandler.on(element, EVENT_MOUSEDOWN, () => { 4009 execute(this._config.clickCallback); 4010 }); 4011 this._isAppended = true; 4012 } 4013 _emulateAnimation(callback) { 4014 executeAfterTransition(callback, this._getElement(), this._config.isAnimated); 4015 } 4016 } 4017 4018 /** 4019 * -------------------------------------------------------------------------- 4020 * Bootstrap util/focustrap.js 4021 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4022 * -------------------------------------------------------------------------- 4023 */ 4024 4025 4026 /** 4027 * Constants 4028 */ 4029 4030 const NAME$8 = 'focustrap'; 4031 const DATA_KEY$5 = 'bs.focustrap'; 4032 const EVENT_KEY$5 = `.${DATA_KEY$5}`; 4033 const EVENT_FOCUSIN$2 = `focusin${EVENT_KEY$5}`; 4034 const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$5}`; 4035 const TAB_KEY = 'Tab'; 4036 const TAB_NAV_FORWARD = 'forward'; 4037 const TAB_NAV_BACKWARD = 'backward'; 4038 const Default$7 = { 4039 autofocus: true, 4040 trapElement: null // The element to trap focus inside of 4041 }; 4042 const DefaultType$7 = { 4043 autofocus: 'boolean', 4044 trapElement: 'element' 4045 }; 4046 4047 /** 4048 * Class definition 4049 */ 4050 4051 class FocusTrap extends Config { 4052 constructor(config) { 4053 super(); 4054 this._config = this._getConfig(config); 4055 this._isActive = false; 4056 this._lastTabNavDirection = null; 4057 } 4058 4059 // Getters 4060 static get Default() { 4061 return Default$7; 4062 } 4063 static get DefaultType() { 4064 return DefaultType$7; 4065 } 4066 static get NAME() { 4067 return NAME$8; 4068 } 4069 4070 // Public 4071 activate() { 4072 if (this._isActive) { 4073 return; 4074 } 4075 if (this._config.autofocus) { 4076 this._config.trapElement.focus(); 4077 } 4078 EventHandler.off(document, EVENT_KEY$5); // guard against infinite focus loop 4079 EventHandler.on(document, EVENT_FOCUSIN$2, event => this._handleFocusin(event)); 4080 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); 4081 this._isActive = true; 4082 } 4083 deactivate() { 4084 if (!this._isActive) { 4085 return; 4086 } 4087 this._isActive = false; 4088 EventHandler.off(document, EVENT_KEY$5); 4089 } 4090 4091 // Private 4092 _handleFocusin(event) { 4093 const { 4094 trapElement 4095 } = this._config; 4096 if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { 4097 return; 4098 } 4099 const elements = SelectorEngine.focusableChildren(trapElement); 4100 if (elements.length === 0) { 4101 trapElement.focus(); 4102 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { 4103 elements[elements.length - 1].focus(); 4104 } else { 4105 elements[0].focus(); 4106 } 4107 } 4108 _handleKeydown(event) { 4109 if (event.key !== TAB_KEY) { 4110 return; 4111 } 4112 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD; 4113 } 4114 } 4115 4116 /** 4117 * -------------------------------------------------------------------------- 4118 * Bootstrap util/scrollBar.js 4119 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4120 * -------------------------------------------------------------------------- 4121 */ 4122 4123 4124 /** 4125 * Constants 4126 */ 4127 4128 const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; 4129 const SELECTOR_STICKY_CONTENT = '.sticky-top'; 4130 const PROPERTY_PADDING = 'padding-right'; 4131 const PROPERTY_MARGIN = 'margin-right'; 4132 4133 /** 4134 * Class definition 4135 */ 4136 4137 class ScrollBarHelper { 4138 constructor() { 4139 this._element = document.body; 4140 } 4141 4142 // Public 4143 getWidth() { 4144 // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes 4145 const documentWidth = document.documentElement.clientWidth; 4146 return Math.abs(window.innerWidth - documentWidth); 4147 } 4148 hide() { 4149 const width = this.getWidth(); 4150 this._disableOverFlow(); 4151 // give padding to element to balance the hidden scrollbar width 4152 this._setElementAttributes(this._element, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 4153 // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth 4154 this._setElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING, calculatedValue => calculatedValue + width); 4155 this._setElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN, calculatedValue => calculatedValue - width); 4156 } 4157 reset() { 4158 this._resetElementAttributes(this._element, 'overflow'); 4159 this._resetElementAttributes(this._element, PROPERTY_PADDING); 4160 this._resetElementAttributes(SELECTOR_FIXED_CONTENT, PROPERTY_PADDING); 4161 this._resetElementAttributes(SELECTOR_STICKY_CONTENT, PROPERTY_MARGIN); 4162 } 4163 isOverflowing() { 4164 return this.getWidth() > 0; 4165 } 4166 4167 // Private 4168 _disableOverFlow() { 4169 this._saveInitialAttribute(this._element, 'overflow'); 4170 this._element.style.overflow = 'hidden'; 4171 } 4172 _setElementAttributes(selector, styleProperty, callback) { 4173 const scrollbarWidth = this.getWidth(); 4174 const manipulationCallBack = element => { 4175 if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) { 4176 return; 4177 } 4178 this._saveInitialAttribute(element, styleProperty); 4179 const calculatedValue = window.getComputedStyle(element).getPropertyValue(styleProperty); 4180 element.style.setProperty(styleProperty, `${callback(Number.parseFloat(calculatedValue))}px`); 4181 }; 4182 this._applyManipulationCallback(selector, manipulationCallBack); 4183 } 4184 _saveInitialAttribute(element, styleProperty) { 4185 const actualValue = element.style.getPropertyValue(styleProperty); 4186 if (actualValue) { 4187 Manipulator.setDataAttribute(element, styleProperty, actualValue); 4188 } 4189 } 4190 _resetElementAttributes(selector, styleProperty) { 4191 const manipulationCallBack = element => { 4192 const value = Manipulator.getDataAttribute(element, styleProperty); 4193 // We only want to remove the property if the value is `null`; the value can also be zero 4194 if (value === null) { 4195 element.style.removeProperty(styleProperty); 4196 return; 4197 } 4198 Manipulator.removeDataAttribute(element, styleProperty); 4199 element.style.setProperty(styleProperty, value); 4200 }; 4201 this._applyManipulationCallback(selector, manipulationCallBack); 4202 } 4203 _applyManipulationCallback(selector, callBack) { 4204 if (isElement$1(selector)) { 4205 callBack(selector); 4206 return; 4207 } 4208 for (const sel of SelectorEngine.find(selector, this._element)) { 4209 callBack(sel); 4210 } 4211 } 4212 } 4213 4214 /** 4215 * -------------------------------------------------------------------------- 4216 * Bootstrap modal.js 4217 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4218 * -------------------------------------------------------------------------- 4219 */ 4220 4221 4222 /** 4223 * Constants 4224 */ 4225 4226 const NAME$7 = 'modal'; 4227 const DATA_KEY$4 = 'bs.modal'; 4228 const EVENT_KEY$4 = `.${DATA_KEY$4}`; 4229 const DATA_API_KEY$2 = '.data-api'; 4230 const ESCAPE_KEY$1 = 'Escape'; 4231 const EVENT_HIDE$4 = `hide${EVENT_KEY$4}`; 4232 const EVENT_HIDE_PREVENTED$1 = `hidePrevented${EVENT_KEY$4}`; 4233 const EVENT_HIDDEN$4 = `hidden${EVENT_KEY$4}`; 4234 const EVENT_SHOW$4 = `show${EVENT_KEY$4}`; 4235 const EVENT_SHOWN$4 = `shown${EVENT_KEY$4}`; 4236 const EVENT_RESIZE$1 = `resize${EVENT_KEY$4}`; 4237 const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY$4}`; 4238 const EVENT_MOUSEDOWN_DISMISS = `mousedown.dismiss${EVENT_KEY$4}`; 4239 const EVENT_KEYDOWN_DISMISS$1 = `keydown.dismiss${EVENT_KEY$4}`; 4240 const EVENT_CLICK_DATA_API$2 = `click${EVENT_KEY$4}${DATA_API_KEY$2}`; 4241 const CLASS_NAME_OPEN = 'modal-open'; 4242 const CLASS_NAME_FADE$3 = 'fade'; 4243 const CLASS_NAME_SHOW$4 = 'show'; 4244 const CLASS_NAME_STATIC = 'modal-static'; 4245 const OPEN_SELECTOR$1 = '.modal.show'; 4246 const SELECTOR_DIALOG = '.modal-dialog'; 4247 const SELECTOR_MODAL_BODY = '.modal-body'; 4248 const SELECTOR_DATA_TOGGLE$2 = '[data-bs-toggle="modal"]'; 4249 const Default$6 = { 4250 backdrop: true, 4251 focus: true, 4252 keyboard: true 4253 }; 4254 const DefaultType$6 = { 4255 backdrop: '(boolean|string)', 4256 focus: 'boolean', 4257 keyboard: 'boolean' 4258 }; 4259 4260 /** 4261 * Class definition 4262 */ 4263 4264 class Modal extends BaseComponent { 4265 constructor(element, config) { 4266 super(element, config); 4267 this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element); 4268 this._backdrop = this._initializeBackDrop(); 4269 this._focustrap = this._initializeFocusTrap(); 4270 this._isShown = false; 4271 this._isTransitioning = false; 4272 this._scrollBar = new ScrollBarHelper(); 4273 this._addEventListeners(); 4274 } 4275 4276 // Getters 4277 static get Default() { 4278 return Default$6; 4279 } 4280 static get DefaultType() { 4281 return DefaultType$6; 4282 } 4283 static get NAME() { 4284 return NAME$7; 4285 } 4286 4287 // Public 4288 toggle(relatedTarget) { 4289 return this._isShown ? this.hide() : this.show(relatedTarget); 4290 } 4291 show(relatedTarget) { 4292 if (this._isShown || this._isTransitioning) { 4293 return; 4294 } 4295 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$4, { 4296 relatedTarget 4297 }); 4298 if (showEvent.defaultPrevented) { 4299 return; 4300 } 4301 this._isShown = true; 4302 this._isTransitioning = true; 4303 this._scrollBar.hide(); 4304 document.body.classList.add(CLASS_NAME_OPEN); 4305 this._adjustDialog(); 4306 this._backdrop.show(() => this._showElement(relatedTarget)); 4307 } 4308 hide() { 4309 if (!this._isShown || this._isTransitioning) { 4310 return; 4311 } 4312 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$4); 4313 if (hideEvent.defaultPrevented) { 4314 return; 4315 } 4316 this._isShown = false; 4317 this._isTransitioning = true; 4318 this._focustrap.deactivate(); 4319 this._element.classList.remove(CLASS_NAME_SHOW$4); 4320 this._queueCallback(() => this._hideModal(), this._element, this._isAnimated()); 4321 } 4322 dispose() { 4323 EventHandler.off(window, EVENT_KEY$4); 4324 EventHandler.off(this._dialog, EVENT_KEY$4); 4325 this._backdrop.dispose(); 4326 this._focustrap.deactivate(); 4327 super.dispose(); 4328 } 4329 handleUpdate() { 4330 this._adjustDialog(); 4331 } 4332 4333 // Private 4334 _initializeBackDrop() { 4335 return new Backdrop({ 4336 isVisible: Boolean(this._config.backdrop), 4337 // 'static' option will be translated to true, and booleans will keep their value, 4338 isAnimated: this._isAnimated() 4339 }); 4340 } 4341 _initializeFocusTrap() { 4342 return new FocusTrap({ 4343 trapElement: this._element 4344 }); 4345 } 4346 _showElement(relatedTarget) { 4347 // try to append dynamic modal 4348 if (!document.body.contains(this._element)) { 4349 document.body.append(this._element); 4350 } 4351 this._element.style.display = 'block'; 4352 this._element.removeAttribute('aria-hidden'); 4353 this._element.setAttribute('aria-modal', true); 4354 this._element.setAttribute('role', 'dialog'); 4355 this._element.scrollTop = 0; 4356 const modalBody = SelectorEngine.findOne(SELECTOR_MODAL_BODY, this._dialog); 4357 if (modalBody) { 4358 modalBody.scrollTop = 0; 4359 } 4360 reflow(this._element); 4361 this._element.classList.add(CLASS_NAME_SHOW$4); 4362 const transitionComplete = () => { 4363 if (this._config.focus) { 4364 this._focustrap.activate(); 4365 } 4366 this._isTransitioning = false; 4367 EventHandler.trigger(this._element, EVENT_SHOWN$4, { 4368 relatedTarget 4369 }); 4370 }; 4371 this._queueCallback(transitionComplete, this._dialog, this._isAnimated()); 4372 } 4373 _addEventListeners() { 4374 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS$1, event => { 4375 if (event.key !== ESCAPE_KEY$1) { 4376 return; 4377 } 4378 if (this._config.keyboard) { 4379 this.hide(); 4380 return; 4381 } 4382 this._triggerBackdropTransition(); 4383 }); 4384 EventHandler.on(window, EVENT_RESIZE$1, () => { 4385 if (this._isShown && !this._isTransitioning) { 4386 this._adjustDialog(); 4387 } 4388 }); 4389 EventHandler.on(this._element, EVENT_MOUSEDOWN_DISMISS, event => { 4390 // a bad trick to segregate clicks that may start inside dialog but end outside, and avoid listen to scrollbar clicks 4391 EventHandler.one(this._element, EVENT_CLICK_DISMISS, event2 => { 4392 if (this._element !== event.target || this._element !== event2.target) { 4393 return; 4394 } 4395 if (this._config.backdrop === 'static') { 4396 this._triggerBackdropTransition(); 4397 return; 4398 } 4399 if (this._config.backdrop) { 4400 this.hide(); 4401 } 4402 }); 4403 }); 4404 } 4405 _hideModal() { 4406 this._element.style.display = 'none'; 4407 this._element.setAttribute('aria-hidden', true); 4408 this._element.removeAttribute('aria-modal'); 4409 this._element.removeAttribute('role'); 4410 this._isTransitioning = false; 4411 this._backdrop.hide(() => { 4412 document.body.classList.remove(CLASS_NAME_OPEN); 4413 this._resetAdjustments(); 4414 this._scrollBar.reset(); 4415 EventHandler.trigger(this._element, EVENT_HIDDEN$4); 4416 }); 4417 } 4418 _isAnimated() { 4419 return this._element.classList.contains(CLASS_NAME_FADE$3); 4420 } 4421 _triggerBackdropTransition() { 4422 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED$1); 4423 if (hideEvent.defaultPrevented) { 4424 return; 4425 } 4426 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 4427 const initialOverflowY = this._element.style.overflowY; 4428 // return if the following background transition hasn't yet completed 4429 if (initialOverflowY === 'hidden' || this._element.classList.contains(CLASS_NAME_STATIC)) { 4430 return; 4431 } 4432 if (!isModalOverflowing) { 4433 this._element.style.overflowY = 'hidden'; 4434 } 4435 this._element.classList.add(CLASS_NAME_STATIC); 4436 this._queueCallback(() => { 4437 this._element.classList.remove(CLASS_NAME_STATIC); 4438 this._queueCallback(() => { 4439 this._element.style.overflowY = initialOverflowY; 4440 }, this._dialog); 4441 }, this._dialog); 4442 this._element.focus(); 4443 } 4444 4445 /** 4446 * The following methods are used to handle overflowing modals 4447 */ 4448 4449 _adjustDialog() { 4450 const isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; 4451 const scrollbarWidth = this._scrollBar.getWidth(); 4452 const isBodyOverflowing = scrollbarWidth > 0; 4453 if (isBodyOverflowing && !isModalOverflowing) { 4454 const property = isRTL() ? 'paddingLeft' : 'paddingRight'; 4455 this._element.style[property] = `${scrollbarWidth}px`; 4456 } 4457 if (!isBodyOverflowing && isModalOverflowing) { 4458 const property = isRTL() ? 'paddingRight' : 'paddingLeft'; 4459 this._element.style[property] = `${scrollbarWidth}px`; 4460 } 4461 } 4462 _resetAdjustments() { 4463 this._element.style.paddingLeft = ''; 4464 this._element.style.paddingRight = ''; 4465 } 4466 4467 // Static 4468 static jQueryInterface(config, relatedTarget) { 4469 return this.each(function () { 4470 const data = Modal.getOrCreateInstance(this, config); 4471 if (typeof config !== 'string') { 4472 return; 4473 } 4474 if (typeof data[config] === 'undefined') { 4475 throw new TypeError(`No method named "${config}"`); 4476 } 4477 data[config](relatedTarget); 4478 }); 4479 } 4480 } 4481 4482 /** 4483 * Data API implementation 4484 */ 4485 4486 EventHandler.on(document, EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) { 4487 const target = SelectorEngine.getElementFromSelector(this); 4488 if (['A', 'AREA'].includes(this.tagName)) { 4489 event.preventDefault(); 4490 } 4491 EventHandler.one(target, EVENT_SHOW$4, showEvent => { 4492 if (showEvent.defaultPrevented) { 4493 // only register focus restorer if modal will actually get shown 4494 return; 4495 } 4496 EventHandler.one(target, EVENT_HIDDEN$4, () => { 4497 if (isVisible(this)) { 4498 this.focus(); 4499 } 4500 }); 4501 }); 4502 4503 // avoid conflict when clicking modal toggler while another one is open 4504 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR$1); 4505 if (alreadyOpen) { 4506 Modal.getInstance(alreadyOpen).hide(); 4507 } 4508 const data = Modal.getOrCreateInstance(target); 4509 data.toggle(this); 4510 }); 4511 enableDismissTrigger(Modal); 4512 4513 /** 4514 * jQuery 4515 */ 4516 4517 defineJQueryPlugin(Modal); 4518 4519 /** 4520 * -------------------------------------------------------------------------- 4521 * Bootstrap offcanvas.js 4522 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4523 * -------------------------------------------------------------------------- 4524 */ 4525 4526 4527 /** 4528 * Constants 4529 */ 4530 4531 const NAME$6 = 'offcanvas'; 4532 const DATA_KEY$3 = 'bs.offcanvas'; 4533 const EVENT_KEY$3 = `.${DATA_KEY$3}`; 4534 const DATA_API_KEY$1 = '.data-api'; 4535 const EVENT_LOAD_DATA_API$2 = `load${EVENT_KEY$3}${DATA_API_KEY$1}`; 4536 const ESCAPE_KEY = 'Escape'; 4537 const CLASS_NAME_SHOW$3 = 'show'; 4538 const CLASS_NAME_SHOWING$1 = 'showing'; 4539 const CLASS_NAME_HIDING = 'hiding'; 4540 const CLASS_NAME_BACKDROP = 'offcanvas-backdrop'; 4541 const OPEN_SELECTOR = '.offcanvas.show'; 4542 const EVENT_SHOW$3 = `show${EVENT_KEY$3}`; 4543 const EVENT_SHOWN$3 = `shown${EVENT_KEY$3}`; 4544 const EVENT_HIDE$3 = `hide${EVENT_KEY$3}`; 4545 const EVENT_HIDE_PREVENTED = `hidePrevented${EVENT_KEY$3}`; 4546 const EVENT_HIDDEN$3 = `hidden${EVENT_KEY$3}`; 4547 const EVENT_RESIZE = `resize${EVENT_KEY$3}`; 4548 const EVENT_CLICK_DATA_API$1 = `click${EVENT_KEY$3}${DATA_API_KEY$1}`; 4549 const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY$3}`; 4550 const SELECTOR_DATA_TOGGLE$1 = '[data-bs-toggle="offcanvas"]'; 4551 const Default$5 = { 4552 backdrop: true, 4553 keyboard: true, 4554 scroll: false 4555 }; 4556 const DefaultType$5 = { 4557 backdrop: '(boolean|string)', 4558 keyboard: 'boolean', 4559 scroll: 'boolean' 4560 }; 4561 4562 /** 4563 * Class definition 4564 */ 4565 4566 class Offcanvas extends BaseComponent { 4567 constructor(element, config) { 4568 super(element, config); 4569 this._isShown = false; 4570 this._backdrop = this._initializeBackDrop(); 4571 this._focustrap = this._initializeFocusTrap(); 4572 this._addEventListeners(); 4573 } 4574 4575 // Getters 4576 static get Default() { 4577 return Default$5; 4578 } 4579 static get DefaultType() { 4580 return DefaultType$5; 4581 } 4582 static get NAME() { 4583 return NAME$6; 4584 } 4585 4586 // Public 4587 toggle(relatedTarget) { 4588 return this._isShown ? this.hide() : this.show(relatedTarget); 4589 } 4590 show(relatedTarget) { 4591 if (this._isShown) { 4592 return; 4593 } 4594 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW$3, { 4595 relatedTarget 4596 }); 4597 if (showEvent.defaultPrevented) { 4598 return; 4599 } 4600 this._isShown = true; 4601 this._backdrop.show(); 4602 if (!this._config.scroll) { 4603 new ScrollBarHelper().hide(); 4604 } 4605 this._element.setAttribute('aria-modal', true); 4606 this._element.setAttribute('role', 'dialog'); 4607 this._element.classList.add(CLASS_NAME_SHOWING$1); 4608 const completeCallBack = () => { 4609 if (!this._config.scroll || this._config.backdrop) { 4610 this._focustrap.activate(); 4611 } 4612 this._element.classList.add(CLASS_NAME_SHOW$3); 4613 this._element.classList.remove(CLASS_NAME_SHOWING$1); 4614 EventHandler.trigger(this._element, EVENT_SHOWN$3, { 4615 relatedTarget 4616 }); 4617 }; 4618 this._queueCallback(completeCallBack, this._element, true); 4619 } 4620 hide() { 4621 if (!this._isShown) { 4622 return; 4623 } 4624 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE$3); 4625 if (hideEvent.defaultPrevented) { 4626 return; 4627 } 4628 this._focustrap.deactivate(); 4629 this._element.blur(); 4630 this._isShown = false; 4631 this._element.classList.add(CLASS_NAME_HIDING); 4632 this._backdrop.hide(); 4633 const completeCallback = () => { 4634 this._element.classList.remove(CLASS_NAME_SHOW$3, CLASS_NAME_HIDING); 4635 this._element.removeAttribute('aria-modal'); 4636 this._element.removeAttribute('role'); 4637 if (!this._config.scroll) { 4638 new ScrollBarHelper().reset(); 4639 } 4640 EventHandler.trigger(this._element, EVENT_HIDDEN$3); 4641 }; 4642 this._queueCallback(completeCallback, this._element, true); 4643 } 4644 dispose() { 4645 this._backdrop.dispose(); 4646 this._focustrap.deactivate(); 4647 super.dispose(); 4648 } 4649 4650 // Private 4651 _initializeBackDrop() { 4652 const clickCallback = () => { 4653 if (this._config.backdrop === 'static') { 4654 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 4655 return; 4656 } 4657 this.hide(); 4658 }; 4659 4660 // 'static' option will be translated to true, and booleans will keep their value 4661 const isVisible = Boolean(this._config.backdrop); 4662 return new Backdrop({ 4663 className: CLASS_NAME_BACKDROP, 4664 isVisible, 4665 isAnimated: true, 4666 rootElement: this._element.parentNode, 4667 clickCallback: isVisible ? clickCallback : null 4668 }); 4669 } 4670 _initializeFocusTrap() { 4671 return new FocusTrap({ 4672 trapElement: this._element 4673 }); 4674 } 4675 _addEventListeners() { 4676 EventHandler.on(this._element, EVENT_KEYDOWN_DISMISS, event => { 4677 if (event.key !== ESCAPE_KEY) { 4678 return; 4679 } 4680 if (this._config.keyboard) { 4681 this.hide(); 4682 return; 4683 } 4684 EventHandler.trigger(this._element, EVENT_HIDE_PREVENTED); 4685 }); 4686 } 4687 4688 // Static 4689 static jQueryInterface(config) { 4690 return this.each(function () { 4691 const data = Offcanvas.getOrCreateInstance(this, config); 4692 if (typeof config !== 'string') { 4693 return; 4694 } 4695 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 4696 throw new TypeError(`No method named "${config}"`); 4697 } 4698 data[config](this); 4699 }); 4700 } 4701 } 4702 4703 /** 4704 * Data API implementation 4705 */ 4706 4707 EventHandler.on(document, EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) { 4708 const target = SelectorEngine.getElementFromSelector(this); 4709 if (['A', 'AREA'].includes(this.tagName)) { 4710 event.preventDefault(); 4711 } 4712 if (isDisabled(this)) { 4713 return; 4714 } 4715 EventHandler.one(target, EVENT_HIDDEN$3, () => { 4716 // focus on trigger when it is closed 4717 if (isVisible(this)) { 4718 this.focus(); 4719 } 4720 }); 4721 4722 // avoid conflict when clicking a toggler of an offcanvas, while another is open 4723 const alreadyOpen = SelectorEngine.findOne(OPEN_SELECTOR); 4724 if (alreadyOpen && alreadyOpen !== target) { 4725 Offcanvas.getInstance(alreadyOpen).hide(); 4726 } 4727 const data = Offcanvas.getOrCreateInstance(target); 4728 data.toggle(this); 4729 }); 4730 EventHandler.on(window, EVENT_LOAD_DATA_API$2, () => { 4731 for (const selector of SelectorEngine.find(OPEN_SELECTOR)) { 4732 Offcanvas.getOrCreateInstance(selector).show(); 4733 } 4734 }); 4735 EventHandler.on(window, EVENT_RESIZE, () => { 4736 for (const element of SelectorEngine.find('[aria-modal][class*=show][class*=offcanvas-]')) { 4737 if (getComputedStyle(element).position !== 'fixed') { 4738 Offcanvas.getOrCreateInstance(element).hide(); 4739 } 4740 } 4741 }); 4742 enableDismissTrigger(Offcanvas); 4743 4744 /** 4745 * jQuery 4746 */ 4747 4748 defineJQueryPlugin(Offcanvas); 4749 4750 /** 4751 * -------------------------------------------------------------------------- 4752 * Bootstrap util/sanitizer.js 4753 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4754 * -------------------------------------------------------------------------- 4755 */ 4756 4757 // js-docs-start allow-list 4758 const ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; 4759 const DefaultAllowlist = { 4760 // Global attributes allowed on any supplied element below. 4761 '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], 4762 a: ['target', 'href', 'title', 'rel'], 4763 area: [], 4764 b: [], 4765 br: [], 4766 col: [], 4767 code: [], 4768 dd: [], 4769 div: [], 4770 dl: [], 4771 dt: [], 4772 em: [], 4773 hr: [], 4774 h1: [], 4775 h2: [], 4776 h3: [], 4777 h4: [], 4778 h5: [], 4779 h6: [], 4780 i: [], 4781 img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], 4782 li: [], 4783 ol: [], 4784 p: [], 4785 pre: [], 4786 s: [], 4787 small: [], 4788 span: [], 4789 sub: [], 4790 sup: [], 4791 strong: [], 4792 u: [], 4793 ul: [] 4794 }; 4795 // js-docs-end allow-list 4796 4797 const uriAttributes = new Set(['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']); 4798 4799 /** 4800 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation 4801 * contexts. 4802 * 4803 * Shout-out to Angular https://github.com/angular/angular/blob/15.2.8/packages/core/src/sanitization/url_sanitizer.ts#L38 4804 */ 4805 // eslint-disable-next-line unicorn/better-regex 4806 const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:/?#]*(?:[/?#]|$))/i; 4807 const allowedAttribute = (attribute, allowedAttributeList) => { 4808 const attributeName = attribute.nodeName.toLowerCase(); 4809 if (allowedAttributeList.includes(attributeName)) { 4810 if (uriAttributes.has(attributeName)) { 4811 return Boolean(SAFE_URL_PATTERN.test(attribute.nodeValue)); 4812 } 4813 return true; 4814 } 4815 4816 // Check if a regular expression validates the attribute. 4817 return allowedAttributeList.filter(attributeRegex => attributeRegex instanceof RegExp).some(regex => regex.test(attributeName)); 4818 }; 4819 function sanitizeHtml(unsafeHtml, allowList, sanitizeFunction) { 4820 if (!unsafeHtml.length) { 4821 return unsafeHtml; 4822 } 4823 if (sanitizeFunction && typeof sanitizeFunction === 'function') { 4824 return sanitizeFunction(unsafeHtml); 4825 } 4826 const domParser = new window.DOMParser(); 4827 const createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); 4828 const elements = [].concat(...createdDocument.body.querySelectorAll('*')); 4829 for (const element of elements) { 4830 const elementName = element.nodeName.toLowerCase(); 4831 if (!Object.keys(allowList).includes(elementName)) { 4832 element.remove(); 4833 continue; 4834 } 4835 const attributeList = [].concat(...element.attributes); 4836 const allowedAttributes = [].concat(allowList['*'] || [], allowList[elementName] || []); 4837 for (const attribute of attributeList) { 4838 if (!allowedAttribute(attribute, allowedAttributes)) { 4839 element.removeAttribute(attribute.nodeName); 4840 } 4841 } 4842 } 4843 return createdDocument.body.innerHTML; 4844 } 4845 4846 /** 4847 * -------------------------------------------------------------------------- 4848 * Bootstrap util/template-factory.js 4849 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4850 * -------------------------------------------------------------------------- 4851 */ 4852 4853 4854 /** 4855 * Constants 4856 */ 4857 4858 const NAME$5 = 'TemplateFactory'; 4859 const Default$4 = { 4860 allowList: DefaultAllowlist, 4861 content: {}, 4862 // { selector : text , selector2 : text2 , } 4863 extraClass: '', 4864 html: false, 4865 sanitize: true, 4866 sanitizeFn: null, 4867 template: '<div></div>' 4868 }; 4869 const DefaultType$4 = { 4870 allowList: 'object', 4871 content: 'object', 4872 extraClass: '(string|function)', 4873 html: 'boolean', 4874 sanitize: 'boolean', 4875 sanitizeFn: '(null|function)', 4876 template: 'string' 4877 }; 4878 const DefaultContentType = { 4879 entry: '(string|element|function|null)', 4880 selector: '(string|element)' 4881 }; 4882 4883 /** 4884 * Class definition 4885 */ 4886 4887 class TemplateFactory extends Config { 4888 constructor(config) { 4889 super(); 4890 this._config = this._getConfig(config); 4891 } 4892 4893 // Getters 4894 static get Default() { 4895 return Default$4; 4896 } 4897 static get DefaultType() { 4898 return DefaultType$4; 4899 } 4900 static get NAME() { 4901 return NAME$5; 4902 } 4903 4904 // Public 4905 getContent() { 4906 return Object.values(this._config.content).map(config => this._resolvePossibleFunction(config)).filter(Boolean); 4907 } 4908 hasContent() { 4909 return this.getContent().length > 0; 4910 } 4911 changeContent(content) { 4912 this._checkContent(content); 4913 this._config.content = { 4914 ...this._config.content, 4915 ...content 4916 }; 4917 return this; 4918 } 4919 toHtml() { 4920 const templateWrapper = document.createElement('div'); 4921 templateWrapper.innerHTML = this._maybeSanitize(this._config.template); 4922 for (const [selector, text] of Object.entries(this._config.content)) { 4923 this._setContent(templateWrapper, text, selector); 4924 } 4925 const template = templateWrapper.children[0]; 4926 const extraClass = this._resolvePossibleFunction(this._config.extraClass); 4927 if (extraClass) { 4928 template.classList.add(...extraClass.split(' ')); 4929 } 4930 return template; 4931 } 4932 4933 // Private 4934 _typeCheckConfig(config) { 4935 super._typeCheckConfig(config); 4936 this._checkContent(config.content); 4937 } 4938 _checkContent(arg) { 4939 for (const [selector, content] of Object.entries(arg)) { 4940 super._typeCheckConfig({ 4941 selector, 4942 entry: content 4943 }, DefaultContentType); 4944 } 4945 } 4946 _setContent(template, content, selector) { 4947 const templateElement = SelectorEngine.findOne(selector, template); 4948 if (!templateElement) { 4949 return; 4950 } 4951 content = this._resolvePossibleFunction(content); 4952 if (!content) { 4953 templateElement.remove(); 4954 return; 4955 } 4956 if (isElement$1(content)) { 4957 this._putElementInTemplate(getElement(content), templateElement); 4958 return; 4959 } 4960 if (this._config.html) { 4961 templateElement.innerHTML = this._maybeSanitize(content); 4962 return; 4963 } 4964 templateElement.textContent = content; 4965 } 4966 _maybeSanitize(arg) { 4967 return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg; 4968 } 4969 _resolvePossibleFunction(arg) { 4970 return execute(arg, [this]); 4971 } 4972 _putElementInTemplate(element, templateElement) { 4973 if (this._config.html) { 4974 templateElement.innerHTML = ''; 4975 templateElement.append(element); 4976 return; 4977 } 4978 templateElement.textContent = element.textContent; 4979 } 4980 } 4981 4982 /** 4983 * -------------------------------------------------------------------------- 4984 * Bootstrap tooltip.js 4985 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 4986 * -------------------------------------------------------------------------- 4987 */ 4988 4989 4990 /** 4991 * Constants 4992 */ 4993 4994 const NAME$4 = 'tooltip'; 4995 const DISALLOWED_ATTRIBUTES = new Set(['sanitize', 'allowList', 'sanitizeFn']); 4996 const CLASS_NAME_FADE$2 = 'fade'; 4997 const CLASS_NAME_MODAL = 'modal'; 4998 const CLASS_NAME_SHOW$2 = 'show'; 4999 const SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; 5000 const SELECTOR_MODAL = `.${CLASS_NAME_MODAL}`; 5001 const EVENT_MODAL_HIDE = 'hide.bs.modal'; 5002 const TRIGGER_HOVER = 'hover'; 5003 const TRIGGER_FOCUS = 'focus'; 5004 const TRIGGER_CLICK = 'click'; 5005 const TRIGGER_MANUAL = 'manual'; 5006 const EVENT_HIDE$2 = 'hide'; 5007 const EVENT_HIDDEN$2 = 'hidden'; 5008 const EVENT_SHOW$2 = 'show'; 5009 const EVENT_SHOWN$2 = 'shown'; 5010 const EVENT_INSERTED = 'inserted'; 5011 const EVENT_CLICK$1 = 'click'; 5012 const EVENT_FOCUSIN$1 = 'focusin'; 5013 const EVENT_FOCUSOUT$1 = 'focusout'; 5014 const EVENT_MOUSEENTER = 'mouseenter'; 5015 const EVENT_MOUSELEAVE = 'mouseleave'; 5016 const AttachmentMap = { 5017 AUTO: 'auto', 5018 TOP: 'top', 5019 RIGHT: isRTL() ? 'left' : 'right', 5020 BOTTOM: 'bottom', 5021 LEFT: isRTL() ? 'right' : 'left' 5022 }; 5023 const Default$3 = { 5024 allowList: DefaultAllowlist, 5025 animation: true, 5026 boundary: 'clippingParents', 5027 container: false, 5028 customClass: '', 5029 delay: 0, 5030 fallbackPlacements: ['top', 'right', 'bottom', 'left'], 5031 html: false, 5032 offset: [0, 6], 5033 placement: 'top', 5034 popperConfig: null, 5035 sanitize: true, 5036 sanitizeFn: null, 5037 selector: false, 5038 template: '<div class="tooltip" role="tooltip">' + '<div class="tooltip-arrow"></div>' + '<div class="tooltip-inner"></div>' + '</div>', 5039 title: '', 5040 trigger: 'hover focus' 5041 }; 5042 const DefaultType$3 = { 5043 allowList: 'object', 5044 animation: 'boolean', 5045 boundary: '(string|element)', 5046 container: '(string|element|boolean)', 5047 customClass: '(string|function)', 5048 delay: '(number|object)', 5049 fallbackPlacements: 'array', 5050 html: 'boolean', 5051 offset: '(array|string|function)', 5052 placement: '(string|function)', 5053 popperConfig: '(null|object|function)', 5054 sanitize: 'boolean', 5055 sanitizeFn: '(null|function)', 5056 selector: '(string|boolean)', 5057 template: 'string', 5058 title: '(string|element|function)', 5059 trigger: 'string' 5060 }; 5061 5062 /** 5063 * Class definition 5064 */ 5065 5066 class Tooltip extends BaseComponent { 5067 constructor(element, config) { 5068 if (typeof Popper === 'undefined') { 5069 throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); 5070 } 5071 super(element, config); 5072 5073 // Private 5074 this._isEnabled = true; 5075 this._timeout = 0; 5076 this._isHovered = null; 5077 this._activeTrigger = {}; 5078 this._popper = null; 5079 this._templateFactory = null; 5080 this._newContent = null; 5081 5082 // Protected 5083 this.tip = null; 5084 this._setListeners(); 5085 if (!this._config.selector) { 5086 this._fixTitle(); 5087 } 5088 } 5089 5090 // Getters 5091 static get Default() { 5092 return Default$3; 5093 } 5094 static get DefaultType() { 5095 return DefaultType$3; 5096 } 5097 static get NAME() { 5098 return NAME$4; 5099 } 5100 5101 // Public 5102 enable() { 5103 this._isEnabled = true; 5104 } 5105 disable() { 5106 this._isEnabled = false; 5107 } 5108 toggleEnabled() { 5109 this._isEnabled = !this._isEnabled; 5110 } 5111 toggle() { 5112 if (!this._isEnabled) { 5113 return; 5114 } 5115 this._activeTrigger.click = !this._activeTrigger.click; 5116 if (this._isShown()) { 5117 this._leave(); 5118 return; 5119 } 5120 this._enter(); 5121 } 5122 dispose() { 5123 clearTimeout(this._timeout); 5124 EventHandler.off(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 5125 if (this._element.getAttribute('data-bs-original-title')) { 5126 this._element.setAttribute('title', this._element.getAttribute('data-bs-original-title')); 5127 } 5128 this._disposePopper(); 5129 super.dispose(); 5130 } 5131 show() { 5132 if (this._element.style.display === 'none') { 5133 throw new Error('Please use show on visible elements'); 5134 } 5135 if (!(this._isWithContent() && this._isEnabled)) { 5136 return; 5137 } 5138 const showEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOW$2)); 5139 const shadowRoot = findShadowRoot(this._element); 5140 const isInTheDom = (shadowRoot || this._element.ownerDocument.documentElement).contains(this._element); 5141 if (showEvent.defaultPrevented || !isInTheDom) { 5142 return; 5143 } 5144 5145 // TODO: v6 remove this or make it optional 5146 this._disposePopper(); 5147 const tip = this._getTipElement(); 5148 this._element.setAttribute('aria-describedby', tip.getAttribute('id')); 5149 const { 5150 container 5151 } = this._config; 5152 if (!this._element.ownerDocument.documentElement.contains(this.tip)) { 5153 container.append(tip); 5154 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_INSERTED)); 5155 } 5156 this._popper = this._createPopper(tip); 5157 tip.classList.add(CLASS_NAME_SHOW$2); 5158 5159 // If this is a touch-enabled device we add extra 5160 // empty mouseover listeners to the body's immediate children; 5161 // only needed because of broken event delegation on iOS 5162 // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html 5163 if ('ontouchstart' in document.documentElement) { 5164 for (const element of [].concat(...document.body.children)) { 5165 EventHandler.on(element, 'mouseover', noop); 5166 } 5167 } 5168 const complete = () => { 5169 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_SHOWN$2)); 5170 if (this._isHovered === false) { 5171 this._leave(); 5172 } 5173 this._isHovered = false; 5174 }; 5175 this._queueCallback(complete, this.tip, this._isAnimated()); 5176 } 5177 hide() { 5178 if (!this._isShown()) { 5179 return; 5180 } 5181 const hideEvent = EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDE$2)); 5182 if (hideEvent.defaultPrevented) { 5183 return; 5184 } 5185 const tip = this._getTipElement(); 5186 tip.classList.remove(CLASS_NAME_SHOW$2); 5187 5188 // If this is a touch-enabled device we remove the extra 5189 // empty mouseover listeners we added for iOS support 5190 if ('ontouchstart' in document.documentElement) { 5191 for (const element of [].concat(...document.body.children)) { 5192 EventHandler.off(element, 'mouseover', noop); 5193 } 5194 } 5195 this._activeTrigger[TRIGGER_CLICK] = false; 5196 this._activeTrigger[TRIGGER_FOCUS] = false; 5197 this._activeTrigger[TRIGGER_HOVER] = false; 5198 this._isHovered = null; // it is a trick to support manual triggering 5199 5200 const complete = () => { 5201 if (this._isWithActiveTrigger()) { 5202 return; 5203 } 5204 if (!this._isHovered) { 5205 this._disposePopper(); 5206 } 5207 this._element.removeAttribute('aria-describedby'); 5208 EventHandler.trigger(this._element, this.constructor.eventName(EVENT_HIDDEN$2)); 5209 }; 5210 this._queueCallback(complete, this.tip, this._isAnimated()); 5211 } 5212 update() { 5213 if (this._popper) { 5214 this._popper.update(); 5215 } 5216 } 5217 5218 // Protected 5219 _isWithContent() { 5220 return Boolean(this._getTitle()); 5221 } 5222 _getTipElement() { 5223 if (!this.tip) { 5224 this.tip = this._createTipElement(this._newContent || this._getContentForTemplate()); 5225 } 5226 return this.tip; 5227 } 5228 _createTipElement(content) { 5229 const tip = this._getTemplateFactory(content).toHtml(); 5230 5231 // TODO: remove this check in v6 5232 if (!tip) { 5233 return null; 5234 } 5235 tip.classList.remove(CLASS_NAME_FADE$2, CLASS_NAME_SHOW$2); 5236 // TODO: v6 the following can be achieved with CSS only 5237 tip.classList.add(`bs-${this.constructor.NAME}-auto`); 5238 const tipId = getUID(this.constructor.NAME).toString(); 5239 tip.setAttribute('id', tipId); 5240 if (this._isAnimated()) { 5241 tip.classList.add(CLASS_NAME_FADE$2); 5242 } 5243 return tip; 5244 } 5245 setContent(content) { 5246 this._newContent = content; 5247 if (this._isShown()) { 5248 this._disposePopper(); 5249 this.show(); 5250 } 5251 } 5252 _getTemplateFactory(content) { 5253 if (this._templateFactory) { 5254 this._templateFactory.changeContent(content); 5255 } else { 5256 this._templateFactory = new TemplateFactory({ 5257 ...this._config, 5258 // the `content` var has to be after `this._config` 5259 // to override config.content in case of popover 5260 content, 5261 extraClass: this._resolvePossibleFunction(this._config.customClass) 5262 }); 5263 } 5264 return this._templateFactory; 5265 } 5266 _getContentForTemplate() { 5267 return { 5268 [SELECTOR_TOOLTIP_INNER]: this._getTitle() 5269 }; 5270 } 5271 _getTitle() { 5272 return this._resolvePossibleFunction(this._config.title) || this._element.getAttribute('data-bs-original-title'); 5273 } 5274 5275 // Private 5276 _initializeOnDelegatedTarget(event) { 5277 return this.constructor.getOrCreateInstance(event.delegateTarget, this._getDelegateConfig()); 5278 } 5279 _isAnimated() { 5280 return this._config.animation || this.tip && this.tip.classList.contains(CLASS_NAME_FADE$2); 5281 } 5282 _isShown() { 5283 return this.tip && this.tip.classList.contains(CLASS_NAME_SHOW$2); 5284 } 5285 _createPopper(tip) { 5286 const placement = execute(this._config.placement, [this, tip, this._element]); 5287 const attachment = AttachmentMap[placement.toUpperCase()]; 5288 return createPopper(this._element, tip, this._getPopperConfig(attachment)); 5289 } 5290 _getOffset() { 5291 const { 5292 offset 5293 } = this._config; 5294 if (typeof offset === 'string') { 5295 return offset.split(',').map(value => Number.parseInt(value, 10)); 5296 } 5297 if (typeof offset === 'function') { 5298 return popperData => offset(popperData, this._element); 5299 } 5300 return offset; 5301 } 5302 _resolvePossibleFunction(arg) { 5303 return execute(arg, [this._element]); 5304 } 5305 _getPopperConfig(attachment) { 5306 const defaultBsPopperConfig = { 5307 placement: attachment, 5308 modifiers: [{ 5309 name: 'flip', 5310 options: { 5311 fallbackPlacements: this._config.fallbackPlacements 5312 } 5313 }, { 5314 name: 'offset', 5315 options: { 5316 offset: this._getOffset() 5317 } 5318 }, { 5319 name: 'preventOverflow', 5320 options: { 5321 boundary: this._config.boundary 5322 } 5323 }, { 5324 name: 'arrow', 5325 options: { 5326 element: `.${this.constructor.NAME}-arrow` 5327 } 5328 }, { 5329 name: 'preSetPlacement', 5330 enabled: true, 5331 phase: 'beforeMain', 5332 fn: data => { 5333 // Pre-set Popper's placement attribute in order to read the arrow sizes properly. 5334 // Otherwise, Popper mixes up the width and height dimensions since the initial arrow style is for top placement 5335 this._getTipElement().setAttribute('data-popper-placement', data.state.placement); 5336 } 5337 }] 5338 }; 5339 return { 5340 ...defaultBsPopperConfig, 5341 ...execute(this._config.popperConfig, [defaultBsPopperConfig]) 5342 }; 5343 } 5344 _setListeners() { 5345 const triggers = this._config.trigger.split(' '); 5346 for (const trigger of triggers) { 5347 if (trigger === 'click') { 5348 EventHandler.on(this._element, this.constructor.eventName(EVENT_CLICK$1), this._config.selector, event => { 5349 const context = this._initializeOnDelegatedTarget(event); 5350 context.toggle(); 5351 }); 5352 } else if (trigger !== TRIGGER_MANUAL) { 5353 const eventIn = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSEENTER) : this.constructor.eventName(EVENT_FOCUSIN$1); 5354 const eventOut = trigger === TRIGGER_HOVER ? this.constructor.eventName(EVENT_MOUSELEAVE) : this.constructor.eventName(EVENT_FOCUSOUT$1); 5355 EventHandler.on(this._element, eventIn, this._config.selector, event => { 5356 const context = this._initializeOnDelegatedTarget(event); 5357 context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; 5358 context._enter(); 5359 }); 5360 EventHandler.on(this._element, eventOut, this._config.selector, event => { 5361 const context = this._initializeOnDelegatedTarget(event); 5362 context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = context._element.contains(event.relatedTarget); 5363 context._leave(); 5364 }); 5365 } 5366 } 5367 this._hideModalHandler = () => { 5368 if (this._element) { 5369 this.hide(); 5370 } 5371 }; 5372 EventHandler.on(this._element.closest(SELECTOR_MODAL), EVENT_MODAL_HIDE, this._hideModalHandler); 5373 } 5374 _fixTitle() { 5375 const title = this._element.getAttribute('title'); 5376 if (!title) { 5377 return; 5378 } 5379 if (!this._element.getAttribute('aria-label') && !this._element.textContent.trim()) { 5380 this._element.setAttribute('aria-label', title); 5381 } 5382 this._element.setAttribute('data-bs-original-title', title); // DO NOT USE IT. Is only for backwards compatibility 5383 this._element.removeAttribute('title'); 5384 } 5385 _enter() { 5386 if (this._isShown() || this._isHovered) { 5387 this._isHovered = true; 5388 return; 5389 } 5390 this._isHovered = true; 5391 this._setTimeout(() => { 5392 if (this._isHovered) { 5393 this.show(); 5394 } 5395 }, this._config.delay.show); 5396 } 5397 _leave() { 5398 if (this._isWithActiveTrigger()) { 5399 return; 5400 } 5401 this._isHovered = false; 5402 this._setTimeout(() => { 5403 if (!this._isHovered) { 5404 this.hide(); 5405 } 5406 }, this._config.delay.hide); 5407 } 5408 _setTimeout(handler, timeout) { 5409 clearTimeout(this._timeout); 5410 this._timeout = setTimeout(handler, timeout); 5411 } 5412 _isWithActiveTrigger() { 5413 return Object.values(this._activeTrigger).includes(true); 5414 } 5415 _getConfig(config) { 5416 const dataAttributes = Manipulator.getDataAttributes(this._element); 5417 for (const dataAttribute of Object.keys(dataAttributes)) { 5418 if (DISALLOWED_ATTRIBUTES.has(dataAttribute)) { 5419 delete dataAttributes[dataAttribute]; 5420 } 5421 } 5422 config = { 5423 ...dataAttributes, 5424 ...(typeof config === 'object' && config ? config : {}) 5425 }; 5426 config = this._mergeConfigObj(config); 5427 config = this._configAfterMerge(config); 5428 this._typeCheckConfig(config); 5429 return config; 5430 } 5431 _configAfterMerge(config) { 5432 config.container = config.container === false ? document.body : getElement(config.container); 5433 if (typeof config.delay === 'number') { 5434 config.delay = { 5435 show: config.delay, 5436 hide: config.delay 5437 }; 5438 } 5439 if (typeof config.title === 'number') { 5440 config.title = config.title.toString(); 5441 } 5442 if (typeof config.content === 'number') { 5443 config.content = config.content.toString(); 5444 } 5445 return config; 5446 } 5447 _getDelegateConfig() { 5448 const config = {}; 5449 for (const [key, value] of Object.entries(this._config)) { 5450 if (this.constructor.Default[key] !== value) { 5451 config[key] = value; 5452 } 5453 } 5454 config.selector = false; 5455 config.trigger = 'manual'; 5456 5457 // In the future can be replaced with: 5458 // const keysWithDifferentValues = Object.entries(this._config).filter(entry => this.constructor.Default[entry[0]] !== this._config[entry[0]]) 5459 // `Object.fromEntries(keysWithDifferentValues)` 5460 return config; 5461 } 5462 _disposePopper() { 5463 if (this._popper) { 5464 this._popper.destroy(); 5465 this._popper = null; 5466 } 5467 if (this.tip) { 5468 this.tip.remove(); 5469 this.tip = null; 5470 } 5471 } 5472 5473 // Static 5474 static jQueryInterface(config) { 5475 return this.each(function () { 5476 const data = Tooltip.getOrCreateInstance(this, config); 5477 if (typeof config !== 'string') { 5478 return; 5479 } 5480 if (typeof data[config] === 'undefined') { 5481 throw new TypeError(`No method named "${config}"`); 5482 } 5483 data[config](); 5484 }); 5485 } 5486 } 5487 5488 /** 5489 * jQuery 5490 */ 5491 5492 defineJQueryPlugin(Tooltip); 5493 5494 /** 5495 * -------------------------------------------------------------------------- 5496 * Bootstrap popover.js 5497 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5498 * -------------------------------------------------------------------------- 5499 */ 5500 5501 5502 /** 5503 * Constants 5504 */ 5505 5506 const NAME$3 = 'popover'; 5507 const SELECTOR_TITLE = '.popover-header'; 5508 const SELECTOR_CONTENT = '.popover-body'; 5509 const Default$2 = { 5510 ...Tooltip.Default, 5511 content: '', 5512 offset: [0, 8], 5513 placement: 'right', 5514 template: '<div class="popover" role="tooltip">' + '<div class="popover-arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div>' + '</div>', 5515 trigger: 'click' 5516 }; 5517 const DefaultType$2 = { 5518 ...Tooltip.DefaultType, 5519 content: '(null|string|element|function)' 5520 }; 5521 5522 /** 5523 * Class definition 5524 */ 5525 5526 class Popover extends Tooltip { 5527 // Getters 5528 static get Default() { 5529 return Default$2; 5530 } 5531 static get DefaultType() { 5532 return DefaultType$2; 5533 } 5534 static get NAME() { 5535 return NAME$3; 5536 } 5537 5538 // Overrides 5539 _isWithContent() { 5540 return this._getTitle() || this._getContent(); 5541 } 5542 5543 // Private 5544 _getContentForTemplate() { 5545 return { 5546 [SELECTOR_TITLE]: this._getTitle(), 5547 [SELECTOR_CONTENT]: this._getContent() 5548 }; 5549 } 5550 _getContent() { 5551 return this._resolvePossibleFunction(this._config.content); 5552 } 5553 5554 // Static 5555 static jQueryInterface(config) { 5556 return this.each(function () { 5557 const data = Popover.getOrCreateInstance(this, config); 5558 if (typeof config !== 'string') { 5559 return; 5560 } 5561 if (typeof data[config] === 'undefined') { 5562 throw new TypeError(`No method named "${config}"`); 5563 } 5564 data[config](); 5565 }); 5566 } 5567 } 5568 5569 /** 5570 * jQuery 5571 */ 5572 5573 defineJQueryPlugin(Popover); 5574 5575 /** 5576 * -------------------------------------------------------------------------- 5577 * Bootstrap scrollspy.js 5578 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5579 * -------------------------------------------------------------------------- 5580 */ 5581 5582 5583 /** 5584 * Constants 5585 */ 5586 5587 const NAME$2 = 'scrollspy'; 5588 const DATA_KEY$2 = 'bs.scrollspy'; 5589 const EVENT_KEY$2 = `.${DATA_KEY$2}`; 5590 const DATA_API_KEY = '.data-api'; 5591 const EVENT_ACTIVATE = `activate${EVENT_KEY$2}`; 5592 const EVENT_CLICK = `click${EVENT_KEY$2}`; 5593 const EVENT_LOAD_DATA_API$1 = `load${EVENT_KEY$2}${DATA_API_KEY}`; 5594 const CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; 5595 const CLASS_NAME_ACTIVE$1 = 'active'; 5596 const SELECTOR_DATA_SPY = '[data-bs-spy="scroll"]'; 5597 const SELECTOR_TARGET_LINKS = '[href]'; 5598 const SELECTOR_NAV_LIST_GROUP = '.nav, .list-group'; 5599 const SELECTOR_NAV_LINKS = '.nav-link'; 5600 const SELECTOR_NAV_ITEMS = '.nav-item'; 5601 const SELECTOR_LIST_ITEMS = '.list-group-item'; 5602 const SELECTOR_LINK_ITEMS = `${SELECTOR_NAV_LINKS}, ${SELECTOR_NAV_ITEMS} > ${SELECTOR_NAV_LINKS}, ${SELECTOR_LIST_ITEMS}`; 5603 const SELECTOR_DROPDOWN = '.dropdown'; 5604 const SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle'; 5605 const Default$1 = { 5606 offset: null, 5607 // TODO: v6 @deprecated, keep it for backwards compatibility reasons 5608 rootMargin: '0px 0px -25%', 5609 smoothScroll: false, 5610 target: null, 5611 threshold: [0.1, 0.5, 1] 5612 }; 5613 const DefaultType$1 = { 5614 offset: '(number|null)', 5615 // TODO v6 @deprecated, keep it for backwards compatibility reasons 5616 rootMargin: 'string', 5617 smoothScroll: 'boolean', 5618 target: 'element', 5619 threshold: 'array' 5620 }; 5621 5622 /** 5623 * Class definition 5624 */ 5625 5626 class ScrollSpy extends BaseComponent { 5627 constructor(element, config) { 5628 super(element, config); 5629 5630 // this._element is the observablesContainer and config.target the menu links wrapper 5631 this._targetLinks = new Map(); 5632 this._observableSections = new Map(); 5633 this._rootElement = getComputedStyle(this._element).overflowY === 'visible' ? null : this._element; 5634 this._activeTarget = null; 5635 this._observer = null; 5636 this._previousScrollData = { 5637 visibleEntryTop: 0, 5638 parentScrollTop: 0 5639 }; 5640 this.refresh(); // initialize 5641 } 5642 5643 // Getters 5644 static get Default() { 5645 return Default$1; 5646 } 5647 static get DefaultType() { 5648 return DefaultType$1; 5649 } 5650 static get NAME() { 5651 return NAME$2; 5652 } 5653 5654 // Public 5655 refresh() { 5656 this._initializeTargetsAndObservables(); 5657 this._maybeEnableSmoothScroll(); 5658 if (this._observer) { 5659 this._observer.disconnect(); 5660 } else { 5661 this._observer = this._getNewObserver(); 5662 } 5663 for (const section of this._observableSections.values()) { 5664 this._observer.observe(section); 5665 } 5666 } 5667 dispose() { 5668 this._observer.disconnect(); 5669 super.dispose(); 5670 } 5671 5672 // Private 5673 _configAfterMerge(config) { 5674 // TODO: on v6 target should be given explicitly & remove the {target: 'ss-target'} case 5675 config.target = getElement(config.target) || document.body; 5676 5677 // TODO: v6 Only for backwards compatibility reasons. Use rootMargin only 5678 config.rootMargin = config.offset ? `${config.offset}px 0px -30%` : config.rootMargin; 5679 if (typeof config.threshold === 'string') { 5680 config.threshold = config.threshold.split(',').map(value => Number.parseFloat(value)); 5681 } 5682 return config; 5683 } 5684 _maybeEnableSmoothScroll() { 5685 if (!this._config.smoothScroll) { 5686 return; 5687 } 5688 5689 // unregister any previous listeners 5690 EventHandler.off(this._config.target, EVENT_CLICK); 5691 EventHandler.on(this._config.target, EVENT_CLICK, SELECTOR_TARGET_LINKS, event => { 5692 const observableSection = this._observableSections.get(event.target.hash); 5693 if (observableSection) { 5694 event.preventDefault(); 5695 const root = this._rootElement || window; 5696 const height = observableSection.offsetTop - this._element.offsetTop; 5697 if (root.scrollTo) { 5698 root.scrollTo({ 5699 top: height, 5700 behavior: 'smooth' 5701 }); 5702 return; 5703 } 5704 5705 // Chrome 60 doesn't support `scrollTo` 5706 root.scrollTop = height; 5707 } 5708 }); 5709 } 5710 _getNewObserver() { 5711 const options = { 5712 root: this._rootElement, 5713 threshold: this._config.threshold, 5714 rootMargin: this._config.rootMargin 5715 }; 5716 return new IntersectionObserver(entries => this._observerCallback(entries), options); 5717 } 5718 5719 // The logic of selection 5720 _observerCallback(entries) { 5721 const targetElement = entry => this._targetLinks.get(`#${entry.target.id}`); 5722 const activate = entry => { 5723 this._previousScrollData.visibleEntryTop = entry.target.offsetTop; 5724 this._process(targetElement(entry)); 5725 }; 5726 const parentScrollTop = (this._rootElement || document.documentElement).scrollTop; 5727 const userScrollsDown = parentScrollTop >= this._previousScrollData.parentScrollTop; 5728 this._previousScrollData.parentScrollTop = parentScrollTop; 5729 for (const entry of entries) { 5730 if (!entry.isIntersecting) { 5731 this._activeTarget = null; 5732 this._clearActiveClass(targetElement(entry)); 5733 continue; 5734 } 5735 const entryIsLowerThanPrevious = entry.target.offsetTop >= this._previousScrollData.visibleEntryTop; 5736 // if we are scrolling down, pick the bigger offsetTop 5737 if (userScrollsDown && entryIsLowerThanPrevious) { 5738 activate(entry); 5739 // if parent isn't scrolled, let's keep the first visible item, breaking the iteration 5740 if (!parentScrollTop) { 5741 return; 5742 } 5743 continue; 5744 } 5745 5746 // if we are scrolling up, pick the smallest offsetTop 5747 if (!userScrollsDown && !entryIsLowerThanPrevious) { 5748 activate(entry); 5749 } 5750 } 5751 } 5752 _initializeTargetsAndObservables() { 5753 this._targetLinks = new Map(); 5754 this._observableSections = new Map(); 5755 const targetLinks = SelectorEngine.find(SELECTOR_TARGET_LINKS, this._config.target); 5756 for (const anchor of targetLinks) { 5757 // ensure that the anchor has an id and is not disabled 5758 if (!anchor.hash || isDisabled(anchor)) { 5759 continue; 5760 } 5761 const observableSection = SelectorEngine.findOne(decodeURI(anchor.hash), this._element); 5762 5763 // ensure that the observableSection exists & is visible 5764 if (isVisible(observableSection)) { 5765 this._targetLinks.set(decodeURI(anchor.hash), anchor); 5766 this._observableSections.set(anchor.hash, observableSection); 5767 } 5768 } 5769 } 5770 _process(target) { 5771 if (this._activeTarget === target) { 5772 return; 5773 } 5774 this._clearActiveClass(this._config.target); 5775 this._activeTarget = target; 5776 target.classList.add(CLASS_NAME_ACTIVE$1); 5777 this._activateParents(target); 5778 EventHandler.trigger(this._element, EVENT_ACTIVATE, { 5779 relatedTarget: target 5780 }); 5781 } 5782 _activateParents(target) { 5783 // Activate dropdown parents 5784 if (target.classList.contains(CLASS_NAME_DROPDOWN_ITEM)) { 5785 SelectorEngine.findOne(SELECTOR_DROPDOWN_TOGGLE$1, target.closest(SELECTOR_DROPDOWN)).classList.add(CLASS_NAME_ACTIVE$1); 5786 return; 5787 } 5788 for (const listGroup of SelectorEngine.parents(target, SELECTOR_NAV_LIST_GROUP)) { 5789 // Set triggered links parents as active 5790 // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor 5791 for (const item of SelectorEngine.prev(listGroup, SELECTOR_LINK_ITEMS)) { 5792 item.classList.add(CLASS_NAME_ACTIVE$1); 5793 } 5794 } 5795 } 5796 _clearActiveClass(parent) { 5797 parent.classList.remove(CLASS_NAME_ACTIVE$1); 5798 const activeNodes = SelectorEngine.find(`${SELECTOR_TARGET_LINKS}.${CLASS_NAME_ACTIVE$1}`, parent); 5799 for (const node of activeNodes) { 5800 node.classList.remove(CLASS_NAME_ACTIVE$1); 5801 } 5802 } 5803 5804 // Static 5805 static jQueryInterface(config) { 5806 return this.each(function () { 5807 const data = ScrollSpy.getOrCreateInstance(this, config); 5808 if (typeof config !== 'string') { 5809 return; 5810 } 5811 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 5812 throw new TypeError(`No method named "${config}"`); 5813 } 5814 data[config](); 5815 }); 5816 } 5817 } 5818 5819 /** 5820 * Data API implementation 5821 */ 5822 5823 EventHandler.on(window, EVENT_LOAD_DATA_API$1, () => { 5824 for (const spy of SelectorEngine.find(SELECTOR_DATA_SPY)) { 5825 ScrollSpy.getOrCreateInstance(spy); 5826 } 5827 }); 5828 5829 /** 5830 * jQuery 5831 */ 5832 5833 defineJQueryPlugin(ScrollSpy); 5834 5835 /** 5836 * -------------------------------------------------------------------------- 5837 * Bootstrap tab.js 5838 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 5839 * -------------------------------------------------------------------------- 5840 */ 5841 5842 5843 /** 5844 * Constants 5845 */ 5846 5847 const NAME$1 = 'tab'; 5848 const DATA_KEY$1 = 'bs.tab'; 5849 const EVENT_KEY$1 = `.${DATA_KEY$1}`; 5850 const EVENT_HIDE$1 = `hide${EVENT_KEY$1}`; 5851 const EVENT_HIDDEN$1 = `hidden${EVENT_KEY$1}`; 5852 const EVENT_SHOW$1 = `show${EVENT_KEY$1}`; 5853 const EVENT_SHOWN$1 = `shown${EVENT_KEY$1}`; 5854 const EVENT_CLICK_DATA_API = `click${EVENT_KEY$1}`; 5855 const EVENT_KEYDOWN = `keydown${EVENT_KEY$1}`; 5856 const EVENT_LOAD_DATA_API = `load${EVENT_KEY$1}`; 5857 const ARROW_LEFT_KEY = 'ArrowLeft'; 5858 const ARROW_RIGHT_KEY = 'ArrowRight'; 5859 const ARROW_UP_KEY = 'ArrowUp'; 5860 const ARROW_DOWN_KEY = 'ArrowDown'; 5861 const HOME_KEY = 'Home'; 5862 const END_KEY = 'End'; 5863 const CLASS_NAME_ACTIVE = 'active'; 5864 const CLASS_NAME_FADE$1 = 'fade'; 5865 const CLASS_NAME_SHOW$1 = 'show'; 5866 const CLASS_DROPDOWN = 'dropdown'; 5867 const SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle'; 5868 const SELECTOR_DROPDOWN_MENU = '.dropdown-menu'; 5869 const NOT_SELECTOR_DROPDOWN_TOGGLE = `:not(${SELECTOR_DROPDOWN_TOGGLE})`; 5870 const SELECTOR_TAB_PANEL = '.list-group, .nav, [role="tablist"]'; 5871 const SELECTOR_OUTER = '.nav-item, .list-group-item'; 5872 const SELECTOR_INNER = `.nav-link${NOT_SELECTOR_DROPDOWN_TOGGLE}, .list-group-item${NOT_SELECTOR_DROPDOWN_TOGGLE}, [role="tab"]${NOT_SELECTOR_DROPDOWN_TOGGLE}`; 5873 const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]'; // TODO: could only be `tab` in v6 5874 const SELECTOR_INNER_ELEM = `${SELECTOR_INNER}, ${SELECTOR_DATA_TOGGLE}`; 5875 const SELECTOR_DATA_TOGGLE_ACTIVE = `.${CLASS_NAME_ACTIVE}[data-bs-toggle="tab"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="pill"], .${CLASS_NAME_ACTIVE}[data-bs-toggle="list"]`; 5876 5877 /** 5878 * Class definition 5879 */ 5880 5881 class Tab extends BaseComponent { 5882 constructor(element) { 5883 super(element); 5884 this._parent = this._element.closest(SELECTOR_TAB_PANEL); 5885 if (!this._parent) { 5886 return; 5887 // TODO: should throw exception in v6 5888 // throw new TypeError(`${element.outerHTML} has not a valid parent ${SELECTOR_INNER_ELEM}`) 5889 } 5890 5891 // Set up initial aria attributes 5892 this._setInitialAttributes(this._parent, this._getChildren()); 5893 EventHandler.on(this._element, EVENT_KEYDOWN, event => this._keydown(event)); 5894 } 5895 5896 // Getters 5897 static get NAME() { 5898 return NAME$1; 5899 } 5900 5901 // Public 5902 show() { 5903 // Shows this elem and deactivate the active sibling if exists 5904 const innerElem = this._element; 5905 if (this._elemIsActive(innerElem)) { 5906 return; 5907 } 5908 5909 // Search for active tab on same parent to deactivate it 5910 const active = this._getActiveElem(); 5911 const hideEvent = active ? EventHandler.trigger(active, EVENT_HIDE$1, { 5912 relatedTarget: innerElem 5913 }) : null; 5914 const showEvent = EventHandler.trigger(innerElem, EVENT_SHOW$1, { 5915 relatedTarget: active 5916 }); 5917 if (showEvent.defaultPrevented || hideEvent && hideEvent.defaultPrevented) { 5918 return; 5919 } 5920 this._deactivate(active, innerElem); 5921 this._activate(innerElem, active); 5922 } 5923 5924 // Private 5925 _activate(element, relatedElem) { 5926 if (!element) { 5927 return; 5928 } 5929 element.classList.add(CLASS_NAME_ACTIVE); 5930 this._activate(SelectorEngine.getElementFromSelector(element)); // Search and activate/show the proper section 5931 5932 const complete = () => { 5933 if (element.getAttribute('role') !== 'tab') { 5934 element.classList.add(CLASS_NAME_SHOW$1); 5935 return; 5936 } 5937 element.removeAttribute('tabindex'); 5938 element.setAttribute('aria-selected', true); 5939 this._toggleDropDown(element, true); 5940 EventHandler.trigger(element, EVENT_SHOWN$1, { 5941 relatedTarget: relatedElem 5942 }); 5943 }; 5944 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 5945 } 5946 _deactivate(element, relatedElem) { 5947 if (!element) { 5948 return; 5949 } 5950 element.classList.remove(CLASS_NAME_ACTIVE); 5951 element.blur(); 5952 this._deactivate(SelectorEngine.getElementFromSelector(element)); // Search and deactivate the shown section too 5953 5954 const complete = () => { 5955 if (element.getAttribute('role') !== 'tab') { 5956 element.classList.remove(CLASS_NAME_SHOW$1); 5957 return; 5958 } 5959 element.setAttribute('aria-selected', false); 5960 element.setAttribute('tabindex', '-1'); 5961 this._toggleDropDown(element, false); 5962 EventHandler.trigger(element, EVENT_HIDDEN$1, { 5963 relatedTarget: relatedElem 5964 }); 5965 }; 5966 this._queueCallback(complete, element, element.classList.contains(CLASS_NAME_FADE$1)); 5967 } 5968 _keydown(event) { 5969 if (![ARROW_LEFT_KEY, ARROW_RIGHT_KEY, ARROW_UP_KEY, ARROW_DOWN_KEY, HOME_KEY, END_KEY].includes(event.key)) { 5970 return; 5971 } 5972 event.stopPropagation(); // stopPropagation/preventDefault both added to support up/down keys without scrolling the page 5973 event.preventDefault(); 5974 const children = this._getChildren().filter(element => !isDisabled(element)); 5975 let nextActiveElement; 5976 if ([HOME_KEY, END_KEY].includes(event.key)) { 5977 nextActiveElement = children[event.key === HOME_KEY ? 0 : children.length - 1]; 5978 } else { 5979 const isNext = [ARROW_RIGHT_KEY, ARROW_DOWN_KEY].includes(event.key); 5980 nextActiveElement = getNextActiveElement(children, event.target, isNext, true); 5981 } 5982 if (nextActiveElement) { 5983 nextActiveElement.focus({ 5984 preventScroll: true 5985 }); 5986 Tab.getOrCreateInstance(nextActiveElement).show(); 5987 } 5988 } 5989 _getChildren() { 5990 // collection of inner elements 5991 return SelectorEngine.find(SELECTOR_INNER_ELEM, this._parent); 5992 } 5993 _getActiveElem() { 5994 return this._getChildren().find(child => this._elemIsActive(child)) || null; 5995 } 5996 _setInitialAttributes(parent, children) { 5997 this._setAttributeIfNotExists(parent, 'role', 'tablist'); 5998 for (const child of children) { 5999 this._setInitialAttributesOnChild(child); 6000 } 6001 } 6002 _setInitialAttributesOnChild(child) { 6003 child = this._getInnerElement(child); 6004 const isActive = this._elemIsActive(child); 6005 const outerElem = this._getOuterElement(child); 6006 child.setAttribute('aria-selected', isActive); 6007 if (outerElem !== child) { 6008 this._setAttributeIfNotExists(outerElem, 'role', 'presentation'); 6009 } 6010 if (!isActive) { 6011 child.setAttribute('tabindex', '-1'); 6012 } 6013 this._setAttributeIfNotExists(child, 'role', 'tab'); 6014 6015 // set attributes to the related panel too 6016 this._setInitialAttributesOnTargetPanel(child); 6017 } 6018 _setInitialAttributesOnTargetPanel(child) { 6019 const target = SelectorEngine.getElementFromSelector(child); 6020 if (!target) { 6021 return; 6022 } 6023 this._setAttributeIfNotExists(target, 'role', 'tabpanel'); 6024 if (child.id) { 6025 this._setAttributeIfNotExists(target, 'aria-labelledby', `${child.id}`); 6026 } 6027 } 6028 _toggleDropDown(element, open) { 6029 const outerElem = this._getOuterElement(element); 6030 if (!outerElem.classList.contains(CLASS_DROPDOWN)) { 6031 return; 6032 } 6033 const toggle = (selector, className) => { 6034 const element = SelectorEngine.findOne(selector, outerElem); 6035 if (element) { 6036 element.classList.toggle(className, open); 6037 } 6038 }; 6039 toggle(SELECTOR_DROPDOWN_TOGGLE, CLASS_NAME_ACTIVE); 6040 toggle(SELECTOR_DROPDOWN_MENU, CLASS_NAME_SHOW$1); 6041 outerElem.setAttribute('aria-expanded', open); 6042 } 6043 _setAttributeIfNotExists(element, attribute, value) { 6044 if (!element.hasAttribute(attribute)) { 6045 element.setAttribute(attribute, value); 6046 } 6047 } 6048 _elemIsActive(elem) { 6049 return elem.classList.contains(CLASS_NAME_ACTIVE); 6050 } 6051 6052 // Try to get the inner element (usually the .nav-link) 6053 _getInnerElement(elem) { 6054 return elem.matches(SELECTOR_INNER_ELEM) ? elem : SelectorEngine.findOne(SELECTOR_INNER_ELEM, elem); 6055 } 6056 6057 // Try to get the outer element (usually the .nav-item) 6058 _getOuterElement(elem) { 6059 return elem.closest(SELECTOR_OUTER) || elem; 6060 } 6061 6062 // Static 6063 static jQueryInterface(config) { 6064 return this.each(function () { 6065 const data = Tab.getOrCreateInstance(this); 6066 if (typeof config !== 'string') { 6067 return; 6068 } 6069 if (data[config] === undefined || config.startsWith('_') || config === 'constructor') { 6070 throw new TypeError(`No method named "${config}"`); 6071 } 6072 data[config](); 6073 }); 6074 } 6075 } 6076 6077 /** 6078 * Data API implementation 6079 */ 6080 6081 EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) { 6082 if (['A', 'AREA'].includes(this.tagName)) { 6083 event.preventDefault(); 6084 } 6085 if (isDisabled(this)) { 6086 return; 6087 } 6088 Tab.getOrCreateInstance(this).show(); 6089 }); 6090 6091 /** 6092 * Initialize on focus 6093 */ 6094 EventHandler.on(window, EVENT_LOAD_DATA_API, () => { 6095 for (const element of SelectorEngine.find(SELECTOR_DATA_TOGGLE_ACTIVE)) { 6096 Tab.getOrCreateInstance(element); 6097 } 6098 }); 6099 /** 6100 * jQuery 6101 */ 6102 6103 defineJQueryPlugin(Tab); 6104 6105 /** 6106 * -------------------------------------------------------------------------- 6107 * Bootstrap toast.js 6108 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6109 * -------------------------------------------------------------------------- 6110 */ 6111 6112 6113 /** 6114 * Constants 6115 */ 6116 6117 const NAME = 'toast'; 6118 const DATA_KEY = 'bs.toast'; 6119 const EVENT_KEY = `.${DATA_KEY}`; 6120 const EVENT_MOUSEOVER = `mouseover${EVENT_KEY}`; 6121 const EVENT_MOUSEOUT = `mouseout${EVENT_KEY}`; 6122 const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; 6123 const EVENT_FOCUSOUT = `focusout${EVENT_KEY}`; 6124 const EVENT_HIDE = `hide${EVENT_KEY}`; 6125 const EVENT_HIDDEN = `hidden${EVENT_KEY}`; 6126 const EVENT_SHOW = `show${EVENT_KEY}`; 6127 const EVENT_SHOWN = `shown${EVENT_KEY}`; 6128 const CLASS_NAME_FADE = 'fade'; 6129 const CLASS_NAME_HIDE = 'hide'; // @deprecated - kept here only for backwards compatibility 6130 const CLASS_NAME_SHOW = 'show'; 6131 const CLASS_NAME_SHOWING = 'showing'; 6132 const DefaultType = { 6133 animation: 'boolean', 6134 autohide: 'boolean', 6135 delay: 'number' 6136 }; 6137 const Default = { 6138 animation: true, 6139 autohide: true, 6140 delay: 5000 6141 }; 6142 6143 /** 6144 * Class definition 6145 */ 6146 6147 class Toast extends BaseComponent { 6148 constructor(element, config) { 6149 super(element, config); 6150 this._timeout = null; 6151 this._hasMouseInteraction = false; 6152 this._hasKeyboardInteraction = false; 6153 this._setListeners(); 6154 } 6155 6156 // Getters 6157 static get Default() { 6158 return Default; 6159 } 6160 static get DefaultType() { 6161 return DefaultType; 6162 } 6163 static get NAME() { 6164 return NAME; 6165 } 6166 6167 // Public 6168 show() { 6169 const showEvent = EventHandler.trigger(this._element, EVENT_SHOW); 6170 if (showEvent.defaultPrevented) { 6171 return; 6172 } 6173 this._clearTimeout(); 6174 if (this._config.animation) { 6175 this._element.classList.add(CLASS_NAME_FADE); 6176 } 6177 const complete = () => { 6178 this._element.classList.remove(CLASS_NAME_SHOWING); 6179 EventHandler.trigger(this._element, EVENT_SHOWN); 6180 this._maybeScheduleHide(); 6181 }; 6182 this._element.classList.remove(CLASS_NAME_HIDE); // @deprecated 6183 reflow(this._element); 6184 this._element.classList.add(CLASS_NAME_SHOW, CLASS_NAME_SHOWING); 6185 this._queueCallback(complete, this._element, this._config.animation); 6186 } 6187 hide() { 6188 if (!this.isShown()) { 6189 return; 6190 } 6191 const hideEvent = EventHandler.trigger(this._element, EVENT_HIDE); 6192 if (hideEvent.defaultPrevented) { 6193 return; 6194 } 6195 const complete = () => { 6196 this._element.classList.add(CLASS_NAME_HIDE); // @deprecated 6197 this._element.classList.remove(CLASS_NAME_SHOWING, CLASS_NAME_SHOW); 6198 EventHandler.trigger(this._element, EVENT_HIDDEN); 6199 }; 6200 this._element.classList.add(CLASS_NAME_SHOWING); 6201 this._queueCallback(complete, this._element, this._config.animation); 6202 } 6203 dispose() { 6204 this._clearTimeout(); 6205 if (this.isShown()) { 6206 this._element.classList.remove(CLASS_NAME_SHOW); 6207 } 6208 super.dispose(); 6209 } 6210 isShown() { 6211 return this._element.classList.contains(CLASS_NAME_SHOW); 6212 } 6213 6214 // Private 6215 6216 _maybeScheduleHide() { 6217 if (!this._config.autohide) { 6218 return; 6219 } 6220 if (this._hasMouseInteraction || this._hasKeyboardInteraction) { 6221 return; 6222 } 6223 this._timeout = setTimeout(() => { 6224 this.hide(); 6225 }, this._config.delay); 6226 } 6227 _onInteraction(event, isInteracting) { 6228 switch (event.type) { 6229 case 'mouseover': 6230 case 'mouseout': 6231 { 6232 this._hasMouseInteraction = isInteracting; 6233 break; 6234 } 6235 case 'focusin': 6236 case 'focusout': 6237 { 6238 this._hasKeyboardInteraction = isInteracting; 6239 break; 6240 } 6241 } 6242 if (isInteracting) { 6243 this._clearTimeout(); 6244 return; 6245 } 6246 const nextElement = event.relatedTarget; 6247 if (this._element === nextElement || this._element.contains(nextElement)) { 6248 return; 6249 } 6250 this._maybeScheduleHide(); 6251 } 6252 _setListeners() { 6253 EventHandler.on(this._element, EVENT_MOUSEOVER, event => this._onInteraction(event, true)); 6254 EventHandler.on(this._element, EVENT_MOUSEOUT, event => this._onInteraction(event, false)); 6255 EventHandler.on(this._element, EVENT_FOCUSIN, event => this._onInteraction(event, true)); 6256 EventHandler.on(this._element, EVENT_FOCUSOUT, event => this._onInteraction(event, false)); 6257 } 6258 _clearTimeout() { 6259 clearTimeout(this._timeout); 6260 this._timeout = null; 6261 } 6262 6263 // Static 6264 static jQueryInterface(config) { 6265 return this.each(function () { 6266 const data = Toast.getOrCreateInstance(this, config); 6267 if (typeof config === 'string') { 6268 if (typeof data[config] === 'undefined') { 6269 throw new TypeError(`No method named "${config}"`); 6270 } 6271 data[config](this); 6272 } 6273 }); 6274 } 6275 } 6276 6277 /** 6278 * Data API implementation 6279 */ 6280 6281 enableDismissTrigger(Toast); 6282 6283 /** 6284 * jQuery 6285 */ 6286 6287 defineJQueryPlugin(Toast); 6288 6289 /** 6290 * -------------------------------------------------------------------------- 6291 * Bootstrap index.umd.js 6292 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) 6293 * -------------------------------------------------------------------------- 6294 */ 6295 6296 const index_umd = { 6297 Alert, 6298 Button, 6299 Carousel, 6300 Collapse, 6301 Dropdown, 6302 Modal, 6303 Offcanvas, 6304 Popover, 6305 ScrollSpy, 6306 Tab, 6307 Toast, 6308 Tooltip 6309 }; 6310 6311 return index_umd; 6312 6313 })); 6314 //# sourceMappingURL=bootstrap.bundle.js.map