/*! * BootstrapVue 2.19.0 * * @link https://bootstrap-vue.org * @source https://github.com/bootstrap-vue/bootstrap-vue * @copyright (c) 2016-2020 BootstrapVue * @license MIT * https://github.com/bootstrap-vue/bootstrap-vue/blob/master/LICENSE */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('vue')) : typeof define === 'function' && define.amd ? define(['vue'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.bootstrapVue = factory(global.Vue)); }(this, (function (Vue) { 'use strict'; function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var Vue__default = /*#__PURE__*/_interopDefaultLegacy(Vue); function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct; } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var e=function(){return (e=Object.assign||function(e){for(var t,r=1,s=arguments.length;r 0; var isIE = /msie|trident/.test(userAgent); // Determine if the browser supports the option passive for events var hasPassiveEventSupport = function () { var passiveEventSupported = false; if (isBrowser) { try { var options = { get passive() { // This function will be called when the browser // attempts to access the passive property. /* istanbul ignore next: will never be called in JSDOM */ passiveEventSupported = true; } }; window.addEventListener('test', options, options); window.removeEventListener('test', options, options); } catch (err) { /* istanbul ignore next: will never be called in JSDOM */ passiveEventSupported = false; } } return passiveEventSupported; }(); var hasTouchSupport = isBrowser && ('ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0); var hasPointerEventSupport = isBrowser && Boolean(window.PointerEvent || window.MSPointerEvent); /* istanbul ignore next: JSDOM only checks for 'IntersectionObserver' */ var hasIntersectionObserverSupport = isBrowser && 'IntersectionObserver' in window && 'IntersectionObserverEntry' in window && // Edge 15 and UC Browser lack support for `isIntersecting` // but we an use intersectionRatio > 0 instead // 'isIntersecting' in window.IntersectionObserverEntry.prototype && 'intersectionRatio' in window.IntersectionObserverEntry.prototype; // --- Getters --- var getEnv = function getEnv(key) { var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var env = typeof process !== 'undefined' && process ? process.env || {} : {}; if (!key) { /* istanbul ignore next */ return env; } return env[key] || fallback; }; var getNoWarn = function getNoWarn() { return getEnv('BOOTSTRAP_VUE_NO_WARN') || getEnv('NODE_ENV') === 'production'; }; var w = hasWindowSupport ? window : {}; var Element$1 = hasWindowSupport ? w.Element : /*#__PURE__*/function (_Object) { _inherits(Element, _Object); var _super = _createSuper(Element); function Element() { _classCallCheck(this, Element); return _super.apply(this, arguments); } return Element; }( /*#__PURE__*/_wrapNativeSuper(Object)); var HTMLElement = hasWindowSupport ? w.HTMLElement : /*#__PURE__*/function (_Element) { _inherits(HTMLElement, _Element); var _super2 = _createSuper(HTMLElement); function HTMLElement() { _classCallCheck(this, HTMLElement); return _super2.apply(this, arguments); } return HTMLElement; }(Element$1); var SVGElement = hasWindowSupport ? w.SVGElement : /*#__PURE__*/function (_Element2) { _inherits(SVGElement, _Element2); var _super3 = _createSuper(SVGElement); function SVGElement() { _classCallCheck(this, SVGElement); return _super3.apply(this, arguments); } return SVGElement; }(Element$1); var File = hasWindowSupport ? w.File : /*#__PURE__*/function (_Object2) { _inherits(File, _Object2); var _super4 = _createSuper(File); function File() { _classCallCheck(this, File); return _super4.apply(this, arguments); } return File; }( /*#__PURE__*/_wrapNativeSuper(Object)); var toType = function toType(val) { return _typeof(val); }; var toRawType = function toRawType(val) { return Object.prototype.toString.call(val).slice(8, -1); }; var isUndefined = function isUndefined(val) { return val === undefined; }; var isNull = function isNull(val) { return val === null; }; var isUndefinedOrNull = function isUndefinedOrNull(val) { return isUndefined(val) || isNull(val); }; var isFunction = function isFunction(val) { return toType(val) === 'function'; }; var isBoolean = function isBoolean(val) { return toType(val) === 'boolean'; }; var isString = function isString(val) { return toType(val) === 'string'; }; var isNumber = function isNumber(val) { return toType(val) === 'number'; }; // Is a value number like (i.e. a number or a number as string) var isNumeric = function isNumeric(value) { return !isNaN(parseInt(value, 10)); }; var isArray = function isArray(val) { return Array.isArray(val); }; // Quick object check // This is primarily used to tell Objects from primitive values // when we know the value is a JSON-compliant type // Note object could be a complex type like array, Date, etc. var isObject = function isObject(obj) { return obj !== null && _typeof(obj) === 'object'; }; // Strict object type check // Only returns true for plain JavaScript objects var isPlainObject = function isPlainObject(obj) { return Object.prototype.toString.call(obj) === '[object Object]'; }; var isDate = function isDate(val) { return val instanceof Date; }; var isEvent = function isEvent(val) { return val instanceof Event; }; var isFile = function isFile(val) { return val instanceof File; }; var isRegExp = function isRegExp(val) { return toRawType(val) === 'RegExp'; }; var isPromise = function isPromise(val) { return !isUndefinedOrNull(val) && isFunction(val.then) && isFunction(val.catch); }; var assign = function assign() { return Object.assign.apply(Object, arguments); }; var create = function create(proto, optionalProps) { return Object.create(proto, optionalProps); }; var defineProperties = function defineProperties(obj, props) { return Object.defineProperties(obj, props); }; var defineProperty = function defineProperty(obj, prop, descriptor) { return Object.defineProperty(obj, prop, descriptor); }; var getOwnPropertyNames = function getOwnPropertyNames(obj) { return Object.getOwnPropertyNames(obj); }; var keys = function keys(obj) { return Object.keys(obj); }; // --- "Instance" --- var hasOwnProperty = function hasOwnProperty(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }; var toString = function toString(obj) { return Object.prototype.toString.call(obj); }; // --- Utilities --- /** * Shallow copy an object. If the passed in object * is null or undefined, returns an empty object */ var clone = function clone(obj) { return _objectSpread2({}, obj); }; /** * Return a shallow copy of object with the specified properties only * @link https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc */ var pick = function pick(obj, props) { return keys(obj).filter(function (key) { return props.indexOf(key) !== -1; }).reduce(function (result, key) { return _objectSpread2(_objectSpread2({}, result), {}, _defineProperty({}, key, obj[key])); }, {}); }; /** * Return a shallow copy of object with the specified properties omitted * @link https://gist.github.com/bisubus/2da8af7e801ffd813fab7ac221aa7afc */ var omit = function omit(obj, props) { return keys(obj).filter(function (key) { return props.indexOf(key) === -1; }).reduce(function (result, key) { return _objectSpread2(_objectSpread2({}, result), {}, _defineProperty({}, key, obj[key])); }, {}); }; /** * Merges two object deeply together * @link https://gist.github.com/Salakar/1d7137de9cb8b704e48a */ var mergeDeep = function mergeDeep(target, source) { if (isObject(target) && isObject(source)) { keys(source).forEach(function (key) { if (isObject(source[key])) { if (!target[key] || !isObject(target[key])) { target[key] = source[key]; } mergeDeep(target[key], source[key]); } else { assign(target, _defineProperty({}, key, source[key])); } }); } return target; }; /** * Convenience method to create a read-only descriptor */ var readonlyDescriptor = function readonlyDescriptor() { return { enumerable: true, configurable: false, writable: false }; }; var cloneDeep = function cloneDeep(obj) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : obj; if (isArray(obj)) { return obj.reduce(function (result, val) { return [].concat(_toConsumableArray(result), [cloneDeep(val, val)]); }, []); } if (isPlainObject(obj)) { return keys(obj).reduce(function (result, key) { return _objectSpread2(_objectSpread2({}, result), {}, _defineProperty({}, key, cloneDeep(obj[key], obj[key]))); }, {}); } return defaultValue; }; // --- General --- var RX_ARRAY_NOTATION = /\[(\d+)]/g; var RX_DIGITS = /^\d+$/; var RX_EXTENSION = /^\..+/; var RX_HASH = /^#/; var RX_HASH_ID = /^#[A-Za-z]+[\w\-:.]*$/; var RX_HTML_TAGS = /(<([^>]+)>)/gi; var RX_HYPHENATE = /\B([A-Z])/g; var RX_LOWER_UPPER = /([a-z])([A-Z])/g; var RX_NUMBER = /^[0-9]*\.?[0-9]+$/; var RX_PLUS = /\+/g; var RX_REGEXP_REPLACE = /[-/\\^$*+?.()|[\]{}]/g; var RX_SPACES = /[\s\uFEFF\xA0]+/g; var RX_SPACE_SPLIT = /\s+/; var RX_STAR = /\/\*$/; var RX_START_SPACE_WORD = /(\s|^)(\w)/g; var RX_TRIM_LEFT = /^\s+/; var RX_UNDERSCORE = /_/g; var RX_UN_KEBAB = /-(\w)/g; // --- Date --- // Loose YYYY-MM-DD matching, ignores any appended time inforation // Matches '1999-12-20', '1999-1-1', '1999-01-20T22:51:49.118Z', '1999-01-02 13:00:00' var RX_DATE = /^\d+-\d\d?-\d\d?(?:\s|T|$)/; // Used to split off the date parts of the YYYY-MM-DD string var RX_DATE_SPLIT = /-|\s|T/; // Time string RegEx (optional seconds) var RX_TIME = /^([0-1]?[0-9]|2[0-3]):[0-5]?[0-9](:[0-5]?[0-9])?$/; // --- URL --- // HREFs must end with a hash followed by at least one non-hash character var RX_HREF = /^.*(#[^#]+)$/; var RX_ENCODED_COMMA = /%2C/g; var RX_ENCODE_REVERSE = /[!'()*]/g; var RX_QUERY_START = /^(\?|#|&)/; // --- Aspect --- var RX_ASPECT = /^\d+(\.\d*)?[/:]\d+(\.\d*)?$/; var RX_ASPECT_SEPARATOR = /[/:]/; // --- Grid --- var RX_COL_CLASS = /^col-/; // --- Icon --- var RX_ICON_PREFIX = /^BIcon/; // --- Locale --- var RX_STRIP_LOCALE_MODS = /-u-.+/; var identity = function identity(x) { return x; }; /** * Get property defined by dot/array notation in string, returns undefined if not found * * @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 * * @param {Object} obj * @param {string|Array} path * @return {*} */ var getRaw = function getRaw(obj, path) { var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; // Handle array of path values path = isArray(path) ? path.join('.') : path; // If no path or no object passed if (!path || !isObject(obj)) { return defaultValue; } // Handle edge case where user has dot(s) in top-level item field key // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2762 // Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters // https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 if (path in obj) { return obj[path]; } // Handle string array notation (numeric indices only) path = String(path).replace(RX_ARRAY_NOTATION, '.$1'); var steps = path.split('.').filter(identity); // Handle case where someone passes a string of only dots if (steps.length === 0) { return defaultValue; } // Traverse path in object to find result // Switched to `in` operator vs `hasOwnProperty` to handle obj.prototype getters // https://github.com/bootstrap-vue/bootstrap-vue/issues/3463 return steps.every(function (step) { return isObject(obj) && step in obj && !isUndefinedOrNull(obj = obj[step]); }) ? obj : isNull(obj) ? null : defaultValue; }; /** * Get property defined by dot/array notation in string. * * @link https://gist.github.com/jeneg/9767afdcca45601ea44930ea03e0febf#gistcomment-1935901 * * @param {Object} obj * @param {string|Array} path * @param {*} defaultValue (optional) * @return {*} */ var get = function get(obj, path) { var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var val = getRaw(obj, path); return isUndefinedOrNull(val) ? defaultValue : val; }; /** * Log a warning message to the console with BootstrapVue formatting * @param {string} message */ var warn = function warn(message) /* istanbul ignore next */ { var source = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; if (!getNoWarn()) { console.warn("[BootstrapVue warn]: ".concat(source ? "".concat(source, " - ") : '').concat(message)); } }; /** * Warn when no Promise support is given * @param {string} source * @returns {boolean} warned */ var warnNotClient = function warnNotClient(source) { /* istanbul ignore else */ if (isBrowser) { return false; } else { warn("".concat(source, ": Can not be called during SSR.")); return true; } }; /** * Warn when no Promise support is given * @param {string} source * @returns {boolean} warned */ var warnNoPromiseSupport = function warnNoPromiseSupport(source) { /* istanbul ignore else */ if (hasPromiseSupport) { return false; } else { warn("".concat(source, ": Requires Promise support.")); return true; } }; /** * Warn when no MutationObserver support is given * @param {string} source * @returns {boolean} warned */ var warnNoMutationObserverSupport = function warnNoMutationObserverSupport(source) { /* istanbul ignore else */ if (hasMutationObserverSupport) { return false; } else { warn("".concat(source, ": Requires MutationObserver support.")); return true; } }; var BvConfig = /*#__PURE__*/function () { function BvConfig() { _classCallCheck(this, BvConfig); this.$_config = {}; } // Method to merge in user config parameters _createClass(BvConfig, [{ key: "setConfig", value: function setConfig() { var _this = this; var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; /* istanbul ignore next */ if (!isPlainObject(config)) { return; } var configKeys = getOwnPropertyNames(config); configKeys.forEach(function (key) { /* istanbul ignore next */ var subConfig = config[key]; if (key === 'breakpoints') { /* istanbul ignore if */ if (!isArray(subConfig) || subConfig.length < 2 || subConfig.some(function (b) { return !isString(b) || b.length === 0; })) { warn('"breakpoints" must be an array of at least 2 breakpoint names', NAME); } else { _this.$_config[key] = cloneDeep(subConfig); } } else if (isPlainObject(subConfig)) { // Component prop defaults _this.$_config[key] = getOwnPropertyNames(subConfig).reduce(function (config, prop) { if (!isUndefined(subConfig[prop])) { config[prop] = cloneDeep(subConfig[prop]); } return config; }, _this.$_config[key] || {}); } }); } // Clear the config }, { key: "resetConfig", value: function resetConfig() { this.$_config = {}; } // Returns a deep copy of the user config }, { key: "getConfig", value: function getConfig() { return cloneDeep(this.$_config); } // Returns a deep copy of the config value }, { key: "getConfigValue", value: function getConfigValue(key) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; return cloneDeep(getRaw(this.$_config, key, defaultValue)); } }]); return BvConfig; }(); // Method for applying a global config var setConfig = function setConfig() { var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var Vue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : Vue__default['default']; // Ensure we have a `$bvConfig` Object on the Vue prototype // We set on Vue and OurVue just in case consumer has not set an alias of `vue` Vue.prototype[PROP_NAME] = Vue__default['default'].prototype[PROP_NAME] = Vue.prototype[PROP_NAME] || Vue__default['default'].prototype[PROP_NAME] || new BvConfig(); // Apply the config values Vue.prototype[PROP_NAME].setConfig(config); }; // Method for resetting the user config /** * Checks if there are multiple instances of Vue, and warns (once) about possible issues. * @param {object} Vue */ var checkMultipleVue = function () { var checkMultipleVueWarned = false; var MULTIPLE_VUE_WARNING = ['Multiple instances of Vue detected!', 'You may need to set up an alias for Vue in your bundler config.', 'See: https://bootstrap-vue.org/docs#using-module-bundlers'].join('\n'); return function (Vue) { /* istanbul ignore next */ if (!checkMultipleVueWarned && Vue__default['default'] !== Vue && !isJSDOM) { warn(MULTIPLE_VUE_WARNING); } checkMultipleVueWarned = true; }; }(); /** * Plugin install factory function. * @param {object} { components, directives } * @returns {function} plugin install function */ var installFactory = function installFactory() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, components = _ref.components, directives = _ref.directives, plugins = _ref.plugins; var install = function install(Vue) { var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (install.installed) { /* istanbul ignore next */ return; } install.installed = true; checkMultipleVue(Vue); setConfig(config, Vue); registerComponents(Vue, components); registerDirectives(Vue, directives); registerPlugins(Vue, plugins); }; install.installed = false; return install; }; /** * Plugin object factory function. * @param {object} { components, directives, plugins } * @returns {object} plugin install object */ var pluginFactory = function pluginFactory() { var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var extend = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return _objectSpread2(_objectSpread2({}, extend), {}, { install: installFactory(options) }); }; /** * Load a group of plugins. * @param {object} Vue * @param {object} Plugin definitions */ var registerPlugins = function registerPlugins(Vue) { var plugins = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; for (var plugin in plugins) { if (plugin && plugins[plugin]) { Vue.use(plugins[plugin]); } } }; /** * Load a component. * @param {object} Vue * @param {string} Component name * @param {object} Component definition */ var registerComponent = function registerComponent(Vue, name, def) { if (Vue && name && def) { Vue.component(name, def); } }; /** * Load a group of components. * @param {object} Vue * @param {object} Object of component definitions */ var registerComponents = function registerComponents(Vue) { var components = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; for (var component in components) { registerComponent(Vue, component, components[component]); } }; /** * Load a directive. * @param {object} Vue * @param {string} Directive name * @param {object} Directive definition */ var registerDirective = function registerDirective(Vue, name, def) { if (Vue && name && def) { // Ensure that any leading V is removed from the // name, as Vue adds it automatically Vue.directive(name.replace(/^VB/, 'B'), def); } }; /** * Load a group of directives. * @param {object} Vue * @param {object} Object of directive definitions */ var registerDirectives = function registerDirectives(Vue) { var directives = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; for (var directive in directives) { registerDirective(Vue, directive, directives[directive]); } }; /** * Install plugin if window.Vue available * @param {object} Plugin definition */ var vueUse = function vueUse(VuePlugin) { /* istanbul ignore next */ if (hasWindowSupport && window.Vue) { window.Vue.use(VuePlugin); } /* istanbul ignore next */ if (hasWindowSupport && VuePlugin.NAME) { window[VuePlugin.NAME] = VuePlugin; } }; var NAME_ALERT = 'BAlert'; var NAME_ASPECT = 'BAspect'; var NAME_AVATAR = 'BAvatar'; var NAME_AVATAR_GROUP = 'BAvatarGroup'; var NAME_BADGE = 'BBadge'; var NAME_BREADCRUMB = 'BBreadcrumb'; var NAME_BREADCRUMB_ITEM = 'BBreadcrumbItem'; var NAME_BREADCRUMB_LINK = 'BBreadcrumbLink'; var NAME_BUTTON = 'BButton'; var NAME_BUTTON_CLOSE = 'BButtonClose'; var NAME_BUTTON_GROUP = 'BButtonGroup'; var NAME_BUTTON_TOOLBAR = 'BButtonToolbar'; var NAME_CALENDAR = 'BCalendar'; var NAME_CARD = 'BCard'; var NAME_CARD_BODY = 'BCardBody'; var NAME_CARD_FOOTER = 'BCardFooter'; var NAME_CARD_GROUP = 'BCardGroup'; var NAME_CARD_HEADER = 'BCardHeader'; var NAME_CARD_IMG = 'BCardImg'; var NAME_CARD_IMG_LAZY = 'BCardImgLazy'; var NAME_CARD_SUB_TITLE = 'BCardSubTitle'; var NAME_CARD_TEXT = 'BCardText'; var NAME_CARD_TITLE = 'BCardTitle'; var NAME_CAROUSEL = 'BCarousel'; var NAME_CAROUSEL_SLIDE = 'BCarouselSlide'; var NAME_COL = 'BCol'; var NAME_COLLAPSE = 'BCollapse'; var NAME_COLLAPSE_HELPER = 'BVCollapse'; var NAME_CONTAINER = 'BContainer'; var NAME_DROPDOWN = 'BDropdown'; var NAME_DROPDOWN_DIVIDER = 'BDropdownDivider'; var NAME_DROPDOWN_FORM = 'BDropdownForm'; var NAME_DROPDOWN_GROUP = 'BDropdownGroup'; var NAME_DROPDOWN_HEADER = 'BDropdownHeader'; var NAME_DROPDOWN_ITEM = 'BDropdownItem'; var NAME_DROPDOWN_ITEM_BUTTON = 'BDropdownItemButton'; var NAME_DROPDOWN_TEXT = 'BDropdownText'; var NAME_EMBED = 'BEmbed'; var NAME_FORM = 'BForm'; var NAME_FORM_BUTTON_LABEL_CONTROL = 'BVFormBtnLabelControl'; var NAME_FORM_CHECKBOX = 'BFormCheckbox'; var NAME_FORM_CHECKBOX_GROUP = 'BFormCheckboxGroup'; var NAME_FORM_DATALIST = 'BFormDatalist'; var NAME_FORM_DATEPICKER = 'BFormDatepicker'; var NAME_FORM_FILE = 'BFormFile'; var NAME_FORM_GROUP = 'BFormGroup'; var NAME_FORM_INPUT = 'BFormInput'; var NAME_FORM_INVALID_FEEDBACK = 'BFormInvalidFeedback'; var NAME_FORM_RADIO = 'BFormRadio'; var NAME_FORM_RADIO_GROUP = 'BFormRadioGroup'; var NAME_FORM_RATING = 'BFormRating'; var NAME_FORM_RATING_STAR = 'BVFormRatingStar'; var NAME_FORM_ROW = 'BFormRow'; var NAME_FORM_SELECT = 'BFormSelect'; var NAME_FORM_SELECT_OPTION = 'BFormSelectOption'; var NAME_FORM_SELECT_OPTION_GROUP = 'BFormSelectOptionGroup'; var NAME_FORM_SPINBUTTON = 'BFormSpinbutton'; var NAME_FORM_TAG = 'BFormTag'; var NAME_FORM_TAGS = 'BFormTags'; var NAME_FORM_TEXT = 'BFormText'; var NAME_FORM_TEXTAREA = 'BFormTextarea'; var NAME_FORM_TIMEPICKER = 'BFormTimepicker'; var NAME_FORM_VALID_FEEDBACK = 'BFormValidFeedback'; var NAME_ICON = 'BIcon'; var NAME_ICONSTACK = 'BIconstack'; var NAME_ICON_BASE = 'BIconBase'; var NAME_IMG = 'BImg'; var NAME_IMG_LAZY = 'BImgLazy'; var NAME_INPUT_GROUP = 'BInputGroup'; var NAME_INPUT_GROUP_ADDON = 'BInputGroupAddon'; var NAME_INPUT_GROUP_APPEND = 'BInputGroupAppend'; var NAME_INPUT_GROUP_PREPEND = 'BInputGroupPrepend'; var NAME_INPUT_GROUP_TEXT = 'BInputGroupText'; var NAME_JUMBOTRON = 'BJumbotron'; var NAME_LINK = 'BLink'; var NAME_LIST_GROUP = 'BListGroup'; var NAME_LIST_GROUP_ITEM = 'BListGroupItem'; var NAME_MEDIA = 'BMedia'; var NAME_MEDIA_ASIDE = 'BMediaAside'; var NAME_MEDIA_BODY = 'BMediaBody'; var NAME_MODAL = 'BModal'; var NAME_MSG_BOX = 'BMsgBox'; var NAME_NAV = 'BNav'; var NAME_NAVBAR = 'BNavbar'; var NAME_NAVBAR_BRAND = 'BNavbarBrand'; var NAME_NAVBAR_NAV = 'BNavbarNav'; var NAME_NAVBAR_TOGGLE = 'BNavbarToggle'; var NAME_NAV_FORM = 'BNavForm'; var NAME_NAV_ITEM = 'BNavItem'; var NAME_NAV_ITEM_DROPDOWN = 'BNavItemDropdown'; var NAME_NAV_TEXT = 'BNavText'; var NAME_OVERLAY = 'BOverlay'; var NAME_PAGINATION = 'BPagination'; var NAME_PAGINATION_NAV = 'BPaginationNav'; var NAME_POPOVER = 'BPopover'; var NAME_POPOVER_HELPER = 'BVPopover'; var NAME_POPOVER_TEMPLATE = 'BVPopoverTemplate'; var NAME_POPPER = 'BVPopper'; var NAME_PROGRESS = 'BProgress'; var NAME_PROGRESS_BAR = 'BProgressBar'; var NAME_ROW = 'BRow'; var NAME_SIDEBAR = 'BSidebar'; var NAME_SKELETON = 'BSkeleton'; var NAME_SKELETON_ICON = 'BSkeletonIcon'; var NAME_SKELETON_IMG = 'BSkeletonImg'; var NAME_SKELETON_TABLE = 'BSkeletonTable'; var NAME_SKELETON_WRAPPER = 'BSkeletonWrapper'; var NAME_SPINNER = 'BSpinner'; var NAME_TAB = 'BTab'; var NAME_TABLE = 'BTable'; var NAME_TABLE_CELL = 'BTableCell'; var NAME_TABLE_LITE = 'BTableLite'; var NAME_TABLE_SIMPLE = 'BTableSimple'; var NAME_TABS = 'BTabs'; var NAME_TAB_BUTTON_HELPER = 'BVTabButton'; var NAME_TBODY = 'BTbody'; var NAME_TFOOT = 'BTfoot'; var NAME_TH = 'BTh'; var NAME_THEAD = 'BThead'; var NAME_TIME = 'BTime'; var NAME_TOAST = 'BToast'; var NAME_TOASTER = 'BToaster'; var NAME_TOAST_POP = 'BVToastPop'; var NAME_TOOLTIP = 'BTooltip'; var NAME_TOOLTIP_HELPER = 'BVTooltip'; var NAME_TOOLTIP_TEMPLATE = 'BVTooltipTemplate'; var NAME_TR = 'BTr'; var NAME_TRANSITION = 'BVTransition'; var NAME_TRANSPORTER_SINGLE = 'BTransporterSingle'; var NAME_TRANSPORTER_TARGET_SINGLE = 'BTransporterTargetSingle'; var memoize = function memoize(fn) { var cache = create(null); return function () { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var argsKey = JSON.stringify(args); return cache[argsKey] = cache[argsKey] || fn.apply(null, args); }; }; var VueProto = Vue__default['default'].prototype; // --- Getter methods --- var getConfigValue = function getConfigValue(key) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; var bvConfig = VueProto[PROP_NAME]; return bvConfig ? bvConfig.getConfigValue(key, defaultValue) : cloneDeep(defaultValue); }; // Method to grab a config value for a particular component var getComponentConfig = function getComponentConfig(key) { var propKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var defaultValue = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined; // Return the particular config value for key if specified, // otherwise we return the full config (or an empty object if not found) return propKey ? getConfigValue("".concat(key, ".").concat(propKey), defaultValue) : getConfigValue(key, {}); }; // Get all breakpoint names var getBreakpoints = function getBreakpoints() { return getConfigValue('breakpoints', DEFAULT_BREAKPOINT); }; // Private method for caching breakpoint names var _getBreakpointsCached = memoize(function () { return getBreakpoints(); }); // Get all breakpoint names (cached) var getBreakpointsCached = function getBreakpointsCached() { return cloneDeep(_getBreakpointsCached()); }; // Get breakpoints with the smallest breakpoint set as '' // Useful for components that create breakpoint specific props var getBreakpointsUpCached = memoize(function () { var breakpoints = getBreakpointsCached(); breakpoints[0] = ''; return breakpoints; }); // Get breakpoints with the largest breakpoint set as '' // Replaces the current `default` key of each prop with a `getComponentConfig()` // call that falls back to the current default value of the prop var makePropsConfigurable = function makePropsConfigurable(props, componentKey) { return keys(props).reduce(function (result, prop) { var currentProp = props[prop]; var defaultValue = currentProp.default; result[prop] = _objectSpread2(_objectSpread2({}, cloneDeep(currentProp)), {}, { default: function _default() { return getComponentConfig(componentKey, prop, isFunction(defaultValue) ? defaultValue() : defaultValue); } }); return result; }, {}); }; // --- Static --- var from = function from() { return Array.from.apply(Array, arguments); }; // --- Instance --- var arrayIncludes = function arrayIncludes(array, value) { return array.indexOf(value) !== -1; }; var concat = function concat() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return Array.prototype.concat.apply([], args); }; // --- Utilities --- var createAndFillArray = function createAndFillArray(size, value) { return Array(size).fill(value); }; var flatten = function flatten(array) { return array.reduce(function (result, item) { return result.concat(item); }, []); }; var flattenDeep = function flattenDeep(array) { return array.reduce(function (result, item) { return result.concat(Array.isArray(item) ? flattenDeep(item) : item); }, []); }; // Number utilities // Converts a value (string, number, etc.) to an integer number // Assumes radix base 10 var toInteger = function toInteger(value) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NaN; var integer = parseInt(value, 10); return isNaN(integer) ? defaultValue : integer; }; // Converts a value (string, number, etc.) to a number var toFloat = function toFloat(value) { var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : NaN; var float = parseFloat(value); return isNaN(float) ? defaultValue : float; }; // Converts a value (string, number, etc.) to a string // representation with `precision` digits after the decimal // Returns the string 'NaN' if the value cannot be converted var toFixed = function toFixed(val, precision) { return toFloat(val).toFixed(toInteger(precision, 0)); }; // String utilities // Converts PascalCase or camelCase to kebab-case var kebabCase = function kebabCase(str) { return str.replace(RX_HYPHENATE, '-$1').toLowerCase(); }; // Converts a kebab-case or camelCase string to PascalCase var pascalCase = function pascalCase(str) { str = kebabCase(str).replace(RX_UN_KEBAB, function (_, c) { return c ? c.toUpperCase() : ''; }); return str.charAt(0).toUpperCase() + str.slice(1); }; // Converts a string, including strings in camelCase or snake_case, into Start Case // It keeps original single quote and hyphen in the word // https://github.com/UrbanCompass/to-start-case var startCase = function startCase(str) { return str.replace(RX_UNDERSCORE, ' ').replace(RX_LOWER_UPPER, function (str, $1, $2) { return $1 + ' ' + $2; }).replace(RX_START_SPACE_WORD, function (str, $1, $2) { return $1 + $2.toUpperCase(); }); }; // Lowercases the first letter of a string and returns a new string var lowerFirst = function lowerFirst(str) { str = isString(str) ? str.trim() : String(str); return str.charAt(0).toLowerCase() + str.slice(1); }; // Uppercases the first letter of a string and returns a new string var upperFirst = function upperFirst(str) { str = isString(str) ? str.trim() : String(str); return str.charAt(0).toUpperCase() + str.slice(1); }; // Escape characters to be used in building a regular expression var escapeRegExp = function escapeRegExp(str) { return str.replace(RX_REGEXP_REPLACE, '\\$&'); }; // Convert a value to a string that can be rendered // `undefined`/`null` will be converted to `''` // Plain objects and arrays will be JSON stringified var toString$1 = function toString(val) { var spaces = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; return isUndefinedOrNull(val) ? '' : isArray(val) || isPlainObject(val) && val.toString === Object.prototype.toString ? JSON.stringify(val, null, spaces) : String(val); }; // Remove leading white space from a string var trimLeft = function trimLeft(str) { return toString$1(str).replace(RX_TRIM_LEFT, ''); }; // Remove Trailing white space from a string var trim = function trim(str) { return toString$1(str).trim(); }; // Lower case a string var lowerCase = function lowerCase(str) { return toString$1(str).toLowerCase(); }; // Upper case a string var TABABLE_SELECTOR = ['button', '[href]:not(.disabled)', 'input', 'select', 'textarea', '[tabindex]', '[contenteditable]'].map(function (s) { return "".concat(s, ":not(:disabled):not([disabled])"); }).join(', '); var w$1 = hasWindowSupport ? window : {}; var d = hasDocumentSupport ? document : {}; var elProto = typeof Element !== 'undefined' ? Element.prototype : {}; // --- Normalization utils --- // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill /* istanbul ignore next */ var matchesEl = elProto.matches || elProto.msMatchesSelector || elProto.webkitMatchesSelector; // See: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest /* istanbul ignore next */ var closestEl = elProto.closest || function (sel) { var el = this; do { // Use our "patched" matches function if (matches(el, sel)) { return el; } el = el.parentElement || el.parentNode; } while (!isNull(el) && el.nodeType === Node.ELEMENT_NODE); return null; }; // `requestAnimationFrame()` convenience method /* istanbul ignore next: JSDOM always returns the first option */ var requestAF = w$1.requestAnimationFrame || w$1.webkitRequestAnimationFrame || w$1.mozRequestAnimationFrame || w$1.msRequestAnimationFrame || w$1.oRequestAnimationFrame || // Fallback, but not a true polyfill // Only needed for Opera Mini /* istanbul ignore next */ function (cb) { return setTimeout(cb, 16); }; var MutationObs = w$1.MutationObserver || w$1.WebKitMutationObserver || w$1.MozMutationObserver || null; // --- Utils --- // Remove a node from DOM var removeNode = function removeNode(el) { return el && el.parentNode && el.parentNode.removeChild(el); }; // Determine if an element is an HTML element var isElement = function isElement(el) { return !!(el && el.nodeType === Node.ELEMENT_NODE); }; // Get the currently active HTML element var getActiveElement = function getActiveElement() { var excludes = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; var activeElement = d.activeElement; return activeElement && !excludes.some(function (el) { return el === activeElement; }) ? activeElement : null; }; // Returns `true` if a tag's name equals `name` var isTag = function isTag(tag, name) { return toString$1(tag).toLowerCase() === toString$1(name).toLowerCase(); }; // Determine if an HTML element is the currently active element var isActiveElement = function isActiveElement(el) { return isElement(el) && el === getActiveElement(); }; // Determine if an HTML element is visible - Faster than CSS check var isVisible = function isVisible(el) { if (!isElement(el) || !el.parentNode || !contains(d.body, el)) { // Note this can fail for shadow dom elements since they // are not a direct descendant of document.body return false; } if (getStyle(el, 'display') === 'none') { // We do this check to help with vue-test-utils when using v-show /* istanbul ignore next */ return false; } // All browsers support getBoundingClientRect(), except JSDOM as it returns all 0's for values :( // So any tests that need isVisible will fail in JSDOM // Except when we override the getBCR prototype in some tests var bcr = getBCR(el); return !!(bcr && bcr.height > 0 && bcr.width > 0); }; // Determine if an element is disabled var isDisabled = function isDisabled(el) { return !isElement(el) || el.disabled || hasAttr(el, 'disabled') || hasClass(el, 'disabled'); }; // Cause/wait-for an element to reflow its content (adjusting its height/width) var reflow = function reflow(el) { // Requesting an elements offsetHight will trigger a reflow of the element content /* istanbul ignore next: reflow doesn't happen in JSDOM */ return isElement(el) && el.offsetHeight; }; // Select all elements matching selector. Returns `[]` if none found var selectAll = function selectAll(selector, root) { return from((isElement(root) ? root : d).querySelectorAll(selector)); }; // Select a single element, returns `null` if not found var select = function select(selector, root) { return (isElement(root) ? root : d).querySelector(selector) || null; }; // Determine if an element matches a selector var matches = function matches(el, selector) { return isElement(el) ? matchesEl.call(el, selector) : false; }; // Finds closest element matching selector. Returns `null` if not found var closest = function closest(selector, root) { var includeRoot = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; if (!isElement(root)) { return null; } var el = closestEl.call(root, selector); // Native closest behaviour when `includeRoot` is truthy, // else emulate jQuery closest and return `null` if match is // the passed in root element when `includeRoot` is falsey return includeRoot ? el : el === root ? null : el; }; // Returns true if the parent element contains the child element var contains = function contains(parent, child) { return parent && isFunction(parent.contains) ? parent.contains(child) : false; }; // Get an element given an ID var getById = function getById(id) { return d.getElementById(/^#/.test(id) ? id.slice(1) : id) || null; }; // Add a class to an element var addClass = function addClass(el, className) { // We are checking for `el.classList` existence here since IE 11 // returns `undefined` for some elements (e.g. SVG elements) // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 if (className && isElement(el) && el.classList) { el.classList.add(className); } }; // Remove a class from an element var removeClass = function removeClass(el, className) { // We are checking for `el.classList` existence here since IE 11 // returns `undefined` for some elements (e.g. SVG elements) // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 if (className && isElement(el) && el.classList) { el.classList.remove(className); } }; // Test if an element has a class var hasClass = function hasClass(el, className) { // We are checking for `el.classList` existence here since IE 11 // returns `undefined` for some elements (e.g. SVG elements) // See https://github.com/bootstrap-vue/bootstrap-vue/issues/2713 if (className && isElement(el) && el.classList) { return el.classList.contains(className); } return false; }; // Set an attribute on an element var setAttr = function setAttr(el, attr, value) { if (attr && isElement(el)) { el.setAttribute(attr, value); } }; // Remove an attribute from an element var removeAttr = function removeAttr(el, attr) { if (attr && isElement(el)) { el.removeAttribute(attr); } }; // Get an attribute value from an element // Returns `null` if not found var getAttr = function getAttr(el, attr) { return attr && isElement(el) ? el.getAttribute(attr) : null; }; // Determine if an attribute exists on an element // Returns `true` or `false`, or `null` if element not found var hasAttr = function hasAttr(el, attr) { return attr && isElement(el) ? el.hasAttribute(attr) : null; }; // Set an style property on an element var setStyle = function setStyle(el, prop, value) { if (prop && isElement(el)) { el.style[prop] = value; } }; // Remove an style property from an element var removeStyle = function removeStyle(el, prop) { if (prop && isElement(el)) { el.style[prop] = ''; } }; // Get an style property value from an element // Returns `null` if not found var getStyle = function getStyle(el, prop) { return prop && isElement(el) ? el.style[prop] || null : null; }; // Return the Bounding Client Rect of an element // Returns `null` if not an element /* istanbul ignore next: getBoundingClientRect() doesn't work in JSDOM */ var getBCR = function getBCR(el) { return isElement(el) ? el.getBoundingClientRect() : null; }; // Get computed style object for an element /* istanbul ignore next: getComputedStyle() doesn't work in JSDOM */ var getCS = function getCS(el) { return hasWindowSupport && isElement(el) ? w$1.getComputedStyle(el) : {}; }; // Returns a `Selection` object representing the range of text selected // Returns `null` if no window support is given /* istanbul ignore next: getSelection() doesn't work in JSDOM */ var getSel = function getSel() { return hasWindowSupport && w$1.getSelection ? w$1.getSelection() : null; }; // Return an element's offset with respect to document element // https://j11y.io/jquery/#v=git&fn=jQuery.fn.offset var offset = function offset(el) /* istanbul ignore next: getBoundingClientRect(), getClientRects() doesn't work in JSDOM */ { var _offset = { top: 0, left: 0 }; if (!isElement(el) || el.getClientRects().length === 0) { return _offset; } var bcr = getBCR(el); if (bcr) { var win = el.ownerDocument.defaultView; _offset.top = bcr.top + win.pageYOffset; _offset.left = bcr.left + win.pageXOffset; } return _offset; }; // Return an element's offset with respect to to its offsetParent // https://j11y.io/jquery/#v=git&fn=jQuery.fn.position var position = function position(el) /* istanbul ignore next: getBoundingClientRect() doesn't work in JSDOM */ { var _offset = { top: 0, left: 0 }; if (!isElement(el)) { return _offset; } var parentOffset = { top: 0, left: 0 }; var elStyles = getCS(el); if (elStyles.position === 'fixed') { _offset = getBCR(el) || _offset; } else { _offset = offset(el); var doc = el.ownerDocument; var offsetParent = el.offsetParent || doc.documentElement; while (offsetParent && (offsetParent === doc.body || offsetParent === doc.documentElement) && getCS(offsetParent).position === 'static') { offsetParent = offsetParent.parentNode; } if (offsetParent && offsetParent !== el && offsetParent.nodeType === Node.ELEMENT_NODE) { parentOffset = offset(offsetParent); var offsetParentStyles = getCS(offsetParent); parentOffset.top += toFloat(offsetParentStyles.borderTopWidth, 0); parentOffset.left += toFloat(offsetParentStyles.borderLeftWidth, 0); } } return { top: _offset.top - parentOffset.top - toFloat(elStyles.marginTop, 0), left: _offset.left - parentOffset.left - toFloat(elStyles.marginLeft, 0) }; }; // Find all tabable elements in the given element // Assumes users have not used `tabindex` > `0` on elements var getTabables = function getTabables() { var rootEl = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document; return selectAll(TABABLE_SELECTOR, rootEl).filter(isVisible).filter(function (el) { return el.tabIndex > -1 && !el.disabled; }); }; // Attempt to focus an element, and return `true` if successful var attemptFocus = function attemptFocus(el) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; try { el.focus(options); } catch (_unused) {} return isActiveElement(el); }; // Attempt to blur an element, and return `true` if successful var attemptBlur = function attemptBlur(el) { try { el.blur(); } catch (_unused2) {} return !isActiveElement(el); }; var NO_FADE_PROPS = { name: '', enterClass: '', enterActiveClass: '', enterToClass: 'show', leaveClass: 'show', leaveActiveClass: '', leaveToClass: '' }; var FADE_PROPS = _objectSpread2(_objectSpread2({}, NO_FADE_PROPS), {}, { enterActiveClass: 'fade', leaveActiveClass: 'fade' }); // @vue/component var BVTransition = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_TRANSITION, functional: true, props: { noFade: { // Only applicable to the built in transition // Has no effect if `trans-props` provided type: Boolean, default: false }, appear: { // Has no effect if `trans-props` provided type: Boolean, default: false }, mode: { // Can be overridden by user supplied trans-props type: String // default: undefined }, // For user supplied transitions (if needed) transProps: { type: Object, default: null } }, render: function render(h, _ref) { var children = _ref.children, data = _ref.data, props = _ref.props; var transProps = props.transProps; if (!isPlainObject(transProps)) { transProps = props.noFade ? NO_FADE_PROPS : FADE_PROPS; if (props.appear) { // Default the appear classes to equal the enter classes transProps = _objectSpread2(_objectSpread2({}, transProps), {}, { appear: true, appearClass: transProps.enterClass, appearActiveClass: transProps.enterActiveClass, appearToClass: transProps.enterToClass }); } } transProps = _objectSpread2(_objectSpread2({ mode: props.mode }, transProps), {}, { // We always need `css` true css: true }); return h('transition', // Any transition event listeners will get merged here a(data, { props: transProps }), children); } }); var SLOT_NAME_APPEND = 'append'; var SLOT_NAME_BUTTON_CONTENT = 'button-content'; var SLOT_NAME_DEFAULT = 'default'; var SLOT_NAME_DESCRIPTION = 'description'; var SLOT_NAME_FIRST = 'first'; var SLOT_NAME_FOOTER = 'footer'; var SLOT_NAME_HEADER = 'header'; var SLOT_NAME_LABEL = 'label'; var SLOT_NAME_LEAD = 'lead'; var SLOT_NAME_PREPEND = 'prepend'; var SLOT_NAME_TEXT = 'text'; var SLOT_NAME_TITLE = 'title'; // In functional components, `slots` is a function so it must be called // first before passing to the below methods. `scopedSlots` is always an // object and may be undefined (for Vue < 2.6.x) /** * Returns true if either scoped or unscoped named slot exists * * @param {String, Array} name or name[] * @param {Object} scopedSlots * @param {Object} slots * @returns {Array|undefined} VNodes */ var hasNormalizedSlot = function hasNormalizedSlot(names) { var $scopedSlots = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var $slots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; // Ensure names is an array names = concat(names).filter(identity); // Returns true if the either a $scopedSlot or $slot exists with the specified name return names.some(function (name) { return $scopedSlots[name] || $slots[name]; }); }; /** * Returns VNodes for named slot either scoped or unscoped * * @param {String, Array} name or name[] * @param {String} scope * @param {Object} scopedSlots * @param {Object} slots * @returns {Array|undefined} VNodes */ var normalizeSlot = function normalizeSlot(names) { var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var $scopedSlots = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; var $slots = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; // Ensure names is an array names = concat(names).filter(identity); var slot; for (var i = 0; i < names.length && !slot; i++) { var name = names[i]; slot = $scopedSlots[name] || $slots[name]; } // Note: in Vue 2.6.x, all named slots are also scoped slots return isFunction(slot) ? slot(scope) : slot; }; // Named exports var normalizeSlotMixin = { methods: { hasNormalizedSlot: function hasNormalizedSlot$1() { var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SLOT_NAME_DEFAULT; // Returns true if the either a $scopedSlot or $slot exists with the specified name // `name` can be a string name or an array of names return hasNormalizedSlot(name, this.$scopedSlots, this.$slots); }, normalizeSlot: function normalizeSlot$1() { var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SLOT_NAME_DEFAULT; var scope = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; // Returns an array of rendered VNodes if slot found. // Returns undefined if not found. // `name` can be a string name or an array of names var vNodes = normalizeSlot(name, scope, this.$scopedSlots, this.$slots); return vNodes ? concat(vNodes) : vNodes; } } }; // Normalize event options based on support of passive option // Exported only for testing purposes var parseEventOptions = function parseEventOptions(options) { /* istanbul ignore else: can't test in JSDOM, as it supports passive */ if (hasPassiveEventSupport) { return isObject(options) ? options : { capture: !!options || false }; } else { // Need to translate to actual Boolean value return !!(isObject(options) ? options.capture : options); } }; // Attach an event listener to an element var eventOn = function eventOn(el, evtName, handler, options) { if (el && el.addEventListener) { el.addEventListener(evtName, handler, parseEventOptions(options)); } }; // Remove an event listener from an element var eventOff = function eventOff(el, evtName, handler, options) { if (el && el.removeEventListener) { el.removeEventListener(evtName, handler, parseEventOptions(options)); } }; // Utility method to add/remove a event listener based on first argument (boolean) // It passes all other arguments to the `eventOn()` or `eventOff` method var eventOnOff = function eventOnOff(on) { var method = on ? eventOn : eventOff; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } method.apply(void 0, args); }; // Utility method to prevent the default event handling and propagation var stopEvent = function stopEvent(evt) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, _ref$preventDefault = _ref.preventDefault, preventDefault = _ref$preventDefault === void 0 ? true : _ref$preventDefault, _ref$propagation = _ref.propagation, propagation = _ref$propagation === void 0 ? true : _ref$propagation, _ref$immediatePropaga = _ref.immediatePropagation, immediatePropagation = _ref$immediatePropaga === void 0 ? false : _ref$immediatePropaga; if (preventDefault) { evt.preventDefault(); } if (propagation) { evt.stopPropagation(); } if (immediatePropagation) { evt.stopImmediatePropagation(); } }; var props = makePropsConfigurable({ content: { type: String, default: '×' }, disabled: { type: Boolean, default: false }, ariaLabel: { type: String, default: 'Close' }, textVariant: { type: String // `textVariant` is `undefined` to inherit the current text color // default: undefined } }, NAME_BUTTON_CLOSE); // @vue/component var BButtonClose = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BUTTON_CLOSE, functional: true, props: props, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, slots = _ref.slots, scopedSlots = _ref.scopedSlots; var $slots = slots(); var $scopedSlots = scopedSlots || {}; var componentData = { staticClass: 'close', class: _defineProperty({}, "text-".concat(props.textVariant), props.textVariant), attrs: { type: 'button', disabled: props.disabled, 'aria-label': props.ariaLabel ? String(props.ariaLabel) : null }, on: { click: function click(evt) { // Ensure click on button HTML content is also disabled /* istanbul ignore if: bug in JSDOM still emits click on inner element */ if (props.disabled && isEvent(evt)) { stopEvent(evt); } } } }; // Careful not to override the default slot with innerHTML if (!hasNormalizedSlot(SLOT_NAME_DEFAULT, $scopedSlots, $slots)) { componentData.domProps = { innerHTML: props.content }; } return h('button', a(data, componentData), normalizeSlot(SLOT_NAME_DEFAULT, {}, $scopedSlots, $slots)); } }); var parseCountDown = function parseCountDown(show) { if (show === '' || isBoolean(show)) { return 0; } show = toInteger(show, 0); return show > 0 ? show : 0; }; // Convert `show` value to a boolean var parseShow = function parseShow(show) { if (show === '' || show === true) { return true; } if (toInteger(show, 0) < 1) { // Boolean will always return false for the above comparison return false; } return !!show; }; // @vue/component var BAlert = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_ALERT, mixins: [normalizeSlotMixin], model: { prop: 'show', event: 'input' }, props: makePropsConfigurable({ variant: { type: String, default: 'info' }, dismissible: { type: Boolean, default: false }, dismissLabel: { type: String, default: 'Close' }, show: { type: [Boolean, Number, String], default: false }, fade: { type: Boolean, default: false } }, NAME_ALERT), data: function data() { return { countDown: 0, // If initially shown, we need to set these for SSR localShow: parseShow(this.show) }; }, watch: { show: function show(newVal) { this.countDown = parseCountDown(newVal); this.localShow = parseShow(newVal); }, countDown: function countDown(newVal) { var _this = this; this.clearCountDownInterval(); if (isNumeric(this.show)) { // Ignore if this.show transitions to a boolean value. this.$emit('dismiss-count-down', newVal); if (this.show !== newVal) { // Update the v-model if needed this.$emit('input', newVal); } if (newVal > 0) { this.localShow = true; this.$_countDownTimeout = setTimeout(function () { _this.countDown--; }, 1000); } else { // Slightly delay the hide to allow any UI updates this.$nextTick(function () { requestAF(function () { _this.localShow = false; }); }); } } }, localShow: function localShow(newVal) { if (!newVal && (this.dismissible || isNumeric(this.show))) { // Only emit dismissed events for dismissible or auto dismissing alerts this.$emit('dismissed'); } if (!isNumeric(this.show) && this.show !== newVal) { // Only emit booleans if we weren't passed a number via `this.show` this.$emit('input', newVal); } } }, created: function created() { // Create private non-reactive props this.$_filterTimer = null; this.countDown = parseCountDown(this.show); this.localShow = parseShow(this.show); }, mounted: function mounted() { this.countDown = parseCountDown(this.show); this.localShow = parseShow(this.show); }, beforeDestroy: function beforeDestroy() { this.clearCountDownInterval(); }, methods: { dismiss: function dismiss() { this.clearCountDownInterval(); this.countDown = 0; this.localShow = false; }, clearCountDownInterval: function clearCountDownInterval() { clearTimeout(this.$_countDownTimeout); this.$_countDownTimeout = null; } }, render: function render(h) { var $alert; // undefined if (this.localShow) { var $dismissBtn = h(); if (this.dismissible) { // Add dismiss button $dismissBtn = h(BButtonClose, { attrs: { 'aria-label': this.dismissLabel }, on: { click: this.dismiss } }, [this.normalizeSlot('dismiss')]); } $alert = h('div', { key: this._uid, staticClass: 'alert', class: _defineProperty({ 'alert-dismissible': this.dismissible }, "alert-".concat(this.variant), this.variant), attrs: { role: 'alert', 'aria-live': 'polite', 'aria-atomic': true } }, [$dismissBtn, this.normalizeSlot()]); $alert = [$alert]; } return h(BVTransition, { props: { noFade: !this.fade } }, $alert); } }); var AlertPlugin = /*#__PURE__*/pluginFactory({ components: { BAlert: BAlert } }); // Math utilty functions var mathMin = Math.min; var mathMax = Math.max; var mathAbs = Math.abs; var mathCeil = Math.ceil; var mathFloor = Math.floor; var mathPow = Math.pow; var mathRound = Math.round; var CLASS_NAME = 'b-aspect'; // --- Main Component --- var BAspect = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_ASPECT, mixins: [normalizeSlotMixin], props: makePropsConfigurable({ aspect: { // Accepts a number (i.e. `16 / 9`, `1`, `4 / 3`) // Or a string (i.e. '16/9', '16:9', '4:3' '1:1') type: [Number, String], default: '1:1' }, tag: { type: String, default: 'div' } }, NAME_ASPECT), computed: { padding: function padding() { var aspect = this.aspect; var ratio = 1; if (RX_ASPECT.test(aspect)) { // Width and/or Height can be a decimal value below `1`, so // we only fallback to `1` if the value is `0` or `NaN` var _aspect$split$map = aspect.split(RX_ASPECT_SEPARATOR).map(function (v) { return toFloat(v) || 1; }), _aspect$split$map2 = _slicedToArray(_aspect$split$map, 2), width = _aspect$split$map2[0], height = _aspect$split$map2[1]; ratio = width / height; } else { ratio = toFloat(aspect) || 1; } return "".concat(100 / mathAbs(ratio), "%"); } }, render: function render(h) { var $sizer = h('div', { staticClass: "".concat(CLASS_NAME, "-sizer flex-grow-1"), style: { paddingBottom: this.padding, height: 0 } }); var $content = h('div', { staticClass: "".concat(CLASS_NAME, "-content flex-grow-1 w-100 mw-100"), style: { marginLeft: '-100%' } }, [this.normalizeSlot()]); return h(this.tag, { staticClass: "".concat(CLASS_NAME, " d-flex") }, [$sizer, $content]); } }); var AspectPlugin = /*#__PURE__*/pluginFactory({ components: { BAspect: BAspect } }); var prefixPropName = function prefixPropName(prefix, value) { return prefix + upperFirst(value); }; // Remove a prefix from a property var unprefixPropName = function unprefixPropName(prefix, value) { return lowerFirst(value.replace(prefix, '')); }; // Suffix can be a falsey value so nothing is appended to string // (helps when looping over props & some shouldn't change) // Use data last parameters to allow for currying var suffixPropName = function suffixPropName(suffix, str) { return str + (suffix ? upperFirst(suffix) : ''); }; // Copies props from one array/object to a new array/object // Prop values are also cloned as new references to prevent possible // mutation of original prop object values // Optionally accepts a function to transform the prop name var copyProps = function copyProps(props) { var transformFn = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : identity; if (isArray(props)) { return props.map(transformFn); } var copied = {}; for (var prop in props) { /* istanbul ignore else */ if (hasOwnProperty(props, prop)) { // If the prop value is an object, do a shallow clone // to prevent potential mutations to the original object copied[transformFn(prop)] = isObject(props[prop]) ? clone(props[prop]) : props[prop]; } } return copied; }; // Given an array of properties or an object of property keys, // plucks all the values off the target object, returning a new object // that has props that reference the original prop values var pluckProps = function pluckProps(keysToPluck, objToPluck) { var transformFn = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : identity; return (isArray(keysToPluck) ? keysToPluck.slice() : keys(keysToPluck)).reduce(function (memo, prop) { memo[transformFn(prop)] = objToPluck[prop]; return memo; }, {}); }; var ANCHOR_TAG = 'a'; // Method to replace reserved chars var encodeReserveReplacer = function encodeReserveReplacer(c) { return '%' + c.charCodeAt(0).toString(16); }; // Fixed encodeURIComponent which is more conformant to RFC3986: // - escapes [!'()*] // - preserve commas var encode = function encode(str) { return encodeURIComponent(toString$1(str)).replace(RX_ENCODE_REVERSE, encodeReserveReplacer).replace(RX_ENCODED_COMMA, ','); }; var decode = decodeURIComponent; // Stringifies an object of query parameters // See: https://github.com/vuejs/vue-router/blob/dev/src/util/query.js var stringifyQueryObj = function stringifyQueryObj(obj) { if (!isPlainObject(obj)) { return ''; } var query = keys(obj).map(function (key) { var val = obj[key]; if (isUndefined(val)) { return ''; } else if (isNull(val)) { return encode(key); } else if (isArray(val)) { return val.reduce(function (results, val2) { if (isNull(val2)) { results.push(encode(key)); } else if (!isUndefined(val2)) { // Faster than string interpolation results.push(encode(key) + '=' + encode(val2)); } return results; }, []).join('&'); } // Faster than string interpolation return encode(key) + '=' + encode(val); }) /* must check for length, as we only want to filter empty strings, not things that look falsey! */ .filter(function (x) { return x.length > 0; }).join('&'); return query ? "?".concat(query) : ''; }; var parseQuery = function parseQuery(query) { var parsed = {}; query = toString$1(query).trim().replace(RX_QUERY_START, ''); if (!query) { return parsed; } query.split('&').forEach(function (param) { var parts = param.replace(RX_PLUS, ' ').split('='); var key = decode(parts.shift()); var val = parts.length > 0 ? decode(parts.join('=')) : null; if (isUndefined(parsed[key])) { parsed[key] = val; } else if (isArray(parsed[key])) { parsed[key].push(val); } else { parsed[key] = [parsed[key], val]; } }); return parsed; }; var isLink = function isLink(props) { return !!(props.href || props.to); }; var isRouterLink = function isRouterLink(tag) { return !!(tag && !isTag(tag, 'a')); }; var computeTag = function computeTag(_ref, thisOrParent) { var to = _ref.to, disabled = _ref.disabled, routerComponentName = _ref.routerComponentName; var hasRouter = !!thisOrParent.$router; if (!hasRouter || hasRouter && (disabled || !to)) { return ANCHOR_TAG; } // TODO: // Check registered components for existence of user supplied router link component name // We would need to check PascalCase, kebab-case, and camelCase versions of name: // const name = routerComponentName // const names = [name, PascalCase(name), KebabCase(name), CamelCase(name)] // exists = names.some(name => !!thisOrParent.$options.components[name]) // And may want to cache the result for performance or we just let the render fail // if the component is not registered return routerComponentName || (thisOrParent.$nuxt ? 'nuxt-link' : 'router-link'); }; var computeRel = function computeRel() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, target = _ref2.target, rel = _ref2.rel; return target === '_blank' && isNull(rel) ? 'noopener' : rel || null; }; var computeHref = function computeHref() { var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, href = _ref3.href, to = _ref3.to; var tag = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ANCHOR_TAG; var fallback = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '#'; var toFallback = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '/'; // Return `href` when explicitly provided if (href) { return href; } // We've checked for `$router` in `computeTag()`, so `isRouterLink()` indicates a live router // When deferring to Vue Router's ``, don't use the `href` attribute at all // We return `null`, and then remove `href` from the attributes passed to `` if (isRouterLink(tag)) { return null; } // Fallback to `to` prop (if `to` is a string) if (isString(to)) { return to || toFallback; } // Fallback to `to.path' + `to.query` + `to.hash` prop (if `to` is an object) if (isPlainObject(to) && (to.path || to.query || to.hash)) { var path = toString$1(to.path); var query = stringifyQueryObj(to.query); var hash = toString$1(to.hash); hash = !hash || hash.charAt(0) === '#' ? hash : "#".concat(hash); return "".concat(path).concat(query).concat(hash) || toFallback; } // If nothing is provided return the fallback return fallback; }; var CODE_BACKSPACE = 8; var CODE_DELETE = 46; var CODE_DOWN = 40; var CODE_END = 35; var CODE_ENTER = 13; var CODE_ESC = 27; var CODE_HOME = 36; var CODE_LEFT = 37; var CODE_PAGEDOWN = 34; var CODE_PAGEUP = 33; var CODE_RIGHT = 39; var CODE_SPACE = 32; var CODE_UP = 38; // Handles when arrays are "sparse" (array.every(...) doesn't handle sparse) var compareArrays = function compareArrays(a, b) { if (a.length !== b.length) { return false; } var equal = true; for (var i = 0; equal && i < a.length; i++) { equal = looseEqual(a[i], b[i]); } return equal; }; /** * Check if two values are loosely equal - that is, * if they are plain objects, do they have the same shape? * Returns boolean true or false */ var looseEqual = function looseEqual(a, b) { if (a === b) { return true; } var aValidType = isDate(a); var bValidType = isDate(b); if (aValidType || bValidType) { return aValidType && bValidType ? a.getTime() === b.getTime() : false; } aValidType = isArray(a); bValidType = isArray(b); if (aValidType || bValidType) { return aValidType && bValidType ? compareArrays(a, b) : false; } aValidType = isObject(a); bValidType = isObject(b); if (aValidType || bValidType) { /* istanbul ignore if: this if will probably never be called */ if (!aValidType || !bValidType) { return false; } var aKeysCount = keys(a).length; var bKeysCount = keys(b).length; if (aKeysCount !== bKeysCount) { return false; } for (var key in a) { var aHasKey = hasOwnProperty(a, key); var bHasKey = hasOwnProperty(b, key); if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) { return false; } } } return String(a) === String(b); }; var isEmpty = function isEmpty(value) { return !value || keys(value).length === 0; }; var makePropWatcher = function makePropWatcher(propName) { return { handler: function handler(newValue, oldValue) { if (looseEqual(newValue, oldValue)) { return; } if (isEmpty(newValue) || isEmpty(oldValue)) { this[propName] = cloneDeep(newValue); return; } for (var key in oldValue) { if (!hasOwnProperty(newValue, key)) { this.$delete(this.$data[propName], key); } } for (var _key in newValue) { this.$set(this.$data[propName], _key, newValue[_key]); } } }; }; var makePropCacheMixin = function makePropCacheMixin(propName, proxyPropName) { return { data: function data() { return _defineProperty({}, proxyPropName, cloneDeep(this[propName])); }, watch: _defineProperty({}, propName, makePropWatcher(proxyPropName)) }; }; var attrsMixin = makePropCacheMixin('$attrs', 'bvAttrs'); var listenersMixin = makePropCacheMixin('$listeners', 'bvListeners'); // specific props var routerLinkProps = { to: { type: [String, Object], default: null }, append: { type: Boolean, default: false }, replace: { type: Boolean, default: false }, event: { type: [String, Array], default: 'click' }, activeClass: { type: String // default: undefined }, exact: { type: Boolean, default: false }, exactActiveClass: { type: String // default: undefined }, routerTag: { type: String, default: 'a' } }; // specific props var nuxtLinkProps = { prefetch: { type: Boolean, // Must be `null` to fall back to the value defined in the // `nuxt.config.js` configuration file for `router.prefetchLinks` // We convert `null` to `undefined`, so that Nuxt.js will use the // compiled default. Vue treats `undefined` as default of `false` // for Boolean props, so we must set it as `null` here to be a // true tri-state prop default: null }, noPrefetch: { type: Boolean, default: false } }; var props$1 = makePropsConfigurable(_objectSpread2(_objectSpread2(_objectSpread2({ href: { type: String, default: null }, rel: { type: String, // Must be `null` if no value provided default: null }, target: { type: String, default: '_self' }, active: { type: Boolean, default: false }, disabled: { type: Boolean, default: false } }, routerLinkProps), nuxtLinkProps), {}, { // To support 3rd party router links based on `` (i.e. `g-link` for Gridsome) // Default is to auto choose between `` and `` // Gridsome doesn't provide a mechanism to auto detect and has caveats // such as not supporting FQDN URLs or hash only URLs routerComponentName: { type: String // default: undefined } }), NAME_LINK); // --- Main component --- // @vue/component var BLink = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_LINK, // Mixin order is important! mixins: [attrsMixin, listenersMixin, normalizeSlotMixin], inheritAttrs: false, props: props$1, computed: { computedTag: function computedTag() { // We don't pass `this` as the first arg as we need reactivity of the props var to = this.to, disabled = this.disabled, routerComponentName = this.routerComponentName; return computeTag({ to: to, disabled: disabled, routerComponentName: routerComponentName }, this); }, isRouterLink: function isRouterLink$1() { return isRouterLink(this.computedTag); }, computedRel: function computedRel() { // We don't pass `this` as the first arg as we need reactivity of the props var target = this.target, rel = this.rel; return computeRel({ target: target, rel: rel }); }, computedHref: function computedHref() { // We don't pass `this` as the first arg as we need reactivity of the props var to = this.to, href = this.href; return computeHref({ to: to, href: href }, this.computedTag); }, computedProps: function computedProps() { var prefetch = this.prefetch; return this.isRouterLink ? _objectSpread2(_objectSpread2({}, pluckProps(_objectSpread2(_objectSpread2({}, routerLinkProps), nuxtLinkProps), this)), {}, { // Coerce `prefetch` value `null` to be `undefined` prefetch: isBoolean(prefetch) ? prefetch : undefined, // Pass `router-tag` as `tag` prop tag: this.routerTag }) : {}; }, computedAttrs: function computedAttrs() { var bvAttrs = this.bvAttrs, href = this.computedHref, rel = this.computedRel, disabled = this.disabled, target = this.target, routerTag = this.routerTag, isRouterLink = this.isRouterLink; return _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, bvAttrs), href ? { href: href } : {}), isRouterLink && !isTag(routerTag, 'a') ? {} : { rel: rel, target: target }), {}, { tabindex: disabled ? '-1' : isUndefined(bvAttrs.tabindex) ? null : bvAttrs.tabindex, 'aria-disabled': disabled ? 'true' : null }); }, computedListeners: function computedListeners() { return _objectSpread2(_objectSpread2({}, this.bvListeners), {}, { // We want to overwrite any click handler since our callback // will invoke the user supplied handler(s) if `!this.disabled` click: this.onClick }); } }, methods: { onClick: function onClick(evt) { var _arguments = arguments; var evtIsEvent = isEvent(evt); var isRouterLink = this.isRouterLink; var suppliedHandler = this.bvListeners.click; if (evtIsEvent && this.disabled) { // Stop event from bubbling up // Kill the event loop attached to this specific `EventTarget` // Needed to prevent `vue-router` for doing its thing stopEvent(evt, { immediatePropagation: true }); } else { /* istanbul ignore next: difficult to test, but we know it works */ if (isRouterLink && evt.currentTarget.__vue__) { // Router links do not emit instance `click` events, so we // add in an `$emit('click', evt)` on its Vue instance evt.currentTarget.__vue__.$emit('click', evt); } // Call the suppliedHandler(s), if any provided concat(suppliedHandler).filter(function (h) { return isFunction(h); }).forEach(function (handler) { handler.apply(void 0, _toConsumableArray(_arguments)); }); // Emit the global `$root` click event this.$root.$emit('clicked::link', evt); } // Stop scroll-to-top behavior or navigation on // regular links when href is just '#' if (evtIsEvent && !isRouterLink && this.computedHref === '#') { stopEvent(evt, { propagation: false }); } }, focus: function focus() { attemptFocus(this.$el); }, blur: function blur() { attemptBlur(this.$el); } }, render: function render(h) { var active = this.active, disabled = this.disabled; return h(this.computedTag, _defineProperty({ class: { active: active, disabled: disabled }, attrs: this.computedAttrs, props: this.computedProps }, this.isRouterLink ? 'nativeOn' : 'on', this.computedListeners), this.normalizeSlot()); } }); var linkProps = omit(props$1, ['event', 'routerTag']); delete linkProps.href.default; delete linkProps.to.default; var props$2 = makePropsConfigurable(_objectSpread2({ block: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, size: { type: String // default: null }, variant: { type: String, default: 'secondary' }, type: { type: String, default: 'button' }, tag: { type: String, default: 'button' }, pill: { type: Boolean, default: false }, squared: { type: Boolean, default: false }, pressed: { // Tri-state: `true`, `false` or `null` // => On, off, not a toggle type: Boolean, default: null } }, linkProps), NAME_BUTTON); // --- Helper methods --- // Focus handler for toggle buttons // Needs class of 'focus' when focused var handleFocus = function handleFocus(evt) { if (evt.type === 'focusin') { addClass(evt.target, 'focus'); } else if (evt.type === 'focusout') { removeClass(evt.target, 'focus'); } }; // Is the requested button a link? // If tag prop is set to `a`, we use a to get proper disabled handling var isLink$1 = function isLink$1(props) { return isLink(props) || isTag(props.tag, 'a'); }; // Is the button to be a toggle button? var isToggle = function isToggle(props) { return isBoolean(props.pressed); }; // Is the button "really" a button? var isButton = function isButton(props) { return !(isLink$1(props) || props.tag && !isTag(props.tag, 'button')); }; // Is the requested tag not a button or link? var isNonStandardTag = function isNonStandardTag(props) { return !isLink$1(props) && !isButton(props); }; // Compute required classes (non static classes) var computeClass = function computeClass(props) { var _ref; return ["btn-".concat(props.variant || 'secondary'), (_ref = {}, _defineProperty(_ref, "btn-".concat(props.size), props.size), _defineProperty(_ref, 'btn-block', props.block), _defineProperty(_ref, 'rounded-pill', props.pill), _defineProperty(_ref, 'rounded-0', props.squared && !props.pill), _defineProperty(_ref, "disabled", props.disabled), _defineProperty(_ref, "active", props.pressed), _ref)]; }; // Compute the link props to pass to b-link (if required) var computeLinkProps = function computeLinkProps(props) { return isLink$1(props) ? pluckProps(linkProps, props) : {}; }; // Compute the attributes for a button var computeAttrs = function computeAttrs(props, data) { var button = isButton(props); var link = isLink$1(props); var toggle = isToggle(props); var nonStandardTag = isNonStandardTag(props); var hashLink = link && props.href === '#'; var role = data.attrs && data.attrs.role ? data.attrs.role : null; var tabindex = data.attrs ? data.attrs.tabindex : null; if (nonStandardTag || hashLink) { tabindex = '0'; } return { // Type only used for "real" buttons type: button && !link ? props.type : null, // Disabled only set on "real" buttons disabled: button ? props.disabled : null, // We add a role of button when the tag is not a link or button for ARIA // Don't bork any role provided in `data.attrs` when `isLink` or `isButton` // Except when link has `href` of `#` role: nonStandardTag || hashLink ? 'button' : role, // We set the `aria-disabled` state for non-standard tags 'aria-disabled': nonStandardTag ? String(props.disabled) : null, // For toggles, we need to set the pressed state for ARIA 'aria-pressed': toggle ? String(props.pressed) : null, // `autocomplete="off"` is needed in toggle mode to prevent some browsers // from remembering the previous setting when using the back button autocomplete: toggle ? 'off' : null, // `tabindex` is used when the component is not a button // Links are tabbable, but don't allow disabled, while non buttons or links // are not tabbable, so we mimic that functionality by disabling tabbing // when disabled, and adding a `tabindex="0"` to non buttons or non links tabindex: props.disabled && !button ? '-1' : tabindex }; }; // --- Main component --- // @vue/component var BButton = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BUTTON, functional: true, props: props$2, render: function render(h, _ref2) { var props = _ref2.props, data = _ref2.data, listeners = _ref2.listeners, children = _ref2.children; var toggle = isToggle(props); var link = isLink$1(props); var nonStandardTag = isNonStandardTag(props); var hashLink = link && props.href === '#'; var on = { keydown: function keydown(evt) { // When the link is a `href="#"` or a non-standard tag (has `role="button"`), // we add a keydown handlers for CODE_SPACE/CODE_ENTER /* istanbul ignore next */ if (props.disabled || !(nonStandardTag || hashLink)) { return; } var keyCode = evt.keyCode; // Add CODE_SPACE handler for `href="#"` and CODE_ENTER handler for non-standard tags if (keyCode === CODE_SPACE || keyCode === CODE_ENTER && nonStandardTag) { var target = evt.currentTarget || evt.target; stopEvent(evt, { propagation: false }); target.click(); } }, click: function click(evt) { /* istanbul ignore if: blink/button disabled should handle this */ if (props.disabled && isEvent(evt)) { stopEvent(evt); } else if (toggle && listeners && listeners['update:pressed']) { // Send `.sync` updates to any "pressed" prop (if `.sync` listeners) // `concat()` will normalize the value to an array without // double wrapping an array value in an array concat(listeners['update:pressed']).forEach(function (fn) { if (isFunction(fn)) { fn(!props.pressed); } }); } } }; if (toggle) { on.focusin = handleFocus; on.focusout = handleFocus; } var componentData = { staticClass: 'btn', class: computeClass(props), props: computeLinkProps(props), attrs: computeAttrs(props, data), on: on }; return h(link ? BLink : props.tag, a(data, componentData), children); } }); var commonIconProps = { title: { type: String // default: null }, variant: { type: String, default: null }, fontScale: { type: [Number, String], default: 1 }, scale: { type: [Number, String], default: 1 }, rotate: { type: [Number, String], default: 0 }, flipH: { type: Boolean, default: false }, flipV: { type: Boolean, default: false }, shiftH: { type: [Number, String], default: 0 }, shiftV: { type: [Number, String], default: 0 }, animation: { type: String, default: null } }; // Base attributes needed on all icons var baseAttrs = { viewBox: '0 0 16 16', width: '1em', height: '1em', focusable: 'false', role: 'img', 'aria-label': 'icon' }; // Attributes that are nulled out when stacked var stackedAttrs = { width: null, height: null, focusable: null, role: null, 'aria-label': null }; // Shared private base component to reduce bundle/runtime size // @vue/component var BVIconBase = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_ICON_BASE, functional: true, props: _objectSpread2({ content: { type: String }, stacked: { type: Boolean, default: false } }, commonIconProps), render: function render(h, _ref) { var _class; var data = _ref.data, props = _ref.props, children = _ref.children; var fontScale = mathMax(toFloat(props.fontScale, 1), 0) || 1; var scale = mathMax(toFloat(props.scale, 1), 0) || 1; var rotate = toFloat(props.rotate, 0); var shiftH = toFloat(props.shiftH, 0); var shiftV = toFloat(props.shiftV, 0); var flipH = props.flipH; var flipV = props.flipV; var animation = props.animation; // Compute the transforms // Note that order is important as SVG transforms are applied in order from // left to right and we want flipping/scale to occur before rotation // Note shifting is applied separately // Assumes that the viewbox is `0 0 16 16` (`8 8` is the center) var hasScale = flipH || flipV || scale !== 1; var hasTransforms = hasScale || rotate; var hasShift = shiftH || shiftV; var transforms = [hasTransforms ? 'translate(8 8)' : null, hasScale ? "scale(".concat((flipH ? -1 : 1) * scale, " ").concat((flipV ? -1 : 1) * scale, ")") : null, rotate ? "rotate(".concat(rotate, ")") : null, hasTransforms ? 'translate(-8 -8)' : null].filter(identity); // Handling stacked icons var isStacked = props.stacked; var hasContent = !isUndefinedOrNull(props.content); // We wrap the content in a `` for handling the transforms (except shift) var $inner = h('g', { attrs: { transform: transforms.join(' ') || null }, domProps: hasContent ? { innerHTML: props.content || '' } : {} }, children); // If needed, we wrap in an additional `` in order to handle the shifting if (hasShift) { $inner = h('g', { attrs: { transform: "translate(".concat(16 * shiftH / 16, " ").concat(-16 * shiftV / 16, ")") } }, [$inner]); } if (isStacked) { // Wrap in an additional `` for proper // animation handling if stacked $inner = h('g', {}, [$inner]); } var $title = props.title ? h('title', props.title) : null; return h('svg', a({ staticClass: 'b-icon bi', class: (_class = {}, _defineProperty(_class, "text-".concat(props.variant), !!props.variant), _defineProperty(_class, "b-icon-animation-".concat(animation), !!animation), _class), attrs: baseAttrs, style: isStacked ? {} : { fontSize: fontScale === 1 ? null : "".concat(fontScale * 100, "%") } }, // Merge in user supplied data data, // If icon is stacked, null out some attrs isStacked ? { attrs: stackedAttrs } : {}, // These cannot be overridden by users { attrs: { xmlns: isStacked ? null : 'http://www.w3.org/2000/svg', fill: 'currentColor' } }), [$title, $inner]); } }); /** * Icon component generator function * * @param {string} icon name (minus the leading `BIcon`) * @param {string} raw `innerHTML` for SVG * @return {VueComponent} */ var makeIcon = function makeIcon(name, content) { // For performance reason we pre-compute some values, so that // they are not computed on each render of the icon component var kebabName = kebabCase(name); var iconName = "BIcon".concat(pascalCase(name)); var iconNameClass = "bi-".concat(kebabName); var iconTitle = kebabName.replace(/-/g, ' '); var svgContent = trim(content || ''); // Return the icon component definition return /*#__PURE__*/Vue__default['default'].extend({ name: iconName, functional: true, props: _objectSpread2(_objectSpread2({}, commonIconProps), {}, { stacked: { type: Boolean, default: false } }), render: function render(h, _ref) { var data = _ref.data, props = _ref.props; return h(BVIconBase, a( // Defaults { props: { title: iconTitle }, attrs: { 'aria-label': iconTitle } }, // User data data, // Required data { staticClass: iconNameClass, props: _objectSpread2(_objectSpread2({}, props), {}, { content: svgContent }) })); } }); }; // --- BEGIN AUTO-GENERATED FILE --- var BIconBlank=/*#__PURE__*/makeIcon('Blank','');// --- Bootstrap Icons --- var BIconCalendar=/*#__PURE__*/makeIcon('Calendar','');// eslint-disable-next-line var BIconCalendarFill=/*#__PURE__*/makeIcon('CalendarFill','');// eslint-disable-next-line var BIconChevronBarLeft=/*#__PURE__*/makeIcon('ChevronBarLeft','');// eslint-disable-next-line var BIconChevronDoubleLeft=/*#__PURE__*/makeIcon('ChevronDoubleLeft','');// eslint-disable-next-line var BIconChevronDown=/*#__PURE__*/makeIcon('ChevronDown','');// eslint-disable-next-line var BIconChevronLeft=/*#__PURE__*/makeIcon('ChevronLeft','');// eslint-disable-next-line var BIconChevronUp=/*#__PURE__*/makeIcon('ChevronUp','');// eslint-disable-next-line var BIconCircleFill=/*#__PURE__*/makeIcon('CircleFill','');// eslint-disable-next-line var BIconClock=/*#__PURE__*/makeIcon('Clock','');// eslint-disable-next-line var BIconClockFill=/*#__PURE__*/makeIcon('ClockFill','');// eslint-disable-next-line var BIconDash=/*#__PURE__*/makeIcon('Dash','');// eslint-disable-next-line var BIconPersonFill=/*#__PURE__*/makeIcon('PersonFill','');// eslint-disable-next-line var BIconPlus=/*#__PURE__*/makeIcon('Plus','');// eslint-disable-next-line var BIconStar=/*#__PURE__*/makeIcon('Star','');// eslint-disable-next-line var BIconStarFill=/*#__PURE__*/makeIcon('StarFill','');// eslint-disable-next-line var BIconStarHalf=/*#__PURE__*/makeIcon('StarHalf','');// eslint-disable-next-line var BIconX=/*#__PURE__*/makeIcon('X','');// eslint-disable-next-line // --- END AUTO-GENERATED FILE --- var findIconComponent = function findIconComponent(ctx, iconName) { if (!ctx) { return null; } var components = (ctx.$options || {}).components; var iconComponent = components[iconName]; return iconComponent || findIconComponent(ctx.$parent, iconName); }; // Helper BIcon component // Requires the requested icon component to be installed var BIcon = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_ICON, functional: true, props: makePropsConfigurable(_objectSpread2(_objectSpread2({ icon: { type: String, default: null } }, commonIconProps), {}, { stacked: { type: Boolean, default: false } }), NAME_ICON), render: function render(h, _ref) { var data = _ref.data, props = _ref.props, parent = _ref.parent; var icon = pascalCase(trim(props.icon || '')).replace(RX_ICON_PREFIX, ''); // If parent context exists, we check to see if the icon has been registered // either locally in the parent component, or globally at the `$root` level // If not registered, we render a blank icon return h(icon ? findIconComponent(parent, "BIcon".concat(icon)) || BIconBlank : BIconBlank, a(data, { props: _objectSpread2(_objectSpread2({}, props), {}, { icon: null }) })); } }); var CLASS_NAME$1 = 'b-avatar'; var SIZES = ['sm', null, 'lg']; var FONT_SIZE_SCALE = 0.4; var BADGE_FONT_SIZE_SCALE = FONT_SIZE_SCALE * 0.7; // --- Utility methods --- var computeSize = function computeSize(value) { // Parse to number when value is a float-like string value = isString(value) && RX_NUMBER.test(value) ? toFloat(value, 0) : value; // Convert all numbers to pixel values return isNumber(value) ? "".concat(value, "px") : value || null; }; // --- Props --- var linkProps$1 = omit(props$1, ['active', 'event', 'routerTag']); // --- Main component --- // @vue/component var BAvatar = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_AVATAR, mixins: [normalizeSlotMixin], inject: { bvAvatarGroup: { default: null } }, props: makePropsConfigurable(_objectSpread2(_objectSpread2({ src: { type: String // default: null }, text: { type: String // default: null }, icon: { type: String // default: null }, alt: { type: String, default: 'avatar' }, variant: { type: String, default: 'secondary' }, size: { type: [Number, String] // default: null }, square: { type: Boolean, default: false }, rounded: { type: [Boolean, String], default: false }, button: { type: Boolean, default: false }, buttonType: { type: String, default: 'button' }, badge: { type: [Boolean, String], default: false }, badgeVariant: { type: String, default: 'primary' }, badgeTop: { type: Boolean, default: false }, badgeLeft: { type: Boolean, default: false }, badgeOffset: { type: String, default: '0px' } }, linkProps$1), {}, { ariaLabel: { type: String // default: null } }), NAME_AVATAR), data: function data() { return { localSrc: this.src || null }; }, computed: { computedSize: function computedSize() { // Always use the avatar group size var bvAvatarGroup = this.bvAvatarGroup; return computeSize(bvAvatarGroup ? bvAvatarGroup.size : this.size); }, computedVariant: function computedVariant() { var bvAvatarGroup = this.bvAvatarGroup; return bvAvatarGroup && bvAvatarGroup.variant ? bvAvatarGroup.variant : this.variant; }, computedRounded: function computedRounded() { var bvAvatarGroup = this.bvAvatarGroup; var square = bvAvatarGroup && bvAvatarGroup.square ? true : this.square; var rounded = bvAvatarGroup && bvAvatarGroup.rounded ? bvAvatarGroup.rounded : this.rounded; return square ? '0' : rounded === '' ? true : rounded || 'circle'; }, fontStyle: function fontStyle() { var size = this.computedSize; var fontSize = SIZES.indexOf(size) === -1 ? "calc(".concat(size, " * ").concat(FONT_SIZE_SCALE, ")") : null; return fontSize ? { fontSize: fontSize } : {}; }, marginStyle: function marginStyle() { var size = this.computedSize, bvAvatarGroup = this.bvAvatarGroup; var overlapScale = bvAvatarGroup ? bvAvatarGroup.overlapScale : 0; var value = size && overlapScale ? "calc(".concat(size, " * -").concat(overlapScale, ")") : null; return value ? { marginLeft: value, marginRight: value } : {}; }, badgeStyle: function badgeStyle() { var size = this.computedSize, badgeTop = this.badgeTop, badgeLeft = this.badgeLeft, badgeOffset = this.badgeOffset; var offset = badgeOffset || '0px'; return { fontSize: SIZES.indexOf(size) === -1 ? "calc(".concat(size, " * ").concat(BADGE_FONT_SIZE_SCALE, " )") : null, top: badgeTop ? offset : null, bottom: badgeTop ? null : offset, left: badgeLeft ? offset : null, right: badgeLeft ? null : offset }; } }, watch: { src: function src(newSrc, oldSrc) { if (newSrc !== oldSrc) { this.localSrc = newSrc || null; } } }, methods: { onImgError: function onImgError(evt) { this.localSrc = null; this.$emit('img-error', evt); }, onClick: function onClick(evt) { this.$emit('click', evt); } }, render: function render(h) { var _class2; var variant = this.computedVariant, disabled = this.disabled, rounded = this.computedRounded, icon = this.icon, src = this.localSrc, text = this.text, fontStyle = this.fontStyle, marginStyle = this.marginStyle, size = this.computedSize, button = this.button, type = this.buttonType, badge = this.badge, badgeVariant = this.badgeVariant, badgeStyle = this.badgeStyle; var link = !button && isLink(this); var tag = button ? BButton : link ? BLink : 'span'; var alt = this.alt; var ariaLabel = this.ariaLabel || null; var $content = null; if (this.hasNormalizedSlot()) { // Default slot overrides props $content = h('span', { staticClass: 'b-avatar-custom' }, [this.normalizeSlot()]); } else if (src) { $content = h('img', { style: variant ? {} : { width: '100%', height: '100%' }, attrs: { src: src, alt: alt }, on: { error: this.onImgError } }); $content = h('span', { staticClass: 'b-avatar-img' }, [$content]); } else if (icon) { $content = h(BIcon, { props: { icon: icon }, attrs: { 'aria-hidden': 'true', alt: alt } }); } else if (text) { $content = h('span', { staticClass: 'b-avatar-text', style: fontStyle }, [h('span', text)]); } else { // Fallback default avatar content $content = h(BIconPersonFill, { attrs: { 'aria-hidden': 'true', alt: alt } }); } var $badge = h(); var hasBadgeSlot = this.hasNormalizedSlot('badge'); if (badge || badge === '' || hasBadgeSlot) { var badgeText = badge === true ? '' : badge; $badge = h('span', { staticClass: 'b-avatar-badge', class: _defineProperty({}, "badge-".concat(badgeVariant), !!badgeVariant), style: badgeStyle }, [hasBadgeSlot ? this.normalizeSlot('badge') : badgeText]); } var componentData = { staticClass: CLASS_NAME$1, class: (_class2 = {}, _defineProperty(_class2, "".concat(CLASS_NAME$1, "-").concat(size), size && SIZES.indexOf(size) !== -1), _defineProperty(_class2, "badge-".concat(variant), !button && variant), _defineProperty(_class2, "rounded", rounded === true), _defineProperty(_class2, "rounded-".concat(rounded), rounded && rounded !== true), _defineProperty(_class2, "disabled", disabled), _class2), style: _objectSpread2(_objectSpread2({}, marginStyle), {}, { width: size, height: size }), attrs: { 'aria-label': ariaLabel || null }, props: button ? { variant: variant, disabled: disabled, type: type } : link ? pluckProps(linkProps$1, this) : {}, on: button || link ? { click: this.onClick } : {} }; return h(tag, componentData, [$content, $badge]); } }); // @vue/component var BAvatarGroup = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_AVATAR_GROUP, mixins: [normalizeSlotMixin], provide: function provide() { return { bvAvatarGroup: this }; }, props: makePropsConfigurable({ variant: { // Child avatars will prefer this variant over their own type: String, default: null }, size: { // Child avatars will always use this over their own size type: String // default: null }, overlap: { type: [Number, String], default: 0.3 }, square: { // Child avatars will prefer this prop (if set) over their own type: Boolean, default: false }, rounded: { // Child avatars will prefer this prop (if set) over their own type: [Boolean, String], default: false }, tag: { type: String, default: 'div' } }, NAME_AVATAR_GROUP), computed: { computedSize: function computedSize() { return computeSize(this.size); }, overlapScale: function overlapScale() { return mathMin(mathMax(toFloat(this.overlap, 0), 0), 1) / 2; }, paddingStyle: function paddingStyle() { var value = this.computedSize; value = value ? "calc(".concat(value, " * ").concat(this.overlapScale, ")") : null; return value ? { paddingLeft: value, paddingRight: value } : {}; } }, render: function render(h) { var $inner = h('div', { staticClass: 'b-avatar-group-inner', style: this.paddingStyle }, [this.normalizeSlot()]); return h(this.tag, { staticClass: 'b-avatar-group', attrs: { role: 'group' } }, [$inner]); } }); var AvatarPlugin = /*#__PURE__*/pluginFactory({ components: { BAvatar: BAvatar, BAvatarGroup: BAvatarGroup } }); var linkProps$2 = omit(props$1, ['event', 'routerTag']); delete linkProps$2.href.default; delete linkProps$2.to.default; var props$3 = makePropsConfigurable(_objectSpread2({ tag: { type: String, default: 'span' }, variant: { type: String, default: 'secondary' }, pill: { type: Boolean, default: false } }, linkProps$2), NAME_BADGE); // --- Main component --- // @vue/component var BBadge = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BADGE, functional: true, props: props$3, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var link = isLink(props); var tag = link ? BLink : props.tag; var componentData = { staticClass: 'badge', class: [props.variant ? "badge-".concat(props.variant) : 'badge-secondary', { 'badge-pill': props.pill, active: props.active, disabled: props.disabled }], props: link ? pluckProps(linkProps$2, props) : {} }; return h(tag, a(data, componentData), children); } }); var BadgePlugin = /*#__PURE__*/pluginFactory({ components: { BBadge: BBadge } }); var stripTags = function stripTags() { var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; return String(text).replace(RX_HTML_TAGS, ''); }; // Generate a `domProps` object for either `innerHTML`, `textContent` or an empty object var htmlOrText = function htmlOrText(innerHTML, textContent) { return innerHTML ? { innerHTML: innerHTML } : textContent ? { textContent: textContent } : {}; }; var props$4 = makePropsConfigurable(_objectSpread2({ text: { type: String, default: null }, html: { type: String, default: null }, ariaCurrent: { type: String, default: 'location' } }, omit(props$1, ['event', 'routerTag'])), NAME_BREADCRUMB_LINK); // --- Main component --- // @vue/component var BBreadcrumbLink = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BREADCRUMB_LINK, functional: true, props: props$4, render: function render(h, _ref) { var suppliedProps = _ref.props, data = _ref.data, children = _ref.children; var active = suppliedProps.active; var tag = active ? 'span' : BLink; var componentData = { attrs: { 'aria-current': active ? suppliedProps.ariaCurrent : null }, props: pluckProps(props$4, suppliedProps) }; if (!children) { componentData.domProps = htmlOrText(suppliedProps.html, suppliedProps.text); } return h(tag, a(data, componentData), children); } }); var BBreadcrumbItem = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BREADCRUMB_ITEM, functional: true, props: makePropsConfigurable(props$4, NAME_BREADCRUMB_ITEM), render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h('li', a(data, { staticClass: 'breadcrumb-item', class: { active: props.active } }), [h(BBreadcrumbLink, { props: props }, children)]); } }); var props$5 = makePropsConfigurable({ items: { type: Array, default: null } }, NAME_BREADCRUMB); // @vue/component var BBreadcrumb = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BREADCRUMB, functional: true, props: props$5, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var childNodes = children; // Build child nodes from items if given. if (isArray(props.items)) { var activeDefined = false; childNodes = props.items.map(function (item, idx) { if (!isObject(item)) { item = { text: toString$1(item) }; } // Copy the value here so we can normalize it. var active = item.active; if (active) { activeDefined = true; } if (!active && !activeDefined) { // Auto-detect active by position in list. active = idx + 1 === props.items.length; } return h(BBreadcrumbItem, { props: _objectSpread2(_objectSpread2({}, item), {}, { active: active }) }); }); } return h('ol', a(data, { staticClass: 'breadcrumb' }), childNodes); } }); var BreadcrumbPlugin = /*#__PURE__*/pluginFactory({ components: { BBreadcrumb: BBreadcrumb, BBreadcrumbItem: BBreadcrumbItem, BBreadcrumbLink: BBreadcrumbLink } }); var ButtonPlugin = /*#__PURE__*/pluginFactory({ components: { BButton: BButton, BBtn: BButton, BButtonClose: BButtonClose, BBtnClose: BButtonClose } }); var props$6 = makePropsConfigurable(_objectSpread2({ vertical: { type: Boolean, default: false }, size: { type: String // default: null }, tag: { type: String, default: 'div' }, ariaRole: { type: String, default: 'group' } }, pick(props$2, ['size'])), NAME_BUTTON_GROUP); // @vue/component var BButtonGroup = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BUTTON_GROUP, functional: true, props: props$6, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.tag, a(data, { class: _defineProperty({ 'btn-group': !props.vertical, 'btn-group-vertical': props.vertical }, "btn-group-".concat(props.size), props.size), attrs: { role: props.ariaRole } }), children); } }); var ButtonGroupPlugin = /*#__PURE__*/pluginFactory({ components: { BButtonGroup: BButtonGroup, BBtnGroup: BButtonGroup } }); var ITEM_SELECTOR = ['.btn:not(.disabled):not([disabled]):not(.dropdown-item)', '.form-control:not(.disabled):not([disabled])', 'select:not(.disabled):not([disabled])', 'input[type="checkbox"]:not(.disabled)', 'input[type="radio"]:not(.disabled)'].join(','); // --- Main component --- // @vue/component var BButtonToolbar = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_BUTTON_TOOLBAR, mixins: [normalizeSlotMixin], props: makePropsConfigurable({ justify: { type: Boolean, default: false }, keyNav: { type: Boolean, default: false } }, NAME_BUTTON_TOOLBAR), mounted: function mounted() { // Pre-set the tabindexes if the markup does not include // `tabindex="-1"` on the toolbar items if (this.keyNav) { this.getItems(); } }, methods: { getItems: function getItems() { var items = selectAll(ITEM_SELECTOR, this.$el); // Ensure `tabindex="-1"` is set on every item items.forEach(function (item) { item.tabIndex = -1; }); return items.filter(function (el) { return isVisible(el); }); }, focusFirst: function focusFirst() { var items = this.getItems(); attemptFocus(items[0]); }, focusPrev: function focusPrev(evt) { var items = this.getItems(); var index = items.indexOf(evt.target); if (index > -1) { items = items.slice(0, index).reverse(); attemptFocus(items[0]); } }, focusNext: function focusNext(evt) { var items = this.getItems(); var index = items.indexOf(evt.target); if (index > -1) { items = items.slice(index + 1); attemptFocus(items[0]); } }, focusLast: function focusLast() { var items = this.getItems().reverse(); attemptFocus(items[0]); }, onFocusin: function onFocusin(evt) { var $el = this.$el; if (evt.target === $el && !contains($el, evt.relatedTarget)) { stopEvent(evt); this.focusFirst(evt); } }, onKeydown: function onKeydown(evt) { var keyCode = evt.keyCode, shiftKey = evt.shiftKey; if (keyCode === CODE_UP || keyCode === CODE_LEFT) { stopEvent(evt); shiftKey ? this.focusFirst(evt) : this.focusPrev(evt); } else if (keyCode === CODE_DOWN || keyCode === CODE_RIGHT) { stopEvent(evt); shiftKey ? this.focusLast(evt) : this.focusNext(evt); } } }, render: function render(h) { return h('div', { staticClass: 'btn-toolbar', class: { 'justify-content-between': this.justify }, attrs: { role: 'toolbar', tabindex: this.keyNav ? '0' : null }, on: this.keyNav ? { focusin: this.onFocusin, keydown: this.onKeydown } : {} }, [this.normalizeSlot()]); } }); var ButtonToolbarPlugin = /*#__PURE__*/pluginFactory({ components: { BButtonToolbar: BButtonToolbar, BBtnToolbar: BButtonToolbar } }); var CALENDAR_GREGORY = 'gregory'; var CALENDAR_LONG = 'long'; var CALENDAR_NARROW = 'narrow'; var CALENDAR_SHORT = 'short'; var DATE_FORMAT_2_DIGIT = '2-digit'; var DATE_FORMAT_NUMERIC = 'numeric'; // Create or clone a date (`new Date(...)` shortcut) var createDate = function createDate() { for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _construct(Date, args); }; // Parse a date sting, or Date object, into a Date object (with no time information) var parseYMD = function parseYMD(date) { if (isString(date) && RX_DATE.test(date.trim())) { var _date$split$map = date.split(RX_DATE_SPLIT).map(function (v) { return toInteger(v, 1); }), _date$split$map2 = _slicedToArray(_date$split$map, 3), year = _date$split$map2[0], month = _date$split$map2[1], day = _date$split$map2[2]; return createDate(year, month - 1, day); } else if (isDate(date)) { return createDate(date.getFullYear(), date.getMonth(), date.getDate()); } return null; }; // Format a date object as `YYYY-MM-DD` format var formatYMD = function formatYMD(date) { date = parseYMD(date); if (!date) { return null; } var year = date.getFullYear(); var month = "0".concat(date.getMonth() + 1).slice(-2); var day = "0".concat(date.getDate()).slice(-2); return "".concat(year, "-").concat(month, "-").concat(day); }; // Given a locale (or locales), resolve the browser available locale var resolveLocale = function resolveLocale(locales) /* istanbul ignore next */ { var calendar = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : CALENDAR_GREGORY; locales = concat(locales).filter(identity); var fmt = new Intl.DateTimeFormat(locales, { calendar: calendar }); return fmt.resolvedOptions().locale; }; // Create a `Intl.DateTimeFormat` formatter function var createDateFormatter = function createDateFormatter(locale, options) /* istanbul ignore next */ { var dtf = new Intl.DateTimeFormat(locale, options); return dtf.format; }; // Determine if two dates are the same date (ignoring time portion) var datesEqual = function datesEqual(date1, date2) { // Returns true of the date portion of two date objects are equal // We don't compare the time portion return formatYMD(date1) === formatYMD(date2); }; // --- Date "math" utility methods (for BCalendar component mainly) --- var firstDateOfMonth = function firstDateOfMonth(date) { date = createDate(date); date.setDate(1); return date; }; var lastDateOfMonth = function lastDateOfMonth(date) { date = createDate(date); date.setMonth(date.getMonth() + 1); date.setDate(0); return date; }; var addYears = function addYears(date, numberOfYears) { date = createDate(date); var month = date.getMonth(); date.setFullYear(date.getFullYear() + numberOfYears); // Handle Feb 29th for leap years if (date.getMonth() !== month) { date.setDate(0); } return date; }; var oneMonthAgo = function oneMonthAgo(date) { date = createDate(date); var month = date.getMonth(); date.setMonth(month - 1); // Handle when days in month are different if (date.getMonth() === month) { date.setDate(0); } return date; }; var oneMonthAhead = function oneMonthAhead(date) { date = createDate(date); var month = date.getMonth(); date.setMonth(month + 1); // Handle when days in month are different if (date.getMonth() === (month + 2) % 12) { date.setDate(0); } return date; }; var oneYearAgo = function oneYearAgo(date) { return addYears(date, -1); }; var oneYearAhead = function oneYearAhead(date) { return addYears(date, 1); }; var oneDecadeAgo = function oneDecadeAgo(date) { return addYears(date, -10); }; var oneDecadeAhead = function oneDecadeAhead(date) { return addYears(date, 10); }; // Helper function to constrain a date between two values // Always returns a `Date` object or `null` if no date passed var constrainDate = function constrainDate(date) { var min = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var max = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; // Ensure values are `Date` objects (or `null`) date = parseYMD(date); min = parseYMD(min) || date; max = parseYMD(max) || date; // Return a new `Date` object (or `null`) return date ? date < min ? min : date > max ? max : date : null; }; // Localization utilities var RTL_LANGS = ['ar', 'az', 'ckb', 'fa', 'he', 'ks', 'lrc', 'mzn', 'ps', 'sd', 'te', 'ug', 'ur', 'yi'].map(function (locale) { return locale.toLowerCase(); }); // Returns true if the locale is RTL var isLocaleRTL = function isLocaleRTL(locale) { // Determines if the locale is RTL (only single locale supported) var parts = toString$1(locale).toLowerCase().replace(RX_STRIP_LOCALE_MODS, '').split('-'); var locale1 = parts.slice(0, 2).join('-'); var locale2 = parts[0]; return arrayIncludes(RTL_LANGS, locale1) || arrayIncludes(RTL_LANGS, locale2); }; // SSR safe client-side ID attribute generation // ID's can only be generated client-side, after mount // `this._uid` is not synched between server and client // @vue/component var idMixin = { props: { id: { type: String // default: null } }, data: function data() { return { localId_: null }; }, computed: { safeId: function safeId() { // Computed property that returns a dynamic function for creating the ID // Reacts to changes in both `.id` and `.localId_` and regenerates a new function var id = this.id || this.localId_; // We return a function that accepts an optional suffix string // So this computed prop looks and works like a method // but benefits from Vue's computed prop caching var fn = function fn(suffix) { if (!id) { return null; } suffix = String(suffix || '').replace(/\s+/g, '_'); return suffix ? id + '_' + suffix : id; }; return fn; } }, mounted: function mounted() { var _this = this; // `mounted()` only occurs client-side this.$nextTick(function () { // Update DOM with auto-generated ID after mount // to prevent SSR hydration errors _this.localId_ = "__BVID__".concat(_this._uid); }); } }; var props$7 = makePropsConfigurable({ value: { type: [String, Date] // default: null }, valueAsDate: { // Always return the `v-model` value as a date object type: Boolean, default: false }, initialDate: { // This specifies the calendar year/month/day that will be shown when // first opening the datepicker if no v-model value is provided // Default is the current date (or `min`/`max`) type: [String, Date] // default: null }, disabled: { type: Boolean, default: false }, readonly: { type: Boolean, default: false }, min: { type: [String, Date] // default: null }, max: { type: [String, Date] // default: null }, dateDisabledFn: { type: Function // default: null }, startWeekday: { // `0` (Sunday), `1` (Monday), ... `6` (Saturday) // Day of week to start calendar on type: [Number, String], default: 0 }, locale: { // Locale(s) to use // Default is to use page/browser default setting type: [String, Array] // default: null }, direction: { // 'ltr', 'rtl', or `null` (for auto detect) type: String // default: null }, selectedVariant: { // Variant color to use for the selected date type: String, default: 'primary' }, todayVariant: { // Variant color to use for today's date (defaults to `selectedVariant`) type: String // default: null }, navButtonVariant: { // Variant color to use for the navigation buttons type: String, default: 'secondary' }, noHighlightToday: { // Disable highlighting today's date type: Boolean, default: false }, dateInfoFn: { // Function to set a class of (classes) on the date cell // if passed a string or an array // TODO: // If the function returns an object, look for class prop for classes, // and other props for handling events/details/descriptions type: Function // default: null }, width: { // Has no effect if prop `block` is set type: String, default: '270px' }, block: { // Makes calendar the full width of its parent container type: Boolean, default: false }, hideHeader: { // When true makes the selected date header `sr-only` type: Boolean, default: false }, showDecadeNav: { // When `true` enables the decade navigation buttons type: Boolean, default: false }, hidden: { // When `true`, renders a comment node, but keeps the component instance active // Mainly for , so that we can get the component's value and locale // But we might just use separate date formatters, using the resolved locale // (adjusted for the gregorian calendar) type: Boolean, default: false }, ariaControls: { type: String // default: null }, noKeyNav: { type: Boolean, default: false }, roleDescription: { type: String // default: null }, // Labels for buttons and keyboard shortcuts labelPrevDecade: { type: String, default: 'Previous decade' }, labelPrevYear: { type: String, default: 'Previous year' }, labelPrevMonth: { type: String, default: 'Previous month' }, labelCurrentMonth: { type: String, default: 'Current month' }, labelNextMonth: { type: String, default: 'Next month' }, labelNextYear: { type: String, default: 'Next year' }, labelNextDecade: { type: String, default: 'Next decade' }, labelToday: { type: String, default: 'Today' }, labelSelected: { type: String, default: 'Selected date' }, labelNoDateSelected: { type: String, default: 'No date selected' }, labelCalendar: { type: String, default: 'Calendar' }, labelNav: { type: String, default: 'Calendar navigation' }, labelHelp: { type: String, default: 'Use cursor keys to navigate calendar dates' }, dateFormatOptions: { // `Intl.DateTimeFormat` object // Note: This value is *not* to be placed in the global config type: Object, default: function _default() { return { year: DATE_FORMAT_NUMERIC, month: CALENDAR_LONG, day: DATE_FORMAT_NUMERIC, weekday: CALENDAR_LONG }; } }, weekdayHeaderFormat: { // Format of the weekday names at the top of the calendar // Note: This value is *not* to be placed in the global config type: String, // `short` is typically a 3 letter abbreviation, // `narrow` is typically a single letter // `long` is the full week day name // Although some locales may override this (i.e `ar`, etc.) default: CALENDAR_SHORT, validator: function validator(value) { return arrayIncludes([CALENDAR_LONG, CALENDAR_SHORT, CALENDAR_NARROW], value); } } }, NAME_CALENDAR); // --- Main component --- // @vue/component var BCalendar = Vue__default['default'].extend({ name: NAME_CALENDAR, // Mixin order is important! mixins: [attrsMixin, idMixin, normalizeSlotMixin], model: { // Even though this is the default that Vue assumes, we need // to add it for the docs to reflect that this is the model // And also for some validation libraries to work prop: 'value', event: 'input' }, props: props$7, data: function data() { var selected = formatYMD(this.value) || ''; return { // Selected date selectedYMD: selected, // Date in calendar grid that has `tabindex` of `0` activeYMD: selected || formatYMD(constrainDate(this.initialDate || this.getToday()), this.min, this.max), // Will be true if the calendar grid has/contains focus gridHasFocus: false, // Flag to enable the `aria-live` region(s) after mount // to prevent screen reader "outbursts" when mounting isLive: false }; }, computed: { valueId: function valueId() { return this.safeId(); }, widgetId: function widgetId() { return this.safeId('_calendar-wrapper_'); }, navId: function navId() { return this.safeId('_calendar-nav_'); }, gridId: function gridId() { return this.safeId('_calendar-grid_'); }, gridCaptionId: function gridCaptionId() { return this.safeId('_calendar-grid-caption_'); }, gridHelpId: function gridHelpId() { return this.safeId('_calendar-grid-help_'); }, activeId: function activeId() { return this.activeYMD ? this.safeId("_cell-".concat(this.activeYMD, "_")) : null; }, // TODO: Use computed props to convert `YYYY-MM-DD` to `Date` object selectedDate: function selectedDate() { // Selected as a `Date` object return parseYMD(this.selectedYMD); }, activeDate: function activeDate() { // Active as a `Date` object return parseYMD(this.activeYMD); }, computedMin: function computedMin() { return parseYMD(this.min); }, computedMax: function computedMax() { return parseYMD(this.max); }, computedWeekStarts: function computedWeekStarts() { // `startWeekday` is a prop (constrained to `0` through `6`) return mathMax(toInteger(this.startWeekday, 0), 0) % 7; }, computedLocale: function computedLocale() { // Returns the resolved locale used by the calendar return resolveLocale(concat(this.locale).filter(identity), CALENDAR_GREGORY); }, computedDateDisabledFn: function computedDateDisabledFn() { var dateDisabledFn = this.dateDisabledFn; var result = null; try { result = dateDisabledFn(); } catch (_unused) {} return isUndefined(result) ? function () { return false; } : dateDisabledFn; }, // TODO: Change `dateInfoFn` to handle events and notes as well as classes computedDateInfoFn: function computedDateInfoFn() { var dateInfoFn = this.dateInfoFn; var result = null; try { result = dateInfoFn(); } catch (_unused2) {} return isUndefined(result) ? function () { return {}; } : dateInfoFn; }, calendarLocale: function calendarLocale() { // This locale enforces the gregorian calendar (for use in formatter functions) // Needed because IE 11 resolves `ar-IR` as islamic-civil calendar // and IE 11 (and some other browsers) do not support the `calendar` option // And we currently only support the gregorian calendar var fmt = new Intl.DateTimeFormat(this.computedLocale, { calendar: CALENDAR_GREGORY }); var calendar = fmt.resolvedOptions().calendar; var locale = fmt.resolvedOptions().locale; /* istanbul ignore if: mainly for IE 11 and a few other browsers, hard to test in JSDOM */ if (calendar !== CALENDAR_GREGORY) { // Ensure the locale requests the gregorian calendar // Mainly for IE 11, and currently we can't handle non-gregorian calendars // TODO: Should we always return this value? locale = locale.replace(/-u-.+$/i, '').concat('-u-ca-gregory'); } return locale; }, calendarYear: function calendarYear() { return this.activeDate.getFullYear(); }, calendarMonth: function calendarMonth() { return this.activeDate.getMonth(); }, calendarFirstDay: function calendarFirstDay() { // We set the time for this date to 12pm to work around // date formatting issues in Firefox and Safari // See: https://github.com/bootstrap-vue/bootstrap-vue/issues/5818 return createDate(this.calendarYear, this.calendarMonth, 1, 12); }, calendarDaysInMonth: function calendarDaysInMonth() { // We create a new date as to not mutate the original var date = createDate(this.calendarFirstDay); date.setMonth(date.getMonth() + 1, 0); return date.getDate(); }, computedVariant: function computedVariant() { return "btn-".concat(this.selectedVariant || 'primary'); }, computedTodayVariant: function computedTodayVariant() { return "btn-outline-".concat(this.todayVariant || this.selectedVariant || 'primary'); }, computedNavButtonVariant: function computedNavButtonVariant() { return "btn-outline-".concat(this.navButtonVariant || 'primary'); }, isRTL: function isRTL() { // `true` if the language requested is RTL var dir = toString$1(this.direction).toLowerCase(); if (dir === 'rtl') { /* istanbul ignore next */ return true; } else if (dir === 'ltr') { /* istanbul ignore next */ return false; } return isLocaleRTL(this.computedLocale); }, context: function context() { var selectedYMD = this.selectedYMD, activeYMD = this.activeYMD; var selectedDate = parseYMD(selectedYMD); var activeDate = parseYMD(activeYMD); return { // The current value of the `v-model` selectedYMD: selectedYMD, selectedDate: selectedDate, selectedFormatted: selectedDate ? this.formatDateString(selectedDate) : this.labelNoDateSelected, // Which date cell is considered active due to navigation activeYMD: activeYMD, activeDate: activeDate, activeFormatted: activeDate ? this.formatDateString(activeDate) : '', // `true` if the date is disabled (when using keyboard navigation) disabled: this.dateDisabled(activeDate), // Locales used in formatting dates locale: this.computedLocale, calendarLocale: this.calendarLocale, rtl: this.isRTL }; }, // Computed props that return a function reference dateOutOfRange: function dateOutOfRange() { // Check whether a date is within the min/max range // Returns a new function ref if the pops change // We do this as we need to trigger the calendar computed prop // to update when these props update var min = this.computedMin, max = this.computedMax; return function (date) { // Handle both `YYYY-MM-DD` and `Date` objects date = parseYMD(date); return min && date < min || max && date > max; }; }, dateDisabled: function dateDisabled() { var _this = this; // Returns a function for validating if a date is within range // We grab this variables first to ensure a new function ref // is generated when the props value changes // We do this as we need to trigger the calendar computed prop // to update when these props update var rangeFn = this.dateOutOfRange; // Return the function ref return function (date) { // Handle both `YYYY-MM-DD` and `Date` objects date = parseYMD(date); var ymd = formatYMD(date); return !!(rangeFn(date) || _this.computedDateDisabledFn(ymd, date)); }; }, // Computed props that return date formatter functions formatDateString: function formatDateString() { // Returns a date formatter function return createDateFormatter(this.calendarLocale, _objectSpread2(_objectSpread2({ // Ensure we have year, month, day shown for screen readers/ARIA // If users really want to leave one of these out, they can // pass `undefined` for the property value year: DATE_FORMAT_NUMERIC, month: DATE_FORMAT_2_DIGIT, day: DATE_FORMAT_2_DIGIT }, this.dateFormatOptions), {}, { // Ensure hours/minutes/seconds are not shown // As we do not support the time portion (yet) hour: undefined, minute: undefined, second: undefined, // Ensure calendar is gregorian calendar: CALENDAR_GREGORY })); }, formatYearMonth: function formatYearMonth() { // Returns a date formatter function return createDateFormatter(this.calendarLocale, { year: DATE_FORMAT_NUMERIC, month: CALENDAR_LONG, calendar: CALENDAR_GREGORY }); }, formatWeekdayName: function formatWeekdayName() { // Long weekday name for weekday header aria-label return createDateFormatter(this.calendarLocale, { weekday: CALENDAR_LONG, calendar: CALENDAR_GREGORY }); }, formatWeekdayNameShort: function formatWeekdayNameShort() { // Weekday header cell format // defaults to 'short' 3 letter days, where possible return createDateFormatter(this.calendarLocale, { weekday: this.weekdayHeaderFormat || CALENDAR_SHORT, calendar: CALENDAR_GREGORY }); }, formatDay: function formatDay() { // Calendar grid day number formatter // We don't use DateTimeFormatter here as it can place extra // character(s) after the number (i.e the `zh` locale) var nf = new Intl.NumberFormat([this.computedLocale], { style: 'decimal', minimumIntegerDigits: 1, minimumFractionDigits: 0, maximumFractionDigits: 0, notation: 'standard' }); // Return a formatter function instance return function (date) { return nf.format(date.getDate()); }; }, // Disabled states for the nav buttons prevDecadeDisabled: function prevDecadeDisabled() { var min = this.computedMin; return this.disabled || min && lastDateOfMonth(oneDecadeAgo(this.activeDate)) < min; }, prevYearDisabled: function prevYearDisabled() { var min = this.computedMin; return this.disabled || min && lastDateOfMonth(oneYearAgo(this.activeDate)) < min; }, prevMonthDisabled: function prevMonthDisabled() { var min = this.computedMin; return this.disabled || min && lastDateOfMonth(oneMonthAgo(this.activeDate)) < min; }, thisMonthDisabled: function thisMonthDisabled() { // TODO: We could/should check if today is out of range return this.disabled; }, nextMonthDisabled: function nextMonthDisabled() { var max = this.computedMax; return this.disabled || max && firstDateOfMonth(oneMonthAhead(this.activeDate)) > max; }, nextYearDisabled: function nextYearDisabled() { var max = this.computedMax; return this.disabled || max && firstDateOfMonth(oneYearAhead(this.activeDate)) > max; }, nextDecadeDisabled: function nextDecadeDisabled() { var max = this.computedMax; return this.disabled || max && firstDateOfMonth(oneDecadeAhead(this.activeDate)) > max; }, // Calendar dates generation calendar: function calendar() { var matrix = []; var firstDay = this.calendarFirstDay; var calendarYear = firstDay.getFullYear(); var calendarMonth = firstDay.getMonth(); var daysInMonth = this.calendarDaysInMonth; var startIndex = firstDay.getDay(); // `0`..`6` var weekOffset = (this.computedWeekStarts > startIndex ? 7 : 0) - this.computedWeekStarts; // Build the calendar matrix var currentDay = 0 - weekOffset - startIndex; for (var week = 0; week < 6 && currentDay < daysInMonth; week++) { // For each week matrix[week] = []; // The following could be a map function for (var j = 0; j < 7; j++) { // For each day in week currentDay++; var date = createDate(calendarYear, calendarMonth, currentDay); var month = date.getMonth(); var dayYMD = formatYMD(date); var dayDisabled = this.dateDisabled(date); // TODO: This could be a normalizer method var dateInfo = this.computedDateInfoFn(dayYMD, parseYMD(dayYMD)); dateInfo = isString(dateInfo) || isArray(dateInfo) ? /* istanbul ignore next */ { class: dateInfo } : isPlainObject(dateInfo) ? _objectSpread2({ class: '' }, dateInfo) : /* istanbul ignore next */ { class: '' }; matrix[week].push({ ymd: dayYMD, // Cell content day: this.formatDay(date), label: this.formatDateString(date), // Flags for styling isThisMonth: month === calendarMonth, isDisabled: dayDisabled, // TODO: Handle other dateInfo properties such as notes/events info: dateInfo }); } } return matrix; }, calendarHeadings: function calendarHeadings() { var _this2 = this; return this.calendar[0].map(function (d) { return { text: _this2.formatWeekdayNameShort(parseYMD(d.ymd)), label: _this2.formatWeekdayName(parseYMD(d.ymd)) }; }); } }, watch: { value: function value(newVal, oldVal) { var selected = formatYMD(newVal) || ''; var old = formatYMD(oldVal) || ''; if (!datesEqual(selected, old)) { this.activeYMD = selected || this.activeYMD; this.selectedYMD = selected; } }, selectedYMD: function selectedYMD(newYMD, oldYMD) { // TODO: // Should we compare to `formatYMD(this.value)` and emit // only if they are different? if (newYMD !== oldYMD) { this.$emit('input', this.valueAsDate ? parseYMD(newYMD) || null : newYMD || ''); } }, context: function context(newVal, oldVal) { if (!looseEqual(newVal, oldVal)) { this.$emit('context', newVal); } }, hidden: function hidden(newVal) { // Reset the active focused day when hidden this.activeYMD = this.selectedYMD || formatYMD(this.value || this.constrainDate(this.initialDate || this.getToday())); // Enable/disable the live regions this.setLive(!newVal); } }, created: function created() { var _this3 = this; this.$nextTick(function () { _this3.$emit('context', _this3.context); }); }, mounted: function mounted() { this.setLive(true); }, /* istanbul ignore next */ activated: function activated() { this.setLive(true); }, /* istanbul ignore next */ deactivated: function deactivated() { this.setLive(false); }, beforeDestroy: function beforeDestroy() { this.setLive(false); }, methods: { // Public method(s) focus: function focus() { if (!this.disabled) { attemptFocus(this.$refs.grid); } }, blur: function blur() { if (!this.disabled) { attemptBlur(this.$refs.grid); } }, // Private methods setLive: function setLive(on) { var _this4 = this; if (on) { this.$nextTick(function () { requestAF(function () { _this4.isLive = true; }); }); } else { this.isLive = false; } }, getToday: function getToday() { return parseYMD(createDate()); }, constrainDate: function constrainDate$1(date) { // Constrains a date between min and max // returns a new `Date` object instance return constrainDate(date, this.computedMin, this.computedMax); }, emitSelected: function emitSelected(date) { var _this5 = this; // Performed in a `$nextTick()` to (probably) ensure // the input event has emitted first this.$nextTick(function () { _this5.$emit('selected', formatYMD(date) || '', parseYMD(date) || null); }); }, // Event handlers setGridFocusFlag: function setGridFocusFlag(evt) { // Sets the gridHasFocus flag to make date "button" look focused this.gridHasFocus = !this.disabled && evt.type === 'focus'; }, onKeydownWrapper: function onKeydownWrapper(evt) { // Calendar keyboard navigation // Handles PAGEUP/PAGEDOWN/END/HOME/LEFT/UP/RIGHT/DOWN // Focuses grid after updating if (this.noKeyNav) { /* istanbul ignore next */ return; } var altKey = evt.altKey, ctrlKey = evt.ctrlKey, keyCode = evt.keyCode; if (!arrayIncludes([CODE_PAGEUP, CODE_PAGEDOWN, CODE_END, CODE_HOME, CODE_LEFT, CODE_UP, CODE_RIGHT, CODE_DOWN], keyCode)) { /* istanbul ignore next */ return; } stopEvent(evt); var activeDate = createDate(this.activeDate); var checkDate = createDate(this.activeDate); var day = activeDate.getDate(); var constrainedToday = this.constrainDate(this.getToday()); var isRTL = this.isRTL; if (keyCode === CODE_PAGEUP) { // PAGEUP - Previous month/year activeDate = (altKey ? ctrlKey ? oneDecadeAgo : oneYearAgo : oneMonthAgo)(activeDate); // We check the first day of month to be in rage checkDate = createDate(activeDate); checkDate.setDate(1); } else if (keyCode === CODE_PAGEDOWN) { // PAGEDOWN - Next month/year activeDate = (altKey ? ctrlKey ? oneDecadeAhead : oneYearAhead : oneMonthAhead)(activeDate); // We check the last day of month to be in rage checkDate = createDate(activeDate); checkDate.setMonth(checkDate.getMonth() + 1); checkDate.setDate(0); } else if (keyCode === CODE_LEFT) { // LEFT - Previous day (or next day for RTL) activeDate.setDate(day + (isRTL ? 1 : -1)); activeDate = this.constrainDate(activeDate); checkDate = activeDate; } else if (keyCode === CODE_RIGHT) { // RIGHT - Next day (or previous day for RTL) activeDate.setDate(day + (isRTL ? -1 : 1)); activeDate = this.constrainDate(activeDate); checkDate = activeDate; } else if (keyCode === CODE_UP) { // UP - Previous week activeDate.setDate(day - 7); activeDate = this.constrainDate(activeDate); checkDate = activeDate; } else if (keyCode === CODE_DOWN) { // DOWN - Next week activeDate.setDate(day + 7); activeDate = this.constrainDate(activeDate); checkDate = activeDate; } else if (keyCode === CODE_HOME) { // HOME - Today activeDate = constrainedToday; checkDate = activeDate; } else if (keyCode === CODE_END) { // END - Selected date, or today if no selected date activeDate = parseYMD(this.selectedDate) || constrainedToday; checkDate = activeDate; } if (!this.dateOutOfRange(checkDate) && !datesEqual(activeDate, this.activeDate)) { // We only jump to date if within min/max // We don't check for individual disabled dates though (via user function) this.activeYMD = formatYMD(activeDate); } // Ensure grid is focused this.focus(); }, onKeydownGrid: function onKeydownGrid(evt) { // Pressing enter/space on grid to select active date var keyCode = evt.keyCode; var activeDate = this.activeDate; if (keyCode === CODE_ENTER || keyCode === CODE_SPACE) { stopEvent(evt); if (!this.disabled && !this.readonly && !this.dateDisabled(activeDate)) { this.selectedYMD = formatYMD(activeDate); this.emitSelected(activeDate); } // Ensure grid is focused this.focus(); } }, onClickDay: function onClickDay(day) { // Clicking on a date "button" to select it var selectedDate = this.selectedDate, activeDate = this.activeDate; var clickedDate = parseYMD(day.ymd); if (!this.disabled && !day.isDisabled && !this.dateDisabled(clickedDate)) { if (!this.readonly) { // If readonly mode, we don't set the selected date, just the active date // If the clicked date is equal to the already selected date, we don't update the model this.selectedYMD = formatYMD(datesEqual(clickedDate, selectedDate) ? selectedDate : clickedDate); this.emitSelected(clickedDate); } this.activeYMD = formatYMD(datesEqual(clickedDate, activeDate) ? activeDate : createDate(clickedDate)); // Ensure grid is focused this.focus(); } }, gotoPrevDecade: function gotoPrevDecade() { this.activeYMD = formatYMD(this.constrainDate(oneDecadeAgo(this.activeDate))); }, gotoPrevYear: function gotoPrevYear() { this.activeYMD = formatYMD(this.constrainDate(oneYearAgo(this.activeDate))); }, gotoPrevMonth: function gotoPrevMonth() { this.activeYMD = formatYMD(this.constrainDate(oneMonthAgo(this.activeDate))); }, gotoCurrentMonth: function gotoCurrentMonth() { // TODO: Maybe this goto date should be configurable? this.activeYMD = formatYMD(this.constrainDate(this.getToday())); }, gotoNextMonth: function gotoNextMonth() { this.activeYMD = formatYMD(this.constrainDate(oneMonthAhead(this.activeDate))); }, gotoNextYear: function gotoNextYear() { this.activeYMD = formatYMD(this.constrainDate(oneYearAhead(this.activeDate))); }, gotoNextDecade: function gotoNextDecade() { this.activeYMD = formatYMD(this.constrainDate(oneDecadeAhead(this.activeDate))); }, onHeaderClick: function onHeaderClick() { if (!this.disabled) { this.activeYMD = this.selectedYMD || formatYMD(this.getToday()); this.focus(); } } }, render: function render(h) { var _this6 = this; // If `hidden` prop is set, render just a placeholder node if (this.hidden) { return h(); } var valueId = this.valueId, widgetId = this.widgetId, navId = this.navId, gridId = this.gridId, gridCaptionId = this.gridCaptionId, gridHelpId = this.gridHelpId, activeId = this.activeId, disabled = this.disabled, noKeyNav = this.noKeyNav, isLive = this.isLive, isRTL = this.isRTL, activeYMD = this.activeYMD, selectedYMD = this.selectedYMD, safeId = this.safeId; var hideDecadeNav = !this.showDecadeNav; var todayYMD = formatYMD(this.getToday()); var highlightToday = !this.noHighlightToday; // Header showing current selected date var $header = h('output', { staticClass: 'form-control form-control-sm text-center', class: { 'text-muted': disabled, readonly: this.readonly || disabled }, attrs: { id: valueId, for: gridId, role: 'status', tabindex: disabled ? null : '-1', // Mainly for testing purposes, as we do not know // the exact format `Intl` will format the date string 'data-selected': toString$1(selectedYMD), // We wait until after mount to enable `aria-live` // to prevent initial announcement on page render 'aria-live': isLive ? 'polite' : 'off', 'aria-atomic': isLive ? 'true' : null }, on: { // Transfer focus/click to focus grid // and focus active date (or today if no selection) click: this.onHeaderClick, focus: this.onHeaderClick } }, this.selectedDate ? [// We use `bdi` elements here in case the label doesn't match the locale // Although IE 11 does not deal with at all (equivalent to a span) h('bdi', { staticClass: 'sr-only' }, " (".concat(toString$1(this.labelSelected), ") ")), h('bdi', this.formatDateString(this.selectedDate))] : this.labelNoDateSelected || "\xA0" // ' ' ); $header = h('header', { staticClass: 'b-calendar-header', class: { 'sr-only': this.hideHeader }, attrs: { title: this.selectedDate ? this.labelSelectedDate || null : null } }, [$header]); // Content for the date navigation buttons var navScope = { isRTL: isRTL }; var navProps = { shiftV: 0.5 }; var navPrevProps = _objectSpread2(_objectSpread2({}, navProps), {}, { flipH: isRTL }); var navNextProps = _objectSpread2(_objectSpread2({}, navProps), {}, { flipH: !isRTL }); var $prevDecadeIcon = this.normalizeSlot('nav-prev-decade', navScope) || h(BIconChevronBarLeft, { props: navPrevProps }); var $prevYearIcon = this.normalizeSlot('nav-prev-year', navScope) || h(BIconChevronDoubleLeft, { props: navPrevProps }); var $prevMonthIcon = this.normalizeSlot('nav-prev-month', navScope) || h(BIconChevronLeft, { props: navPrevProps }); var $thisMonthIcon = this.normalizeSlot('nav-this-month', navScope) || h(BIconCircleFill, { props: navProps }); var $nextMonthIcon = this.normalizeSlot('nav-next-month', navScope) || h(BIconChevronLeft, { props: navNextProps }); var $nextYearIcon = this.normalizeSlot('nav-next-year', navScope) || h(BIconChevronDoubleLeft, { props: navNextProps }); var $nextDecadeIcon = this.normalizeSlot('nav-next-decade', navScope) || h(BIconChevronBarLeft, { props: navNextProps }); // Utility to create the date navigation buttons var makeNavBtn = function makeNavBtn(content, label, handler, btnDisabled, shortcut) { return h('button', { staticClass: 'btn btn-sm border-0 flex-fill', class: [_this6.computedNavButtonVariant, { disabled: btnDisabled }], attrs: { title: label || null, type: 'button', tabindex: noKeyNav ? '-1' : null, 'aria-label': label || null, 'aria-disabled': btnDisabled ? 'true' : null, 'aria-keyshortcuts': shortcut || null }, on: btnDisabled ? {} : { click: handler } }, [h('div', { attrs: { 'aria-hidden': 'true' } }, [content])]); }; // Generate the date navigation buttons var $nav = h('div', { staticClass: 'b-calendar-nav d-flex', attrs: { id: navId, role: 'group', tabindex: noKeyNav ? '-1' : null, 'aria-hidden': disabled ? 'true' : null, 'aria-label': this.labelNav || null, 'aria-controls': gridId } }, [hideDecadeNav ? h() : makeNavBtn($prevDecadeIcon, this.labelPrevDecade, this.gotoPrevDecade, this.prevDecadeDisabled, 'Ctrl+Alt+PageDown'), makeNavBtn($prevYearIcon, this.labelPrevYear, this.gotoPrevYear, this.prevYearDisabled, 'Alt+PageDown'), makeNavBtn($prevMonthIcon, this.labelPrevMonth, this.gotoPrevMonth, this.prevMonthDisabled, 'PageDown'), makeNavBtn($thisMonthIcon, this.labelCurrentMonth, this.gotoCurrentMonth, this.thisMonthDisabled, 'Home'), makeNavBtn($nextMonthIcon, this.labelNextMonth, this.gotoNextMonth, this.nextMonthDisabled, 'PageUp'), makeNavBtn($nextYearIcon, this.labelNextYear, this.gotoNextYear, this.nextYearDisabled, 'Alt+PageUp'), hideDecadeNav ? h() : makeNavBtn($nextDecadeIcon, this.labelNextDecade, this.gotoNextDecade, this.nextDecadeDisabled, 'Ctrl+Alt+PageUp')]); // Caption for calendar grid var $gridCaption = h('header', { key: 'grid-caption', staticClass: 'b-calendar-grid-caption text-center font-weight-bold', class: { 'text-muted': disabled }, attrs: { id: gridCaptionId, 'aria-live': isLive ? 'polite' : null, 'aria-atomic': isLive ? 'true' : null } }, this.formatYearMonth(this.calendarFirstDay)); // Calendar weekday headings var $gridWeekDays = h('div', { staticClass: 'b-calendar-grid-weekdays row no-gutters border-bottom', attrs: { 'aria-hidden': 'true' } }, this.calendarHeadings.map(function (d, idx) { return h('small', { key: idx, staticClass: 'col text-truncate', class: { 'text-muted': disabled }, attrs: { title: d.label === d.text ? null : d.label, 'aria-label': d.label } }, d.text); })); // Calendar day grid var $gridBody = this.calendar.map(function (week) { var $cells = week.map(function (day, dIndex) { var _class; var isSelected = day.ymd === selectedYMD; var isActive = day.ymd === activeYMD; var isToday = day.ymd === todayYMD; var idCell = safeId("_cell-".concat(day.ymd, "_")); // "fake" button var $btn = h('span', { staticClass: 'btn border-0 rounded-circle text-nowrap', // Should we add some classes to signify if today/selected/etc? class: (_class = { // Give the fake button a focus ring focus: isActive && _this6.gridHasFocus, // Styling disabled: day.isDisabled || disabled, active: isSelected }, _defineProperty(_class, _this6.computedVariant, isSelected), _defineProperty(_class, _this6.computedTodayVariant, isToday && highlightToday && !isSelected && day.isThisMonth), _defineProperty(_class, 'btn-outline-light', !(isToday && highlightToday) && !isSelected && !isActive), _defineProperty(_class, 'btn-light', !(isToday && highlightToday) && !isSelected && isActive), _defineProperty(_class, 'text-muted', !day.isThisMonth && !isSelected), _defineProperty(_class, 'text-dark', !(isToday && highlightToday) && !isSelected && !isActive && day.isThisMonth), _defineProperty(_class, 'font-weight-bold', (isSelected || day.isThisMonth) && !day.isDisabled), _class), on: { click: function click() { return _this6.onClickDay(day); } } }, day.day); return h('div', // Cell with button { key: dIndex, staticClass: 'col p-0', class: day.isDisabled ? 'bg-light' : day.info.class || '', attrs: { id: idCell, role: 'button', 'data-date': day.ymd, // Primarily for testing purposes // Only days in the month are presented as buttons to screen readers 'aria-hidden': day.isThisMonth ? null : 'true', 'aria-disabled': day.isDisabled || disabled ? 'true' : null, 'aria-label': [day.label, isSelected ? "(".concat(_this6.labelSelected, ")") : null, isToday ? "(".concat(_this6.labelToday, ")") : null].filter(identity).join(' '), // NVDA doesn't convey `aria-selected`, but does `aria-current`, // ChromeVox doesn't convey `aria-current`, but does `aria-selected`, // so we set both attributes for robustness 'aria-selected': isSelected ? 'true' : null, 'aria-current': isSelected ? 'date' : null } }, [$btn]); }); // Return the week "row" // We use the first day of the weeks YMD value as a // key for efficient DOM patching / element re-use return h('div', { key: week[0].ymd, staticClass: 'row no-gutters' }, $cells); }); $gridBody = h('div', { // A key is only required on the body if we add in transition support // key: this.activeYMD.slice(0, -3), staticClass: 'b-calendar-grid-body', style: disabled ? { pointerEvents: 'none' } : {} }, $gridBody); var $gridHelp = h('footer', { staticClass: 'b-calendar-grid-help border-top small text-muted text-center bg-light', attrs: { id: gridHelpId } }, [h('div', { staticClass: 'small' }, this.labelHelp)]); var $grid = h('div', { ref: 'grid', staticClass: 'b-calendar-grid form-control h-auto text-center', attrs: { id: gridId, role: 'application', tabindex: noKeyNav ? '-1' : disabled ? null : '0', 'data-month': activeYMD.slice(0, -3), // `YYYY-MM`, mainly for testing 'aria-roledescription': this.labelCalendar || null, 'aria-labelledby': gridCaptionId, 'aria-describedby': gridHelpId, // `aria-readonly` is not considered valid on `role="application"` // https://www.w3.org/TR/wai-aria-1.1/#aria-readonly // 'aria-readonly': this.readonly && !disabled ? 'true' : null, 'aria-disabled': disabled ? 'true' : null, 'aria-activedescendant': activeId }, on: { keydown: this.onKeydownGrid, focus: this.setGridFocusFlag, blur: this.setGridFocusFlag } }, [$gridCaption, $gridWeekDays, $gridBody, $gridHelp]); // Optional bottom slot var $slot = this.normalizeSlot(); $slot = $slot ? h('footer', { staticClass: 'b-calendar-footer' }, $slot) : h(); var $widget = h('div', { staticClass: 'b-calendar-inner', style: this.block ? {} : { width: this.width }, attrs: { id: widgetId, dir: isRTL ? 'rtl' : 'ltr', lang: this.computedLocale || null, role: 'group', 'aria-disabled': disabled ? 'true' : null, // If datepicker controls an input, this will specify the ID of the input 'aria-controls': this.ariaControls || null, // This should be a prop (so it can be changed to Date picker, etc, localized 'aria-roledescription': this.roleDescription || null, 'aria-describedby': [// Should the attr (if present) go last? // Or should this attr be a prop? this.bvAttrs['aria-describedby'], valueId, gridHelpId].filter(identity).join(' ') }, on: { keydown: this.onKeydownWrapper } }, [$header, $nav, $grid, $slot]); // Wrap in an outer div that can be styled return h('div', { staticClass: 'b-calendar', class: { 'd-block': this.block } }, [$widget]); } }); var CalendarPlugin = /*#__PURE__*/pluginFactory({ components: { BCalendar: BCalendar } }); var props$8 = makePropsConfigurable({ tag: { type: String, default: 'div' }, bgVariant: { type: String // default: null }, borderVariant: { type: String // default: null }, textVariant: { type: String // default: null } }, NAME_CARD); // --- Mixin --- var props$9 = makePropsConfigurable({ title: { type: String // default: null }, titleTag: { type: String, default: 'h4' } }, NAME_CARD_TITLE); // @vue/component var BCardTitle = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_TITLE, functional: true, props: props$9, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.titleTag, a(data, { staticClass: 'card-title' }), children || toString$1(props.title)); } }); var props$a = makePropsConfigurable({ subTitle: { type: String // default: null }, subTitleTag: { type: String, default: 'h6' }, subTitleTextVariant: { type: String, default: 'muted' } }, NAME_CARD_SUB_TITLE); // @vue/component var BCardSubTitle = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_SUB_TITLE, functional: true, props: props$a, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.subTitleTag, a(data, { staticClass: 'card-subtitle', class: [props.subTitleTextVariant ? "text-".concat(props.subTitleTextVariant) : null] }), children || toString$1(props.subTitle)); } }); var props$b = makePropsConfigurable(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, copyProps(props$8, prefixPropName.bind(null, 'body'))), {}, { bodyClass: { type: [String, Object, Array] // default: null } }, props$9), props$a), {}, { overlay: { type: Boolean, default: false } }), NAME_CARD_BODY); // @vue/component var BCardBody = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_BODY, functional: true, props: props$b, render: function render(h, _ref) { var _ref2; var props = _ref.props, data = _ref.data, children = _ref.children; var cardTitle = h(); var cardSubTitle = h(); var cardContent = children || [h()]; if (props.title) { cardTitle = h(BCardTitle, { props: pluckProps(props$9, props) }); } if (props.subTitle) { cardSubTitle = h(BCardSubTitle, { props: pluckProps(props$a, props), class: ['mb-2'] }); } return h(props.bodyTag, a(data, { staticClass: 'card-body', class: [(_ref2 = { 'card-img-overlay': props.overlay }, _defineProperty(_ref2, "bg-".concat(props.bodyBgVariant), props.bodyBgVariant), _defineProperty(_ref2, "border-".concat(props.bodyBorderVariant), props.bodyBorderVariant), _defineProperty(_ref2, "text-".concat(props.bodyTextVariant), props.bodyTextVariant), _ref2), props.bodyClass || {}] }), [cardTitle, cardSubTitle].concat(_toConsumableArray(cardContent))); } }); var props$c = makePropsConfigurable(_objectSpread2(_objectSpread2({}, copyProps(props$8, prefixPropName.bind(null, 'header'))), {}, { header: { type: String // default: null }, headerHtml: { type: String // default: null }, headerClass: { type: [String, Object, Array] // default: null } }), NAME_CARD_HEADER); // --- Main component --- // @vue/component var BCardHeader = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_HEADER, functional: true, props: props$c, render: function render(h, _ref) { var _ref2; var props = _ref.props, data = _ref.data, children = _ref.children; var headerBgVariant = props.headerBgVariant, headerBorderVariant = props.headerBorderVariant, headerTextVariant = props.headerTextVariant; return h(props.headerTag, a(data, { staticClass: 'card-header', class: [props.headerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(headerBgVariant), headerBgVariant), _defineProperty(_ref2, "border-".concat(headerBorderVariant), headerBorderVariant), _defineProperty(_ref2, "text-".concat(headerTextVariant), headerTextVariant), _ref2)], domProps: children ? {} : htmlOrText(props.headerHtml, props.header) }), children); } }); var props$d = makePropsConfigurable(_objectSpread2(_objectSpread2({}, copyProps(props$8, prefixPropName.bind(null, 'footer'))), {}, { footer: { type: String // default: null }, footerHtml: { type: String // default: null }, footerClass: { type: [String, Object, Array] // default: null } }), NAME_CARD_FOOTER); // --- Main component --- // @vue/component var BCardFooter = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_FOOTER, functional: true, props: props$d, render: function render(h, _ref) { var _ref2; var props = _ref.props, data = _ref.data, children = _ref.children; var footerBgVariant = props.footerBgVariant, footerBorderVariant = props.footerBorderVariant, footerTextVariant = props.footerTextVariant; return h(props.footerTag, a(data, { staticClass: 'card-footer', class: [props.footerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(footerBgVariant), footerBgVariant), _defineProperty(_ref2, "border-".concat(footerBorderVariant), footerBorderVariant), _defineProperty(_ref2, "text-".concat(footerTextVariant), footerTextVariant), _ref2)], domProps: children ? {} : htmlOrText(props.footerHtml, props.footer) }), children); } }); var props$e = makePropsConfigurable({ src: { type: String, required: true }, alt: { type: String, default: null }, top: { type: Boolean, default: false }, bottom: { type: Boolean, default: false }, start: { type: Boolean, default: false }, left: { // alias of 'start' type: Boolean, default: false }, end: { type: Boolean, default: false }, right: { // alias of 'end' type: Boolean, default: false }, height: { type: [Number, String] // default: null }, width: { type: [Number, String] // default: null } }, NAME_CARD_IMG); // @vue/component var BCardImg = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_IMG, functional: true, props: props$e, render: function render(h, _ref) { var props = _ref.props, data = _ref.data; var baseClass = 'card-img'; if (props.top) { baseClass += '-top'; } else if (props.right || props.end) { baseClass += '-right'; } else if (props.bottom) { baseClass += '-bottom'; } else if (props.left || props.start) { baseClass += '-left'; } return h('img', a(data, { class: [baseClass], attrs: { src: props.src || null, alt: props.alt, height: props.height || null, width: props.width || null } })); } }); var cardImgProps = copyProps(props$e, prefixPropName.bind(null, 'img')); cardImgProps.imgSrc.required = false; var props$f = makePropsConfigurable(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, props$b), props$c), props$d), cardImgProps), props$8), {}, { align: { type: String // default: null }, noBody: { type: Boolean, default: false } }), NAME_CARD); // --- Main component --- // @vue/component var BCard = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD, functional: true, props: props$f, render: function render(h, _ref) { var _class; var props = _ref.props, data = _ref.data, slots = _ref.slots, scopedSlots = _ref.scopedSlots; var imgSrc = props.imgSrc, imgLeft = props.imgLeft, imgRight = props.imgRight, imgStart = props.imgStart, imgEnd = props.imgEnd, imgBottom = props.imgBottom, header = props.header, headerHtml = props.headerHtml, footer = props.footer, footerHtml = props.footerHtml, align = props.align, textVariant = props.textVariant, bgVariant = props.bgVariant, borderVariant = props.borderVariant; var $scopedSlots = scopedSlots || {}; var $slots = slots(); var slotScope = {}; var $imgFirst = h(); var $imgLast = h(); if (imgSrc) { var $img = h(BCardImg, { props: pluckProps(cardImgProps, props, unprefixPropName.bind(null, 'img')) }); if (imgBottom) { $imgLast = $img; } else { $imgFirst = $img; } } var $header = h(); var hasHeaderSlot = hasNormalizedSlot(SLOT_NAME_HEADER, $scopedSlots, $slots); if (hasHeaderSlot || header || headerHtml) { $header = h(BCardHeader, { props: pluckProps(props$c, props), domProps: hasHeaderSlot ? {} : htmlOrText(headerHtml, header) }, normalizeSlot(SLOT_NAME_HEADER, slotScope, $scopedSlots, $slots)); } var $content = normalizeSlot(SLOT_NAME_DEFAULT, slotScope, $scopedSlots, $slots); // Wrap content in `` when `noBody` prop set if (!props.noBody) { $content = h(BCardBody, { props: pluckProps(props$b, props) }, $content); // When the `overlap` prop is set we need to wrap the `` and `` // into a relative positioned wrapper to don't distract a potential header or footer if (props.overlay && imgSrc) { $content = h('div', { staticClass: 'position-relative' }, [$imgFirst, $content, $imgLast]); // Reset image variables since they are already in the wrapper $imgFirst = h(); $imgLast = h(); } } var $footer = h(); var hasFooterSlot = hasNormalizedSlot(SLOT_NAME_FOOTER, $scopedSlots, $slots); if (hasFooterSlot || footer || footerHtml) { $footer = h(BCardFooter, { props: pluckProps(props$d, props), domProps: hasHeaderSlot ? {} : htmlOrText(footerHtml, footer) }, normalizeSlot(SLOT_NAME_FOOTER, slotScope, $scopedSlots, $slots)); } return h(props.tag, a(data, { staticClass: 'card', class: (_class = { 'flex-row': imgLeft || imgStart, 'flex-row-reverse': (imgRight || imgEnd) && !(imgLeft || imgStart) }, _defineProperty(_class, "text-".concat(align), align), _defineProperty(_class, "bg-".concat(bgVariant), bgVariant), _defineProperty(_class, "border-".concat(borderVariant), borderVariant), _defineProperty(_class, "text-".concat(textVariant), textVariant), _class) }), [$imgFirst, $header, $content, $footer, $imgLast]); } }); var OBSERVER_PROP_NAME = '__bv__visibility_observer'; var VisibilityObserver = /*#__PURE__*/function () { function VisibilityObserver(el, options, vnode) { _classCallCheck(this, VisibilityObserver); this.el = el; this.callback = options.callback; this.margin = options.margin || 0; this.once = options.once || false; this.observer = null; this.visible = undefined; this.doneOnce = false; // Create the observer instance (if possible) this.createObserver(vnode); } _createClass(VisibilityObserver, [{ key: "createObserver", value: function createObserver(vnode) { var _this = this; // Remove any previous observer if (this.observer) { /* istanbul ignore next */ this.stop(); } // Should only be called once and `callback` prop should be a function if (this.doneOnce || !isFunction(this.callback)) { /* istanbul ignore next */ return; } // Create the observer instance try { // Future: Possibly add in other modifiers for left/right/top/bottom // offsets, root element reference, and thresholds this.observer = new IntersectionObserver(this.handler.bind(this), { // `null` = 'viewport' root: null, // Pixels away from view port to consider "visible" rootMargin: this.margin, // Intersection ratio of el and root (as a value from 0 to 1) threshold: 0 }); } catch (_unused) { // No IntersectionObserver support, so just stop trying to observe this.doneOnce = true; this.observer = undefined; this.callback(null); return; } // Start observing in a `$nextTick()` (to allow DOM to complete rendering) /* istanbul ignore next: IntersectionObserver not supported in JSDOM */ vnode.context.$nextTick(function () { requestAF(function () { // Placed in an `if` just in case we were destroyed before // this `requestAnimationFrame` runs if (_this.observer) { _this.observer.observe(_this.el); } }); }); } /* istanbul ignore next */ }, { key: "handler", value: function handler(entries) { var entry = entries ? entries[0] : {}; var isIntersecting = Boolean(entry.isIntersecting || entry.intersectionRatio > 0.0); if (isIntersecting !== this.visible) { this.visible = isIntersecting; this.callback(isIntersecting); if (this.once && this.visible) { this.doneOnce = true; this.stop(); } } } }, { key: "stop", value: function stop() { /* istanbul ignore next */ this.observer && this.observer.disconnect(); this.observer = null; } }]); return VisibilityObserver; }(); var destroy = function destroy(el) { var observer = el[OBSERVER_PROP_NAME]; if (observer && observer.stop) { observer.stop(); } delete el[OBSERVER_PROP_NAME]; }; var bind = function bind(el, _ref, vnode) { var value = _ref.value, modifiers = _ref.modifiers; // `value` is the callback function var options = { margin: '0px', once: false, callback: value }; // Parse modifiers keys(modifiers).forEach(function (mod) { /* istanbul ignore else: Until is switched to use this directive */ if (RX_DIGITS.test(mod)) { options.margin = "".concat(mod, "px"); } else if (mod.toLowerCase() === 'once') { options.once = true; } }); // Destroy any previous observer destroy(el); // Create new observer el[OBSERVER_PROP_NAME] = new VisibilityObserver(el, options, vnode); // Store the current modifiers on the object (cloned) el[OBSERVER_PROP_NAME]._prevModifiers = clone(modifiers); }; // When the directive options may have been updated (or element) var componentUpdated = function componentUpdated(el, _ref2, vnode) { var value = _ref2.value, oldValue = _ref2.oldValue, modifiers = _ref2.modifiers; // Compare value/oldValue and modifiers to see if anything has changed // and if so, destroy old observer and create new observer /* istanbul ignore next */ modifiers = clone(modifiers); /* istanbul ignore next */ if (el && (value !== oldValue || !el[OBSERVER_PROP_NAME] || !looseEqual(modifiers, el[OBSERVER_PROP_NAME]._prevModifiers))) { // Re-bind on element bind(el, { value: value, modifiers: modifiers }, vnode); } }; // When directive un-binds from element var unbind = function unbind(el) { // Remove the observer destroy(el); }; // Export the directive var VBVisible = { bind: bind, componentUpdated: componentUpdated, unbind: unbind }; // Blank image with fill template var BLANK_TEMPLATE = '' + '' + ''; var props$g = makePropsConfigurable({ src: { type: String // default: null }, srcset: { type: [String, Array] // default: null }, sizes: { type: [String, Array] // default: null }, alt: { type: String, default: null }, width: { type: [Number, String] // default: null }, height: { type: [Number, String] // default: null }, block: { type: Boolean, default: false }, fluid: { type: Boolean, default: false }, fluidGrow: { // Gives fluid images class `w-100` to make them grow to fit container type: Boolean, default: false }, rounded: { // rounded can be: // false: no rounding of corners // true: slightly rounded corners // 'top': top corners rounded // 'right': right corners rounded // 'bottom': bottom corners rounded // 'left': left corners rounded // 'circle': circle/oval // '0': force rounding off type: [Boolean, String], default: false }, thumbnail: { type: Boolean, default: false }, left: { type: Boolean, default: false }, right: { type: Boolean, default: false }, center: { type: Boolean, default: false }, blank: { type: Boolean, default: false }, blankColor: { type: String, default: 'transparent' } }, NAME_IMG); // --- Helper methods --- var makeBlankImgSrc = function makeBlankImgSrc(width, height, color) { var src = encodeURIComponent(BLANK_TEMPLATE.replace('%{w}', toString$1(width)).replace('%{h}', toString$1(height)).replace('%{f}', color)); return "data:image/svg+xml;charset=UTF-8,".concat(src); }; // @vue/component var BImg = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_IMG, functional: true, props: props$g, render: function render(h, _ref) { var _class; var props = _ref.props, data = _ref.data; var src = props.src; var width = toInteger(props.width) || null; var height = toInteger(props.height) || null; var align = null; var block = props.block; var srcset = concat(props.srcset).filter(identity).join(','); var sizes = concat(props.sizes).filter(identity).join(','); if (props.blank) { if (!height && width) { height = width; } else if (!width && height) { width = height; } if (!width && !height) { width = 1; height = 1; } // Make a blank SVG image src = makeBlankImgSrc(width, height, props.blankColor || 'transparent'); // Disable srcset and sizes srcset = null; sizes = null; } if (props.left) { align = 'float-left'; } else if (props.right) { align = 'float-right'; } else if (props.center) { align = 'mx-auto'; block = true; } return h('img', a(data, { attrs: { src: src, alt: props.alt, width: width ? toString$1(width) : null, height: height ? toString$1(height) : null, srcset: srcset || null, sizes: sizes || null }, class: (_class = { 'img-thumbnail': props.thumbnail, 'img-fluid': props.fluid || props.fluidGrow, 'w-100': props.fluidGrow, rounded: props.rounded === '' || props.rounded === true }, _defineProperty(_class, "rounded-".concat(props.rounded), isString(props.rounded) && props.rounded !== ''), _defineProperty(_class, align, align), _defineProperty(_class, 'd-block', block), _class) })); } }); var props$h = makePropsConfigurable(_objectSpread2(_objectSpread2({}, omit(props$g, ['blank'])), {}, { blankSrc: { // If null, a blank image is generated type: String, default: null }, blankColor: { type: String, default: 'transparent' }, blankWidth: { type: [Number, String] // default: null }, blankHeight: { type: [Number, String] // default: null }, show: { type: Boolean, default: false }, offset: { // Distance away from viewport (in pixels) before being // considered "visible" type: [Number, String], default: 360 } }), NAME_IMG_LAZY); // @vue/component var BImgLazy = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_IMG_LAZY, directives: { bVisible: VBVisible }, props: props$h, data: function data() { return { isShown: this.show }; }, computed: { computedSrc: function computedSrc() { return !this.blankSrc || this.isShown ? this.src : this.blankSrc; }, computedBlank: function computedBlank() { return !(this.isShown || this.blankSrc); }, computedWidth: function computedWidth() { return this.isShown ? this.width : this.blankWidth || this.width; }, computedHeight: function computedHeight() { return this.isShown ? this.height : this.blankHeight || this.height; }, computedSrcset: function computedSrcset() { var srcset = concat(this.srcset).filter(identity).join(','); return !this.blankSrc || this.isShown ? srcset : null; }, computedSizes: function computedSizes() { var sizes = concat(this.sizes).filter(identity).join(','); return !this.blankSrc || this.isShown ? sizes : null; } }, watch: { show: function show(newVal, oldVal) { if (newVal !== oldVal) { // If IntersectionObserver support is not available, image is always shown var visible = hasIntersectionObserverSupport ? newVal : true; this.isShown = visible; if (visible !== newVal) { // Ensure the show prop is synced (when no IntersectionObserver) this.$nextTick(this.updateShowProp); } } }, isShown: function isShown(newVal, oldVal) { if (newVal !== oldVal) { // Update synched show prop this.updateShowProp(); } } }, mounted: function mounted() { // If IntersectionObserver is not available, image is always shown this.isShown = hasIntersectionObserverSupport ? this.show : true; }, methods: { updateShowProp: function updateShowProp() { this.$emit('update:show', this.isShown); }, doShow: function doShow(visible) { // If IntersectionObserver is not supported, the callback // will be called with `null` rather than `true` or `false` if ((visible || visible === null) && !this.isShown) { this.isShown = true; } } }, render: function render(h) { var directives = []; if (!this.isShown) { var _modifiers; // We only add the visible directive if we are not shown directives.push({ // Visible directive will silently do nothing if // IntersectionObserver is not supported name: 'b-visible', // Value expects a callback (passed one arg of `visible` = `true` or `false`) value: this.doShow, modifiers: (_modifiers = {}, _defineProperty(_modifiers, "".concat(toInteger(this.offset, 0)), true), _defineProperty(_modifiers, "once", true), _modifiers) }); } return h(BImg, { directives: directives, props: { // Computed value props src: this.computedSrc, blank: this.computedBlank, width: this.computedWidth, height: this.computedHeight, srcset: this.computedSrcset || null, sizes: this.computedSizes || null, // Passthrough props alt: this.alt, blankColor: this.blankColor, fluid: this.fluid, fluidGrow: this.fluidGrow, block: this.block, thumbnail: this.thumbnail, rounded: this.rounded, left: this.left, right: this.right, center: this.center } }); } }); // The `omit()` util creates a new object, so we can just pass the original props var lazyProps = omit(props$h, ['left', 'right', 'center', 'block', 'rounded', 'thumbnail', 'fluid', 'fluidGrow']); var props$i = makePropsConfigurable(_objectSpread2(_objectSpread2({}, lazyProps), {}, { top: { type: Boolean, default: false }, bottom: { type: Boolean, default: false }, start: { type: Boolean, default: false }, left: { // alias of 'start' type: Boolean, default: false }, end: { type: Boolean, default: false }, right: { // alias of 'end' type: Boolean, default: false } }), NAME_CARD_IMG_LAZY); // @vue/component var BCardImgLazy = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_IMG_LAZY, functional: true, props: props$i, render: function render(h, _ref) { var props = _ref.props, data = _ref.data; var baseClass = 'card-img'; if (props.top) { baseClass += '-top'; } else if (props.right || props.end) { baseClass += '-right'; } else if (props.bottom) { baseClass += '-bottom'; } else if (props.left || props.start) { baseClass += '-left'; } // False out the left/center/right props before passing to b-img-lazy var lazyProps = _objectSpread2(_objectSpread2({}, props), {}, { left: false, right: false, center: false }); return h(BImgLazy, a(data, { class: [baseClass], props: lazyProps })); } }); var props$j = makePropsConfigurable({ textTag: { type: String, default: 'p' } }, NAME_CARD_TEXT); // @vue/component var BCardText = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_TEXT, functional: true, props: props$j, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.textTag, a(data, { staticClass: 'card-text' }), children); } }); var props$k = makePropsConfigurable({ tag: { type: String, default: 'div' }, deck: { type: Boolean, default: false }, columns: { type: Boolean, default: false } }, NAME_CARD_GROUP); // @vue/component var BCardGroup = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CARD_GROUP, functional: true, props: props$k, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.tag, a(data, { class: props.deck ? 'card-deck' : props.columns ? 'card-columns' : 'card-group' }), children); } }); var CardPlugin = /*#__PURE__*/pluginFactory({ components: { BCard: BCard, BCardHeader: BCardHeader, BCardBody: BCardBody, BCardTitle: BCardTitle, BCardSubTitle: BCardSubTitle, BCardFooter: BCardFooter, BCardImg: BCardImg, BCardImgLazy: BCardImgLazy, BCardText: BCardText, BCardGroup: BCardGroup } }); var EVENT_OPTIONS_PASSIVE = { passive: true }; var EVENT_OPTIONS_NO_CAPTURE = { passive: true, capture: false }; var noop = function noop() {}; /** * Observe a DOM element changes, falls back to eventListener mode * @param {Element} el The DOM element to observe * @param {Function} callback callback to be called on change * @param {object} [options={childList: true, subtree: true}] observe options * @see https://stackoverflow.com/questions/3219758 */ var observeDom = function observeDom(el, callback, options) /* istanbul ignore next: difficult to test in JSDOM */ { // Handle cases where we might be passed a Vue instance el = el ? el.$el || el : null; // Early exit when we have no element /* istanbul ignore next: difficult to test in JSDOM */ if (!isElement(el)) { return null; } // Exit and throw a warning when `MutationObserver` isn't available if (warnNoMutationObserverSupport('observeDom')) { return null; } // Define a new observer var obs = new MutationObs(function (mutations) { var changed = false; // A mutation can contain several change records, so we loop // through them to see what has changed // We break out of the loop early if any "significant" change // has been detected for (var i = 0; i < mutations.length && !changed; i++) { // The mutation record var mutation = mutations[i]; // Mutation type var type = mutation.type; // DOM node (could be any DOM node type - HTMLElement, Text, comment, etc.) var target = mutation.target; // Detect whether a change happened based on type and target if (type === 'characterData' && target.nodeType === Node.TEXT_NODE) { // We ignore nodes that are not TEXT (i.e. comments, etc.) // as they don't change layout changed = true; } else if (type === 'attributes') { changed = true; } else if (type === 'childList' && (mutation.addedNodes.length > 0 || mutation.removedNodes.length > 0)) { // This includes HTMLElement and text nodes being // added/removed/re-arranged changed = true; } } // We only call the callback if a change that could affect // layout/size truly happened if (changed) { callback(); } }); // Have the observer observe foo for changes in children, etc obs.observe(el, _objectSpread2({ childList: true, subtree: true }, options)); // We return a reference to the observer so that `obs.disconnect()` // can be called if necessary // To reduce overhead when the root element is hidden return obs; }; var DIRECTION = { next: { dirClass: 'carousel-item-left', overlayClass: 'carousel-item-next' }, prev: { dirClass: 'carousel-item-right', overlayClass: 'carousel-item-prev' } }; // Fallback Transition duration (with a little buffer) in ms var TRANS_DURATION = 600 + 50; // Time for mouse compat events to fire after touch var TOUCH_EVENT_COMPAT_WAIT = 500; // Number of pixels to consider touch move a swipe var SWIPE_THRESHOLD = 40; // PointerEvent pointer types var PointerType = { TOUCH: 'touch', PEN: 'pen' }; // Transition Event names var TransitionEndEvents = { WebkitTransition: 'webkitTransitionEnd', MozTransition: 'transitionend', OTransition: 'otransitionend oTransitionEnd', transition: 'transitionend' }; // Return the browser specific transitionEnd event name var getTransitionEndEvent = function getTransitionEndEvent(el) { for (var name in TransitionEndEvents) { if (!isUndefined(el.style[name])) { return TransitionEndEvents[name]; } } // Fallback /* istanbul ignore next */ return null; }; // @vue/component var BCarousel = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CAROUSEL, mixins: [idMixin, normalizeSlotMixin], provide: function provide() { return { bvCarousel: this }; }, model: { prop: 'value', event: 'input' }, props: makePropsConfigurable({ labelPrev: { type: String, default: 'Previous slide' }, labelNext: { type: String, default: 'Next slide' }, labelGotoSlide: { type: String, default: 'Goto slide' }, labelIndicators: { type: String, default: 'Select a slide to display' }, interval: { type: Number, default: 5000 }, indicators: { type: Boolean, default: false }, controls: { type: Boolean, default: false }, noAnimation: { // Disable slide/fade animation type: Boolean, default: false }, fade: { // Enable cross-fade animation instead of slide animation type: Boolean, default: false }, noWrap: { // Disable wrapping/looping when start/end is reached type: Boolean, default: false }, noTouch: { // Sniffed by carousel-slide type: Boolean, default: false }, noHoverPause: { // Disable pause on hover type: Boolean, default: false }, imgWidth: { // Sniffed by carousel-slide type: [Number, String] // default: undefined }, imgHeight: { // Sniffed by carousel-slide type: [Number, String] // default: undefined }, background: { type: String // default: undefined }, value: { type: Number, default: 0 } }, NAME_CAROUSEL), data: function data() { return { index: this.value || 0, isSliding: false, transitionEndEvent: null, slides: [], direction: null, isPaused: !(toInteger(this.interval, 0) > 0), // Touch event handling values touchStartX: 0, touchDeltaX: 0 }; }, computed: { numSlides: function numSlides() { return this.slides.length; } }, watch: { value: function value(newVal, oldVal) { if (newVal !== oldVal) { this.setSlide(toInteger(newVal, 0)); } }, interval: function interval(newVal, oldVal) { if (newVal === oldVal) { /* istanbul ignore next */ return; } if (!newVal) { // Pausing slide show this.pause(false); } else { // Restarting or Changing interval this.pause(true); this.start(false); } }, isPaused: function isPaused(newVal, oldVal) { if (newVal !== oldVal) { this.$emit(newVal ? 'paused' : 'unpaused'); } }, index: function index(to, from) { if (to === from || this.isSliding) { /* istanbul ignore next */ return; } this.doSlide(to, from); } }, created: function created() { // Create private non-reactive props this.$_interval = null; this.$_animationTimeout = null; this.$_touchTimeout = null; this.$_observer = null; // Set initial paused state this.isPaused = !(toInteger(this.interval, 0) > 0); }, mounted: function mounted() { // Cache current browser transitionend event name this.transitionEndEvent = getTransitionEndEvent(this.$el) || null; // Get all slides this.updateSlides(); // Observe child changes so we can update slide list this.setObserver(true); }, beforeDestroy: function beforeDestroy() { this.clearInterval(); this.clearAnimationTimeout(); this.clearTouchTimeout(); this.setObserver(false); }, methods: { clearInterval: function (_clearInterval) { function clearInterval() { return _clearInterval.apply(this, arguments); } clearInterval.toString = function () { return _clearInterval.toString(); }; return clearInterval; }(function () { clearInterval(this.$_interval); this.$_interval = null; }), clearAnimationTimeout: function clearAnimationTimeout() { clearTimeout(this.$_animationTimeout); this.$_animationTimeout = null; }, clearTouchTimeout: function clearTouchTimeout() { clearTimeout(this.$_touchTimeout); this.$_touchTimeout = null; }, setObserver: function setObserver() { var on = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; this.$_observer && this.$_observer.disconnect(); this.$_observer = null; if (on) { this.$_observer = observeDom(this.$refs.inner, this.updateSlides.bind(this), { subtree: false, childList: true, attributes: true, attributeFilter: ['id'] }); } }, // Set slide setSlide: function setSlide(slide) { var _this = this; var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; // Don't animate when page is not visible /* istanbul ignore if: difficult to test */ if (isBrowser && document.visibilityState && document.hidden) { return; } var noWrap = this.noWrap; var numSlides = this.numSlides; // Make sure we have an integer (you never know!) slide = mathFloor(slide); // Don't do anything if nothing to slide to if (numSlides === 0) { return; } // Don't change slide while transitioning, wait until transition is done if (this.isSliding) { // Schedule slide after sliding complete this.$once('sliding-end', function () { // Wrap in `requestAF()` to allow the slide to properly finish to avoid glitching requestAF(function () { return _this.setSlide(slide, direction); }); }); return; } this.direction = direction; // Set new slide index // Wrap around if necessary (if no-wrap not enabled) this.index = slide >= numSlides ? noWrap ? numSlides - 1 : 0 : slide < 0 ? noWrap ? 0 : numSlides - 1 : slide; // Ensure the v-model is synched up if no-wrap is enabled // and user tried to slide pass either ends if (noWrap && this.index !== slide && this.index !== this.value) { this.$emit('input', this.index); } }, // Previous slide prev: function prev() { this.setSlide(this.index - 1, 'prev'); }, // Next slide next: function next() { this.setSlide(this.index + 1, 'next'); }, // Pause auto rotation pause: function pause(evt) { if (!evt) { this.isPaused = true; } this.clearInterval(); }, // Start auto rotate slides start: function start(evt) { if (!evt) { this.isPaused = false; } /* istanbul ignore next: most likely will never happen, but just in case */ this.clearInterval(); // Don't start if no interval, or less than 2 slides if (this.interval && this.numSlides > 1) { this.$_interval = setInterval(this.next, mathMax(1000, this.interval)); } }, // Restart auto rotate slides when focus/hover leaves the carousel /* istanbul ignore next */ restart: function restart() { if (!this.$el.contains(getActiveElement())) { this.start(); } }, doSlide: function doSlide(to, from) { var _this2 = this; var isCycling = Boolean(this.interval); // Determine sliding direction var direction = this.calcDirection(this.direction, from, to); var overlayClass = direction.overlayClass; var dirClass = direction.dirClass; // Determine current and next slides var currentSlide = this.slides[from]; var nextSlide = this.slides[to]; // Don't do anything if there aren't any slides to slide to if (!currentSlide || !nextSlide) { /* istanbul ignore next */ return; } // Start animating this.isSliding = true; if (isCycling) { this.pause(false); } this.$emit('sliding-start', to); // Update v-model this.$emit('input', this.index); if (this.noAnimation) { addClass(nextSlide, 'active'); removeClass(currentSlide, 'active'); this.isSliding = false; // Notify ourselves that we're done sliding (slid) this.$nextTick(function () { return _this2.$emit('sliding-end', to); }); } else { addClass(nextSlide, overlayClass); // Trigger a reflow of next slide reflow(nextSlide); addClass(currentSlide, dirClass); addClass(nextSlide, dirClass); // Transition End handler var called = false; /* istanbul ignore next: difficult to test */ var onceTransEnd = function onceTransEnd() { if (called) { return; } called = true; /* istanbul ignore if: transition events cant be tested in JSDOM */ if (_this2.transitionEndEvent) { var events = _this2.transitionEndEvent.split(/\s+/); events.forEach(function (evt) { return eventOff(nextSlide, evt, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE); }); } _this2.clearAnimationTimeout(); removeClass(nextSlide, dirClass); removeClass(nextSlide, overlayClass); addClass(nextSlide, 'active'); removeClass(currentSlide, 'active'); removeClass(currentSlide, dirClass); removeClass(currentSlide, overlayClass); setAttr(currentSlide, 'aria-current', 'false'); setAttr(nextSlide, 'aria-current', 'true'); setAttr(currentSlide, 'aria-hidden', 'true'); setAttr(nextSlide, 'aria-hidden', 'false'); _this2.isSliding = false; _this2.direction = null; // Notify ourselves that we're done sliding (slid) _this2.$nextTick(function () { return _this2.$emit('sliding-end', to); }); }; // Set up transitionend handler /* istanbul ignore if: transition events cant be tested in JSDOM */ if (this.transitionEndEvent) { var events = this.transitionEndEvent.split(/\s+/); events.forEach(function (event) { return eventOn(nextSlide, event, onceTransEnd, EVENT_OPTIONS_NO_CAPTURE); }); } // Fallback to setTimeout() this.$_animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION); } if (isCycling) { this.start(false); } }, // Update slide list updateSlides: function updateSlides() { this.pause(true); // Get all slides as DOM elements this.slides = selectAll('.carousel-item', this.$refs.inner); var numSlides = this.slides.length; // Keep slide number in range var index = mathMax(0, mathMin(mathFloor(this.index), numSlides - 1)); this.slides.forEach(function (slide, idx) { var n = idx + 1; if (idx === index) { addClass(slide, 'active'); setAttr(slide, 'aria-current', 'true'); } else { removeClass(slide, 'active'); setAttr(slide, 'aria-current', 'false'); } setAttr(slide, 'aria-posinset', String(n)); setAttr(slide, 'aria-setsize', String(numSlides)); }); // Set slide as active this.setSlide(index); this.start(this.isPaused); }, calcDirection: function calcDirection() { var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; var curIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; var nextIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0; if (!direction) { return nextIndex > curIndex ? DIRECTION.next : DIRECTION.prev; } return DIRECTION[direction]; }, handleClick: function handleClick(evt, fn) { var keyCode = evt.keyCode; if (evt.type === 'click' || keyCode === CODE_SPACE || keyCode === CODE_ENTER) { stopEvent(evt); fn(); } }, /* istanbul ignore next: JSDOM doesn't support touch events */ handleSwipe: function handleSwipe() { var absDeltaX = mathAbs(this.touchDeltaX); if (absDeltaX <= SWIPE_THRESHOLD) { return; } var direction = absDeltaX / this.touchDeltaX; // Reset touch delta X // https://github.com/twbs/bootstrap/pull/28558 this.touchDeltaX = 0; if (direction > 0) { // Swipe left this.prev(); } else if (direction < 0) { // Swipe right this.next(); } }, /* istanbul ignore next: JSDOM doesn't support touch events */ touchStart: function touchStart(evt) { if (hasPointerEventSupport && PointerType[evt.pointerType.toUpperCase()]) { this.touchStartX = evt.clientX; } else if (!hasPointerEventSupport) { this.touchStartX = evt.touches[0].clientX; } }, /* istanbul ignore next: JSDOM doesn't support touch events */ touchMove: function touchMove(evt) { // Ensure swiping with one touch and not pinching if (evt.touches && evt.touches.length > 1) { this.touchDeltaX = 0; } else { this.touchDeltaX = evt.touches[0].clientX - this.touchStartX; } }, /* istanbul ignore next: JSDOM doesn't support touch events */ touchEnd: function touchEnd(evt) { if (hasPointerEventSupport && PointerType[evt.pointerType.toUpperCase()]) { this.touchDeltaX = evt.clientX - this.touchStartX; } this.handleSwipe(); // If it's a touch-enabled device, mouseenter/leave are fired as // part of the mouse compatibility events on first tap - the carousel // would stop cycling until user tapped out of it; // here, we listen for touchend, explicitly pause the carousel // (as if it's the second time we tap on it, mouseenter compat event // is NOT fired) and after a timeout (to allow for mouse compatibility // events to fire) we explicitly restart cycling this.pause(false); this.clearTouchTimeout(); this.$_touchTimeout = setTimeout(this.start, TOUCH_EVENT_COMPAT_WAIT + mathMax(1000, this.interval)); } }, render: function render(h) { var _this3 = this; // Wrapper for slides var inner = h('div', { ref: 'inner', class: ['carousel-inner'], attrs: { id: this.safeId('__BV_inner_'), role: 'list' } }, [this.normalizeSlot()]); // Prev and next controls var controls = h(); if (this.controls) { var prevHandler = function prevHandler(evt) { /* istanbul ignore next */ if (!_this3.isSliding) { _this3.handleClick(evt, _this3.prev); } else { stopEvent(evt, { propagation: false }); } }; var nextHandler = function nextHandler(evt) { /* istanbul ignore next */ if (!_this3.isSliding) { _this3.handleClick(evt, _this3.next); } else { stopEvent(evt, { propagation: false }); } }; controls = [h('a', { class: ['carousel-control-prev'], attrs: { href: '#', role: 'button', 'aria-controls': this.safeId('__BV_inner_'), 'aria-disabled': this.isSliding ? 'true' : null }, on: { click: prevHandler, keydown: prevHandler } }, [h('span', { class: ['carousel-control-prev-icon'], attrs: { 'aria-hidden': 'true' } }), h('span', { class: ['sr-only'] }, [this.labelPrev])]), h('a', { class: ['carousel-control-next'], attrs: { href: '#', role: 'button', 'aria-controls': this.safeId('__BV_inner_'), 'aria-disabled': this.isSliding ? 'true' : null }, on: { click: nextHandler, keydown: nextHandler } }, [h('span', { class: ['carousel-control-next-icon'], attrs: { 'aria-hidden': 'true' } }), h('span', { class: ['sr-only'] }, [this.labelNext])])]; } // Indicators var indicators = h('ol', { class: ['carousel-indicators'], directives: [{ name: 'show', rawName: 'v-show', value: this.indicators, expression: 'indicators' }], attrs: { id: this.safeId('__BV_indicators_'), 'aria-hidden': this.indicators ? 'false' : 'true', 'aria-label': this.labelIndicators, 'aria-owns': this.safeId('__BV_inner_') } }, this.slides.map(function (slide, n) { return h('li', { key: "slide_".concat(n), class: { active: n === _this3.index }, attrs: { role: 'button', id: _this3.safeId("__BV_indicator_".concat(n + 1, "_")), tabindex: _this3.indicators ? '0' : '-1', 'aria-current': n === _this3.index ? 'true' : 'false', 'aria-label': "".concat(_this3.labelGotoSlide, " ").concat(n + 1), 'aria-describedby': _this3.slides[n].id || null, 'aria-controls': _this3.safeId('__BV_inner_') }, on: { click: function click(evt) { _this3.handleClick(evt, function () { _this3.setSlide(n); }); }, keydown: function keydown(evt) { _this3.handleClick(evt, function () { _this3.setSlide(n); }); } } }); })); var on = { mouseenter: this.noHoverPause ? noop : this.pause, mouseleave: this.noHoverPause ? noop : this.restart, focusin: this.pause, focusout: this.restart, keydown: function keydown(evt) { if (/input|textarea/i.test(evt.target.tagName)) { /* istanbul ignore next */ return; } var keyCode = evt.keyCode; if (keyCode === CODE_LEFT || keyCode === CODE_RIGHT) { stopEvent(evt); _this3[keyCode === CODE_LEFT ? 'prev' : 'next'](); } } }; // Touch support event handlers for environment if (!this.noTouch && hasTouchSupport) { // Attach appropriate listeners (prepend event name with '&' for passive mode) /* istanbul ignore next: JSDOM doesn't support touch events */ if (hasPointerEventSupport) { on['&pointerdown'] = this.touchStart; on['&pointerup'] = this.touchEnd; } else { on['&touchstart'] = this.touchStart; on['&touchmove'] = this.touchMove; on['&touchend'] = this.touchEnd; } } // Return the carousel return h('div', { staticClass: 'carousel', class: { slide: !this.noAnimation, 'carousel-fade': !this.noAnimation && this.fade, 'pointer-event': !this.noTouch && hasTouchSupport && hasPointerEventSupport }, style: { background: this.background }, attrs: { role: 'region', id: this.safeId(), 'aria-busy': this.isSliding ? 'true' : 'false' }, on: on }, [inner, controls, indicators]); } }); var imgProps = { imgSrc: { type: String // default: undefined }, imgAlt: { type: String // default: undefined }, imgWidth: { type: [Number, String] // default: undefined }, imgHeight: { type: [Number, String] // default: undefined }, imgBlank: { type: Boolean, default: false }, imgBlankColor: { type: String, default: 'transparent' } }; var props$l = makePropsConfigurable(_objectSpread2(_objectSpread2({}, imgProps), {}, { contentVisibleUp: { type: String }, contentTag: { type: String, default: 'div' }, caption: { type: String }, captionHtml: { type: String }, captionTag: { type: String, default: 'h3' }, text: { type: String }, textHtml: { type: String }, textTag: { type: String, default: 'p' }, background: { type: String } }), NAME_CAROUSEL_SLIDE); // --- Main component --- // @vue/component var BCarouselSlide = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_CAROUSEL_SLIDE, mixins: [idMixin, normalizeSlotMixin], inject: { bvCarousel: { default: function _default() { return { // Explicitly disable touch if not a child of carousel noTouch: true }; } } }, props: props$l, computed: { contentClasses: function contentClasses() { return [this.contentVisibleUp ? 'd-none' : '', this.contentVisibleUp ? "d-".concat(this.contentVisibleUp, "-block") : '']; }, computedWidth: function computedWidth() { // Use local width, or try parent width return this.imgWidth || this.bvCarousel.imgWidth || null; }, computedHeight: function computedHeight() { // Use local height, or try parent height return this.imgHeight || this.bvCarousel.imgHeight || null; } }, render: function render(h) { var $img = this.normalizeSlot('img'); if (!$img && (this.imgSrc || this.imgBlank)) { var on = {}; // Touch support event handler /* istanbul ignore if: difficult to test in JSDOM */ if (!this.bvCarousel.noTouch && hasTouchSupport) { on.dragstart = function (evt) { return stopEvent(evt, { propagation: false }); }; } $img = h(BImg, { props: _objectSpread2(_objectSpread2({}, pluckProps(imgProps, this.$props, unprefixPropName.bind(null, 'img'))), {}, { width: this.computedWidth, height: this.computedHeight, fluidGrow: true, block: true }), on: on }); } var $contentChildren = [// Caption this.caption || this.captionHtml ? h(this.captionTag, { domProps: htmlOrText(this.captionHtml, this.caption) }) : false, // Text this.text || this.textHtml ? h(this.textTag, { domProps: htmlOrText(this.textHtml, this.text) }) : false, // Children this.normalizeSlot() || false]; var $content = h(); if ($contentChildren.some(Boolean)) { $content = h(this.contentTag, { staticClass: 'carousel-caption', class: this.contentClasses }, $contentChildren.map(function ($child) { return $child || h(); })); } return h('div', { staticClass: 'carousel-item', style: { background: this.background || this.bvCarousel.background || null }, attrs: { id: this.safeId(), role: 'listitem' } }, [$img, $content]); } }); var CarouselPlugin = /*#__PURE*/ pluginFactory({ components: { BCarousel: BCarousel, BCarouselSlide: BCarouselSlide } }); // Generic collapse transion helper component var onEnter = function onEnter(el) { setStyle(el, 'height', 0); // In a `requestAF()` for `appear` to work requestAF(function () { reflow(el); setStyle(el, 'height', "".concat(el.scrollHeight, "px")); }); }; var onAfterEnter = function onAfterEnter(el) { removeStyle(el, 'height'); }; var onLeave = function onLeave(el) { setStyle(el, 'height', 'auto'); setStyle(el, 'display', 'block'); setStyle(el, 'height', "".concat(getBCR(el).height, "px")); reflow(el); setStyle(el, 'height', 0); }; var onAfterLeave = function onAfterLeave(el) { removeStyle(el, 'height'); }; // Default transition props // `appear` will use the enter classes var TRANSITION_PROPS = { css: true, enterClass: '', enterActiveClass: 'collapsing', enterToClass: 'collapse show', leaveClass: 'collapse show', leaveActiveClass: 'collapsing', leaveToClass: 'collapse' }; // Default transition handlers // `appear` will use the enter handlers var TRANSITION_HANDLERS = { enter: onEnter, afterEnter: onAfterEnter, leave: onLeave, afterLeave: onAfterLeave }; // @vue/component var BVCollapse = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_COLLAPSE_HELPER, functional: true, props: { appear: { // If `true` (and `visible` is `true` on mount), animate initially visible type: Boolean, default: false } }, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h('transition', // We merge in the `appear` prop last a(data, { props: TRANSITION_PROPS, on: TRANSITION_HANDLERS }, { props: props }), // Note: `` supports a single root element only children); } }); // @vue/component var listenOnRootMixin = { methods: { /** * Safely register event listeners on the root Vue node * While Vue automatically removes listeners for individual components, * when a component registers a listener on root and is destroyed, * this orphans a callback because the node is gone, * but the root does not clear the callback * * When registering a `$root` listener, it also registers a listener on * the component's `beforeDestroy()` hook to automatically remove the * event listener from the `$root` instance * * @param {string} event * @param {function} callback */ listenOnRoot: function listenOnRoot(event, callback) { var _this = this; this.$root.$on(event, callback); this.$on('hook:beforeDestroy', function () { _this.$root.$off(event, callback); }); }, /** * Safely register a `$once()` event listener on the root Vue node * While Vue automatically removes listeners for individual components, * when a component registers a listener on root and is destroyed, * this orphans a callback because the node is gone, * but the root does not clear the callback * * When registering a $root listener, it also registers a listener on * the component's `beforeDestroy` hook to automatically remove the * event listener from the $root instance. * * @param {string} event * @param {function} callback */ listenOnRootOnce: function listenOnRootOnce(event, callback) { var _this2 = this; this.$root.$once(event, callback); this.$on('hook:beforeDestroy', function () { _this2.$root.$off(event, callback); }); }, /** * Convenience method for calling `vm.$emit()` on `vm.$root` * * @param {string} event * @param {*} args */ emitOnRoot: function emitOnRoot(event) { var _this$$root; for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { args[_key - 1] = arguments[_key]; } (_this$$root = this.$root).$emit.apply(_this$$root, [event].concat(args)); } } }; // Classes to apply to trigger element var CLASS_BV_TOGGLE_COLLAPSED = 'collapsed'; var CLASS_BV_TOGGLE_NOT_COLLAPSED = 'not-collapsed'; // Property key for handler storage var BV_BASE = '__BV_toggle'; // Root event listener property (Function) var BV_TOGGLE_ROOT_HANDLER = "".concat(BV_BASE, "_HANDLER__"); // Trigger element click handler property (Function) var BV_TOGGLE_CLICK_HANDLER = "".concat(BV_BASE, "_CLICK__"); // Target visibility state property (Boolean) var BV_TOGGLE_STATE = "".concat(BV_BASE, "_STATE__"); // Target ID list property (Array) var BV_TOGGLE_TARGETS = "".concat(BV_BASE, "_TARGETS__"); // Commonly used strings var STRING_FALSE = 'false'; var STRING_TRUE = 'true'; // Commonly used attribute names var ATTR_ARIA_CONTROLS = 'aria-controls'; var ATTR_ARIA_EXPANDED = 'aria-expanded'; var ATTR_ROLE = 'role'; var ATTR_TABINDEX = 'tabindex'; // Commonly used style properties var STYLE_OVERFLOW_ANCHOR = 'overflow-anchor'; // Emitted control event for collapse (emitted to collapse) var EVENT_TOGGLE = 'bv::toggle::collapse'; // Listen to event for toggle state update (emitted by collapse) var EVENT_STATE = 'bv::collapse::state'; // Private event emitted on `$root` to ensure the toggle state is always synced // Gets emitted even if the state of b-collapse has not changed // This event is NOT to be documented as people should not be using it var EVENT_STATE_SYNC = 'bv::collapse::sync::state'; // Private event we send to collapse to request state update sync event var EVENT_STATE_REQUEST = 'bv::request::collapse::state'; var KEYDOWN_KEY_CODES = [CODE_ENTER, CODE_SPACE]; // --- Helper methods --- var isNonStandardTag$1 = function isNonStandardTag(el) { return !arrayIncludes(['button', 'a'], el.tagName.toLowerCase()); }; var getTargets = function getTargets(_ref, el) { var modifiers = _ref.modifiers, arg = _ref.arg, value = _ref.value; // Any modifiers are considered target IDs var targets = keys(modifiers || {}); // If value is a string, split out individual targets (if space delimited) value = isString(value) ? value.split(RX_SPACE_SPLIT) : value; // Support target ID as link href (`href="#id"`) if (isTag(el.tagName, 'a')) { var href = getAttr(el, 'href') || ''; if (RX_HASH_ID.test(href)) { targets.push(href.replace(RX_HASH, '')); } } // Add ID from `arg` (if provided), and support value // as a single string ID or an array of string IDs // If `value` is not an array or string, then it gets filtered out concat(arg, value).forEach(function (t) { return isString(t) && targets.push(t); }); // Return only unique and truthy target IDs return targets.filter(function (t, index, arr) { return t && arr.indexOf(t) === index; }); }; var removeClickListener = function removeClickListener(el) { var handler = el[BV_TOGGLE_CLICK_HANDLER]; if (handler) { eventOff(el, 'click', handler, EVENT_OPTIONS_PASSIVE); eventOff(el, 'keydown', handler, EVENT_OPTIONS_PASSIVE); } el[BV_TOGGLE_CLICK_HANDLER] = null; }; var addClickListener = function addClickListener(el, vnode) { removeClickListener(el); if (vnode.context) { var handler = function handler(evt) { if (!(evt.type === 'keydown' && !arrayIncludes(KEYDOWN_KEY_CODES, evt.keyCode)) && !isDisabled(el)) { var targets = el[BV_TOGGLE_TARGETS] || []; targets.forEach(function (target) { vnode.context.$root.$emit(EVENT_TOGGLE, target); }); } }; el[BV_TOGGLE_CLICK_HANDLER] = handler; eventOn(el, 'click', handler, EVENT_OPTIONS_PASSIVE); if (isNonStandardTag$1(el)) { eventOn(el, 'keydown', handler, EVENT_OPTIONS_PASSIVE); } } }; var removeRootListeners = function removeRootListeners(el, vnode) { if (el[BV_TOGGLE_ROOT_HANDLER] && vnode.context) { vnode.context.$root.$off([EVENT_STATE, EVENT_STATE_SYNC], el[BV_TOGGLE_ROOT_HANDLER]); } el[BV_TOGGLE_ROOT_HANDLER] = null; }; var addRootListeners = function addRootListeners(el, vnode) { removeRootListeners(el, vnode); if (vnode.context) { var handler = function handler(id, state) { // `state` will be `true` if target is expanded if (arrayIncludes(el[BV_TOGGLE_TARGETS] || [], id)) { // Set/Clear 'collapsed' visibility class state el[BV_TOGGLE_STATE] = state; // Set `aria-expanded` and class state on trigger element setToggleState(el, state); } }; el[BV_TOGGLE_ROOT_HANDLER] = handler; // Listen for toggle state changes (public) and sync (private) vnode.context.$root.$on([EVENT_STATE, EVENT_STATE_SYNC], handler); } }; var setToggleState = function setToggleState(el, state) { // State refers to the visibility of the collapse/sidebar if (state) { removeClass(el, CLASS_BV_TOGGLE_COLLAPSED); addClass(el, CLASS_BV_TOGGLE_NOT_COLLAPSED); setAttr(el, ATTR_ARIA_EXPANDED, STRING_TRUE); } else { removeClass(el, CLASS_BV_TOGGLE_NOT_COLLAPSED); addClass(el, CLASS_BV_TOGGLE_COLLAPSED); setAttr(el, ATTR_ARIA_EXPANDED, STRING_FALSE); } }; // Reset and remove a property from the provided element var resetProp = function resetProp(el, prop) { el[prop] = null; delete el[prop]; }; // Handle directive updates var handleUpdate = function handleUpdate(el, binding, vnode) { /* istanbul ignore next: should never happen */ if (!isBrowser || !vnode.context) { return; } // If element is not a button or link, we add `role="button"` // and `tabindex="0"` for accessibility reasons if (isNonStandardTag$1(el)) { if (!hasAttr(el, ATTR_ROLE)) { setAttr(el, ATTR_ROLE, 'button'); } if (!hasAttr(el, ATTR_TABINDEX)) { setAttr(el, ATTR_TABINDEX, '0'); } } // Ensure the collapse class and `aria-*` attributes persist // after element is updated (either by parent re-rendering // or changes to this element or its contents) setToggleState(el, el[BV_TOGGLE_STATE]); // Parse list of target IDs var targets = getTargets(binding, el); // Ensure the `aria-controls` hasn't been overwritten // or removed when vnode updates // Also ensure to set `overflow-anchor` to `none` to prevent // the browser's scroll anchoring behavior /* istanbul ignore else */ if (targets.length > 0) { setAttr(el, ATTR_ARIA_CONTROLS, targets.join(' ')); setStyle(el, STYLE_OVERFLOW_ANCHOR, 'none'); } else { removeAttr(el, ATTR_ARIA_CONTROLS); removeStyle(el, STYLE_OVERFLOW_ANCHOR); } // Add/Update our click listener(s) // Wrap in a `requestAF()` to allow any previous // click handling to occur first requestAF(function () { addClickListener(el, vnode); }); // If targets array has changed, update if (!looseEqual(targets, el[BV_TOGGLE_TARGETS])) { // Update targets array to element storage el[BV_TOGGLE_TARGETS] = targets; // Ensure `aria-controls` is up to date // Request a state update from targets so that we can // ensure expanded state is correct (in most cases) targets.forEach(function (target) { vnode.context.$root.$emit(EVENT_STATE_REQUEST, target); }); } }; /* * Export our directive */ var VBToggle = { bind: function bind(el, binding, vnode) { // State is initially collapsed until we receive a state event el[BV_TOGGLE_STATE] = false; // Assume no targets initially el[BV_TOGGLE_TARGETS] = []; // Add our root listeners addRootListeners(el, vnode); // Initial update of trigger handleUpdate(el, binding, vnode); }, componentUpdated: handleUpdate, updated: handleUpdate, unbind: function unbind(el, binding, vnode) { removeClickListener(el); // Remove our $root listener removeRootListeners(el, vnode); // Reset custom props resetProp(el, BV_TOGGLE_ROOT_HANDLER); resetProp(el, BV_TOGGLE_CLICK_HANDLER); resetProp(el, BV_TOGGLE_STATE); resetProp(el, BV_TOGGLE_TARGETS); // Reset classes/attrs/styles removeClass(el, CLASS_BV_TOGGLE_COLLAPSED); removeClass(el, CLASS_BV_TOGGLE_NOT_COLLAPSED); removeAttr(el, ATTR_ARIA_EXPANDED); removeAttr(el, ATTR_ARIA_CONTROLS); removeAttr(el, ATTR_ROLE); removeStyle(el, STYLE_OVERFLOW_ANCHOR); } }; // Accordion event name we emit on `$root` var EVENT_ACCORDION = 'bv::collapse::accordion'; // --- Main component --- // @vue/component var BCollapse = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_COLLAPSE, mixins: [idMixin, listenOnRootMixin, normalizeSlotMixin], model: { prop: 'visible', event: 'input' }, props: makePropsConfigurable({ isNav: { type: Boolean, default: false }, accordion: { type: String // default: null }, visible: { type: Boolean, default: false }, tag: { type: String, default: 'div' }, appear: { // If `true` (and `visible` is `true` on mount), animate initially visible type: Boolean, default: false } }, NAME_COLLAPSE), data: function data() { return { show: this.visible, transitioning: false }; }, computed: { classObject: function classObject() { return { 'navbar-collapse': this.isNav, collapse: !this.transitioning, show: this.show && !this.transitioning }; } }, watch: { visible: function visible(newVal) { if (newVal !== this.show) { this.show = newVal; } }, show: function show(newVal, oldVal) { if (newVal !== oldVal) { this.emitState(); } } }, created: function created() { this.show = this.visible; }, mounted: function mounted() { var _this = this; this.show = this.visible; // Listen for toggle events to open/close us this.listenOnRoot(EVENT_TOGGLE, this.handleToggleEvt); // Listen to other collapses for accordion events this.listenOnRoot(EVENT_ACCORDION, this.handleAccordionEvt); if (this.isNav) { // Set up handlers this.setWindowEvents(true); this.handleResize(); } this.$nextTick(function () { _this.emitState(); }); // Listen for "Sync state" requests from `v-b-toggle` this.listenOnRoot(EVENT_STATE_REQUEST, function (id) { if (id === _this.safeId()) { _this.$nextTick(_this.emitSync); } }); }, updated: function updated() { // Emit a private event every time this component updates to ensure // the toggle button is in sync with the collapse's state // It is emitted regardless if the visible state changes this.emitSync(); }, /* istanbul ignore next */ deactivated: function deactivated() { if (this.isNav) { this.setWindowEvents(false); } }, /* istanbul ignore next */ activated: function activated() { if (this.isNav) { this.setWindowEvents(true); } this.emitSync(); }, beforeDestroy: function beforeDestroy() { // Trigger state emit if needed this.show = false; if (this.isNav && isBrowser) { this.setWindowEvents(false); } }, methods: { setWindowEvents: function setWindowEvents(on) { eventOnOff(on, window, 'resize', this.handleResize, EVENT_OPTIONS_NO_CAPTURE); eventOnOff(on, window, 'orientationchange', this.handleResize, EVENT_OPTIONS_NO_CAPTURE); }, toggle: function toggle() { this.show = !this.show; }, onEnter: function onEnter() { this.transitioning = true; // This should be moved out so we can add cancellable events this.$emit('show'); }, onAfterEnter: function onAfterEnter() { this.transitioning = false; this.$emit('shown'); }, onLeave: function onLeave() { this.transitioning = true; // This should be moved out so we can add cancellable events this.$emit('hide'); }, onAfterLeave: function onAfterLeave() { this.transitioning = false; this.$emit('hidden'); }, emitState: function emitState() { this.$emit('input', this.show); // Let `v-b-toggle` know the state of this collapse this.emitOnRoot(EVENT_STATE, this.safeId(), this.show); if (this.accordion && this.show) { // Tell the other collapses in this accordion to close this.emitOnRoot(EVENT_ACCORDION, this.safeId(), this.accordion); } }, emitSync: function emitSync() { // Emit a private event every time this component updates to ensure // the toggle button is in sync with the collapse's state // It is emitted regardless if the visible state changes this.emitOnRoot(EVENT_STATE_SYNC, this.safeId(), this.show); }, checkDisplayBlock: function checkDisplayBlock() { // Check to see if the collapse has `display: block !important` set // We can't set `display: none` directly on `this.$el`, as it would // trigger a new transition to start (or cancel a current one) var restore = hasClass(this.$el, 'show'); removeClass(this.$el, 'show'); var isBlock = getCS(this.$el).display === 'block'; if (restore) { addClass(this.$el, 'show'); } return isBlock; }, clickHandler: function clickHandler(evt) { // If we are in a nav/navbar, close the collapse when non-disabled link clicked var el = evt.target; if (!this.isNav || !el || getCS(this.$el).display !== 'block') { /* istanbul ignore next: can't test getComputedStyle in JSDOM */ return; } if (matches(el, '.nav-link,.dropdown-item') || closest('.nav-link,.dropdown-item', el)) { if (!this.checkDisplayBlock()) { // Only close the collapse if it is not forced to be `display: block !important` this.show = false; } } }, handleToggleEvt: function handleToggleEvt(target) { if (target !== this.safeId()) { return; } this.toggle(); }, handleAccordionEvt: function handleAccordionEvt(openedId, accordion) { if (!this.accordion || accordion !== this.accordion) { return; } if (openedId === this.safeId()) { // Open this collapse if not shown if (!this.show) { this.toggle(); } } else { // Close this collapse if shown if (this.show) { this.toggle(); } } }, handleResize: function handleResize() { // Handler for orientation/resize to set collapsed state in nav/navbar this.show = getCS(this.$el).display === 'block'; } }, render: function render(h) { var _this2 = this; var scope = { visible: this.show, close: function close() { return _this2.show = false; } }; var content = h(this.tag, { class: this.classObject, directives: [{ name: 'show', value: this.show }], attrs: { id: this.safeId() }, on: { click: this.clickHandler } }, [this.normalizeSlot(SLOT_NAME_DEFAULT, scope)]); return h(BVCollapse, { props: { appear: this.appear }, on: { enter: this.onEnter, afterEnter: this.onAfterEnter, leave: this.onLeave, afterLeave: this.onAfterLeave } }, [content]); } }); var VBTogglePlugin = /*#__PURE__*/pluginFactory({ directives: { VBToggle: VBToggle } }); var CollapsePlugin = /*#__PURE__*/pluginFactory({ components: { BCollapse: BCollapse }, plugins: { VBTogglePlugin: VBTogglePlugin } }); /**! * @fileOverview Kickass library to create and place poppers near their reference elements. * @version 1.16.1 * @license * Copyright (c) 2016 Federico Zivolo and contributors * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var isBrowser$1 = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; var timeoutDuration = function () { var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { if (isBrowser$1 && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { return 1; } } return 0; }(); function microtaskDebounce(fn) { var called = false; return function () { if (called) { return; } called = true; window.Promise.resolve().then(function () { called = false; fn(); }); }; } function taskDebounce(fn) { var scheduled = false; return function () { if (!scheduled) { scheduled = true; setTimeout(function () { scheduled = false; fn(); }, timeoutDuration); } }; } var supportsMicroTasks = isBrowser$1 && window.Promise; /** * Create a debounced version of a method, that's asynchronously deferred * but called in the minimum time possible. * * @method * @memberof Popper.Utils * @argument {Function} fn * @returns {Function} */ var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; /** * Check if the given variable is a function * @method * @memberof Popper.Utils * @argument {Any} functionToCheck - variable to check * @returns {Boolean} answer to: is a function? */ function isFunction$1(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; } /** * Get CSS computed property of the given element * @method * @memberof Popper.Utils * @argument {Eement} element * @argument {String} property */ function getStyleComputedProperty(element, property) { if (element.nodeType !== 1) { return []; } // NOTE: 1 DOM access here var window = element.ownerDocument.defaultView; var css = window.getComputedStyle(element, null); return property ? css[property] : css; } /** * Returns the parentNode or the host of the element * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} parent */ function getParentNode(element) { if (element.nodeName === 'HTML') { return element; } return element.parentNode || element.host; } /** * Returns the scrolling parent of the given element * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} scroll parent */ function getScrollParent(element) { // Return body, `getScroll` will take care to get the correct `scrollTop` from it if (!element) { return document.body; } switch (element.nodeName) { case 'HTML': case 'BODY': return element.ownerDocument.body; case '#document': return element.body; } // Firefox want us to check `-x` and `-y` variations as well var _getStyleComputedProp = getStyleComputedProperty(element), overflow = _getStyleComputedProp.overflow, overflowX = _getStyleComputedProp.overflowX, overflowY = _getStyleComputedProp.overflowY; if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { return element; } return getScrollParent(getParentNode(element)); } /** * Returns the reference node of the reference object, or the reference object itself. * @method * @memberof Popper.Utils * @param {Element|Object} reference - the reference element (the popper will be relative to this) * @returns {Element} parent */ function getReferenceNode(reference) { return reference && reference.referenceNode ? reference.referenceNode : reference; } var isIE11 = isBrowser$1 && !!(window.MSInputMethodContext && document.documentMode); var isIE10 = isBrowser$1 && /MSIE 10/.test(navigator.userAgent); /** * Determines if the browser is Internet Explorer * @method * @memberof Popper.Utils * @param {Number} version to check * @returns {Boolean} isIE */ function isIE$1(version) { if (version === 11) { return isIE11; } if (version === 10) { return isIE10; } return isIE11 || isIE10; } /** * Returns the offset parent of the given element * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} offset parent */ function getOffsetParent(element) { if (!element) { return document.documentElement; } var noOffsetParent = isIE$1(10) ? document.body : null; // NOTE: 1 DOM access here var offsetParent = element.offsetParent || null; // Skip hidden elements which don't have an offsetParent while (offsetParent === noOffsetParent && element.nextElementSibling) { offsetParent = (element = element.nextElementSibling).offsetParent; } var nodeName = offsetParent && offsetParent.nodeName; if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { return element ? element.ownerDocument.documentElement : document.documentElement; } // .offsetParent will return the closest TH, TD or TABLE in case // no offsetParent is present, I hate this job... if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { return getOffsetParent(offsetParent); } return offsetParent; } function isOffsetContainer(element) { var nodeName = element.nodeName; if (nodeName === 'BODY') { return false; } return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; } /** * Finds the root node (document, shadowDOM root) of the given element * @method * @memberof Popper.Utils * @argument {Element} node * @returns {Element} root node */ function getRoot(node) { if (node.parentNode !== null) { return getRoot(node.parentNode); } return node; } /** * Finds the offset parent common to the two provided nodes * @method * @memberof Popper.Utils * @argument {Element} element1 * @argument {Element} element2 * @returns {Element} common offset parent */ function findCommonOffsetParent(element1, element2) { // This check is needed to avoid errors in case one of the elements isn't defined for any reason if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { return document.documentElement; } // Here we make sure to give as "start" the element that comes first in the DOM var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; var start = order ? element1 : element2; var end = order ? element2 : element1; // Get common ancestor container var range = document.createRange(); range.setStart(start, 0); range.setEnd(end, 0); var commonAncestorContainer = range.commonAncestorContainer; // Both nodes are inside #document if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { if (isOffsetContainer(commonAncestorContainer)) { return commonAncestorContainer; } return getOffsetParent(commonAncestorContainer); } // one of the nodes is inside shadowDOM, find which one var element1root = getRoot(element1); if (element1root.host) { return findCommonOffsetParent(element1root.host, element2); } else { return findCommonOffsetParent(element1, getRoot(element2).host); } } /** * Gets the scroll value of the given element in the given side (top and left) * @method * @memberof Popper.Utils * @argument {Element} element * @argument {String} side `top` or `left` * @returns {number} amount of scrolled pixels */ function getScroll(element) { var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; var nodeName = element.nodeName; if (nodeName === 'BODY' || nodeName === 'HTML') { var html = element.ownerDocument.documentElement; var scrollingElement = element.ownerDocument.scrollingElement || html; return scrollingElement[upperSide]; } return element[upperSide]; } /* * Sum or subtract the element scroll values (left and top) from a given rect object * @method * @memberof Popper.Utils * @param {Object} rect - Rect object you want to change * @param {HTMLElement} element - The element from the function reads the scroll values * @param {Boolean} subtract - set to true if you want to subtract the scroll values * @return {Object} rect - The modifier rect object */ function includeScroll(rect, element) { var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var scrollTop = getScroll(element, 'top'); var scrollLeft = getScroll(element, 'left'); var modifier = subtract ? -1 : 1; rect.top += scrollTop * modifier; rect.bottom += scrollTop * modifier; rect.left += scrollLeft * modifier; rect.right += scrollLeft * modifier; return rect; } /* * Helper to detect borders of a given element * @method * @memberof Popper.Utils * @param {CSSStyleDeclaration} styles * Result of `getStyleComputedProperty` on the given element * @param {String} axis - `x` or `y` * @return {number} borders - The borders size of the given axis */ function getBordersSize(styles, axis) { var sideA = axis === 'x' ? 'Left' : 'Top'; var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']); } function getSize(axis, body, html, computedStyle) { return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE$1(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); } function getWindowSizes(document) { var body = document.body; var html = document.documentElement; var computedStyle = isIE$1(10) && getComputedStyle(html); return { height: getSize('Height', body, html, computedStyle), width: getSize('Width', body, html, computedStyle) }; } var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var defineProperty$1 = function (obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** * Given element offsets, generate an output similar to getBoundingClientRect * @method * @memberof Popper.Utils * @argument {Object} offsets * @returns {Object} ClientRect like output */ function getClientRect(offsets) { return _extends({}, offsets, { right: offsets.left + offsets.width, bottom: offsets.top + offsets.height }); } /** * Get bounding client rect of given element * @method * @memberof Popper.Utils * @param {HTMLElement} element * @return {Object} client rect */ function getBoundingClientRect(element) { var rect = {}; // IE10 10 FIX: Please, don't ask, the element isn't // considered in DOM in some circumstances... // This isn't reproducible in IE10 compatibility mode of IE11 try { if (isIE$1(10)) { rect = element.getBoundingClientRect(); var scrollTop = getScroll(element, 'top'); var scrollLeft = getScroll(element, 'left'); rect.top += scrollTop; rect.left += scrollLeft; rect.bottom += scrollTop; rect.right += scrollLeft; } else { rect = element.getBoundingClientRect(); } } catch (e) {} var result = { left: rect.left, top: rect.top, width: rect.right - rect.left, height: rect.bottom - rect.top }; // subtract scrollbar size from sizes var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; var width = sizes.width || element.clientWidth || result.width; var height = sizes.height || element.clientHeight || result.height; var horizScrollbar = element.offsetWidth - width; var vertScrollbar = element.offsetHeight - height; // if an hypothetical scrollbar is detected, we must be sure it's not a `border` // we make this check conditional for performance reasons if (horizScrollbar || vertScrollbar) { var styles = getStyleComputedProperty(element); horizScrollbar -= getBordersSize(styles, 'x'); vertScrollbar -= getBordersSize(styles, 'y'); result.width -= horizScrollbar; result.height -= vertScrollbar; } return getClientRect(result); } function getOffsetRectRelativeToArbitraryNode(children, parent) { var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; var isIE10 = isIE$1(10); var isHTML = parent.nodeName === 'HTML'; var childrenRect = getBoundingClientRect(children); var parentRect = getBoundingClientRect(parent); var scrollParent = getScrollParent(children); var styles = getStyleComputedProperty(parent); var borderTopWidth = parseFloat(styles.borderTopWidth); var borderLeftWidth = parseFloat(styles.borderLeftWidth); // In cases where the parent is fixed, we must ignore negative scroll in offset calc if (fixedPosition && isHTML) { parentRect.top = Math.max(parentRect.top, 0); parentRect.left = Math.max(parentRect.left, 0); } var offsets = getClientRect({ top: childrenRect.top - parentRect.top - borderTopWidth, left: childrenRect.left - parentRect.left - borderLeftWidth, width: childrenRect.width, height: childrenRect.height }); offsets.marginTop = 0; offsets.marginLeft = 0; // Subtract margins of documentElement in case it's being used as parent // we do this only on HTML because it's the only element that behaves // differently when margins are applied to it. The margins are included in // the box of the documentElement, in the other cases not. if (!isIE10 && isHTML) { var marginTop = parseFloat(styles.marginTop); var marginLeft = parseFloat(styles.marginLeft); offsets.top -= borderTopWidth - marginTop; offsets.bottom -= borderTopWidth - marginTop; offsets.left -= borderLeftWidth - marginLeft; offsets.right -= borderLeftWidth - marginLeft; // Attach marginTop and marginLeft because in some circumstances we may need them offsets.marginTop = marginTop; offsets.marginLeft = marginLeft; } if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { offsets = includeScroll(offsets, parent); } return offsets; } function getViewportOffsetRectRelativeToArtbitraryNode(element) { var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var html = element.ownerDocument.documentElement; var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); var width = Math.max(html.clientWidth, window.innerWidth || 0); var height = Math.max(html.clientHeight, window.innerHeight || 0); var scrollTop = !excludeScroll ? getScroll(html) : 0; var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; var offset = { top: scrollTop - relativeOffset.top + relativeOffset.marginTop, left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, width: width, height: height }; return getClientRect(offset); } /** * Check if the given element is fixed or is inside a fixed parent * @method * @memberof Popper.Utils * @argument {Element} element * @argument {Element} customContainer * @returns {Boolean} answer to "isFixed?" */ function isFixed(element) { var nodeName = element.nodeName; if (nodeName === 'BODY' || nodeName === 'HTML') { return false; } if (getStyleComputedProperty(element, 'position') === 'fixed') { return true; } var parentNode = getParentNode(element); if (!parentNode) { return false; } return isFixed(parentNode); } /** * Finds the first parent of an element that has a transformed property defined * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Element} first transformed parent or documentElement */ function getFixedPositionOffsetParent(element) { // This check is needed to avoid errors in case one of the elements isn't defined for any reason if (!element || !element.parentElement || isIE$1()) { return document.documentElement; } var el = element.parentElement; while (el && getStyleComputedProperty(el, 'transform') === 'none') { el = el.parentElement; } return el || document.documentElement; } /** * Computed the boundaries limits and return them * @method * @memberof Popper.Utils * @param {HTMLElement} popper * @param {HTMLElement} reference * @param {number} padding * @param {HTMLElement} boundariesElement - Element used to define the boundaries * @param {Boolean} fixedPosition - Is in fixed position mode * @returns {Object} Coordinates of the boundaries */ function getBoundaries(popper, reference, padding, boundariesElement) { var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; // NOTE: 1 DOM access here var boundaries = { top: 0, left: 0 }; var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); // Handle viewport case if (boundariesElement === 'viewport') { boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); } else { // Handle other cases based on DOM element used as boundaries var boundariesNode = void 0; if (boundariesElement === 'scrollParent') { boundariesNode = getScrollParent(getParentNode(reference)); if (boundariesNode.nodeName === 'BODY') { boundariesNode = popper.ownerDocument.documentElement; } } else if (boundariesElement === 'window') { boundariesNode = popper.ownerDocument.documentElement; } else { boundariesNode = boundariesElement; } var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); // In case of HTML, we need a different computation if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { var _getWindowSizes = getWindowSizes(popper.ownerDocument), height = _getWindowSizes.height, width = _getWindowSizes.width; boundaries.top += offsets.top - offsets.marginTop; boundaries.bottom = height + offsets.top; boundaries.left += offsets.left - offsets.marginLeft; boundaries.right = width + offsets.left; } else { // for all the other DOM elements, this one is good boundaries = offsets; } } // Add paddings padding = padding || 0; var isPaddingNumber = typeof padding === 'number'; boundaries.left += isPaddingNumber ? padding : padding.left || 0; boundaries.top += isPaddingNumber ? padding : padding.top || 0; boundaries.right -= isPaddingNumber ? padding : padding.right || 0; boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; return boundaries; } function getArea(_ref) { var width = _ref.width, height = _ref.height; return width * height; } /** * Utility used to transform the `auto` placement to the placement with more * available space. * @method * @memberof Popper.Utils * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; if (placement.indexOf('auto') === -1) { return placement; } var boundaries = getBoundaries(popper, reference, padding, boundariesElement); var rects = { top: { width: boundaries.width, height: refRect.top - boundaries.top }, right: { width: boundaries.right - refRect.right, height: boundaries.height }, bottom: { width: boundaries.width, height: boundaries.bottom - refRect.bottom }, left: { width: refRect.left - boundaries.left, height: boundaries.height } }; var sortedAreas = Object.keys(rects).map(function (key) { return _extends({ key: key }, rects[key], { area: getArea(rects[key]) }); }).sort(function (a, b) { return b.area - a.area; }); var filteredAreas = sortedAreas.filter(function (_ref2) { var width = _ref2.width, height = _ref2.height; return width >= popper.clientWidth && height >= popper.clientHeight; }); var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; var variation = placement.split('-')[1]; return computedPlacement + (variation ? '-' + variation : ''); } /** * Get offsets to the reference element * @method * @memberof Popper.Utils * @param {Object} state * @param {Element} popper - the popper element * @param {Element} reference - the reference element (the popper will be relative to this) * @param {Element} fixedPosition - is in fixed position mode * @returns {Object} An object containing the offsets which will be applied to the popper */ function getReferenceOffsets(state, popper, reference) { var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); } /** * Get the outer sizes of the given element (offset size + margins) * @method * @memberof Popper.Utils * @argument {Element} element * @returns {Object} object containing width and height properties */ function getOuterSizes(element) { var window = element.ownerDocument.defaultView; var styles = window.getComputedStyle(element); var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); var result = { width: element.offsetWidth + y, height: element.offsetHeight + x }; return result; } /** * Get the opposite placement of the given one * @method * @memberof Popper.Utils * @argument {String} placement * @returns {String} flipped placement */ function getOppositePlacement(placement) { var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; return placement.replace(/left|right|bottom|top/g, function (matched) { return hash[matched]; }); } /** * Get offsets to the popper * @method * @memberof Popper.Utils * @param {Object} position - CSS position the Popper will get applied * @param {HTMLElement} popper - the popper element * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) * @param {String} placement - one of the valid placement options * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper */ function getPopperOffsets(popper, referenceOffsets, placement) { placement = placement.split('-')[0]; // Get popper node sizes var popperRect = getOuterSizes(popper); // Add position, width and height to our offsets object var popperOffsets = { width: popperRect.width, height: popperRect.height }; // depending by the popper placement we have to compute its offsets slightly differently var isHoriz = ['right', 'left'].indexOf(placement) !== -1; var mainSide = isHoriz ? 'top' : 'left'; var secondarySide = isHoriz ? 'left' : 'top'; var measurement = isHoriz ? 'height' : 'width'; var secondaryMeasurement = !isHoriz ? 'height' : 'width'; popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; if (placement === secondarySide) { popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; } else { popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; } return popperOffsets; } /** * Mimics the `find` method of Array * @method * @memberof Popper.Utils * @argument {Array} arr * @argument prop * @argument value * @returns index or -1 */ function find(arr, check) { // use native find if supported if (Array.prototype.find) { return arr.find(check); } // use `filter` to obtain the same behavior of `find` return arr.filter(check)[0]; } /** * Return the index of the matching object * @method * @memberof Popper.Utils * @argument {Array} arr * @argument prop * @argument value * @returns index or -1 */ function findIndex(arr, prop, value) { // use native findIndex if supported if (Array.prototype.findIndex) { return arr.findIndex(function (cur) { return cur[prop] === value; }); } // use `find` + `indexOf` if `findIndex` isn't supported var match = find(arr, function (obj) { return obj[prop] === value; }); return arr.indexOf(match); } /** * Loop trough the list of modifiers and run them in order, * each of them will then edit the data object. * @method * @memberof Popper.Utils * @param {dataObject} data * @param {Array} modifiers * @param {String} ends - Optional modifier name used as stopper * @returns {dataObject} */ function runModifiers(modifiers, data, ends) { var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); modifiersToRun.forEach(function (modifier) { if (modifier['function']) { // eslint-disable-line dot-notation console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); } var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation if (modifier.enabled && isFunction$1(fn)) { // Add properties to offsets to make them a complete clientRect object // we do this before each modifier to make sure the previous one doesn't // mess with these values data.offsets.popper = getClientRect(data.offsets.popper); data.offsets.reference = getClientRect(data.offsets.reference); data = fn(data, modifier); } }); return data; } /** * Updates the position of the popper, computing the new offsets and applying * the new style.
* Prefer `scheduleUpdate` over `update` because of performance reasons. * @method * @memberof Popper */ function update() { // if popper is destroyed, don't perform any further update if (this.state.isDestroyed) { return; } var data = { instance: this, styles: {}, arrowStyles: {}, attributes: {}, flipped: false, offsets: {} }; // compute reference element offsets data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); // compute auto placement, store placement inside the data object, // modifiers will be able to edit `placement` if needed // and refer to originalPlacement to know the original value data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); // store the computed placement inside `originalPlacement` data.originalPlacement = data.placement; data.positionFixed = this.options.positionFixed; // compute the popper offsets data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; // run the modifiers data = runModifiers(this.modifiers, data); // the first `update` will call `onCreate` callback // the other ones will call `onUpdate` callback if (!this.state.isCreated) { this.state.isCreated = true; this.options.onCreate(data); } else { this.options.onUpdate(data); } } /** * Helper used to know if the given modifier is enabled. * @method * @memberof Popper.Utils * @returns {Boolean} */ function isModifierEnabled(modifiers, modifierName) { return modifiers.some(function (_ref) { var name = _ref.name, enabled = _ref.enabled; return enabled && name === modifierName; }); } /** * Get the prefixed supported property name * @method * @memberof Popper.Utils * @argument {String} property (camelCase) * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) */ function getSupportedPropertyName(property) { var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; var upperProp = property.charAt(0).toUpperCase() + property.slice(1); for (var i = 0; i < prefixes.length; i++) { var prefix = prefixes[i]; var toCheck = prefix ? '' + prefix + upperProp : property; if (typeof document.body.style[toCheck] !== 'undefined') { return toCheck; } } return null; } /** * Destroys the popper. * @method * @memberof Popper */ function destroy$1() { this.state.isDestroyed = true; // touch DOM only if `applyStyle` modifier is enabled if (isModifierEnabled(this.modifiers, 'applyStyle')) { this.popper.removeAttribute('x-placement'); this.popper.style.position = ''; this.popper.style.top = ''; this.popper.style.left = ''; this.popper.style.right = ''; this.popper.style.bottom = ''; this.popper.style.willChange = ''; this.popper.style[getSupportedPropertyName('transform')] = ''; } this.disableEventListeners(); // remove the popper if user explicitly asked for the deletion on destroy // do not use `remove` because IE11 doesn't support it if (this.options.removeOnDestroy) { this.popper.parentNode.removeChild(this.popper); } return this; } /** * Get the window associated with the element * @argument {Element} element * @returns {Window} */ function getWindow(element) { var ownerDocument = element.ownerDocument; return ownerDocument ? ownerDocument.defaultView : window; } function attachToScrollParents(scrollParent, event, callback, scrollParents) { var isBody = scrollParent.nodeName === 'BODY'; var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; target.addEventListener(event, callback, { passive: true }); if (!isBody) { attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); } scrollParents.push(target); } /** * Setup needed event listeners used to update the popper position * @method * @memberof Popper.Utils * @private */ function setupEventListeners(reference, options, state, updateBound) { // Resize event listener on window state.updateBound = updateBound; getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); // Scroll event listener on scroll parents var scrollElement = getScrollParent(reference); attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); state.scrollElement = scrollElement; state.eventsEnabled = true; return state; } /** * It will add resize/scroll events and start recalculating * position of the popper element when they are triggered. * @method * @memberof Popper */ function enableEventListeners() { if (!this.state.eventsEnabled) { this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); } } /** * Remove event listeners used to update the popper position * @method * @memberof Popper.Utils * @private */ function removeEventListeners(reference, state) { // Remove resize event listener on window getWindow(reference).removeEventListener('resize', state.updateBound); // Remove scroll event listener on scroll parents state.scrollParents.forEach(function (target) { target.removeEventListener('scroll', state.updateBound); }); // Reset state state.updateBound = null; state.scrollParents = []; state.scrollElement = null; state.eventsEnabled = false; return state; } /** * It will remove resize/scroll events and won't recalculate popper position * when they are triggered. It also won't trigger `onUpdate` callback anymore, * unless you call `update` method manually. * @method * @memberof Popper */ function disableEventListeners() { if (this.state.eventsEnabled) { cancelAnimationFrame(this.scheduleUpdate); this.state = removeEventListeners(this.reference, this.state); } } /** * Tells if a given input is a number * @method * @memberof Popper.Utils * @param {*} input to check * @return {Boolean} */ function isNumeric$1(n) { return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); } /** * Set the style to the given popper * @method * @memberof Popper.Utils * @argument {Element} element - Element to apply the style to * @argument {Object} styles * Object with a list of properties and values which will be applied to the element */ function setStyles(element, styles) { Object.keys(styles).forEach(function (prop) { var unit = ''; // add unit if the value is numeric and is one of the following if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric$1(styles[prop])) { unit = 'px'; } element.style[prop] = styles[prop] + unit; }); } /** * Set the attributes to the given popper * @method * @memberof Popper.Utils * @argument {Element} element - Element to apply the attributes to * @argument {Object} styles * Object with a list of properties and values which will be applied to the element */ function setAttributes(element, attributes) { Object.keys(attributes).forEach(function (prop) { var value = attributes[prop]; if (value !== false) { element.setAttribute(prop, attributes[prop]); } else { element.removeAttribute(prop); } }); } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} data.styles - List of style properties - values to apply to popper element * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element * @argument {Object} options - Modifiers configuration and options * @returns {Object} The same data object */ function applyStyle(data) { // any property present in `data.styles` will be applied to the popper, // in this way we can make the 3rd party modifiers add custom styles to it // Be aware, modifiers could override the properties defined in the previous // lines of this modifier! setStyles(data.instance.popper, data.styles); // any property present in `data.attributes` will be applied to the popper, // they will be set as HTML attributes of the element setAttributes(data.instance.popper, data.attributes); // if arrowElement is defined and arrowStyles has some properties if (data.arrowElement && Object.keys(data.arrowStyles).length) { setStyles(data.arrowElement, data.arrowStyles); } return data; } /** * Set the x-placement attribute before everything else because it could be used * to add margins to the popper margins needs to be calculated to get the * correct popper offsets. * @method * @memberof Popper.modifiers * @param {HTMLElement} reference - The reference element used to position the popper * @param {HTMLElement} popper - The HTML element used as popper * @param {Object} options - Popper.js options */ function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { // compute reference element offsets var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); // compute auto placement, store placement inside the data object, // modifiers will be able to edit `placement` if needed // and refer to originalPlacement to know the original value var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); popper.setAttribute('x-placement', placement); // Apply `position` to popper before anything else because // without the position applied we can't guarantee correct computations setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); return options; } /** * @function * @memberof Popper.Utils * @argument {Object} data - The data object generated by `update` method * @argument {Boolean} shouldRound - If the offsets should be rounded at all * @returns {Object} The popper's position offsets rounded * * The tale of pixel-perfect positioning. It's still not 100% perfect, but as * good as it can be within reason. * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 * * Low DPI screens cause a popper to be blurry if not using full pixels (Safari * as well on High DPI screens). * * Firefox prefers no rounding for positioning and does not have blurriness on * high DPI screens. * * Only horizontal placement and left/right values need to be considered. */ function getRoundedOffsets(data, shouldRound) { var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var round = Math.round, floor = Math.floor; var noRound = function noRound(v) { return v; }; var referenceWidth = round(reference.width); var popperWidth = round(popper.width); var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; var isVariation = data.placement.indexOf('-') !== -1; var sameWidthParity = referenceWidth % 2 === popperWidth % 2; var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; var verticalToInteger = !shouldRound ? noRound : round; return { left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), top: verticalToInteger(popper.top), bottom: verticalToInteger(popper.bottom), right: horizontalToInteger(popper.right) }; } var isFirefox = isBrowser$1 && /Firefox/i.test(navigator.userAgent); /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function computeStyle(data, options) { var x = options.x, y = options.y; var popper = data.offsets.popper; // Remove this legacy support in Popper.js v2 var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { return modifier.name === 'applyStyle'; }).gpuAcceleration; if (legacyGpuAccelerationOption !== undefined) { console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); } var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; var offsetParent = getOffsetParent(data.instance.popper); var offsetParentRect = getBoundingClientRect(offsetParent); // Styles var styles = { position: popper.position }; var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); var sideA = x === 'bottom' ? 'top' : 'bottom'; var sideB = y === 'right' ? 'left' : 'right'; // if gpuAcceleration is set to `true` and transform is supported, // we use `translate3d` to apply the position to the popper we // automatically use the supported prefixed version if needed var prefixedProperty = getSupportedPropertyName('transform'); // now, let's make a step back and look at this code closely (wtf?) // If the content of the popper grows once it's been positioned, it // may happen that the popper gets misplaced because of the new content // overflowing its reference element // To avoid this problem, we provide two options (x and y), which allow // the consumer to define the offset origin. // If we position a popper on top of a reference element, we can set // `x` to `top` to make the popper grow towards its top instead of // its bottom. var left = void 0, top = void 0; if (sideA === 'bottom') { // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) // and not the bottom of the html element if (offsetParent.nodeName === 'HTML') { top = -offsetParent.clientHeight + offsets.bottom; } else { top = -offsetParentRect.height + offsets.bottom; } } else { top = offsets.top; } if (sideB === 'right') { if (offsetParent.nodeName === 'HTML') { left = -offsetParent.clientWidth + offsets.right; } else { left = -offsetParentRect.width + offsets.right; } } else { left = offsets.left; } if (gpuAcceleration && prefixedProperty) { styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; styles[sideA] = 0; styles[sideB] = 0; styles.willChange = 'transform'; } else { // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties var invertTop = sideA === 'bottom' ? -1 : 1; var invertLeft = sideB === 'right' ? -1 : 1; styles[sideA] = top * invertTop; styles[sideB] = left * invertLeft; styles.willChange = sideA + ', ' + sideB; } // Attributes var attributes = { 'x-placement': data.placement }; // Update `data` attributes, styles and arrowStyles data.attributes = _extends({}, attributes, data.attributes); data.styles = _extends({}, styles, data.styles); data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); return data; } /** * Helper used to know if the given modifier depends from another one.
* It checks if the needed modifier is listed and enabled. * @method * @memberof Popper.Utils * @param {Array} modifiers - list of modifiers * @param {String} requestingName - name of requesting modifier * @param {String} requestedName - name of requested modifier * @returns {Boolean} */ function isModifierRequired(modifiers, requestingName, requestedName) { var requesting = find(modifiers, function (_ref) { var name = _ref.name; return name === requestingName; }); var isRequired = !!requesting && modifiers.some(function (modifier) { return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; }); if (!isRequired) { var _requesting = '`' + requestingName + '`'; var requested = '`' + requestedName + '`'; console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); } return isRequired; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function arrow(data, options) { var _data$offsets$arrow; // arrow depends on keepTogether in order to work if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { return data; } var arrowElement = options.element; // if arrowElement is a string, suppose it's a CSS selector if (typeof arrowElement === 'string') { arrowElement = data.instance.popper.querySelector(arrowElement); // if arrowElement is not found, don't run the modifier if (!arrowElement) { return data; } } else { // if the arrowElement isn't a query selector we must check that the // provided DOM node is child of its popper node if (!data.instance.popper.contains(arrowElement)) { console.warn('WARNING: `arrow.element` must be child of its popper element!'); return data; } } var placement = data.placement.split('-')[0]; var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var isVertical = ['left', 'right'].indexOf(placement) !== -1; var len = isVertical ? 'height' : 'width'; var sideCapitalized = isVertical ? 'Top' : 'Left'; var side = sideCapitalized.toLowerCase(); var altSide = isVertical ? 'left' : 'top'; var opSide = isVertical ? 'bottom' : 'right'; var arrowElementSize = getOuterSizes(arrowElement)[len]; // // extends keepTogether behavior making sure the popper and its // reference have enough pixels in conjunction // // top/left side if (reference[opSide] - arrowElementSize < popper[side]) { data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); } // bottom/right side if (reference[side] + arrowElementSize > popper[opSide]) { data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; } data.offsets.popper = getClientRect(data.offsets.popper); // compute center of the popper var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; // Compute the sideValue using the updated popper offsets // take popper margin in account because we don't have this info available var css = getStyleComputedProperty(data.instance.popper); var popperMarginSide = parseFloat(css['margin' + sideCapitalized]); var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']); var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; // prevent arrowElement from being placed not contiguously to its popper sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); data.arrowElement = arrowElement; data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty$1(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty$1(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); return data; } /** * Get the opposite placement variation of the given one * @method * @memberof Popper.Utils * @argument {String} placement variation * @returns {String} flipped placement variation */ function getOppositeVariation(variation) { if (variation === 'end') { return 'start'; } else if (variation === 'start') { return 'end'; } return variation; } /** * List of accepted placements to use as values of the `placement` option.
* Valid placements are: * - `auto` * - `top` * - `right` * - `bottom` * - `left` * * Each placement can have a variation from this list: * - `-start` * - `-end` * * Variations are interpreted easily if you think of them as the left to right * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` * is right.
* Vertically (`left` and `right`), `start` is top and `end` is bottom. * * Some valid examples are: * - `top-end` (on top of reference, right aligned) * - `right-start` (on right of reference, top aligned) * - `bottom` (on bottom, centered) * - `auto-end` (on the side with more space available, alignment depends by placement) * * @static * @type {Array} * @enum {String} * @readonly * @method placements * @memberof Popper */ var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; // Get rid of `auto` `auto-start` and `auto-end` var validPlacements = placements.slice(3); /** * Given an initial placement, returns all the subsequent placements * clockwise (or counter-clockwise). * * @method * @memberof Popper.Utils * @argument {String} placement - A valid placement (it accepts variations) * @argument {Boolean} counter - Set to true to walk the placements counterclockwise * @returns {Array} placements including their variations */ function clockwise(placement) { var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; var index = validPlacements.indexOf(placement); var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); return counter ? arr.reverse() : arr; } var BEHAVIORS = { FLIP: 'flip', CLOCKWISE: 'clockwise', COUNTERCLOCKWISE: 'counterclockwise' }; /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function flip(data, options) { // if `inner` modifier is enabled, we can't use the `flip` modifier if (isModifierEnabled(data.instance.modifiers, 'inner')) { return data; } if (data.flipped && data.placement === data.originalPlacement) { // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides return data; } var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); var placement = data.placement.split('-')[0]; var placementOpposite = getOppositePlacement(placement); var variation = data.placement.split('-')[1] || ''; var flipOrder = []; switch (options.behavior) { case BEHAVIORS.FLIP: flipOrder = [placement, placementOpposite]; break; case BEHAVIORS.CLOCKWISE: flipOrder = clockwise(placement); break; case BEHAVIORS.COUNTERCLOCKWISE: flipOrder = clockwise(placement, true); break; default: flipOrder = options.behavior; } flipOrder.forEach(function (step, index) { if (placement !== step || flipOrder.length === index + 1) { return data; } placement = data.placement.split('-')[0]; placementOpposite = getOppositePlacement(placement); var popperOffsets = data.offsets.popper; var refOffsets = data.offsets.reference; // using floor because the reference offsets may contain decimals we are not going to consider here var floor = Math.floor; var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; // flip the variation if required var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; // flips variation if reference element overflows boundaries var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); // flips variation if popper content overflows boundaries var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); var flippedVariation = flippedVariationByRef || flippedVariationByContent; if (overlapsRef || overflowsBoundaries || flippedVariation) { // this boolean to detect any flip loop data.flipped = true; if (overlapsRef || overflowsBoundaries) { placement = flipOrder[index + 1]; } if (flippedVariation) { variation = getOppositeVariation(variation); } data.placement = placement + (variation ? '-' + variation : ''); // this object contains `position`, we want to preserve it along with // any additional property we may add in the future data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); data = runModifiers(data.instance.modifiers, data, 'flip'); } }); return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function keepTogether(data) { var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var placement = data.placement.split('-')[0]; var floor = Math.floor; var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; var side = isVertical ? 'right' : 'bottom'; var opSide = isVertical ? 'left' : 'top'; var measurement = isVertical ? 'width' : 'height'; if (popper[side] < floor(reference[opSide])) { data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; } if (popper[opSide] > floor(reference[side])) { data.offsets.popper[opSide] = floor(reference[side]); } return data; } /** * Converts a string containing value + unit into a px value number * @function * @memberof {modifiers~offset} * @private * @argument {String} str - Value + unit string * @argument {String} measurement - `height` or `width` * @argument {Object} popperOffsets * @argument {Object} referenceOffsets * @returns {Number|String} * Value in pixels, or original string if no values were extracted */ function toValue(str, measurement, popperOffsets, referenceOffsets) { // separate value from unit var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); var value = +split[1]; var unit = split[2]; // If it's not a number it's an operator, I guess if (!value) { return str; } if (unit.indexOf('%') === 0) { var element = void 0; switch (unit) { case '%p': element = popperOffsets; break; case '%': case '%r': default: element = referenceOffsets; } var rect = getClientRect(element); return rect[measurement] / 100 * value; } else if (unit === 'vh' || unit === 'vw') { // if is a vh or vw, we calculate the size based on the viewport var size = void 0; if (unit === 'vh') { size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); } else { size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); } return size / 100 * value; } else { // if is an explicit pixel unit, we get rid of the unit and keep the value // if is an implicit unit, it's px, and we return just the value return value; } } /** * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. * @function * @memberof {modifiers~offset} * @private * @argument {String} offset * @argument {Object} popperOffsets * @argument {Object} referenceOffsets * @argument {String} basePlacement * @returns {Array} a two cells array with x and y offsets in numbers */ function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { var offsets = [0, 0]; // Use height if placement is left or right and index is 0 otherwise use width // in this way the first offset will use an axis and the second one // will use the other one var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; // Split the offset string to obtain a list of values and operands // The regex addresses values with the plus or minus sign in front (+10, -20, etc) var fragments = offset.split(/(\+|\-)/).map(function (frag) { return frag.trim(); }); // Detect if the offset string contains a pair of values or a single one // they could be separated by comma or space var divider = fragments.indexOf(find(fragments, function (frag) { return frag.search(/,|\s/) !== -1; })); if (fragments[divider] && fragments[divider].indexOf(',') === -1) { console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); } // If divider is found, we divide the list of values and operands to divide // them by ofset X and Y. var splitRegex = /\s*,\s*|\s+/; var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; // Convert the values with units to absolute pixels to allow our computations ops = ops.map(function (op, index) { // Most of the units rely on the orientation of the popper var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; var mergeWithPrevious = false; return op // This aggregates any `+` or `-` sign that aren't considered operators // e.g.: 10 + +5 => [10, +, +5] .reduce(function (a, b) { if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { a[a.length - 1] = b; mergeWithPrevious = true; return a; } else if (mergeWithPrevious) { a[a.length - 1] += b; mergeWithPrevious = false; return a; } else { return a.concat(b); } }, []) // Here we convert the string values into number values (in px) .map(function (str) { return toValue(str, measurement, popperOffsets, referenceOffsets); }); }); // Loop trough the offsets arrays and execute the operations ops.forEach(function (op, index) { op.forEach(function (frag, index2) { if (isNumeric$1(frag)) { offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); } }); }); return offsets; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @argument {Number|String} options.offset=0 * The offset value as described in the modifier description * @returns {Object} The data object, properly modified */ function offset$1(data, _ref) { var offset = _ref.offset; var placement = data.placement, _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var basePlacement = placement.split('-')[0]; var offsets = void 0; if (isNumeric$1(+offset)) { offsets = [+offset, 0]; } else { offsets = parseOffset(offset, popper, reference, basePlacement); } if (basePlacement === 'left') { popper.top += offsets[0]; popper.left -= offsets[1]; } else if (basePlacement === 'right') { popper.top += offsets[0]; popper.left += offsets[1]; } else if (basePlacement === 'top') { popper.left += offsets[0]; popper.top -= offsets[1]; } else if (basePlacement === 'bottom') { popper.left += offsets[0]; popper.top += offsets[1]; } data.popper = popper; return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function preventOverflow(data, options) { var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); // If offsetParent is the reference element, we really want to // go one step up and use the next offsetParent as reference to // avoid to make this modifier completely useless and look like broken if (data.instance.reference === boundariesElement) { boundariesElement = getOffsetParent(boundariesElement); } // NOTE: DOM access here // resets the popper's position so that the document size can be calculated excluding // the size of the popper element itself var transformProp = getSupportedPropertyName('transform'); var popperStyles = data.instance.popper.style; // assignment to help minification var top = popperStyles.top, left = popperStyles.left, transform = popperStyles[transformProp]; popperStyles.top = ''; popperStyles.left = ''; popperStyles[transformProp] = ''; var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); // NOTE: DOM access here // restores the original style properties after the offsets have been computed popperStyles.top = top; popperStyles.left = left; popperStyles[transformProp] = transform; options.boundaries = boundaries; var order = options.priority; var popper = data.offsets.popper; var check = { primary: function primary(placement) { var value = popper[placement]; if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { value = Math.max(popper[placement], boundaries[placement]); } return defineProperty$1({}, placement, value); }, secondary: function secondary(placement) { var mainSide = placement === 'right' ? 'left' : 'top'; var value = popper[mainSide]; if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); } return defineProperty$1({}, mainSide, value); } }; order.forEach(function (placement) { var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; popper = _extends({}, popper, check[side](placement)); }); data.offsets.popper = popper; return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function shift(data) { var placement = data.placement; var basePlacement = placement.split('-')[0]; var shiftvariation = placement.split('-')[1]; // if shift shiftvariation is specified, run the modifier if (shiftvariation) { var _data$offsets = data.offsets, reference = _data$offsets.reference, popper = _data$offsets.popper; var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; var side = isVertical ? 'left' : 'top'; var measurement = isVertical ? 'width' : 'height'; var shiftOffsets = { start: defineProperty$1({}, side, reference[side]), end: defineProperty$1({}, side, reference[side] + reference[measurement] - popper[measurement]) }; data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); } return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by update method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function hide(data) { if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { return data; } var refRect = data.offsets.reference; var bound = find(data.instance.modifiers, function (modifier) { return modifier.name === 'preventOverflow'; }).boundaries; if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { // Avoid unnecessary DOM access if visibility hasn't changed if (data.hide === true) { return data; } data.hide = true; data.attributes['x-out-of-boundaries'] = ''; } else { // Avoid unnecessary DOM access if visibility hasn't changed if (data.hide === false) { return data; } data.hide = false; data.attributes['x-out-of-boundaries'] = false; } return data; } /** * @function * @memberof Modifiers * @argument {Object} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {Object} The data object, properly modified */ function inner(data) { var placement = data.placement; var basePlacement = placement.split('-')[0]; var _data$offsets = data.offsets, popper = _data$offsets.popper, reference = _data$offsets.reference; var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); data.placement = getOppositePlacement(placement); data.offsets.popper = getClientRect(popper); return data; } /** * Modifier function, each modifier can have a function of this type assigned * to its `fn` property.
* These functions will be called on each update, this means that you must * make sure they are performant enough to avoid performance bottlenecks. * * @function ModifierFn * @argument {dataObject} data - The data object generated by `update` method * @argument {Object} options - Modifiers configuration and options * @returns {dataObject} The data object, properly modified */ /** * Modifiers are plugins used to alter the behavior of your poppers.
* Popper.js uses a set of 9 modifiers to provide all the basic functionalities * needed by the library. * * Usually you don't want to override the `order`, `fn` and `onLoad` props. * All the other properties are configurations that could be tweaked. * @namespace modifiers */ var modifiers = { /** * Modifier used to shift the popper on the start or end of its reference * element.
* It will read the variation of the `placement` property.
* It can be one either `-end` or `-start`. * @memberof modifiers * @inner */ shift: { /** @prop {number} order=100 - Index used to define the order of execution */ order: 100, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: shift }, /** * The `offset` modifier can shift your popper on both its axis. * * It accepts the following units: * - `px` or unit-less, interpreted as pixels * - `%` or `%r`, percentage relative to the length of the reference element * - `%p`, percentage relative to the length of the popper element * - `vw`, CSS viewport width unit * - `vh`, CSS viewport height unit * * For length is intended the main axis relative to the placement of the popper.
* This means that if the placement is `top` or `bottom`, the length will be the * `width`. In case of `left` or `right`, it will be the `height`. * * You can provide a single value (as `Number` or `String`), or a pair of values * as `String` divided by a comma or one (or more) white spaces.
* The latter is a deprecated method because it leads to confusion and will be * removed in v2.
* Additionally, it accepts additions and subtractions between different units. * Note that multiplications and divisions aren't supported. * * Valid examples are: * ``` * 10 * '10%' * '10, 10' * '10%, 10' * '10 + 10%' * '10 - 5vh + 3%' * '-10px + 5vh, 5px - 6%' * ``` * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap * > with their reference element, unfortunately, you will have to disable the `flip` modifier. * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). * * @memberof modifiers * @inner */ offset: { /** @prop {number} order=200 - Index used to define the order of execution */ order: 200, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: offset$1, /** @prop {Number|String} offset=0 * The offset value as described in the modifier description */ offset: 0 }, /** * Modifier used to prevent the popper from being positioned outside the boundary. * * A scenario exists where the reference itself is not within the boundaries.
* We can say it has "escaped the boundaries" — or just "escaped".
* In this case we need to decide whether the popper should either: * * - detach from the reference and remain "trapped" in the boundaries, or * - if it should ignore the boundary and "escape with its reference" * * When `escapeWithReference` is set to`true` and reference is completely * outside its boundaries, the popper will overflow (or completely leave) * the boundaries in order to remain attached to the edge of the reference. * * @memberof modifiers * @inner */ preventOverflow: { /** @prop {number} order=300 - Index used to define the order of execution */ order: 300, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: preventOverflow, /** * @prop {Array} [priority=['left','right','top','bottom']] * Popper will try to prevent overflow following these priorities by default, * then, it could overflow on the left and on top of the `boundariesElement` */ priority: ['left', 'right', 'top', 'bottom'], /** * @prop {number} padding=5 * Amount of pixel used to define a minimum distance between the boundaries * and the popper. This makes sure the popper always has a little padding * between the edges of its container */ padding: 5, /** * @prop {String|HTMLElement} boundariesElement='scrollParent' * Boundaries used by the modifier. Can be `scrollParent`, `window`, * `viewport` or any DOM element. */ boundariesElement: 'scrollParent' }, /** * Modifier used to make sure the reference and its popper stay near each other * without leaving any gap between the two. Especially useful when the arrow is * enabled and you want to ensure that it points to its reference element. * It cares only about the first axis. You can still have poppers with margin * between the popper and its reference element. * @memberof modifiers * @inner */ keepTogether: { /** @prop {number} order=400 - Index used to define the order of execution */ order: 400, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: keepTogether }, /** * This modifier is used to move the `arrowElement` of the popper to make * sure it is positioned between the reference element and its popper element. * It will read the outer size of the `arrowElement` node to detect how many * pixels of conjunction are needed. * * It has no effect if no `arrowElement` is provided. * @memberof modifiers * @inner */ arrow: { /** @prop {number} order=500 - Index used to define the order of execution */ order: 500, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: arrow, /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ element: '[x-arrow]' }, /** * Modifier used to flip the popper's placement when it starts to overlap its * reference element. * * Requires the `preventOverflow` modifier before it in order to work. * * **NOTE:** this modifier will interrupt the current update cycle and will * restart it if it detects the need to flip the placement. * @memberof modifiers * @inner */ flip: { /** @prop {number} order=600 - Index used to define the order of execution */ order: 600, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: flip, /** * @prop {String|Array} behavior='flip' * The behavior used to change the popper's placement. It can be one of * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid * placements (with optional variations) */ behavior: 'flip', /** * @prop {number} padding=5 * The popper will flip if it hits the edges of the `boundariesElement` */ padding: 5, /** * @prop {String|HTMLElement} boundariesElement='viewport' * The element which will define the boundaries of the popper position. * The popper will never be placed outside of the defined boundaries * (except if `keepTogether` is enabled) */ boundariesElement: 'viewport', /** * @prop {Boolean} flipVariations=false * The popper will switch placement variation between `-start` and `-end` when * the reference element overlaps its boundaries. * * The original placement should have a set variation. */ flipVariations: false, /** * @prop {Boolean} flipVariationsByContent=false * The popper will switch placement variation between `-start` and `-end` when * the popper element overlaps its reference boundaries. * * The original placement should have a set variation. */ flipVariationsByContent: false }, /** * Modifier used to make the popper flow toward the inner of the reference element. * By default, when this modifier is disabled, the popper will be placed outside * the reference element. * @memberof modifiers * @inner */ inner: { /** @prop {number} order=700 - Index used to define the order of execution */ order: 700, /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ enabled: false, /** @prop {ModifierFn} */ fn: inner }, /** * Modifier used to hide the popper when its reference element is outside of the * popper boundaries. It will set a `x-out-of-boundaries` attribute which can * be used to hide with a CSS selector the popper when its reference is * out of boundaries. * * Requires the `preventOverflow` modifier before it in order to work. * @memberof modifiers * @inner */ hide: { /** @prop {number} order=800 - Index used to define the order of execution */ order: 800, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: hide }, /** * Computes the style that will be applied to the popper element to gets * properly positioned. * * Note that this modifier will not touch the DOM, it just prepares the styles * so that `applyStyle` modifier can apply it. This separation is useful * in case you need to replace `applyStyle` with a custom implementation. * * This modifier has `850` as `order` value to maintain backward compatibility * with previous versions of Popper.js. Expect the modifiers ordering method * to change in future major versions of the library. * * @memberof modifiers * @inner */ computeStyle: { /** @prop {number} order=850 - Index used to define the order of execution */ order: 850, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: computeStyle, /** * @prop {Boolean} gpuAcceleration=true * If true, it uses the CSS 3D transformation to position the popper. * Otherwise, it will use the `top` and `left` properties */ gpuAcceleration: true, /** * @prop {string} [x='bottom'] * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. * Change this if your popper should grow in a direction different from `bottom` */ x: 'bottom', /** * @prop {string} [x='left'] * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. * Change this if your popper should grow in a direction different from `right` */ y: 'right' }, /** * Applies the computed styles to the popper element. * * All the DOM manipulations are limited to this modifier. This is useful in case * you want to integrate Popper.js inside a framework or view library and you * want to delegate all the DOM manipulations to it. * * Note that if you disable this modifier, you must make sure the popper element * has its position set to `absolute` before Popper.js can do its work! * * Just disable this modifier and define your own to achieve the desired effect. * * @memberof modifiers * @inner */ applyStyle: { /** @prop {number} order=900 - Index used to define the order of execution */ order: 900, /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ enabled: true, /** @prop {ModifierFn} */ fn: applyStyle, /** @prop {Function} */ onLoad: applyStyleOnLoad, /** * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier * @prop {Boolean} gpuAcceleration=true * If true, it uses the CSS 3D transformation to position the popper. * Otherwise, it will use the `top` and `left` properties */ gpuAcceleration: undefined } }; /** * The `dataObject` is an object containing all the information used by Popper.js. * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. * @name dataObject * @property {Object} data.instance The Popper.js instance * @property {String} data.placement Placement applied to popper * @property {String} data.originalPlacement Placement originally defined on init * @property {Boolean} data.flipped True if popper has been flipped by flip modifier * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) * @property {Object} data.boundaries Offsets of the popper boundaries * @property {Object} data.offsets The measurements of popper, reference and arrow elements * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 */ /** * Default options provided to Popper.js constructor.
* These can be overridden using the `options` argument of Popper.js.
* To override an option, simply pass an object with the same * structure of the `options` object, as the 3rd argument. For example: * ``` * new Popper(ref, pop, { * modifiers: { * preventOverflow: { enabled: false } * } * }) * ``` * @type {Object} * @static * @memberof Popper */ var Defaults = { /** * Popper's placement. * @prop {Popper.placements} placement='bottom' */ placement: 'bottom', /** * Set this to true if you want popper to position it self in 'fixed' mode * @prop {Boolean} positionFixed=false */ positionFixed: false, /** * Whether events (resize, scroll) are initially enabled. * @prop {Boolean} eventsEnabled=true */ eventsEnabled: true, /** * Set to true if you want to automatically remove the popper when * you call the `destroy` method. * @prop {Boolean} removeOnDestroy=false */ removeOnDestroy: false, /** * Callback called when the popper is created.
* By default, it is set to no-op.
* Access Popper.js instance with `data.instance`. * @prop {onCreate} */ onCreate: function onCreate() {}, /** * Callback called when the popper is updated. This callback is not called * on the initialization/creation of the popper, but only on subsequent * updates.
* By default, it is set to no-op.
* Access Popper.js instance with `data.instance`. * @prop {onUpdate} */ onUpdate: function onUpdate() {}, /** * List of modifiers used to modify the offsets before they are applied to the popper. * They provide most of the functionalities of Popper.js. * @prop {modifiers} */ modifiers: modifiers }; /** * @callback onCreate * @param {dataObject} data */ /** * @callback onUpdate * @param {dataObject} data */ // Utils // Methods var Popper = function () { /** * Creates a new Popper.js instance. * @class Popper * @param {Element|referenceObject} reference - The reference element used to position the popper * @param {Element} popper - The HTML / XML element used as the popper * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) * @return {Object} instance - The generated Popper.js instance */ function Popper(reference, popper) { var _this = this; var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; classCallCheck(this, Popper); this.scheduleUpdate = function () { return requestAnimationFrame(_this.update); }; // make update() debounced, so that it only runs at most once-per-tick this.update = debounce(this.update.bind(this)); // with {} we create a new object with the options inside it this.options = _extends({}, Popper.Defaults, options); // init state this.state = { isDestroyed: false, isCreated: false, scrollParents: [] }; // get reference and popper elements (allow jQuery wrappers) this.reference = reference && reference.jquery ? reference[0] : reference; this.popper = popper && popper.jquery ? popper[0] : popper; // Deep merge modifiers options this.options.modifiers = {}; Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); }); // Refactoring modifiers' list (Object => Array) this.modifiers = Object.keys(this.options.modifiers).map(function (name) { return _extends({ name: name }, _this.options.modifiers[name]); }) // sort the modifiers by order .sort(function (a, b) { return a.order - b.order; }); // modifiers have the ability to execute arbitrary code when Popper.js get inited // such code is executed in the same order of its modifier // they could add new properties to their options configuration // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! this.modifiers.forEach(function (modifierOptions) { if (modifierOptions.enabled && isFunction$1(modifierOptions.onLoad)) { modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); } }); // fire the first update to position the popper in the right place this.update(); var eventsEnabled = this.options.eventsEnabled; if (eventsEnabled) { // setup event listeners, they will take care of update the position in specific situations this.enableEventListeners(); } this.state.eventsEnabled = eventsEnabled; } // We can't use class properties because they don't get listed in the // class prototype and break stuff like Sinon stubs createClass(Popper, [{ key: 'update', value: function update$$1() { return update.call(this); } }, { key: 'destroy', value: function destroy$$1() { return destroy$1.call(this); } }, { key: 'enableEventListeners', value: function enableEventListeners$$1() { return enableEventListeners.call(this); } }, { key: 'disableEventListeners', value: function disableEventListeners$$1() { return disableEventListeners.call(this); } /** * Schedules an update. It will run on the next UI update available. * @method scheduleUpdate * @memberof Popper */ /** * Collection of utilities useful when writing custom modifiers. * Starting from version 1.7, this method is available only if you * include `popper-utils.js` before `popper.js`. * * **DEPRECATION**: This way to access PopperUtils is deprecated * and will be removed in v2! Use the PopperUtils module directly instead. * Due to the high instability of the methods contained in Utils, we can't * guarantee them to follow semver. Use them at your own risk! * @static * @private * @type {Object} * @deprecated since version 1.8 * @member Utils * @memberof Popper */ }]); return Popper; }(); /** * The `referenceObject` is an object that provides an interface compatible with Popper.js * and lets you use it as replacement of a real DOM node.
* You can use this method to position a popper relatively to a set of coordinates * in case you don't have a DOM node to use as reference. * * ``` * new Popper(referenceObject, popperNode); * ``` * * NB: This feature isn't supported in Internet Explorer 10. * @name referenceObject * @property {Function} data.getBoundingClientRect * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. * @property {number} data.clientWidth * An ES6 getter that will return the width of the virtual reference element. * @property {number} data.clientHeight * An ES6 getter that will return the height of the virtual reference element. */ Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; Popper.placements = placements; Popper.Defaults = Defaults; var PLACEMENT_TOP_START = 'top-start'; var PLACEMENT_TOP_END = 'top-end'; var PLACEMENT_BOTTOM_START = 'bottom-start'; var PLACEMENT_BOTTOM_END = 'bottom-end'; var PLACEMENT_RIGHT_START = 'right-start'; var PLACEMENT_LEFT_START = 'left-start'; var BvEvent = /*#__PURE__*/function () { function BvEvent(type) { var eventInit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; _classCallCheck(this, BvEvent); // Start by emulating native Event constructor if (!type) { /* istanbul ignore next */ throw new TypeError("Failed to construct '".concat(this.constructor.name, "'. 1 argument required, ").concat(arguments.length, " given.")); } // Merge defaults first, the eventInit, and the type last // so it can't be overwritten assign(this, BvEvent.Defaults, this.constructor.Defaults, eventInit, { type: type }); // Freeze some props as readonly, but leave them enumerable defineProperties(this, { type: readonlyDescriptor(), cancelable: readonlyDescriptor(), nativeEvent: readonlyDescriptor(), target: readonlyDescriptor(), relatedTarget: readonlyDescriptor(), vueTarget: readonlyDescriptor(), componentId: readonlyDescriptor() }); // Create a private variable using closure scoping var defaultPrevented = false; // Recreate preventDefault method. One way setter this.preventDefault = function preventDefault() { if (this.cancelable) { defaultPrevented = true; } }; // Create `defaultPrevented` publicly accessible prop that // can only be altered by the preventDefault method defineProperty(this, 'defaultPrevented', { enumerable: true, get: function get() { return defaultPrevented; } }); } _createClass(BvEvent, null, [{ key: "Defaults", get: function get() { return { type: '', cancelable: true, nativeEvent: null, target: null, relatedTarget: null, vueTarget: null, componentId: null }; } }]); return BvEvent; }(); // Named Exports var clickOutMixin = { data: function data() { return { listenForClickOut: false }; }, watch: { listenForClickOut: function listenForClickOut(newValue, oldValue) { if (newValue !== oldValue) { eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); if (newValue) { eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); } } } }, beforeCreate: function beforeCreate() { // Declare non-reactive properties this.clickOutElement = null; this.clickOutEventName = null; }, mounted: function mounted() { if (!this.clickOutElement) { this.clickOutElement = document; } if (!this.clickOutEventName) { this.clickOutEventName = 'click'; } if (this.listenForClickOut) { eventOn(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); } }, beforeDestroy: function beforeDestroy() { eventOff(this.clickOutElement, this.clickOutEventName, this._clickOutHandler, EVENT_OPTIONS_NO_CAPTURE); }, methods: { isClickOut: function isClickOut(evt) { return !contains(this.$el, evt.target); }, _clickOutHandler: function _clickOutHandler(evt) { if (this.clickOutHandler && this.isClickOut(evt)) { this.clickOutHandler(evt); } } } }; var focusInMixin = { data: function data() { return { listenForFocusIn: false }; }, watch: { listenForFocusIn: function listenForFocusIn(newValue, oldValue) { if (newValue !== oldValue) { eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); if (newValue) { eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); } } } }, beforeCreate: function beforeCreate() { // Declare non-reactive properties this.focusInElement = null; }, mounted: function mounted() { if (!this.focusInElement) { this.focusInElement = document; } if (this.listenForFocusIn) { eventOn(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); } }, beforeDestroy: function beforeDestroy() { eventOff(this.focusInElement, 'focusin', this._focusInHandler, EVENT_OPTIONS_NO_CAPTURE); }, methods: { _focusInHandler: function _focusInHandler(evt) { if (this.focusInHandler) { this.focusInHandler(evt); } } } }; // Root dropdown event names var ROOT_EVENT_PREFIX = 'bv::dropdown::'; var ROOT_EVENT_SHOWN = "".concat(ROOT_EVENT_PREFIX, "shown"); var ROOT_EVENT_HIDDEN = "".concat(ROOT_EVENT_PREFIX, "hidden"); // CSS selectors var SELECTOR_FORM_CHILD = '.dropdown form'; var SELECTOR_ITEM = ['.dropdown-item', '.b-dropdown-form'].map(function (selector) { return "".concat(selector, ":not(.disabled):not([disabled])"); }).join(', '); // --- Utility methods --- // Return an array of visible items var filterVisibles = function filterVisibles(els) { return (els || []).filter(isVisible); }; // --- Props --- var commonProps = makePropsConfigurable({ dropup: { // place on top if possible type: Boolean, default: false }, dropright: { // place right if possible type: Boolean, default: false }, dropleft: { // place left if possible type: Boolean, default: false }, right: { // Right align menu (default is left align) type: Boolean, default: false }, offset: { // Number of pixels to offset menu, or a CSS unit value (i.e. `1px`, `1rem`, etc.) type: [Number, String], default: 0 }, noFlip: { // Disable auto-flipping of menu from bottom <=> top type: Boolean, default: false }, popperOpts: { type: Object, default: function _default() {} }, boundary: { // String: `scrollParent`, `window` or `viewport` // HTMLElement: HTML Element reference type: [String, HTMLElement], default: 'scrollParent' } }, NAME_DROPDOWN); var props$m = _objectSpread2(_objectSpread2({}, commonProps), makePropsConfigurable({ disabled: { type: Boolean, default: false } }, NAME_DROPDOWN)); // --- Mixin --- // @vue/component var dropdownMixin = { mixins: [idMixin, clickOutMixin, focusInMixin], provide: function provide() { return { bvDropdown: this }; }, inject: { bvNavbar: { default: null } }, props: props$m, data: function data() { return { visible: false, visibleChangePrevented: false }; }, computed: { inNavbar: function inNavbar() { return !isNull(this.bvNavbar); }, toggler: function toggler() { var toggle = this.$refs.toggle; return toggle ? toggle.$el || toggle : null; }, directionClass: function directionClass() { if (this.dropup) { return 'dropup'; } else if (this.dropright) { return 'dropright'; } else if (this.dropleft) { return 'dropleft'; } return ''; }, boundaryClass: function boundaryClass() { // Position `static` is needed to allow menu to "breakout" of the `scrollParent` // boundaries when boundary is anything other than `scrollParent` // See: https://github.com/twbs/bootstrap/issues/24251#issuecomment-341413786 return this.boundary !== 'scrollParent' && !this.inNavbar ? 'position-static' : ''; } }, watch: { visible: function visible(newValue, oldValue) { if (this.visibleChangePrevented) { this.visibleChangePrevented = false; return; } if (newValue !== oldValue) { var evtName = newValue ? 'show' : 'hide'; var bvEvt = new BvEvent(evtName, { cancelable: true, vueTarget: this, target: this.$refs.menu, relatedTarget: null, componentId: this.safeId ? this.safeId() : this.id || null }); this.emitEvent(bvEvt); if (bvEvt.defaultPrevented) { // Reset value and exit if canceled this.visibleChangePrevented = true; this.visible = oldValue; // Just in case a child element triggered `this.hide(true)` this.$off('hidden', this.focusToggler); return; } if (evtName === 'show') { this.showMenu(); } else { this.hideMenu(); } } }, disabled: function disabled(newValue, oldValue) { if (newValue !== oldValue && newValue && this.visible) { // Hide dropdown if disabled changes to true this.visible = false; } } }, created: function created() { // Create private non-reactive props this.$_popper = null; this.$_hideTimeout = null; }, /* istanbul ignore next */ deactivated: function deactivated() { // In case we are inside a `` this.visible = false; this.whileOpenListen(false); this.destroyPopper(); }, beforeDestroy: function beforeDestroy() { this.visible = false; this.whileOpenListen(false); this.destroyPopper(); this.clearHideTimeout(); }, methods: { // Event emitter emitEvent: function emitEvent(bvEvt) { var type = bvEvt.type; this.$emit(type, bvEvt); this.$root.$emit("".concat(ROOT_EVENT_PREFIX).concat(type), bvEvt); }, showMenu: function showMenu() { var _this = this; if (this.disabled) { /* istanbul ignore next */ return; } // Only instantiate Popper.js when dropdown is not in `` if (!this.inNavbar) { if (typeof Popper === 'undefined') { /* istanbul ignore next */ warn('Popper.js not found. Falling back to CSS positioning', NAME_DROPDOWN); } else { // For dropup with alignment we use the parent element as popper container var el = this.dropup && this.right || this.split ? this.$el : this.$refs.toggle; // Make sure we have a reference to an element, not a component! el = el.$el || el; // Instantiate Popper.js this.createPopper(el); } } // Ensure other menus are closed this.$root.$emit(ROOT_EVENT_SHOWN, this); // Enable listeners this.whileOpenListen(true); // Wrap in `$nextTick()` to ensure menu is fully rendered/shown this.$nextTick(function () { // Focus on the menu container on show _this.focusMenu(); // Emit the shown event _this.$emit('shown'); }); }, hideMenu: function hideMenu() { this.whileOpenListen(false); this.$root.$emit(ROOT_EVENT_HIDDEN, this); this.$emit('hidden'); this.destroyPopper(); }, createPopper: function createPopper(element) { this.destroyPopper(); this.$_popper = new Popper(element, this.$refs.menu, this.getPopperConfig()); }, // Ensure popper event listeners are removed cleanly destroyPopper: function destroyPopper() { this.$_popper && this.$_popper.destroy(); this.$_popper = null; }, // Instructs popper to re-computes the dropdown position // useful if the content changes size updatePopper: function updatePopper() { try { this.$_popper.scheduleUpdate(); } catch (_unused) {} }, clearHideTimeout: function clearHideTimeout() { clearTimeout(this.$_hideTimeout); this.$_hideTimeout = null; }, getPopperConfig: function getPopperConfig() { var placement = PLACEMENT_BOTTOM_START; if (this.dropup) { placement = this.right ? PLACEMENT_TOP_END : PLACEMENT_TOP_START; } else if (this.dropright) { placement = PLACEMENT_RIGHT_START; } else if (this.dropleft) { placement = PLACEMENT_LEFT_START; } else if (this.right) { placement = PLACEMENT_BOTTOM_END; } var popperConfig = { placement: placement, modifiers: { offset: { offset: this.offset || 0 }, flip: { enabled: !this.noFlip } } }; var boundariesElement = this.boundary; if (boundariesElement) { popperConfig.modifiers.preventOverflow = { boundariesElement: boundariesElement }; } return mergeDeep(popperConfig, this.popperOpts || {}); }, // Turn listeners on/off while open whileOpenListen: function whileOpenListen(isOpen) { // Hide the dropdown when clicked outside this.listenForClickOut = isOpen; // Hide the dropdown when it loses focus this.listenForFocusIn = isOpen; // Hide the dropdown when another dropdown is opened var method = isOpen ? '$on' : '$off'; this.$root[method](ROOT_EVENT_SHOWN, this.rootCloseListener); }, rootCloseListener: function rootCloseListener(vm) { if (vm !== this) { this.visible = false; } }, // Public method to show dropdown show: function show() { var _this2 = this; if (this.disabled) { return; } // Wrap in a `requestAF()` to allow any previous // click handling to occur first requestAF(function () { _this2.visible = true; }); }, // Public method to hide dropdown hide: function hide() { var refocus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; /* istanbul ignore next */ if (this.disabled) { return; } this.visible = false; if (refocus) { // Child element is closing the dropdown on click this.$once('hidden', this.focusToggler); } }, // Called only by a button that toggles the menu toggle: function toggle(evt) { evt = evt || {}; // Early exit when not a click event or ENTER, SPACE or DOWN were pressed var _evt = evt, type = _evt.type, keyCode = _evt.keyCode; if (type !== 'click' && !(type === 'keydown' && [CODE_ENTER, CODE_SPACE, CODE_DOWN].indexOf(keyCode) !== -1)) { /* istanbul ignore next */ return; } /* istanbul ignore next */ if (this.disabled) { this.visible = false; return; } this.$emit('toggle', evt); stopEvent(evt); // Toggle visibility if (this.visible) { this.hide(true); } else { this.show(); } }, // Mousedown handler for the toggle /* istanbul ignore next */ onMousedown: function onMousedown(evt) { // We prevent the 'mousedown' event for the toggle to stop the // 'focusin' event from being fired // The event would otherwise be picked up by the global 'focusin' // listener and there is no cross-browser solution to detect it // relates to the toggle click // The 'click' event will still be fired and we handle closing // other dropdowns there too // See https://github.com/bootstrap-vue/bootstrap-vue/issues/4328 stopEvent(evt, { propagation: false }); }, // Called from dropdown menu context onKeydown: function onKeydown(evt) { var keyCode = evt.keyCode; if (keyCode === CODE_ESC) { // Close on ESC this.onEsc(evt); } else if (keyCode === CODE_DOWN) { // Down Arrow this.focusNext(evt, false); } else if (keyCode === CODE_UP) { // Up Arrow this.focusNext(evt, true); } }, // If user presses ESC, close the menu onEsc: function onEsc(evt) { if (this.visible) { this.visible = false; stopEvent(evt); // Return focus to original trigger button this.$once('hidden', this.focusToggler); } }, // Called only in split button mode, for the split button onSplitClick: function onSplitClick(evt) { /* istanbul ignore next */ if (this.disabled) { this.visible = false; return; } this.$emit('click', evt); }, // Shared hide handler between click-out and focus-in events hideHandler: function hideHandler(evt) { var _this3 = this; var target = evt.target; if (this.visible && !contains(this.$refs.menu, target) && !contains(this.toggler, target)) { this.clearHideTimeout(); this.$_hideTimeout = setTimeout(function () { return _this3.hide(); }, this.inNavbar ? 300 : 0); } }, // Document click-out listener clickOutHandler: function clickOutHandler(evt) { this.hideHandler(evt); }, // Document focus-in listener focusInHandler: function focusInHandler(evt) { this.hideHandler(evt); }, // Keyboard nav focusNext: function focusNext(evt, up) { var _this4 = this; // Ignore key up/down on form elements var target = evt.target; if (!this.visible || evt && closest(SELECTOR_FORM_CHILD, target)) { /* istanbul ignore next: should never happen */ return; } stopEvent(evt); this.$nextTick(function () { var items = _this4.getItems(); if (items.length < 1) { /* istanbul ignore next: should never happen */ return; } var index = items.indexOf(target); if (up && index > 0) { index--; } else if (!up && index < items.length - 1) { index++; } if (index < 0) { /* istanbul ignore next: should never happen */ index = 0; } _this4.focusItem(index, items); }); }, focusItem: function focusItem(index, items) { var el = items.find(function (el, i) { return i === index; }); attemptFocus(el); }, getItems: function getItems() { // Get all items return filterVisibles(selectAll(SELECTOR_ITEM, this.$refs.menu)); }, focusMenu: function focusMenu() { attemptFocus(this.$refs.menu); }, focusToggler: function focusToggler() { var _this5 = this; this.$nextTick(function () { attemptFocus(_this5.toggler); }); } } }; var props$n = makePropsConfigurable(_objectSpread2(_objectSpread2({}, props$m), {}, { text: { type: String // default: null }, html: { type: String // default: null }, variant: { type: String, default: 'secondary' }, size: { type: String // default: null }, block: { type: Boolean, default: false }, menuClass: { type: [String, Array, Object] // default: null }, toggleTag: { type: String, default: 'button' }, toggleText: { // TODO: This really should be `toggleLabel` type: String, default: 'Toggle dropdown' }, toggleClass: { type: [String, Array, Object] // default: null }, noCaret: { type: Boolean, default: false }, split: { type: Boolean, default: false }, splitHref: { type: String // default: undefined }, splitTo: { type: [String, Object] // default: undefined }, splitVariant: { type: String // default: undefined }, splitClass: { type: [String, Array, Object] // default: null }, splitButtonType: { type: String, default: 'button', validator: function validator(value) { return arrayIncludes(['button', 'submit', 'reset'], value); } }, lazy: { // If true, only render menu contents when open type: Boolean, default: false }, role: { type: String, default: 'menu' } }), NAME_DROPDOWN); // --- Main component --- // @vue/component var BDropdown = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN, mixins: [idMixin, dropdownMixin, normalizeSlotMixin], props: props$n, computed: { dropdownClasses: function dropdownClasses() { var block = this.block, split = this.split; return [this.directionClass, this.boundaryClass, { show: this.visible, // The 'btn-group' class is required in `split` mode for button alignment // It needs also to be applied when `block` is disabled to allow multiple // dropdowns to be aligned one line 'btn-group': split || !block, // When `block` is enabled and we are in `split` mode the 'd-flex' class // needs to be applied to allow the buttons to stretch to full width 'd-flex': block && split }]; }, menuClasses: function menuClasses() { return [this.menuClass, { 'dropdown-menu-right': this.right, show: this.visible }]; }, toggleClasses: function toggleClasses() { var split = this.split; return [this.toggleClass, { 'dropdown-toggle-split': split, 'dropdown-toggle-no-caret': this.noCaret && !split }]; } }, render: function render(h) { var visible = this.visible, variant = this.variant, size = this.size, block = this.block, disabled = this.disabled, split = this.split, role = this.role, hide = this.hide, toggle = this.toggle; var commonProps = { variant: variant, size: size, block: block, disabled: disabled }; var buttonContentSlotName = 'button-content'; var $buttonChildren = this.normalizeSlot(buttonContentSlotName); var buttonContentDomProps = this.hasNormalizedSlot(buttonContentSlotName) ? {} : htmlOrText(this.html, this.text); var $split = h(); if (split) { var splitTo = this.splitTo, splitHref = this.splitHref, splitButtonType = this.splitButtonType; var btnProps = _objectSpread2(_objectSpread2({}, commonProps), {}, { variant: this.splitVariant || variant }); // We add these as needed due to issues with // defined property with `undefined`/`null` values if (splitTo) { btnProps.to = splitTo; } else if (splitHref) { btnProps.href = splitHref; } else if (splitButtonType) { btnProps.type = splitButtonType; } $split = h(BButton, { class: this.splitClass, attrs: { id: this.safeId('_BV_button_') }, props: btnProps, domProps: buttonContentDomProps, on: { click: this.onSplitClick }, ref: 'button' }, $buttonChildren); // Overwrite button content for the toggle when in `split` mode $buttonChildren = [h('span', { class: ['sr-only'] }, [this.toggleText])]; buttonContentDomProps = {}; } var $toggle = h(BButton, { staticClass: 'dropdown-toggle', class: this.toggleClasses, attrs: { id: this.safeId('_BV_toggle_'), 'aria-haspopup': 'true', 'aria-expanded': toString$1(visible) }, props: _objectSpread2(_objectSpread2({}, commonProps), {}, { tag: this.toggleTag, block: block && !split }), domProps: buttonContentDomProps, on: { mousedown: this.onMousedown, click: toggle, keydown: toggle // Handle ENTER, SPACE and DOWN }, ref: 'toggle' }, $buttonChildren); var $menu = h('ul', { staticClass: 'dropdown-menu', class: this.menuClasses, attrs: { role: role, tabindex: '-1', 'aria-labelledby': this.safeId(split ? '_BV_button_' : '_BV_toggle_') }, on: { keydown: this.onKeydown // Handle UP, DOWN and ESC }, ref: 'menu' }, [!this.lazy || visible ? this.normalizeSlot(SLOT_NAME_DEFAULT, { hide: hide }) : h()]); return h('div', { staticClass: 'dropdown b-dropdown', class: this.dropdownClasses, attrs: { id: this.safeId() } }, [$split, $toggle, $menu]); } }); var props$o = omit(props$1, ['event', 'routerTag']); // @vue/component var BDropdownItem = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_ITEM, mixins: [attrsMixin, normalizeSlotMixin], inject: { bvDropdown: { default: null } }, inheritAttrs: false, props: makePropsConfigurable(_objectSpread2(_objectSpread2({}, props$o), {}, { linkClass: { type: [String, Array, Object] // default: null }, variant: { type: String // default: null } }), NAME_DROPDOWN_ITEM), computed: { computedAttrs: function computedAttrs() { return _objectSpread2(_objectSpread2({}, this.bvAttrs), {}, { role: 'menuitem' }); } }, methods: { closeDropdown: function closeDropdown() { var _this = this; // Close on next animation frame to allow time to process requestAF(function () { if (_this.bvDropdown) { _this.bvDropdown.hide(true); } }); }, onClick: function onClick(evt) { this.$emit('click', evt); this.closeDropdown(); } }, render: function render(h) { var linkClass = this.linkClass, variant = this.variant, active = this.active, disabled = this.disabled, onClick = this.onClick; return h('li', { attrs: { role: 'presentation' } }, [h(BLink, { staticClass: 'dropdown-item', class: [linkClass, _defineProperty({}, "text-".concat(variant), variant && !(active || disabled))], props: this.$props, attrs: this.computedAttrs, on: { click: onClick }, ref: 'item' }, this.normalizeSlot())]); } }); var props$p = makePropsConfigurable({ active: { type: Boolean, default: false }, activeClass: { type: String, default: 'active' }, buttonClass: { type: [String, Array, Object] // default: null }, disabled: { type: Boolean, default: false }, variant: { type: String // default: null } }, NAME_DROPDOWN_ITEM_BUTTON); // @vue/component var BDropdownItemButton = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_ITEM_BUTTON, mixins: [attrsMixin, normalizeSlotMixin], inject: { bvDropdown: { default: null } }, inheritAttrs: false, props: props$p, computed: { computedAttrs: function computedAttrs() { return _objectSpread2(_objectSpread2({}, this.bvAttrs), {}, { role: 'menuitem', type: 'button', disabled: this.disabled }); } }, methods: { closeDropdown: function closeDropdown() { if (this.bvDropdown) { this.bvDropdown.hide(true); } }, onClick: function onClick(evt) { this.$emit('click', evt); this.closeDropdown(); } }, render: function render(h) { var _ref; return h('li', { attrs: { role: 'presentation' } }, [h('button', { staticClass: 'dropdown-item', class: [this.buttonClass, (_ref = {}, _defineProperty(_ref, this.activeClass, this.active), _defineProperty(_ref, "text-".concat(this.variant), this.variant && !(this.active || this.disabled)), _ref)], attrs: this.computedAttrs, on: { click: this.onClick }, ref: 'button' }, this.normalizeSlot())]); } }); var props$q = makePropsConfigurable({ id: { type: String // default: null }, tag: { type: String, default: 'header' }, variant: { type: String // default: null } }, NAME_DROPDOWN_HEADER); // @vue/component var BDropdownHeader = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_HEADER, functional: true, props: props$q, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var $attrs = data.attrs || {}; data.attrs = {}; return h('li', a(data, { attrs: { role: 'presentation' } }), [h(props.tag, { staticClass: 'dropdown-header', class: _defineProperty({}, "text-".concat(props.variant), props.variant), attrs: _objectSpread2(_objectSpread2({}, $attrs), {}, { id: props.id || null, role: 'heading' }), ref: 'header' }, children)]); } }); var props$r = makePropsConfigurable({ tag: { type: String, default: 'hr' } }, NAME_DROPDOWN_DIVIDER); // @vue/component var BDropdownDivider = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_DIVIDER, functional: true, props: props$r, render: function render(h, _ref) { var props = _ref.props, data = _ref.data; var $attrs = data.attrs || {}; data.attrs = {}; return h('li', a(data, { attrs: { role: 'presentation' } }), [h(props.tag, { staticClass: 'dropdown-divider', attrs: _objectSpread2(_objectSpread2({}, $attrs), {}, { role: 'separator', 'aria-orientation': 'horizontal' }), ref: 'divider' })]); } }); var props$s = makePropsConfigurable({ id: { type: String // default: null }, inline: { type: Boolean, default: false }, novalidate: { type: Boolean, default: false }, validated: { type: Boolean, default: false } }, NAME_FORM); // @vue/component var BForm = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_FORM, functional: true, props: props$s, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h('form', a(data, { class: { 'form-inline': props.inline, 'was-validated': props.validated }, attrs: { id: props.id, novalidate: props.novalidate } }), children); } }); var BDropdownForm = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_FORM, functional: true, props: makePropsConfigurable(_objectSpread2(_objectSpread2({}, props$s), {}, { disabled: { type: Boolean, default: false }, formClass: { type: [String, Object, Array] // default: null } }), NAME_DROPDOWN_FORM), render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var $attrs = data.attrs || {}; var $listeners = data.on || {}; data.attrs = {}; data.on = {}; return h('li', a(data, { attrs: { role: 'presentation' } }), [h(BForm, { ref: 'form', staticClass: 'b-dropdown-form', class: [props.formClass, { disabled: props.disabled }], props: props, attrs: _objectSpread2(_objectSpread2({}, $attrs), {}, { disabled: props.disabled, // Tab index of -1 for keyboard navigation tabindex: props.disabled ? null : '-1' }), on: $listeners }, children)]); } }); var BDropdownText = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_TEXT, functional: true, props: makePropsConfigurable({ tag: { type: String, default: 'p' }, textClass: { type: [String, Array, Object] // default: null }, variant: { type: String // default: null } }, NAME_DROPDOWN_TEXT), render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; var tag = props.tag, textClass = props.textClass, variant = props.variant; var attrs = data.attrs || {}; data.attrs = {}; return h('li', a(data, { attrs: { role: 'presentation' } }), [h(tag, { staticClass: 'b-dropdown-text', class: [textClass, _defineProperty({}, "text-".concat(variant), variant)], props: props, attrs: attrs, ref: 'text' }, children)]); } }); var props$t = makePropsConfigurable({ id: { type: String // default: null }, header: { type: String // default: null }, headerTag: { type: String, default: 'header' }, headerVariant: { type: String // default: null }, headerClasses: { type: [String, Array, Object] // default: null }, ariaDescribedby: { type: String // default: null } }, NAME_DROPDOWN_GROUP); // @vue/component var BDropdownGroup = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_DROPDOWN_GROUP, functional: true, props: props$t, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, slots = _ref.slots, scopedSlots = _ref.scopedSlots; var $slots = slots(); var $scopedSlots = scopedSlots || {}; var $attrs = data.attrs || {}; data.attrs = {}; var header; var headerId = null; if (hasNormalizedSlot(SLOT_NAME_HEADER, $scopedSlots, $slots) || props.header) { headerId = props.id ? "_bv_".concat(props.id, "_group_dd_header") : null; header = h(props.headerTag, { staticClass: 'dropdown-header', class: [props.headerClasses, _defineProperty({}, "text-".concat(props.variant), props.variant)], attrs: { id: headerId, role: 'heading' } }, normalizeSlot(SLOT_NAME_HEADER, {}, $scopedSlots, $slots) || props.header); } var adb = [headerId, props.ariaDescribedBy].filter(identity).join(' ').trim(); return h('li', a(data, { attrs: { role: 'presentation' } }), [header || h(), h('ul', { staticClass: 'list-unstyled', attrs: _objectSpread2(_objectSpread2({}, $attrs), {}, { id: props.id || null, role: 'group', 'aria-describedby': adb || null }) }, normalizeSlot(SLOT_NAME_DEFAULT, {}, $scopedSlots, $slots))]); } }); var DropdownPlugin = /*#__PURE__*/pluginFactory({ components: { BDropdown: BDropdown, BDd: BDropdown, BDropdownItem: BDropdownItem, BDdItem: BDropdownItem, BDropdownItemButton: BDropdownItemButton, BDropdownItemBtn: BDropdownItemButton, BDdItemButton: BDropdownItemButton, BDdItemBtn: BDropdownItemButton, BDropdownHeader: BDropdownHeader, BDdHeader: BDropdownHeader, BDropdownDivider: BDropdownDivider, BDdDivider: BDropdownDivider, BDropdownForm: BDropdownForm, BDdForm: BDropdownForm, BDropdownText: BDropdownText, BDdText: BDropdownText, BDropdownGroup: BDropdownGroup, BDdGroup: BDropdownGroup } }); var TYPES = ['iframe', 'embed', 'video', 'object', 'img', 'b-img', 'b-img-lazy']; // --- Props --- var props$u = makePropsConfigurable({ type: { type: String, default: 'iframe', validator: function validator(value) { return arrayIncludes(TYPES, value); } }, tag: { type: String, default: 'div' }, aspect: { type: String, default: '16by9' } }, NAME_EMBED); // --- Main component --- // @vue/component var BEmbed = /*#__PURE__*/Vue__default['default'].extend({ name: NAME_EMBED, functional: true, props: props$u, render: function render(h, _ref) { var props = _ref.props, data = _ref.data, children = _ref.children; return h(props.tag, { ref: data.ref, staticClass: 'embed-responsive', class: _defineProperty({}, "embed-responsive-".concat(props.aspect), props.aspect) }, [h(props.type, a(data, { ref: '', staticClass: 'embed-responsive-item' }), children)]); } }); var EmbedPlugin = /*#__PURE__*/pluginFactory({ components: { BEmbed: BEmbed } }); var OPTIONS_OBJECT_DEPRECATED_MSG = 'Setting prop "options" to an object is deprecated. Use the array format instead.'; // --- Props --- var props$v = makePropsConfigurable({ options: { type: [Array, Object], default: function _default() { return []; } }, valueField: { type: String, default: 'value' }, textField: { type: String, default: 'text' }, htmlField: { type: String, default: 'html' }, disabledField: { type: String, default: 'disabled' } }, 'formOptionControls'); // --- Mixin --- // @vue/component var formOptionsMixin = { props: props$v, computed: { formOptions: function formOptions() { return this.normalizeOptions(this.options); } }, methods: { normalizeOption: function normalizeOption(option) { var key = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; // When the option is an object, normalize it if (isPlainObject(option)) { var value = get(option, this.valueField); var text = get(option, this.textField); return { value: isUndefined(value) ? key || text : value, text: stripTags(String(isUndefined(text) ? key : text)), html: get(option, this.htmlField), disabled: Boolean(get(option, this.disabledField)) }; } // Otherwise create an `