text: /*!
    * Bootstrap offcanvas.js v5.0.2 (https://getbootstrap.com/)
    * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
    * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
    */
  (function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('./dom/selector-engine.js'), require('./dom/manipulator.js'), require('./dom/event-handler.js'), require('./base-component.js')) :
    typeof define === 'function' && define.amd ? define(['./dom/selector-engine', './dom/manipulator', './dom/event-handler', './base-component'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Offcanvas = factory(global.SelectorEngine, global.Manipulator, global.EventHandler, global.Base));
  }(this, (function (SelectorEngine, Manipulator, EventHandler, BaseComponent) { 'use strict';
  
    function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
  
    var SelectorEngine__default = /*#__PURE__*/_interopDefaultLegacy(SelectorEngine);
    var Manipulator__default = /*#__PURE__*/_interopDefaultLegacy(Manipulator);
    var EventHandler__default = /*#__PURE__*/_interopDefaultLegacy(EventHandler);
    var BaseComponent__default = /*#__PURE__*/_interopDefaultLegacy(BaseComponent);
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v5.0.2): util/index.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
     * --------------------------------------------------------------------------
     */
    const MILLISECONDS_MULTIPLIER = 1000;
    const TRANSITION_END = 'transitionend'; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
  
    const toType = obj => {
      if (obj === null || obj === undefined) {
        return `${obj}`;
      }
  
      return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
    };
  
    const getSelector = element => {
      let selector = element.getAttribute('data-bs-target');
  
      if (!selector || selector === '#') {
        let hrefAttr = element.getAttribute('href'); // The only valid content that could double as a selector are IDs or classes,
        // so everything starting with `#` or `.`. If a "real" URL is used as the selector,
        // `document.querySelector` will rightfully complain it is invalid.
        // See https://github.com/twbs/bootstrap/issues/32273
  
        if (!hrefAttr || !hrefAttr.includes('#') && !hrefAttr.startsWith('.')) {
          return null;
        } // Just in case some CMS puts out a full URL with the anchor appended
  
  
        if (hrefAttr.includes('#') && !hrefAttr.startsWith('#')) {
          hrefAttr = `#${hrefAttr.split('#')[1]}`;
        }
  
        selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : null;
      }
  
      return selector;
    };
  
    const getElementFromSelector = element => {
      const selector = getSelector(element);
      return selector ? document.querySelector(selector) : null;
    };
  
    const getTransitionDurationFromElement = element => {
      if (!element) {
        return 0;
      } // Get transition-duration of the element
  
  
      let {
        transitionDuration,
        transitionDelay
      } = window.getComputedStyle(element);
      const floatTransitionDuration = Number.parseFloat(transitionDuration);
      const floatTransitionDelay = Number.parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
  
      if (!floatTransitionDuration && !floatTransitionDelay) {
        return 0;
      } // If multiple durations are defined, take the first
  
  
      transitionDuration = transitionDuration.split(',')[0];
      transitionDelay = transitionDelay.split(',')[0];
      return (Number.parseFloat(transitionDuration) + Number.parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
    };
  
    const triggerTransitionEnd = element => {
      element.dispatchEvent(new Event(TRANSITION_END));
    };
  
    const isElement = obj => {
      if (!obj || typeof obj !== 'object') {
        return false;
      }
  
      if (typeof obj.jquery !== 'undefined') {
        obj = obj[0];
      }
  
      return typeof obj.nodeType !== 'undefined';
    };
  
    const getElement = obj => {
      if (isElement(obj)) {
        // it's a jQuery object or a node element
        return obj.jquery ? obj[0] : obj;
      }
  
      if (typeof obj === 'string' && obj.length > 0) {
        return document.querySelector(obj);
      }
  
      return null;
    };
  
    const typeCheckConfig = (componentName, config, configTypes) => {
      Object.keys(configTypes).forEach(property => {
        const expectedTypes = configTypes[property];
        const value = config[property];
        const valueType = value && isElement(value) ? 'element' : toType(value);
  
        if (!new RegExp(expectedTypes).test(valueType)) {
          throw new TypeError(`${componentName.toUpperCase()}: Option "${property}" provided type "${valueType}" but expected type "${expectedTypes}".`);
        }
      });
    };
  
    const isVisible = element => {
      if (!isElement(element) || element.getClientRects().length === 0) {
        return false;
      }
  
      return getComputedStyle(element).getPropertyValue('visibility') === 'visible';
    };
  
    const isDisabled = element => {
      if (!element || element.nodeType !== Node.ELEMENT_NODE) {
        return true;
      }
  
      if (element.classList.contains('disabled')) {
        return true;
      }
  
      if (typeof element.disabled !== 'undefined') {
        return element.disabled;
      }
  
      return element.hasAttribute('disabled') && element.getAttribute('disabled') !== 'false';
    };
    /**
     * Trick to restart an element's animation
     *
     * @param {HTMLElement} element
     * @return void
     *
     * @see https://www.charistheo.io/blog/2021/02/restart-a-css-animation-with-javascript/#restarting-a-css-animation
     */
  
  
    const reflow = element => {
      // eslint-disable-next-line no-unused-expressions
      element.offsetHeight;
    };
  
    const getjQuery = () => {
      const {
        jQuery
      } = window;
  
      if (jQuery && !document.body.hasAttribute('data-bs-no-jquery')) {
        return jQuery;
      }
  
      return null;
    };
  
    const DOMContentLoadedCallbacks = [];
  
    const onDOMContentLoaded = callback => {
      if (document.readyState === 'loading') {
        // add listener on the first call when the document is in loading state
        if (!DOMContentLoadedCallbacks.length) {
          document.addEventListener('DOMContentLoaded', () => {
            DOMContentLoadedCallbacks.forEach(callback => callback());
          });
        }
  
        DOMContentLoadedCallbacks.push(callback);
      } else {
        callback();
      }
    };
  
    const defineJQueryPlugin = plugin => {
      onDOMContentLoaded(() => {
        const $ = getjQuery();
        /* istanbul ignore if */
  
        if ($) {
          const name = plugin.NAME;
          const JQUERY_NO_CONFLICT = $.fn[name];
          $.fn[name] = plugin.jQueryInterface;
          $.fn[name].Constructor = plugin;
  
          $.fn[name].noConflict = () => {
            $.fn[name] = JQUERY_NO_CONFLICT;
            return plugin.jQueryInterface;
          };
        }
      });
    };
  
    const execute = callback => {
      if (typeof callback === 'function') {
        callback();
      }
    };
  
    const executeAfterTransition = (callback, transitionElement, waitForTransition = true) => {
      if (!waitForTransition) {
        execute(callback);
        return;
      }
  
      const durationPadding = 5;
      const emulatedDuration = getTransitionDurationFromElement(transitionElement) + durationPadding;
      let called = false;
  
      const handler = ({
        target
      }) => {
        if (target !== transitionElement) {
          return;
        }
  
        called = true;
        transitionElement.removeEventListener(TRANSITION_END, handler);
        execute(callback);
      };
  
      transitionElement.addEventListener(TRANSITION_END, handler);
      setTimeout(() => {
        if (!called) {
          triggerTransitionEnd(transitionElement);
        }
      }, emulatedDuration);
    };
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v5.0.2): util/scrollBar.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
     * --------------------------------------------------------------------------
     */
    const SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
    const SELECTOR_STICKY_CONTENT = '.sticky-top';
  
    class ScrollBarHelper {
      constructor() {
        this._element = document.body;
      }
  
      getWidth() {
        // https://developer.mozilla.org/en-US/docs/Web/API/Window/innerWidth#usage_notes
        const documentWidth = document.documentElement.clientWidth;
        return Math.abs(window.innerWidth - documentWidth);
      }
  
      hide() {
        const width = this.getWidth();
  
        this._disableOverFlow(); // give padding to element to balance the hidden scrollbar width
  
  
        this._setElementAttributes(this._element, 'paddingRight', calculatedValue => calculatedValue + width); // trick: We adjust positive paddingRight and negative marginRight to sticky-top elements to keep showing fullwidth
  
  
        this._setElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight', calculatedValue => calculatedValue + width);
  
        this._setElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight', calculatedValue => calculatedValue - width);
      }
  
      _disableOverFlow() {
        this._saveInitialAttribute(this._element, 'overflow');
  
        this._element.style.overflow = 'hidden';
      }
  
      _setElementAttributes(selector, styleProp, callback) {
        const scrollbarWidth = this.getWidth();
  
        const manipulationCallBack = element => {
          if (element !== this._element && window.innerWidth > element.clientWidth + scrollbarWidth) {
            return;
          }
  
          this._saveInitialAttribute(element, styleProp);
  
          const calculatedValue = window.getComputedStyle(element)[styleProp];
          element.style[styleProp] = `${callback(Number.parseFloat(calculatedValue))}px`;
        };
  
        this._applyManipulationCallback(selector, manipulationCallBack);
      }
  
      reset() {
        this._resetElementAttributes(this._element, 'overflow');
  
        this._resetElementAttributes(this._element, 'paddingRight');
  
        this._resetElementAttributes(SELECTOR_FIXED_CONTENT, 'paddingRight');
  
        this._resetElementAttributes(SELECTOR_STICKY_CONTENT, 'marginRight');
      }
  
      _saveInitialAttribute(element, styleProp) {
        const actualValue = element.style[styleProp];
  
        if (actualValue) {
          Manipulator__default['default'].setDataAttribute(element, styleProp, actualValue);
        }
      }
  
      _resetElementAttributes(selector, styleProp) {
        const manipulationCallBack = element => {
          const value = Manipulator__default['default'].getDataAttribute(element, styleProp);
  
          if (typeof value === 'undefined') {
            element.style.removeProperty(styleProp);
          } else {
            Manipulator__default['default'].removeDataAttribute(element, styleProp);
            element.style[styleProp] = value;
          }
        };
  
        this._applyManipulationCallback(selector, manipulationCallBack);
      }
  
      _applyManipulationCallback(selector, callBack) {
        if (isElement(selector)) {
          callBack(selector);
        } else {
          SelectorEngine__default['default'].find(selector, this._element).forEach(callBack);
        }
      }
  
      isOverflowing() {
        return this.getWidth() > 0;
      }
  
    }
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v5.0.2): util/backdrop.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * --------------------------------------------------------------------------
     */
    const Default$2 = {
      className: 'modal-backdrop',
      isVisible: true,
      // if false, we use the backdrop helper without adding any element to the dom
      isAnimated: false,
      rootElement: 'body',
      // give the choice to place backdrop under different elements
      clickCallback: null
    };
    const DefaultType$2 = {
      className: 'string',
      isVisible: 'boolean',
      isAnimated: 'boolean',
      rootElement: '(element|string)',
      clickCallback: '(function|null)'
    };
    const NAME$2 = 'backdrop';
    const CLASS_NAME_FADE = 'fade';
    const CLASS_NAME_SHOW$1 = 'show';
    const EVENT_MOUSEDOWN = `mousedown.bs.${NAME$2}`;
  
    class Backdrop {
      constructor(config) {
        this._config = this._getConfig(config);
        this._isAppended = false;
        this._element = null;
      }
  
      show(callback) {
        if (!this._config.isVisible) {
          execute(callback);
          return;
        }
  
        this._append();
  
        if (this._config.isAnimated) {
          reflow(this._getElement());
        }
  
        this._getElement().classList.add(CLASS_NAME_SHOW$1);
  
        this._emulateAnimation(() => {
          execute(callback);
        });
      }
  
      hide(callback) {
        if (!this._config.isVisible) {
          execute(callback);
          return;
        }
  
        this._getElement().classList.remove(CLASS_NAME_SHOW$1);
  
        this._emulateAnimation(() => {
          this.dispose();
          execute(callback);
        });
      } // Private
  
  
      _getElement() {
        if (!this._element) {
          const backdrop = document.createElement('div');
          backdrop.className = this._config.className;
  
          if (this._config.isAnimated) {
            backdrop.classList.add(CLASS_NAME_FADE);
          }
  
          this._element = backdrop;
        }
  
        return this._element;
      }
  
      _getConfig(config) {
        config = { ...Default$2,
          ...(typeof config === 'object' ? config : {})
        }; // use getElement() with the default "body" to get a fresh Element on each instantiation
  
        config.rootElement = getElement(config.rootElement);
        typeCheckConfig(NAME$2, config, DefaultType$2);
        return config;
      }
  
      _append() {
        if (this._isAppended) {
          return;
        }
  
        this._config.rootElement.appendChild(this._getElement());
  
        EventHandler__default['default'].on(this._getElement(), EVENT_MOUSEDOWN, () => {
          execute(this._config.clickCallback);
        });
        this._isAppended = true;
      }
  
      dispose() {
        if (!this._isAppended) {
          return;
        }
  
        EventHandler__default['default'].off(this._element, EVENT_MOUSEDOWN);
  
        this._element.remove();
  
        this._isAppended = false;
      }
  
      _emulateAnimation(callback) {
        executeAfterTransition(callback, this._getElement(), this._config.isAnimated);
      }
  
    }
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v5.0.2): util/focustrap.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * --------------------------------------------------------------------------
     */
    const Default$1 = {
      trapElement: null,
      // The element to trap focus inside of
      autofocus: true
    };
    const DefaultType$1 = {
      trapElement: 'element',
      autofocus: 'boolean'
    };
    const NAME$1 = 'focustrap';
    const DATA_KEY$1 = 'bs.focustrap';
    const EVENT_KEY$1 = `.${DATA_KEY$1}`;
    const EVENT_FOCUSIN = `focusin${EVENT_KEY$1}`;
    const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY$1}`;
    const TAB_KEY = 'Tab';
    const TAB_NAV_FORWARD = 'forward';
    const TAB_NAV_BACKWARD = 'backward';
  
    class FocusTrap {
      constructor(config) {
        this._config = this._getConfig(config);
        this._isActive = false;
        this._lastTabNavDirection = null;
      }
  
      activate() {
        const {
          trapElement,
          autofocus
        } = this._config;
  
        if (this._isActive) {
          return;
        }
  
        if (autofocus) {
          trapElement.focus();
        }
  
        EventHandler__default['default'].off(document, EVENT_KEY$1); // guard against infinite focus loop
  
        EventHandler__default['default'].on(document, EVENT_FOCUSIN, event => this._handleFocusin(event));
        EventHandler__default['default'].on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event));
        this._isActive = true;
      }
  
      deactivate() {
        if (!this._isActive) {
          return;
        }
  
        this._isActive = false;
        EventHandler__default['default'].off(document, EVENT_KEY$1);
      } // Private
  
  
      _handleFocusin(event) {
        const {
          target
        } = event;
        const {
          trapElement
        } = this._config;
  
        if (target === document || target === trapElement || trapElement.contains(target)) {
          return;
        }
  
        const elements = SelectorEngine__default['default'].focusableChildren(trapElement);
  
        if (elements.length === 0) {
          trapElement.focus();
        } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
          elements[elements.length - 1].focus();
        } else {
          elements[0].focus();
        }
      }
  
      _handleKeydown(event) {
        if (event.key !== TAB_KEY) {
          return;
        }
  
        this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD;
      }
  
      _getConfig(config) {
        config = { ...Default$1,
          ...(typeof config === 'object' ? config : {})
        };
        typeCheckConfig(NAME$1, config, DefaultType$1);
        return config;
      }
  
    }
  
    /**
     * --------------------------------------------------------------------------
     * Bootstrap (v5.0.2): offcanvas.js
     * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
     * --------------------------------------------------------------------------
     */
    /**
     * ------------------------------------------------------------------------
     * Constants
     * ------------------------------------------------------------------------
     */
  
    const NAME = 'offcanvas';
    const DATA_KEY = 'bs.offcanvas';
    const EVENT_KEY = `.${DATA_KEY}`;
    const DATA_API_KEY = '.data-api';
    const EVENT_LOAD_DATA_API = `load${EVENT_KEY}${DATA_API_KEY}`;
    const ESCAPE_KEY = 'Escape';
    const Default = {
      backdrop: true,
      keyboard: true,
      scroll: false
    };
    const DefaultType = {
      backdrop: 'boolean',
      keyboard: 'boolean',
      scroll: 'boolean'
    };
    const CLASS_NAME_SHOW = 'show';
    const CLASS_NAME_BACKDROP = 'offcanvas-backdrop';
    const OPEN_SELECTOR = '.offcanvas.show';
    const EVENT_SHOW = `show${EVENT_KEY}`;
    const EVENT_SHOWN = `shown${EVENT_KEY}`;
    const EVENT_HIDE = `hide${EVENT_KEY}`;
    const EVENT_HIDDEN = `hidden${EVENT_KEY}`;
    const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`;
    const EVENT_CLICK_DISMISS = `click.dismiss${EVENT_KEY}`;
    const EVENT_KEYDOWN_DISMISS = `keydown.dismiss${EVENT_KEY}`;
    const SELECTOR_DATA_DISMISS = '[data-bs-dismiss="offcanvas"]';
    const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="offcanvas"]';
    /**
     * ------------------------------------------------------------------------
     * Class Definition
     * ------------------------------------------------------------------------
     */
  
    class Offcanvas extends BaseComponent__default['default'] {
      constructor(element, config) {
        super(element);
        this._config = this._getConfig(config);
        this._isShown = false;
        this._backdrop = this._initializeBackDrop();
        this._focustrap = this._initializeFocusTrap();
  
        this._addEventListeners();
      } // Getters
  
  
      static get NAME() {
        return NAME;
      }
  
      static get Default() {
        return Default;
      } // Public
  
  
      toggle(relatedTarget) {
        return this._isShown ? this.hide() : this.show(relatedTarget);
      }
  
      show(relatedTarget) {
        if (this._isShown) {
          return;
        }
  
        const showEvent = EventHandler__default['default'].trigger(this._element, EVENT_SHOW, {
          relatedTarget
        });
  
        if (showEvent.defaultPrevented) {
          return;
        }
  
        this._isShown = true;
        this._element.style.visibility = 'visible';
  
        this._backdrop.show();
  
        if (!this._config.scroll) {
          new ScrollBarHelper().hide();
        }
  
        this._element.removeAttribute('aria-hidden');
  
        this._element.setAttribute('aria-modal', true);
  
        this._element.setAttribute('role', 'dialog');
  
        this._element.classList.add(CLASS_NAME_SHOW);
  
        const completeCallBack = () => {
          if (!this._config.scroll) {
            this._focustrap.activate();
          }
  
          EventHandler__default['default'].trigger(this._element, EVENT_SHOWN, {
            relatedTarget
          });
        };
  
        this._queueCallback(completeCallBack, this._element, true);
      }
  
      hide() {
        if (!this._isShown) {
          return;
        }
  
        const hideEvent = EventHandler__default['default'].trigger(this._element, EVENT_HIDE);
  
        if (hideEvent.defaultPrevented) {
          return;
        }
  
        this._focustrap.deactivate();
  
        this._element.blur();
  
        this._isShown = false;
  
        this._element.classList.remove(CLASS_NAME_SHOW);
  
        this._backdrop.hide();
  
        const completeCallback = () => {
          this._element.setAttribute('aria-hidden', true);
  
          this._element.removeAttribute('aria-modal');
  
          this._element.removeAttribute('role');
  
          this._element.style.visibility = 'hidden';
  
          if (!this._config.scroll) {
            new ScrollBarHelper().reset();
          }
  
          EventHandler__default['default'].trigger(this._element, EVENT_HIDDEN);
        };
  
        this._queueCallback(completeCallback, this._element, true);
      }
  
      dispose() {
        this._backdrop.dispose();
  
        this._focustrap.deactivate();
  
        super.dispose();
      } // Private
  
  
      _getConfig(config) {
        config = { ...Default,
          ...Manipulator__default['default'].getDataAttributes(this._element),
          ...(typeof config === 'object' ? config : {})
        };
        typeCheckConfig(NAME, config, DefaultType);
        return config;
      }
  
      _initializeBackDrop() {
        return new Backdrop({
          className: CLASS_NAME_BACKDROP,
          isVisible: this._config.backdrop,
          isAnimated: true,
          rootElement: this._element.parentNode,
          clickCallback: () => this.hide()
        });
      }
  
      _initializeFocusTrap() {
        return new FocusTrap({
          trapElement: this._element
        });
      }
  
      _addEventListeners() {
        EventHandler__default['default'].on(this._element, EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, () => this.hide());
        EventHandler__default['default'].on(this._element, EVENT_KEYDOWN_DISMISS, event => {
          if (this._config.keyboard && event.key === ESCAPE_KEY) {
            this.hide();
          }
        });
      } // Static
  
  
      static jQueryInterface(config) {
        return this.each(function () {
          const data = Offcanvas.getOrCreateInstance(this, config);
  
          if (typeof config !== 'string') {
            return;
          }
  
          if (data[config] === undefined || config.startsWith('_') || config === 'constructor') {
            throw new TypeError(`No method named "${config}"`);
          }
  
          data[config](this);
        });
      }
  
    }
    /**
     * ------------------------------------------------------------------------
     * Data Api implementation
     * ------------------------------------------------------------------------
     */
  
  
    EventHandler__default['default'].on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function (event) {
      const target = getElementFromSelector(this);
  
      if (['A', 'AREA'].includes(this.tagName)) {
        event.preventDefault();
      }
  
      if (isDisabled(this)) {
        return;
      }
  
      EventHandler__default['default'].one(target, EVENT_HIDDEN, () => {
        // focus on trigger when it is closed
        if (isVisible(this)) {
          this.focus();
        }
      }); // avoid conflict when clicking a toggler of an offcanvas, while another is open
  
      const allReadyOpen = SelectorEngine__default['default'].findOne(OPEN_SELECTOR);
  
      if (allReadyOpen && allReadyOpen !== target) {
        Offcanvas.getInstance(allReadyOpen).hide();
      }
  
      const data = Offcanvas.getOrCreateInstance(target);
      data.toggle(this);
    });
    EventHandler__default['default'].on(window, EVENT_LOAD_DATA_API, () => SelectorEngine__default['default'].find(OPEN_SELECTOR).forEach(el => Offcanvas.getOrCreateInstance(el).show()));
    /**
     * ------------------------------------------------------------------------
     * jQuery
     * ------------------------------------------------------------------------
     */
  
    defineJQueryPlugin(Offcanvas);
  
    return Offcanvas;
  
  })));
  //# sourceMappingURL=offcanvas.js.map
  