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