From 5ca843655778391316e8337c7e0f2568d93a6043 Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 16 Jun 2026 08:40:59 -0700 Subject: [PATCH 1/3] refactor: split monolithic source into modular ESM-ready fragments Split the ~3000-line bootstrap-select.js into 11 focused source files: - helpers.js (246 lines): DOM utilities, sanitizer, data parsing - search.js (166 lines): search/filter/normalization logic - constants.js (309 lines): keycodes, classnames, element templates - class.js (351 lines): constructor, event helpers, init, createDropdown - virtual-scroll.js (364 lines): virtual scroll/view management - data.js (309 lines): fetchData, buildData, buildList - render.js (443 lines): render, syncTagEditor, option UI - sizing.js (492 lines): liHeight, setSize, positioning, state mgmt - interaction.js (432 lines): click/search event listeners - api.js (579 lines): public API, keyboard nav, lifecycle, statics - runtime.js (72 lines): auto-init, global exposure control Added multi-format build support: - ESM (.mjs) for modern bundlers - CJS (.cjs) for Node.js require() - UMD (.js) for browser globals/CDN Updated package.json exports map, README, and docs with usage examples for all three consumption styles. All 22 tests passing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- Gruntfile.js | 36 +- README.md | 80 +- docs/content/index.md | 69 +- js/bootstrap-select.api.js | 579 ++++ js/bootstrap-select.class.js | 351 +++ js/bootstrap-select.constants.js | 309 ++ js/bootstrap-select.data.js | 309 ++ js/bootstrap-select.helpers.js | 246 ++ js/bootstrap-select.interaction.js | 432 +++ js/bootstrap-select.js | 3728 ------------------------- js/bootstrap-select.render.js | 443 +++ js/bootstrap-select.runtime.js | 72 + js/bootstrap-select.search.js | 166 ++ js/bootstrap-select.sizing.js | 492 ++++ js/bootstrap-select.virtual-scroll.js | 364 +++ js/cjs-intro.js | 13 + js/cjs-outro.js | 5 + js/esm-intro.js | 2 + js/umd-intro.js | 1 + package.json | 5 +- tests/e2e/module-import.spec.js | 78 +- tests/packaging.html | 13 + 22 files changed, 4047 insertions(+), 3746 deletions(-) create mode 100644 js/bootstrap-select.api.js create mode 100644 js/bootstrap-select.class.js create mode 100644 js/bootstrap-select.constants.js create mode 100644 js/bootstrap-select.data.js create mode 100644 js/bootstrap-select.helpers.js create mode 100644 js/bootstrap-select.interaction.js delete mode 100644 js/bootstrap-select.js create mode 100644 js/bootstrap-select.render.js create mode 100644 js/bootstrap-select.runtime.js create mode 100644 js/bootstrap-select.search.js create mode 100644 js/bootstrap-select.sizing.js create mode 100644 js/bootstrap-select.virtual-scroll.js create mode 100644 js/cjs-intro.js create mode 100644 js/cjs-outro.js create mode 100644 tests/packaging.html diff --git a/Gruntfile.js b/Gruntfile.js index ada3fe73..c84cb12c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,18 @@ module.exports = function (grunt) { + var jsSources = [ + 'js/bootstrap-select.helpers.js', + 'js/bootstrap-select.search.js', + 'js/bootstrap-select.constants.js', + 'js/bootstrap-select.class.js', + 'js/bootstrap-select.virtual-scroll.js', + 'js/bootstrap-select.data.js', + 'js/bootstrap-select.render.js', + 'js/bootstrap-select.sizing.js', + 'js/bootstrap-select.interaction.js', + 'js/bootstrap-select.api.js', + 'js/bootstrap-select.runtime.js' + ]; + function asArray (value) { return Array.isArray(value) ? value.reduce(function (result, item) { return result.concat(asArray(item)); @@ -45,11 +59,15 @@ module.exports = function (grunt) { }, main: { src: [ - 'js/*.js', + 'js/bootstrap-select.helpers.js', + 'js/bootstrap-select.search.js', + 'js/bootstrap-select.constants.js', '!js/umd-intro.js', '!js/umd-outro.js', '!js/esm-intro.js', - '!js/esm-outro.js' + '!js/esm-outro.js', + '!js/cjs-intro.js', + '!js/cjs-outro.js' ] }, i18n: { @@ -63,7 +81,7 @@ module.exports = function (grunt) { sourceMap: true }, main: { - src: 'js/bootstrap-select.js', + src: jsSources, dest: 'dist/js/bootstrap-select.js', options: { banner: '<%= banner %>\n' + grunt.file.read('js/umd-intro.js'), @@ -71,13 +89,21 @@ module.exports = function (grunt) { } }, esm: { - src: 'js/bootstrap-select.js', + src: jsSources, dest: 'dist/js/bootstrap-select.esm.mjs', options: { banner: '<%= banner %>\n' + grunt.file.read('js/esm-intro.js'), footer: grunt.file.read('js/esm-outro.js') } }, + cjs: { + src: jsSources, + dest: 'dist/js/bootstrap-select.cjs', + options: { + banner: '<%= banner %>\n' + grunt.file.read('js/cjs-intro.js'), + footer: grunt.file.read('js/cjs-outro.js') + } + }, i18n: { expand: true, src: '<%= eslint.i18n.src %>', @@ -197,7 +223,7 @@ module.exports = function (grunt) { prefix: 'Selectpicker.VERSION = \'' }, src: [ - 'js/bootstrap-select.js' + 'js/bootstrap-select.api.js' ] }, docs: { diff --git a/README.md b/README.md index 58a7663d..5d3df761 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ npm install @crestapps/bootstrap-select bootstrap ``` Load Bootstrap 5, then bootstrap-select's CSS and JS. **Load bootstrap-select -after Bootstrap's JavaScript.** +after Bootstrap's JavaScript** when using the browser-global build. ```html @@ -82,11 +82,79 @@ You can replace `@1.1.2` with the version you want to consume. During development, `@latest` also works, but a fixed version is safer for production deployments. -When loaded via a ` + + + + + + ``` ## Usage @@ -116,8 +184,8 @@ Existing bootstrap-select markup that uses `title="..."` placeholders or ### Via JavaScript -Initialize an instance with the `Selectpicker` class. You can pass an element or -a CSS selector string: +Initialize an instance with the `Selectpicker` class from your chosen module +style. You can pass an element or a CSS selector string: ```js // Initialize a single select diff --git a/docs/content/index.md b/docs/content/index.md index 216156d2..6c84840c 100644 --- a/docs/content/index.md +++ b/docs/content/index.md @@ -21,7 +21,7 @@ Install with [npm](https://www.npmjs.com/package/@crestapps/bootstrap-select): npm install @crestapps/bootstrap-select bootstrap ``` -Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript): +Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript when using the browser-global build): ```html @@ -54,11 +54,72 @@ Prefer pinning an explicit package version in production: You can replace `@1.1.2` with the version you want to consume. During development, `@latest` also works, but a fixed version is safer for production deployments. -When loaded via a ` + + + + + + ``` # Usage diff --git a/js/bootstrap-select.api.js b/js/bootstrap-select.api.js new file mode 100644 index 00000000..21be9132 --- /dev/null +++ b/js/bootstrap-select.api.js @@ -0,0 +1,579 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + val (value) { + var element = this.element; + + if (typeof value !== 'undefined') { + var selectedOptions = getSelectedOptions.call(this), + prevValue = getSelectValues.call(this, selectedOptions); + + changedArguments = [null, null, prevValue]; + + if (!Array.isArray(value)) value = [ value ]; + + value.map(String); + + for (var i = 0; i < selectedOptions.length; i++) { + var item = selectedOptions[i]; + + if (item && value.indexOf(String(item.value)) === -1) { + this.setSelected(item, false); + } + } + + // only update selected value if it matches an existing option + this.selectpicker.main.data.filter(function (item) { + if (value.indexOf(String(item.value)) !== -1) { + this.setSelected(item, true); + return true; + } + + return false; + }, this); + + if (this.options.source.data) element.appendChild(this.selectpicker.main.optionQueue); + + this._emit('changed', changedArguments ? { + clickedIndex: changedArguments[0], + isSelected: changedArguments[1], + previousValue: changedArguments[2] + } : null); + + if (this.newElement.classList.contains(classNames.SHOW)) { + if (this.multiple) { + this.setOptionStatus(true); + } else { + var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex; + + if (typeof liSelectedIndex === 'number') { + this.setSelected(this.selectpicker.current.data[liSelectedIndex], true); + } + } + } + + this.render(); + + changedArguments = null; + + return this.element; + } else { + return this.getValue(); + } + } + + changeAll (status) { + if (!this.multiple) return; + if (typeof status === 'undefined') status = true; + + var element = this.element, + previousSelected = 0, + currentSelected = 0, + prevValue = getSelectValues.call(this); + + element.classList.add('bs-select-hidden'); + + for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) { + var liData = data[i], + option = liData.option; + + if (option && !liData.disabled && liData.type !== 'divider') { + if (liData.selected) previousSelected++; + option.selected = status; + liData.selected = status; + if (status === true) currentSelected++; + } + } + + element.classList.remove('bs-select-hidden'); + + if (previousSelected === currentSelected) return; + + this.setOptionStatus(); + + changedArguments = [null, null, prevValue]; + + triggerNative(this.element, 'change'); + } + + selectAll () { + return this.changeAll(true); + } + + deselectAll () { + return this.changeAll(false); + } + + toggle (e, state) { + var isActive, + triggerToggle = state === undefined; + + if (e && e.stopPropagation) e.stopPropagation(); + + if (triggerToggle === false) { + isActive = this.newElement.classList.contains(classNames.SHOW); + triggerToggle = (state === true && isActive === false) || (state === false && isActive === true); + } + + if (triggerToggle) this.dropdown.toggle(); + } + + open (e) { + this.toggle(e, true); + } + + close (e) { + this.toggle(e, false); + } + + _keydown (e, el) { + var that = this, + which = e.which || e.keyCode, + isToggle = el.classList.contains('dropdown-toggle'), + items = that.findLis(), + index, + isActive, + liActive, + activeLi, + offsetVal, + updateScroll = false, + downOnTab = which === keyCodes.TAB && !isToggle && !that.options.selectOnTab, + isArrowKey = REGEXP_ARROW.test(which) || downOnTab, + scrollTop = that.menuInner.scrollTop, + isVirtual = that.isVirtual(), + position0 = isVirtual === true ? that.selectpicker.view.position0 : 0; + + // do nothing if a function key is pressed + if (which >= 112 && which <= 123) return; + + isActive = that.menu.classList.contains(classNames.SHOW); + + if ( + !isActive && + ( + isArrowKey || + (which >= 48 && which <= 57) || + (which >= 96 && which <= 105) || + (which >= 65 && which <= 90) + ) + ) { + that.dropdown.show(); + + if (that.options.liveSearch) { + that.searchbox.focus(); + return; + } + } + + if (which === keyCodes.ESCAPE && isActive) { + e.preventDefault(); + that.dropdown.hide(); + that.button.focus(); + } + + if (isArrowKey) { // if up or down + if (!items.length) return; + + liActive = that.activeElement; + index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1; + + if (index !== -1) { + that.defocusItem(liActive); + } + + if (which === keyCodes.ARROW_UP) { // up + if (index !== -1) index--; + if (index + position0 < 0) index += items.length; + + if (!that.selectpicker.view.canHighlight[index + position0]) { + index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0; + if (index === -1) index = items.length - 1; + } + } else if (which === keyCodes.ARROW_DOWN || downOnTab) { // down + index++; + if (index + position0 >= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex; + + if (!that.selectpicker.view.canHighlight[index + position0]) { + index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true); + } + } + + e.preventDefault(); + + var liActiveIndex = position0 + index; + + if (which === keyCodes.ARROW_UP) { // up + // scroll to bottom and highlight last option + if (position0 === 0 && index === items.length - 1) { + that.menuInner.scrollTop = that.menuInner.scrollHeight; + + liActiveIndex = that.selectpicker.current.elements.length - 1; + } else { + activeLi = that.selectpicker.current.data[liActiveIndex]; + + // could be undefined if no results exist + if (activeLi) { + offsetVal = activeLi.position - activeLi.height; + + updateScroll = offsetVal < scrollTop; + } + } + } else if (which === keyCodes.ARROW_DOWN || downOnTab) { // down + // scroll to top and highlight first option + if (index === that.selectpicker.view.firstHighlightIndex) { + that.menuInner.scrollTop = 0; + + liActiveIndex = that.selectpicker.view.firstHighlightIndex; + } else { + activeLi = that.selectpicker.current.data[liActiveIndex]; + + // could be undefined if no results exist + if (activeLi) { + offsetVal = activeLi.position - that.sizeInfo.menuInnerHeight; + + updateScroll = offsetVal > scrollTop; + } + } + } + + liActive = that.selectpicker.current.elements[liActiveIndex]; + + that.activeElement = (that.selectpicker.current.data[liActiveIndex] || {}).element; + + that.focusItem(liActive); + + that.selectpicker.view.currentActive = liActive; + + if (updateScroll) that.menuInner.scrollTop = offsetVal; + + if (that.options.liveSearch) { + that.searchbox.focus(); + } else { + el.focus(); + } + } else if ( + (!el.matches('input') && !REGEXP_TAB_OR_ESCAPE.test(which)) || + (which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory) + ) { + var matches = [], + keyHistory; + + e.preventDefault(); + + that.selectpicker.keydown.keyHistory += keyCodeMap[which]; + + if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel); + that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start(); + + keyHistory = that.selectpicker.keydown.keyHistory; + + // if all letters are the same, set keyHistory to just the first character when searching + if (/^(.)\1+$/.test(keyHistory)) { + keyHistory = keyHistory.charAt(0); + } + + // find matches + for (var i = 0; i < that.selectpicker.current.data.length; i++) { + var li = that.selectpicker.current.data[i], + hasMatch; + + hasMatch = stringSearch(li, keyHistory, 'startsWith', true); + + if (hasMatch && that.selectpicker.view.canHighlight[i]) { + matches.push(li.element); + } + } + + if (matches.length) { + var matchIndex = 0; + + Array.prototype.forEach.call(items, function (item) { + item.classList.remove('active'); + if (item.firstChild) item.firstChild.classList.remove('active'); + }); + + // either only one key has been pressed or they are all the same key + if (keyHistory.length === 1) { + matchIndex = matches.indexOf(that.activeElement); + + if (matchIndex === -1 || matchIndex === matches.length - 1) { + matchIndex = 0; + } else { + matchIndex++; + } + } + + activeLi = that.selectpicker.main.data[that.selectpicker.main.elements.indexOf(matches[matchIndex])]; + + if (activeLi) { + if (scrollTop - activeLi.position > 0) { + offsetVal = activeLi.position - activeLi.height; + updateScroll = true; + } else { + offsetVal = activeLi.position - that.sizeInfo.menuInnerHeight; + // if the option is already visible at the current scroll position, just keep it the same + updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight; + } + } + + liActive = matches[matchIndex]; + + that.activeElement = liActive; + + that.focusItem(liActive); + + if (liActive) liActive.firstChild.focus(); + + if (updateScroll) that.menuInner.scrollTop = offsetVal; + + el.focus(); + } + } + + // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. + if ( + isActive && + ( + (which === keyCodes.SPACE && !that.selectpicker.keydown.keyHistory) || + which === keyCodes.ENTER || + (which === keyCodes.TAB && that.options.selectOnTab) + ) + ) { + if (which !== keyCodes.SPACE) e.preventDefault(); + + if (!that.options.liveSearch || which !== keyCodes.SPACE) { + var activeAnchor = that.menuInner.querySelector('.active a'); + if (activeAnchor) that.onOptionClick(activeAnchor, e, true); // retain active class + el.focus(); + + if (!that.options.liveSearch) { + // Prevent screen from scrolling if the user hits the spacebar + e.preventDefault(); + // Fixes spacebar selection of dropdown items in FF & IE + spaceSelectFlag = true; + } + } + } + } + + mobile () { + // ensure mobile is set to true if mobile function is called after init + this.options.mobile = true; + this.element.classList.add('mobile-device'); + } + + resetMenuData () { + this.selectpicker.main.data = []; + this.selectpicker.main.elements = []; + this.selectpicker.main.hasMore = false; + this.selectpicker.search.data = []; + this.selectpicker.search.elements = []; + this.selectpicker.search.hasMore = false; + this.selectpicker.current.data = this.selectpicker.main.data; + this.selectpicker.current.elements = this.selectpicker.main.elements; + this.selectpicker.current.hasMore = false; + this.selectpicker.isSearching = false; + } + + refresh () { + var that = this; + // update options if data attributes have been changed + var config = stripRemovedOptions(Object.assign({}, this.options, getAttributesObject(this.element), getDataset(this.element))); + this.options = config; + + if (this.options.source.data) { + this.render(); + this.buildList(); + } else { + this.resetMenuData(); + this.fetchData(function () { + that.render(); + that.buildList(); + }); + } + + this.checkDisabled(); + this.setStyle(); + this.setWidth(); + + this.setSize(true); + + this._emit('refreshed'); + } + + hide () { + this.newElement.style.display = 'none'; + } + + show () { + this.newElement.style.display = ''; + } + + remove () { + if (this.newElement.parentNode) this.newElement.parentNode.removeChild(this.newElement); + instanceMap.delete(this.element); + } + + destroy () { + // move the select back out of newElement, then remove newElement + if (this.newElement.parentNode) { + this.newElement.parentNode.insertBefore(this.element, this.newElement); + this.newElement.parentNode.removeChild(this.newElement); + } + + if (this.bsContainer) { + if (this.bsContainer.parentNode) this.bsContainer.parentNode.removeChild(this.bsContainer); + } else if (this.menu && this.menu.parentNode) { + this.menu.parentNode.removeChild(this.menu); + } + + if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) { + this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption); + } + + // remove all tracked event listeners + for (var i = 0; i < this._listeners.length; i++) { + var l = this._listeners[i]; + l.el.removeEventListener(l.type, l.handler, l.options); + } + this._listeners = []; + + for (var key in this._named) { + if (Object.prototype.hasOwnProperty.call(this._named, key)) { + this._removeNamed(key); + } + } + + if (this.dropdown && typeof this.dropdown.dispose === 'function') { + this.dropdown.dispose(); + } + + this.element.classList.remove('bs-select-hidden', 'selectpicker', 'mobile-device'); + + instanceMap.delete(this.element); + } +} + +// stores element -> Selectpicker instance +var instanceMap = new WeakMap(); + +Selectpicker.NAME = 'selectpicker'; +Selectpicker.VERSION = '1.1.2'; + +// user-provided global defaults (set via Selectpicker.setDefaults, used by i18n files) +Selectpicker.defaults = null; + +// part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both. +Selectpicker.DEFAULTS = { + noneSelectedText: 'Nothing selected', + noneResultsText: 'No results matched {0}', + countSelectedText: function (numSelected) { + return (numSelected == 1) ? '{0} item selected' : '{0} items selected'; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', + (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' + ]; + }, + selectAllText: 'Select All', + deselectAllText: 'Deselect All', + source: { + pageSize: 40, + create: null + }, + chunkSize: 40, + doneButton: false, + doneButtonText: 'Close', + multipleSeparator: ', ', + style: classNames.BUTTONCLASS, + size: 'auto', + placeholder: null, + allowClear: false, + selectedTextFormat: 'values', + width: false, + hideDisabled: false, + showSubtext: false, + showIcon: true, + showContent: true, + dropupAuto: true, + header: false, + liveSearch: false, + liveSearchPlaceholder: null, + liveSearchNormalize: false, + liveSearchStyle: 'contains', + openOptions: false, + openOptionsText: 'Create "{0}"', + selectionIndicator: 'checkmark', + actionsBox: false, + iconBase: classNames.ICONBASE, + tickIcon: classNames.TICKICON, + showTick: false, + showSelectedTags: false, + selectedItemsStyle: 'tags', + selectedTagRemoveLabel: 'Remove', + template: { + caret: '' + }, + maxOptions: false, + selectOnTab: true, + dropdownAlignRight: false, + virtualScroll: 600, + sanitize: true, + sanitizeFn: null, + whiteList: DefaultWhitelist +}; + +Selectpicker._buildConfig = function (element, options) { + options = stripRemovedOptions(options || {}); + + var dataAttributes = stripRemovedOptions(getDataset(element)); + + for (var dataAttr in dataAttributes) { + if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { + delete dataAttributes[dataAttr]; + } + } + + var userDefaults = stripRemovedOptions(Selectpicker.defaults || {}); + + var config = Object.assign({}, Selectpicker.DEFAULTS, userDefaults, getAttributesObject(element), dataAttributes, options); + config.template = Object.assign({}, Selectpicker.DEFAULTS.template, userDefaults.template || {}, dataAttributes.template, options.template); + config.source = Object.assign({}, Selectpicker.DEFAULTS.source, userDefaults.source || {}, options.source); + + return applyLegacyOptions(element, config); +}; + +Selectpicker.setDefaults = function (newDefaults) { + Selectpicker.defaults = stripRemovedOptions(Object.assign({}, Selectpicker.defaults, newDefaults)); +}; + +Selectpicker.getInstance = function (element) { + if (typeof element === 'string') element = document.querySelector(element); + return instanceMap.get(element) || null; +}; + +Selectpicker.getOrCreateInstance = function (element, options) { + if (typeof element === 'string') element = document.querySelector(element); + if (!element || element.tagName !== 'SELECT') return null; + + var instance = instanceMap.get(element); + + if (instance) { + options = stripRemovedOptions(options); + + if (options && typeof options === 'object') { + for (var i in options) { + if (Object.prototype.hasOwnProperty.call(options, i)) { + instance.options[i] = options[i]; + } + } + } + + return instance; + } + + return new Selectpicker(element, typeof options === 'object' ? options : {}); +}; + +// Runtime wiring lives in js/bootstrap-select.runtime.js so each distribution +// can choose whether it should expose a browser global or stay module-scoped. diff --git a/js/bootstrap-select.class.js b/js/bootstrap-select.class.js new file mode 100644 index 00000000..f882f857 --- /dev/null +++ b/js/bootstrap-select.class.js @@ -0,0 +1,351 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + +class Selectpicker { + constructor (element, options) { + if (typeof element === 'string') { + element = document.querySelector(element); + } + + if (!element || element.tagName !== 'SELECT') { + throw new TypeError('Selectpicker requires a select element or selector.'); + } + + this.element = element; + this.newElement = null; + this.button = null; + this.menu = null; + this.options = Selectpicker._buildConfig(element, options || {}); + + // tracked event listeners for clean teardown + this._listeners = []; + this._named = {}; + + this.selectpicker = { + main: { + data: [], + optionQueue: elementTemplates.fragment.cloneNode(false), + hasMore: false + }, + search: { + data: [], + hasMore: false + }, + current: {}, // current is either equal to main or search depending on if a search is in progress + view: {}, + // map of option values and their respective data (only used in conjunction with options.source) + optionValuesDataMap: {}, + createdOptions: [], + openOption: { + isCreating: false + }, + isSearching: false, + keydown: { + keyHistory: '', + resetKeyHistory: { + start: () => { + return setTimeout(() => { + this.selectpicker.keydown.keyHistory = ''; + }, 800); + } + } + } + }; + + this.sizeInfo = {}; + + this.init(); + + instanceMap.set(element, this); + } + + // + _on (el, type, handler, options) { + el.addEventListener(type, handler, options); + this._listeners.push({ el: el, type: type, handler: handler, options: options }); + return handler; + } + + _delegate (el, type, selector, handler, options) { + var listener = function (e) { + var target = e.target.closest(selector); + if (target && el.contains(target)) { + handler.call(target, e); + } + }; + return this._on(el, type, listener, options); + } + + _emit (name, detail) { + var event = new CustomEvent(name + EVENT_KEY, { + bubbles: true, + cancelable: true, + detail: detail || null + }); + this.element.dispatchEvent(event); + return event; + } + + // adds an event listener that replaces any previously-registered listener under `key` + _replace (key, el, type, handler, options) { + this._removeNamed(key); + el.addEventListener(type, handler, options); + this._named[key] = { el: el, type: type, handler: handler, options: options }; + } + + _removeNamed (key) { + var prev = this._named[key]; + if (prev) { + prev.el.removeEventListener(prev.type, prev.handler, prev.options); + delete this._named[key]; + } + } + // + + init () { + var that = this, + id = this.element.getAttribute('id'), + element = this.element, + form = element.form; + + selectId++; + this.selectId = 'bs-select-' + selectId; + + element.classList.add('bs-select-hidden'); + + this.multiple = this.element.multiple; + this.autofocus = this.element.autofocus; + + if (element.classList.contains('show-tick')) { + this.options.showTick = true; + } + + this.newElement = this.createDropdown(); + + // insert newElement after element, then move element to be the first child of newElement + element.parentNode.insertBefore(this.newElement, element.nextSibling); + this.newElement.insertBefore(element, this.newElement.firstChild); + + // ensure select is associated with form element if it got unlinked after moving it inside newElement + if (form && element.form === null) { + if (!form.id) form.id = 'form-' + this.selectId; + element.setAttribute('form', form.id); + } + + this.button = this.newElement.querySelector(':scope > button'); + if (this.options.allowClear) this.clearButton = this.button.querySelector('.bs-select-clear-selected'); + this.menu = this.newElement.querySelector(':scope > ' + Selector.MENU); + this.menuInner = this.menu.querySelector('.inner'); + this.searchbox = this.menu.querySelector('input'); + this.selectedItems = this.newElement.querySelector(':scope > .bs-selected-items-external') || this.menu.querySelector('.bs-selected-items'); + this.createOptionButton = this.menu.querySelector('.bs-create-option'); + + element.classList.remove('bs-select-hidden'); + + this.fetchData(function () { + that.render(true); + that.buildList(); + + requestAnimationFrame(function () { + that._emit('loaded'); + }); + }); + + if (this.options.dropdownAlignRight === true) this.menu.classList.add(classNames.MENUEND); + + if (typeof id !== 'undefined' && id !== null) { + this.button.setAttribute('data-id', id); + } + + this.checkDisabled(); + this.clickListener(); + + var Dropdown = getDropdown(); + this.dropdown = new Dropdown(this.button); + + // store a reference to the instance for delegated handlers + this.newElement.bootstrapSelectInstance = this; + this.menu.bootstrapSelectInstance = this; + + if (this.options.liveSearch) { + this.liveSearchListener(); + this.focusedParent = this.searchbox; + } else { + this.focusedParent = this.menuInner; + } + + this.setStyle(); + this.setWidth(); + this._on(this.element, 'hide' + EVENT_KEY, function () { + if (that.isVirtual()) { + // empty menu on close + var menuInner = that.menuInner, + emptyMenu = menuInner.firstChild.cloneNode(false); + + // replace the existing UL with an empty one - this is faster than emptying it + menuInner.replaceChild(emptyMenu, menuInner.firstChild); + menuInner.scrollTop = 0; + } + }); + + // re-emit Bootstrap dropdown events as bootstrap-select events + this._on(this.newElement, 'hide.bs.dropdown', function (e) { + that._emit('hide', { bsEvent: e }); + }); + this._on(this.newElement, 'hidden.bs.dropdown', function (e) { + that._emit('hidden', { bsEvent: e }); + }); + this._on(this.newElement, 'show.bs.dropdown', function (e) { + that.onShow(e); + that._emit('show', { bsEvent: e }); + }); + this._on(this.newElement, 'shown.bs.dropdown', function (e) { + that._emit('shown', { bsEvent: e }); + }); + + if (element.hasAttribute('required')) { + this._on(this.element, 'invalid', function () { + that.button.classList.add('bs-invalid'); + + var onShownInvalid = function () { + // set the value to hide the validation message in Chrome when menu is opened + triggerNative(that.element, 'change'); + that.element.removeEventListener('shown' + EVENT_KEY, onShownInvalid); + }; + that._on(that.element, 'shown' + EVENT_KEY, onShownInvalid); + + var onRendered = function () { + // if select is no longer invalid, remove the bs-invalid class + if (that.element.validity.valid) that.button.classList.remove('bs-invalid'); + that.element.removeEventListener('rendered' + EVENT_KEY, onRendered); + }; + that._on(that.element, 'rendered' + EVENT_KEY, onRendered); + + var onBlur = function () { + that.element.focus(); + that.element.blur(); + that.button.removeEventListener('blur' + EVENT_KEY, onBlur); + }; + that._on(that.button, 'blur' + EVENT_KEY, onBlur); + }); + } + + if (form) { + this._on(form, 'reset', function () { + requestAnimationFrame(function () { + that.render(); + }); + }); + } + } + + createDropdown () { + // If we are multiple or showTick option is set, then add the show-tick class + var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '', + showSelectedTags = this.options.showSelectedTags ? ' show-selected-tags' : '', + selectedItemsStyle = this.options.selectedItemsStyle === 'list' ? ' selected-items-style-list' : '', + selectionIndicator = this.options.selectionIndicator === 'checkbox' ? ' selection-indicator-checkbox' : '', + multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', + autofocus = this.autofocus ? ' autofocus' : '', + liveSearchPlaceholder = this.options.liveSearchPlaceholder; + + if (liveSearchPlaceholder === null && (this.options.showSelectedTags || this.options.openOptions)) { + liveSearchPlaceholder = this.options.placeholder || 'Search'; + } + + // Elements + var drop, + header = '', + searchbox = '', + actionsbox = '', + donebutton = '', + clearButton = ''; + + if (this.options.header) { + header = + '
' + + '' + + this.options.header + + '
'; + } + + if (this.options.liveSearch) { + searchbox = + ''; + } + + if (this.multiple && this.options.actionsBox) { + actionsbox = + '
' + + '
' + + '' + + '' + + '
' + + '
'; + } + + if (this.multiple && this.options.doneButton) { + donebutton = + '
' + + '
' + + '' + + '
' + + '
'; + } + + if (this.options.allowClear) { + clearButton = '×'; + } + + drop = + ''; + + return createFromHTML(drop); + } + diff --git a/js/bootstrap-select.constants.js b/js/bootstrap-select.constants.js new file mode 100644 index 00000000..5bb6e452 --- /dev/null +++ b/js/bootstrap-select.constants.js @@ -0,0 +1,309 @@ +/* eslint-disable no-undef, no-unused-vars */ +// Shared ordered source fragment consumed by the Grunt JS build. + +// +var keyCodeMap = { + 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', + 55: '7', 56: '8', 57: '9', 59: ';', + 65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H', + 73: 'I', 74: 'J', 75: 'K', 76: 'L', 77: 'M', 78: 'N', 79: 'O', 80: 'P', + 81: 'Q', 82: 'R', 83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', + 89: 'Y', 90: 'Z', + 96: '0', 97: '1', 98: '2', 99: '3', 100: '4', 101: '5', 102: '6', + 103: '7', 104: '8', 105: '9' +}; + +var keyCodes = { + ESCAPE: 27, + ENTER: 13, + SPACE: 32, + TAB: 9, + ARROW_UP: 38, + ARROW_DOWN: 40 +}; + +var selectId = 0; + +var EVENT_KEY = '.bs.select'; + +// Bootstrap 5 class names. +var classNames = { + DISABLED: 'disabled', + DIVIDER: 'dropdown-divider', + SHOW: 'show', + DROPUP: 'dropup', + MENU: 'dropdown-menu', + MENUEND: 'dropdown-menu-end', + BUTTONCLASS: 'btn-light', + POPOVERHEADER: 'popover-header', + ICONBASE: '', + TICKICON: 'bs-ok-default' +}; + +var Selector = { + MENU: '.' + classNames.MENU, + DATA_TOGGLE: 'data-bs-toggle="dropdown"' +}; + +var elementTemplates = { + div: document.createElement('div'), + span: document.createElement('span'), + i: document.createElement('i'), + subtext: document.createElement('small'), + a: document.createElement('a'), + li: document.createElement('li'), + whitespace: document.createTextNode('\u00A0'), + fragment: document.createDocumentFragment(), + option: document.createElement('option') +}; + +elementTemplates.selectedOption = elementTemplates.option.cloneNode(false); +elementTemplates.selectedOption.setAttribute('selected', true); + +elementTemplates.noResults = elementTemplates.li.cloneNode(false); +elementTemplates.noResults.className = 'no-results'; + +elementTemplates.a.setAttribute('role', 'option'); +elementTemplates.a.className = 'dropdown-item'; + +elementTemplates.subtext.className = 'text-muted'; + +elementTemplates.text = elementTemplates.span.cloneNode(false); +elementTemplates.text.className = 'text'; + +elementTemplates.checkMark = elementTemplates.span.cloneNode(false); + +var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN); +var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE); + +var generateOption = { + li: function (content, classes, optgroup) { + var li = elementTemplates.li.cloneNode(false); + + if (content) { + if (content.nodeType === 1 || content.nodeType === 11) { + li.appendChild(content); + } else { + li.innerHTML = content; + } + } + + if (typeof classes !== 'undefined' && classes !== '') li.className = classes; + if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup); + + return li; + }, + + a: function (text, classes, inline) { + var a = elementTemplates.a.cloneNode(true); + + if (text) { + if (text.nodeType === 11) { + a.appendChild(text); + } else { + a.insertAdjacentHTML('beforeend', text); + } + } + + if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/)); + if (inline) a.setAttribute('style', inline); + + return a; + }, + + text: function (options, useFragment) { + var textElement = elementTemplates.text.cloneNode(false), + subtextElement, + iconElement; + + if (options.content) { + textElement.innerHTML = options.content; + } else { + textElement.textContent = options.text; + + if (options.icon) { + var whitespace = elementTemplates.whitespace.cloneNode(false); + + // need to use for icons in the button to prevent a breaking change + iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false); + iconElement.className = this.options.iconBase + ' ' + options.icon; + + elementTemplates.fragment.appendChild(iconElement); + elementTemplates.fragment.appendChild(whitespace); + } + + if (options.subtext) { + subtextElement = elementTemplates.subtext.cloneNode(false); + subtextElement.textContent = options.subtext; + textElement.appendChild(subtextElement); + } + } + + if (useFragment === true) { + while (textElement.childNodes.length > 0) { + elementTemplates.fragment.appendChild(textElement.childNodes[0]); + } + } else { + elementTemplates.fragment.appendChild(textElement); + } + + return elementTemplates.fragment; + }, + + label: function (options) { + var textElement = elementTemplates.text.cloneNode(false), + subtextElement, + iconElement; + + textElement.innerHTML = options.display; + + if (options.icon) { + var whitespace = elementTemplates.whitespace.cloneNode(false); + + iconElement = elementTemplates.span.cloneNode(false); + iconElement.className = this.options.iconBase + ' ' + options.icon; + + elementTemplates.fragment.appendChild(iconElement); + elementTemplates.fragment.appendChild(whitespace); + } + + if (options.subtext) { + subtextElement = elementTemplates.subtext.cloneNode(false); + subtextElement.textContent = options.subtext; + textElement.appendChild(subtextElement); + } + + elementTemplates.fragment.appendChild(textElement); + + return elementTemplates.fragment; + } +}; + +var getOptionData = { + fromOption: function (option, type) { + var value; + + switch (type) { + case 'divider': + value = option.getAttribute('data-divider') === 'true'; + break; + + case 'text': + value = option.textContent; + break; + + case 'label': + value = option.label; + break; + + case 'style': + value = option.style.cssText; + break; + + case 'title': + value = option.title; + break; + + default: + value = option.getAttribute('data-' + toKebabCase(type)); + break; + } + + return value; + }, + fromDataSource: function (option, type) { + var value; + + switch (type) { + case 'text': + case 'label': + value = option.text || option.value || ''; + break; + + default: + value = option[type]; + break; + } + + return value; + } +}; + +function showNoResults (searchMatch, searchValue) { + if (!searchMatch.length) { + elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"'); + this.menuInner.firstChild.appendChild(elementTemplates.noResults); + } +} + +function filterHidden (item) { + return !(item.hidden || this.options.hideDisabled && item.disabled); +} + +function getSelectedOptions () { + var options = this.selectpicker.main.data; + + if (this.options.source.data || this.options.source.search) { + options = Object.values(this.selectpicker.optionValuesDataMap); + } + + var selectedOptions = options.filter(function (item) { + if (item.selected) { + if (this.options.hideDisabled && item.disabled) return false; + return true; + } + + return false; + }, this); + + // ensure only 1 option is selected if multiple are set in the data source + if (this.options.source.data && !this.multiple && selectedOptions.length > 1) { + for (var i = 0; i < selectedOptions.length - 1; i++) { + selectedOptions[i].selected = false; + } + + selectedOptions = [ selectedOptions[selectedOptions.length - 1] ]; + } + + return selectedOptions; +} + +function getSelectValues (selectedOptions) { + var value = [], + options = selectedOptions || getSelectedOptions.call(this), + opt; + + for (var i = 0, len = options.length; i < len; i++) { + opt = options[i]; + + if (!opt.disabled) { + value.push(opt.value === undefined ? opt.text : opt.value); + } + } + + if (!this.multiple) { + return !value.length ? null : value[0]; + } + + return value; +} +// + +var changedArguments = null; + +// shared flag for spacebar selection handling (mirrors original document data flag) +var spaceSelectFlag = false; + +var REMOVED_OPTIONS = ['container', 'display', 'mobile', 'styleBase', 'windowPadding']; + +function stripRemovedOptions (source) { + if (!source || typeof source !== 'object') return source; + + var result = Object.assign({}, source); + + for (var i = 0; i < REMOVED_OPTIONS.length; i++) { + delete result[REMOVED_OPTIONS[i]]; + } + + return result; +} diff --git a/js/bootstrap-select.data.js b/js/bootstrap-select.data.js new file mode 100644 index 00000000..e15b46e2 --- /dev/null +++ b/js/bootstrap-select.data.js @@ -0,0 +1,309 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + fetchData (callback, type, page, searchValue) { + page = page || 1; + type = type || 'data'; + + var that = this, + data = this.options.source[type], + builtData; + + if (data) { + this.options.virtualScroll = true; + + if (typeof data === 'function') { + data.call( + this, + function (data, more, totalItems) { + var current = that.selectpicker[type === 'search' ? 'search' : 'main']; + current.hasMore = more; + current.totalItems = totalItems; + builtData = that.buildData(data, type); + callback.call(that, builtData); + that._emit('fetched'); + }, + page, + searchValue + ); + } else if (Array.isArray(data)) { + builtData = that.buildData(data, type); + callback.call(that, builtData); + } + } else { + builtData = this.buildData(false, type); + callback.call(that, builtData); + } + } + + buildData (data, type) { + var that = this; + var dataGetter = data === false ? getOptionData.fromOption : getOptionData.fromDataSource; + + var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([style*="display: none"])', + mainData = [], + startLen = this.selectpicker.main.data ? this.selectpicker.main.data.length : 0, + optID = 0, + startIndex = this.setPlaceholder() && !data ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop + + if (type === 'search') { + startLen = this.selectpicker.search.data.length; + } + + if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; + + var selectOptions = data ? data.filter(filterHidden, this) : this.element.querySelectorAll('select > *' + optionSelector); + + function addDivider (config) { + var previousData = mainData[mainData.length - 1]; + + // ensure optgroup doesn't create back-to-back dividers + if ( + previousData && + previousData.type === 'divider' && + (previousData.optID || config.optID) + ) { + return; + } + + config = config || {}; + config.type = 'divider'; + + mainData.push(config); + } + + function addOption (item, config) { + config = config || {}; + + config.divider = dataGetter(item, 'divider'); + + if (config.divider === true) { + addDivider({ + optID: config.optID + }); + } else { + var liIndex = mainData.length + startLen, + cssText = dataGetter(item, 'style'), + inlineStyle = cssText ? htmlEscape(cssText) : '', + optionClass = (item.className || '') + (config.optgroupClass || ''); + + if (config.optID) optionClass = 'opt ' + optionClass; + + config.optionClass = optionClass.trim(); + config.inlineStyle = inlineStyle; + + config.text = dataGetter(item, 'text'); + config.title = dataGetter(item, 'title'); + config.content = dataGetter(item, 'content'); + config.tokens = dataGetter(item, 'tokens'); + config.subtext = dataGetter(item, 'subtext'); + config.icon = dataGetter(item, 'icon'); + + config.display = config.content || config.text; + config.value = item.value === undefined ? item.text : item.value; + config.type = 'option'; + config.index = liIndex; + + config.option = !item.option ? item : item.option; // reference option element if it exists + config.option.liIndex = liIndex; + config.selected = !!item.selected; + config.disabled = config.disabled || !!item.disabled; + + if (data !== false) { + if (that.selectpicker.optionValuesDataMap[config.value]) { + config = Object.assign(that.selectpicker.optionValuesDataMap[config.value], config); + } else { + that.selectpicker.optionValuesDataMap[config.value] = config; + } + } + + mainData.push(config); + } + } + + function addOptgroup (index, selectOptions) { + var optgroup = selectOptions[index], + // skip placeholder option + previous = index - 1 < startIndex ? false : selectOptions[index - 1], + next = selectOptions[index + 1], + options = data ? optgroup.children.filter(filterHidden, this) : optgroup.querySelectorAll('option' + optionSelector); + + if (!options.length) return; + + var config = { + display: htmlEscape(dataGetter(item, 'label')), + subtext: dataGetter(optgroup, 'subtext'), + icon: dataGetter(optgroup, 'icon'), + type: 'optgroup-label', + optgroupClass: ' ' + (optgroup.className || ''), + optgroup: optgroup + }, + headerIndex, + lastIndex; + + optID++; + + if (previous) { + addDivider({ optID: optID }); + } + + config.optID = optID; + + mainData.push(config); + + for (var j = 0, len = options.length; j < len; j++) { + var option = options[j]; + + if (j === 0) { + headerIndex = mainData.length - 1; + lastIndex = headerIndex + len; + } + + addOption(option, { + headerIndex: headerIndex, + lastIndex: lastIndex, + optID: config.optID, + optgroupClass: config.optgroupClass, + disabled: optgroup.disabled + }); + } + + if (next) { + addDivider({ optID: optID }); + } + } + + var item; + + for (var len = selectOptions.length, i = startIndex; i < len; i++) { + item = selectOptions[i]; + var children = item.children; + + if (children && children.length) { + addOptgroup.call(this, i, selectOptions); + } else { + addOption.call(this, item, {}); + } + } + + switch (type) { + case 'data': { + if (!this.selectpicker.main.data) { + this.selectpicker.main.data = []; + } + Array.prototype.push.apply(this.selectpicker.main.data, mainData); + this.selectpicker.current.data = this.selectpicker.main.data; + break; + } + case 'search': { + Array.prototype.push.apply(this.selectpicker.search.data, mainData); + break; + } + } + + return mainData; + } + + buildList (size, searching) { + var that = this, + selectData = searching ? this.selectpicker.search.data : this.selectpicker.main.data, + mainElements = [], + widestOptionLength = 0; + + if (that.options.showTick || that.multiple) { + elementTemplates.checkMark.className = this.options.selectionIndicator === 'checkbox' + ? 'check-mark bs-selection-indicator' + : this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark'; + + if (!elementTemplates.checkMark.parentNode) { + elementTemplates.a.appendChild(elementTemplates.checkMark); + } + } + + function buildElement (mainElements, item) { + var liElement, + combinedLength = 0; + + switch (item.type) { + case 'divider': + liElement = generateOption.li( + false, + classNames.DIVIDER, + (item.optID ? item.optID + 'div' : undefined) + ); + + break; + + case 'option': + liElement = generateOption.li( + generateOption.a( + generateOption.text.call(that, item), + item.optionClass, + item.inlineStyle + ), + '', + item.optID + ); + + if (liElement.firstChild) { + liElement.firstChild.id = that.selectId + '-' + item.index; + } + + break; + + case 'optgroup-label': + liElement = generateOption.li( + generateOption.label.call(that, item), + 'dropdown-header' + item.optgroupClass, + item.optID + ); + + break; + } + + if (item.content) item.sanitized = false; + + if (!item.element) { + item.element = liElement; + } else { + item.element.innerHTML = liElement.innerHTML; + } + mainElements.push(item.element); + + // count the number of characters in the option - not perfect, but should work in most cases + if (item.display) combinedLength += item.display.length; + if (item.subtext) combinedLength += item.subtext.length; + // if there is an icon, ensure this option's width is checked + if (item.icon) combinedLength += 1; + + if (combinedLength > widestOptionLength) { + widestOptionLength = combinedLength; + + // guess which option is the widest + that.selectpicker.view.widestOption = mainElements[mainElements.length - 1]; + } + } + + var startIndex = size || 0; + + for (var len = selectData.length, i = startIndex; i < len; i++) { + var item = selectData[i]; + + buildElement(mainElements, item); + } + + if (size) { + if (searching) { + Array.prototype.push.apply(this.selectpicker.search.elements, mainElements); + } else { + Array.prototype.push.apply(this.selectpicker.main.elements, mainElements); + this.selectpicker.current.elements = this.selectpicker.main.elements; + } + } else { + if (searching) { + this.selectpicker.search.elements = mainElements; + } else { + this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements; + } + } + } + diff --git a/js/bootstrap-select.helpers.js b/js/bootstrap-select.helpers.js new file mode 100644 index 00000000..4042dfa7 --- /dev/null +++ b/js/bootstrap-select.helpers.js @@ -0,0 +1,246 @@ +/* eslint-disable no-unused-vars */ +// Shared ordered source fragment consumed by the Grunt JS build. + +'use strict'; + +// Resolve Bootstrap's Dropdown component (Bootstrap 5+). It may be provided +// by the UMD factory (`bootstrap`), or available as a global. +function getDropdown () { + var bs = bootstrap || (typeof window !== 'undefined' ? window.bootstrap : undefined); + return (bs && bs.Dropdown) || (typeof window !== 'undefined' ? window.Dropdown : undefined); +} + +// +function createFromHTML (html) { + var wrapper = document.createElement('div'); + wrapper.innerHTML = html.trim(); + return wrapper.firstChild; +} + +function toInteger (value) { + return parseInt(value, 10) || 0; +} + +function offset (el) { + var rect = el.getBoundingClientRect(); + return { + top: rect.top + window.pageYOffset, + left: rect.left + window.pageXOffset + }; +} + +// Resolves a container option (selector string or element) to an element. +function resolveContainer (container) { + if (!container) return null; + return typeof container === 'string' ? document.querySelector(container) : container; +} + +function outerHeight (el, includeMargin) { + var height = el.offsetHeight; + if (includeMargin) { + var style = window.getComputedStyle(el); + height += toInteger(style.marginTop) + toInteger(style.marginBottom); + } + return height; +} + +function setStyles (el, styles) { + for (var prop in styles) { + if (Object.prototype.hasOwnProperty.call(styles, prop)) { + el.style[prop] = styles[prop]; + } + } +} + +function triggerNative (el, eventName) { + el.dispatchEvent(new Event(eventName, { bubbles: true })); +} + +// shallow array comparison +function isEqual (array1, array2) { + return array1.length === array2.length && array1.every(function (element, index) { + return element === array2[index]; + }); +} + +function toKebabCase (str) { + return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) { + return (ofs ? '-' : '') + $.toLowerCase(); + }); +} + +function toCamelCase (str) { + return str.replace(/-([a-z])/g, function (m, letter) { + return letter.toUpperCase(); + }); +} + +// Read options from data-* attributes using native values where possible. +function convertDataValue (value) { + if (value === 'true') return true; + if (value === 'false') return false; + if (value === 'null') return null; + if (value === +value + '') return +value; + if (/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/.test(value)) { + try { + return JSON.parse(value); + } catch (e) { + return value; + } + } + return value; +} + +function getDataset (el) { + var dataset = {}, + attributes = el.attributes; + + for (var i = 0; i < attributes.length; i++) { + var name = attributes[i].name; + if (name.indexOf('data-') === 0) { + dataset[toCamelCase(name.slice(5))] = convertDataValue(attributes[i].value); + } + } + + return dataset; +} +// + +// +var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; + +var uriAttrs = [ + 'background', + 'cite', + 'href', + 'itemtype', + 'longdesc', + 'poster', + 'src', + 'xlink:href' +]; + +var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; + +var DefaultWhitelist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] +}; + +// A pattern that recognizes a commonly useful subset of URLs that are safe. +var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; + +// A pattern that matches safe data URLs. Only matches image, video and audio types. +var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; + +var ParseableAttributes = ['placeholder']; // attributes to use as settings, can add others in the future + +function applyLegacyOptions (element, config) { + if (!config.placeholder) { + var title = element.getAttribute('title'); + if (title) config.placeholder = title; + } + + return config; +} + +function allowedAttribute (attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase(); + + if (allowedAttributeList.indexOf(attrName) !== -1) { + if (uriAttrs.indexOf(attrName) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); + } + + return true; + } + + var regExp = allowedAttributeList.filter(function (value) { + return value instanceof RegExp; + }); + + // Check if a regular expression validates the attribute. + for (var i = 0, l = regExp.length; i < l; i++) { + if (attrName.match(regExp[i])) { + return true; + } + } + + return false; +} + +function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) { + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeElements); + } + + var whitelistKeys = Object.keys(whiteList); + + for (var i = 0, len = unsafeElements.length; i < len; i++) { + var elements = unsafeElements[i].querySelectorAll('*'); + + for (var j = 0, len2 = elements.length; j < len2; j++) { + var el = elements[j]; + var elName = el.nodeName.toLowerCase(); + + if (whitelistKeys.indexOf(elName) === -1) { + el.parentNode.removeChild(el); + + continue; + } + + var attributeList = [].slice.call(el.attributes); + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); + + for (var k = 0, len3 = attributeList.length; k < len3; k++) { + var attr = attributeList[k]; + + if (!allowedAttribute(attr, whitelistedAttributes)) { + el.removeAttribute(attr.nodeName); + } + } + } + } +} +// + +function getAttributesObject (element) { + var attributesObject = {}, + attrVal; + + ParseableAttributes.forEach(function (item) { + attrVal = element.getAttribute(item); + if (attrVal) attributesObject[item] = attrVal; + }); + + return attributesObject; +} diff --git a/js/bootstrap-select.interaction.js b/js/bootstrap-select.interaction.js new file mode 100644 index 00000000..78ec5f0d --- /dev/null +++ b/js/bootstrap-select.interaction.js @@ -0,0 +1,432 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + clickListener () { + var that = this; + + spaceSelectFlag = false; + + this._on(this.button, 'keyup', function (e) { + if (/(32)/.test(e.keyCode.toString(10)) && spaceSelectFlag) { + e.preventDefault(); + spaceSelectFlag = false; + } + }); + + function clearSelection (e) { + if (that.multiple) { + that.deselectAll(); + } else { + var element = that.element, + prevValue = element.value, + prevIndex = element.selectedIndex, + prevOption = element.options[prevIndex], + prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false; + + if (prevData) { + that.setSelected(prevData, false); + } + + element.selectedIndex = 0; + + changedArguments = [prevIndex, false, prevValue]; + triggerNative(that.element, 'change'); + } + + // remove selected styling if menu is open + if (that.newElement.classList.contains(classNames.SHOW)) { + if (that.options.liveSearch) { + that.searchbox.focus(); + } + + that.createView(false); + } + } + + if (this.options.allowClear) { + this._on(this.button, 'click', function (e) { + var target = e.target, + clearButton = that.clearButton; + + if (target === clearButton || target.parentElement === clearButton) { + e.stopImmediatePropagation(); + clearSelection(e); + } + }); + } + + function setFocus () { + if (that.options.liveSearch) { + that.searchbox.focus(); + } else { + that.menuInner.focus(); + } + } + + function checkPopperExists () { + if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state) { + setFocus(); + } else { + requestAnimationFrame(checkPopperExists); + } + } + + this._on(this.element, 'shown' + EVENT_KEY, function () { + if (that.menuInner.scrollTop !== that.selectpicker.view.scrollTop) { + that.menuInner.scrollTop = that.selectpicker.view.scrollTop; + } + + requestAnimationFrame(checkPopperExists); + }); + + // ensure posinset and setsize are correct before selecting an option via a click + this._delegate(this.menuInner, 'mouseover', 'li a', function () { + var hoverLi = this.parentElement, + position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, + index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi), + hoverData = that.selectpicker.current.data[index + position0]; + + that.focusItem(hoverLi, hoverData, true); + }); + + this._delegate(this.menuInner, 'click', 'li a', function (e) { + that.onOptionClick(this, e); + }); + + this._delegate(this.menu, 'click', 'li.' + classNames.DISABLED + ' a, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.btn-close):not(.close)', function (e) { + if (e.currentTarget === this || e.target === this) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch && !e.target.classList.contains('btn-close') && !e.target.classList.contains('close')) { + that.searchbox.focus(); + } else { + that.button.focus(); + } + } + }); + + this._delegate(this.menuInner, 'click', '.divider, .dropdown-header', function (e) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch) { + that.searchbox.focus(); + } else { + that.button.focus(); + } + }); + + this._delegate(this.menu, 'click', '.' + classNames.POPOVERHEADER + ' .btn-close, .' + classNames.POPOVERHEADER + ' .close', function () { + that.dropdown.hide(); + }); + + this._delegate(this.newElement, 'click', '.bs-selected-item', function (e) { + e.preventDefault(); + e.stopPropagation(); + that.removeSelectedTag(this.getAttribute('data-option-value')); + }); + + this._delegate(this.menu, 'click', '.bs-create-option', function (e) { + e.preventDefault(); + e.stopPropagation(); + that.createOpenOption(this.getAttribute('data-search-value')); + }); + + if (this.searchbox) { + this._on(this.searchbox, 'click', function (e) { + e.stopPropagation(); + }); + } + + this._delegate(this.menu, 'click', '.actions-btn', function (e) { + if (that.options.liveSearch) { + that.searchbox.focus(); + } else { + that.button.focus(); + } + + e.preventDefault(); + e.stopPropagation(); + + if (this.classList.contains('bs-select-all')) { + that.selectAll(); + } else { + that.deselectAll(); + } + }); + + this._on(this.button, 'focus', function (e) { + var tabindex = that.element.getAttribute('tabindex'); + + // only change when button is actually focused + if (tabindex !== undefined && tabindex !== null && e.isTrusted) { + // apply select element's tabindex to ensure correct order is followed when tabbing to the next element + this.setAttribute('tabindex', tabindex); + // set element's tabindex to -1 to allow for reverse tabbing + that.element.setAttribute('tabindex', -1); + that.selectpicker.view.tabindex = tabindex; + } + }); + + this._on(this.button, 'blur', function (e) { + // revert everything to original tabindex + if (that.selectpicker.view.tabindex !== undefined && e.isTrusted) { + that.element.setAttribute('tabindex', that.selectpicker.view.tabindex); + this.setAttribute('tabindex', -1); + that.selectpicker.view.tabindex = undefined; + } + }); + + this._on(this.element, 'change', function () { + that.render(); + that._emit('changed', changedArguments ? { + clickedIndex: changedArguments[0], + isSelected: changedArguments[1], + previousValue: changedArguments[2] + } : null); + changedArguments = null; + }); + + this._on(this.element, 'focus', function () { + if (!that.options.mobile) that.button.focus(); + }); + } + + onOptionClick (clickedAnchor, e, retainActive) { + var that = this, + element = that.element, + li = clickedAnchor.parentElement, + position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, + clickedData = that.selectpicker.current.data[Array.prototype.indexOf.call(li.parentElement.children, li) + position0], + clickedElement = clickedData.element, + prevValue = getSelectValues.call(that), + prevIndex = element.selectedIndex, + prevOption = element.options[prevIndex], + prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false, + triggerChange = true; + + // Don't close on multi choice menu + if (that.multiple && that.options.maxOptions !== 1) { + e.stopPropagation(); + } + + e.preventDefault(); + + // Don't run if the select is disabled + if (!that.isDisabled() && !li.classList.contains(classNames.DISABLED)) { + var option = clickedData.option, + state = option.selected, + optgroupData = that.selectpicker.current.data.find(function (datum) { + return datum.optID === clickedData.optID && datum.type === 'optgroup-label'; + }), + optgroup = optgroupData ? optgroupData.optgroup : undefined, + dataGetter = optgroup instanceof Element ? getOptionData.fromOption : getOptionData.fromDataSource, + optgroupOptions = optgroup && optgroup.children, + maxOptions = parseInt(that.options.maxOptions), + maxOptionsGrp = optgroup && parseInt(dataGetter(optgroup, 'maxOptions')) || false; + + if (clickedElement === that.activeElement) retainActive = true; + + if (!retainActive) { + that.prevActiveElement = that.activeElement; + that.activeElement = undefined; + } + + if (!that.multiple || maxOptions === 1) { // Deselect previous option if not multi select + if (prevData) that.setSelected(prevData, false); + that.setSelected(clickedData, true); + } else { // Toggle the clicked option if multi select. + that.setSelected(clickedData, !state); + that.focusedParent.focus(); + + if (maxOptions !== false || maxOptionsGrp !== false) { + var maxReached = maxOptions < getSelectedOptions.call(that).length, + selectedGroupOptions = 0; + + if (optgroup && optgroup.children) { + for (var i = 0; i < optgroup.children.length; i++) { + if (optgroup.children[i].selected) selectedGroupOptions++; + } + } + + var maxReachedGrp = maxOptionsGrp < selectedGroupOptions; + + if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { + if (maxOptions && maxOptions === 1) { + element.selectedIndex = -1; + that.setOptionStatus(true); + } else if (maxOptionsGrp && maxOptionsGrp === 1) { + for (var j = 0; j < optgroupOptions.length; j++) { + var _option = optgroupOptions[j]; + that.setSelected(that.selectpicker.current.data[_option.liIndex], false); + } + + that.setSelected(clickedData, true); + } else { + var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, + maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, + maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), + maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), + notify = createFromHTML('
'); + + that.menu.appendChild(notify); + + if (maxOptions && maxReached) { + notify.appendChild(createFromHTML('
' + maxTxt + '
')); + triggerChange = false; + that._emit('maxReached'); + } + + if (maxOptionsGrp && maxReachedGrp) { + notify.appendChild(createFromHTML('
' + maxTxtGrp + '
')); + triggerChange = false; + that._emit('maxReachedGrp'); + } + + setTimeout(function () { + that.setSelected(clickedData, false); + }, 10); + + notify.classList.add('fadeOut'); + + setTimeout(function () { + notify.remove(); + }, 1050); + } + } + } + } + + if (that.options.source.data) that.element.appendChild(that.selectpicker.main.optionQueue); + + if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { + that.button.focus(); + } else if (that.options.liveSearch) { + that.searchbox.focus(); + } + + // Trigger select 'change' + if (triggerChange) { + if (that.multiple || prevIndex !== element.selectedIndex) { + changedArguments = [option.index, option.selected, prevValue]; + triggerNative(that.element, 'change'); + } + } + } + } + + liveSearchListener () { + var that = this; + + this._on(this.searchbox, 'click', function (e) { + e.stopPropagation(); + }); + this._on(this.searchbox, 'focus', function (e) { + e.stopPropagation(); + }); + this._on(this.searchbox, 'touchend', function (e) { + e.stopPropagation(); + }); + this._on(this.searchbox, 'keydown', function (e) { + if (e.key === 'Enter' && that.createOptionButton && !that.createOptionButton.hidden && !that.selectpicker.current.data.length) { + e.preventDefault(); + e.stopPropagation(); + that.createOpenOption(that.searchbox.value); + } + }); + + this._on(this.searchbox, 'input', function () { + var searchValue = that.searchbox.value; + + that.selectpicker.search.elements = []; + that.selectpicker.search.data = []; + + if (searchValue) { + that.selectpicker.search.previousValue = searchValue; + + if (that.options.source.search) { + that.fetchData(function () { + that.appendCreatedSearchResults(searchValue); + that.render(); + that.buildList(undefined, true); + that.noScroll = true; + that.menuInner.scrollTop = 0; + that.createView(true); + showNoResults.call(that, that.selectpicker.search.data, searchValue); + }, 'search', 0, searchValue); + } else { + var searchMatch = [], + q = searchValue.toUpperCase(), + cache = {}, + cacheArr = [], + searchStyle = that._searchStyle(), + normalizeSearch = that.options.liveSearchNormalize; + + if (normalizeSearch) q = normalizeToBase(q); + + for (var i = 0; i < that.selectpicker.main.data.length; i++) { + var li = that.selectpicker.main.data[i]; + + if (!cache[i]) { + cache[i] = stringSearch(li, q, searchStyle, normalizeSearch); + } + + if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) { + if (li.headerIndex > 0) { + cache[li.headerIndex - 1] = true; + cacheArr.push(li.headerIndex - 1); + } + + cache[li.headerIndex] = true; + cacheArr.push(li.headerIndex); + + cache[li.lastIndex + 1] = true; + } + + if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i); + } + + for (var j = 0, cacheLen = cacheArr.length; j < cacheLen; j++) { + var index = cacheArr[j], + prevIndex = cacheArr[j - 1], + liData = that.selectpicker.main.data[index], + liPrev = that.selectpicker.main.data[prevIndex]; + + if (liData.type !== 'divider' || (liData.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== j)) { + that.selectpicker.search.data.push(liData); + searchMatch.push(that.selectpicker.main.elements[index]); + } + } + + that.activeElement = undefined; + that.noScroll = true; + that.menuInner.scrollTop = 0; + that.selectpicker.search.elements = searchMatch; + that.createView(true); + showNoResults.call(that, searchMatch, searchValue); + } + } else if (that.selectpicker.search.previousValue) { + that.menuInner.scrollTop = 0; + that.createView(false); + } + + that.syncOpenOptionButton(); + }); + } + + _searchStyle () { + return this.options.liveSearchStyle || 'contains'; + } + + getValue () { + var element = this.element; + + if (this.multiple) { + var values = []; + for (var i = 0; i < element.options.length; i++) { + if (element.options[i].selected) values.push(element.options[i].value); + } + return values; + } + + return element.value; + } + diff --git a/js/bootstrap-select.js b/js/bootstrap-select.js deleted file mode 100644 index 55dafd9d..00000000 --- a/js/bootstrap-select.js +++ /dev/null @@ -1,3728 +0,0 @@ -'use strict'; - -// Resolve Bootstrap's Dropdown component (Bootstrap 5+). It may be provided -// by the UMD factory (`bootstrap`), or available as a global. -function getDropdown () { - var bs = bootstrap || (typeof window !== 'undefined' ? window.bootstrap : undefined); - return (bs && bs.Dropdown) || (typeof window !== 'undefined' ? window.Dropdown : undefined); -} - -// -function createFromHTML (html) { - var wrapper = document.createElement('div'); - wrapper.innerHTML = html.trim(); - return wrapper.firstChild; -} - -function toInteger (value) { - return parseInt(value, 10) || 0; -} - -function offset (el) { - var rect = el.getBoundingClientRect(); - return { - top: rect.top + window.pageYOffset, - left: rect.left + window.pageXOffset - }; -} - -// Resolves a container option (selector string or element) to an element. -function resolveContainer (container) { - if (!container) return null; - return typeof container === 'string' ? document.querySelector(container) : container; -} - -function outerHeight (el, includeMargin) { - var height = el.offsetHeight; - if (includeMargin) { - var style = window.getComputedStyle(el); - height += toInteger(style.marginTop) + toInteger(style.marginBottom); - } - return height; -} - -function setStyles (el, styles) { - for (var prop in styles) { - if (Object.prototype.hasOwnProperty.call(styles, prop)) { - el.style[prop] = styles[prop]; - } - } -} - -function triggerNative (el, eventName) { - el.dispatchEvent(new Event(eventName, { bubbles: true })); -} - -// shallow array comparison -function isEqual (array1, array2) { - return array1.length === array2.length && array1.every(function (element, index) { - return element === array2[index]; - }); -} - -function toKebabCase (str) { - return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) { - return (ofs ? '-' : '') + $.toLowerCase(); - }); -} - -function toCamelCase (str) { - return str.replace(/-([a-z])/g, function (m, letter) { - return letter.toUpperCase(); - }); -} - -// Read options from data-* attributes using native values where possible. -function convertDataValue (value) { - if (value === 'true') return true; - if (value === 'false') return false; - if (value === 'null') return null; - if (value === +value + '') return +value; - if (/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/.test(value)) { - try { - return JSON.parse(value); - } catch (e) { - return value; - } - } - return value; -} - -function getDataset (el) { - var dataset = {}, - attributes = el.attributes; - - for (var i = 0; i < attributes.length; i++) { - var name = attributes[i].name; - if (name.indexOf('data-') === 0) { - dataset[toCamelCase(name.slice(5))] = convertDataValue(attributes[i].value); - } - } - - return dataset; -} -// - -// -var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; - -var uriAttrs = [ - 'background', - 'cite', - 'href', - 'itemtype', - 'longdesc', - 'poster', - 'src', - 'xlink:href' -]; - -var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; - -var DefaultWhitelist = { - // Global attributes allowed on any supplied element below. - '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN], - a: ['target', 'href', 'title', 'rel'], - area: [], - b: [], - br: [], - col: [], - code: [], - div: [], - em: [], - hr: [], - h1: [], - h2: [], - h3: [], - h4: [], - h5: [], - h6: [], - i: [], - img: ['src', 'alt', 'title', 'width', 'height'], - li: [], - ol: [], - p: [], - pre: [], - s: [], - small: [], - span: [], - sub: [], - sup: [], - strong: [], - u: [], - ul: [] -}; - -// A pattern that recognizes a commonly useful subset of URLs that are safe. -var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; - -// A pattern that matches safe data URLs. Only matches image, video and audio types. -var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; - -var ParseableAttributes = ['placeholder']; // attributes to use as settings, can add others in the future - -function applyLegacyOptions (element, config) { - if (!config.placeholder) { - var title = element.getAttribute('title'); - if (title) config.placeholder = title; - } - - return config; -} - -function allowedAttribute (attr, allowedAttributeList) { - var attrName = attr.nodeName.toLowerCase(); - - if (allowedAttributeList.indexOf(attrName) !== -1) { - if (uriAttrs.indexOf(attrName) !== -1) { - return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)); - } - - return true; - } - - var regExp = allowedAttributeList.filter(function (value) { - return value instanceof RegExp; - }); - - // Check if a regular expression validates the attribute. - for (var i = 0, l = regExp.length; i < l; i++) { - if (attrName.match(regExp[i])) { - return true; - } - } - - return false; -} - -function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) { - if (sanitizeFn && typeof sanitizeFn === 'function') { - return sanitizeFn(unsafeElements); - } - - var whitelistKeys = Object.keys(whiteList); - - for (var i = 0, len = unsafeElements.length; i < len; i++) { - var elements = unsafeElements[i].querySelectorAll('*'); - - for (var j = 0, len2 = elements.length; j < len2; j++) { - var el = elements[j]; - var elName = el.nodeName.toLowerCase(); - - if (whitelistKeys.indexOf(elName) === -1) { - el.parentNode.removeChild(el); - - continue; - } - - var attributeList = [].slice.call(el.attributes); - var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); - - for (var k = 0, len3 = attributeList.length; k < len3; k++) { - var attr = attributeList[k]; - - if (!allowedAttribute(attr, whitelistedAttributes)) { - el.removeAttribute(attr.nodeName); - } - } - } - } -} -// - -function getAttributesObject (element) { - var attributesObject = {}, - attrVal; - - ParseableAttributes.forEach(function (item) { - attrVal = element.getAttribute(item); - if (attrVal) attributesObject[item] = attrVal; - }); - - return attributesObject; -} - -// -function stringSearch (li, searchString, method, normalize) { - var stringTypes = [ - 'display', - 'subtext', - 'tokens' - ], - searchSuccess = false; - - for (var i = 0; i < stringTypes.length; i++) { - var stringType = stringTypes[i], - string = li[stringType]; - - if (string) { - string = string.toString(); - - // Strip HTML tags. This isn't perfect, but it's much faster than any other method - if (stringType === 'display') { - string = string.replace(/<[^>]+>/g, ''); - } - - if (normalize) string = normalizeToBase(string); - string = string.toUpperCase(); - - if (typeof method === 'function') { - searchSuccess = method(string, searchString); - } else if (method === 'contains') { - searchSuccess = string.indexOf(searchString) >= 0; - } else { - searchSuccess = string.startsWith(searchString); - } - - if (searchSuccess) break; - } - } - - return searchSuccess; -} - -function normalizeSearchInput (value, normalize) { - if (value === undefined || value === null) value = ''; - value = value.toString().trim(); - - if (normalize && value) value = normalizeToBase(value); - - return value.toUpperCase(); -} - -function getOptionLabelText (option) { - if (!option) return ''; - - return option.title || option.text || option.value || ''; -} - -// Borrowed from Lodash (_.deburr) -/** Used to map Latin Unicode letters to basic Latin letters. */ -var deburredLetters = { - // Latin-1 Supplement block. - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss', - // Latin Extended-A block. - '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', - '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', - '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', - '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', - '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', - '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', - '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', - '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', - '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', - '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', - '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', - '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', - '\u0134': 'J', '\u0135': 'j', - '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', - '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', - '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', - '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', - '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', - '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', - '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', - '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', - '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', - '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', - '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', - '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', - '\u0163': 't', '\u0165': 't', '\u0167': 't', - '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', - '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', - '\u0174': 'W', '\u0175': 'w', - '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', - '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', - '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', - '\u0132': 'IJ', '\u0133': 'ij', - '\u0152': 'Oe', '\u0153': 'oe', - '\u0149': "'n", '\u017f': 's' -}; - -/** Used to match Latin Unicode letters (excluding mathematical operators). */ -var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; - -/** Used to compose unicode character classes. */ -var rsComboMarksRange = '\\u0300-\\u036f', - reComboHalfMarksRange = '\\ufe20-\\ufe2f', - rsComboSymbolsRange = '\\u20d0-\\u20ff', - rsComboMarksExtendedRange = '\\u1ab0-\\u1aff', - rsComboMarksSupplementRange = '\\u1dc0-\\u1dff', - rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange; - -/** Used to compose unicode capture groups. */ -var rsCombo = '[' + rsComboRange + ']'; - -var reComboMark = RegExp(rsCombo, 'g'); - -function deburrLetter (key) { - return deburredLetters[key]; -} - -function normalizeToBase (string) { - string = string.toString(); - return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); -} - -// List of HTML entities for escaping. -var escapeMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' -}; - -var createEscaper = function (map) { - var escaper = function (match) { - return map[match]; - }; - var source = '(?:' + Object.keys(map).join('|') + ')'; - var testRegexp = RegExp(source); - var replaceRegexp = RegExp(source, 'g'); - return function (string) { - string = string == null ? '' : '' + string; - return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; - }; -}; - -var htmlEscape = createEscaper(escapeMap); -// - -// -var keyCodeMap = { - 32: ' ', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', - 55: '7', 56: '8', 57: '9', 59: ';', - 65: 'A', 66: 'B', 67: 'C', 68: 'D', 69: 'E', 70: 'F', 71: 'G', 72: 'H', - 73: 'I', 74: 'J', 75: 'K', 76: 'L', 77: 'M', 78: 'N', 79: 'O', 80: 'P', - 81: 'Q', 82: 'R', 83: 'S', 84: 'T', 85: 'U', 86: 'V', 87: 'W', 88: 'X', - 89: 'Y', 90: 'Z', - 96: '0', 97: '1', 98: '2', 99: '3', 100: '4', 101: '5', 102: '6', - 103: '7', 104: '8', 105: '9' -}; - -var keyCodes = { - ESCAPE: 27, - ENTER: 13, - SPACE: 32, - TAB: 9, - ARROW_UP: 38, - ARROW_DOWN: 40 -}; - -var selectId = 0; - -var EVENT_KEY = '.bs.select'; - -// Bootstrap 5 class names. -var classNames = { - DISABLED: 'disabled', - DIVIDER: 'dropdown-divider', - SHOW: 'show', - DROPUP: 'dropup', - MENU: 'dropdown-menu', - MENUEND: 'dropdown-menu-end', - BUTTONCLASS: 'btn-light', - POPOVERHEADER: 'popover-header', - ICONBASE: '', - TICKICON: 'bs-ok-default' -}; - -var Selector = { - MENU: '.' + classNames.MENU, - DATA_TOGGLE: 'data-bs-toggle="dropdown"' -}; - -var elementTemplates = { - div: document.createElement('div'), - span: document.createElement('span'), - i: document.createElement('i'), - subtext: document.createElement('small'), - a: document.createElement('a'), - li: document.createElement('li'), - whitespace: document.createTextNode('\u00A0'), - fragment: document.createDocumentFragment(), - option: document.createElement('option') -}; - -elementTemplates.selectedOption = elementTemplates.option.cloneNode(false); -elementTemplates.selectedOption.setAttribute('selected', true); - -elementTemplates.noResults = elementTemplates.li.cloneNode(false); -elementTemplates.noResults.className = 'no-results'; - -elementTemplates.a.setAttribute('role', 'option'); -elementTemplates.a.className = 'dropdown-item'; - -elementTemplates.subtext.className = 'text-muted'; - -elementTemplates.text = elementTemplates.span.cloneNode(false); -elementTemplates.text.className = 'text'; - -elementTemplates.checkMark = elementTemplates.span.cloneNode(false); - -var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN); -var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE); - -var generateOption = { - li: function (content, classes, optgroup) { - var li = elementTemplates.li.cloneNode(false); - - if (content) { - if (content.nodeType === 1 || content.nodeType === 11) { - li.appendChild(content); - } else { - li.innerHTML = content; - } - } - - if (typeof classes !== 'undefined' && classes !== '') li.className = classes; - if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup); - - return li; - }, - - a: function (text, classes, inline) { - var a = elementTemplates.a.cloneNode(true); - - if (text) { - if (text.nodeType === 11) { - a.appendChild(text); - } else { - a.insertAdjacentHTML('beforeend', text); - } - } - - if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/)); - if (inline) a.setAttribute('style', inline); - - return a; - }, - - text: function (options, useFragment) { - var textElement = elementTemplates.text.cloneNode(false), - subtextElement, - iconElement; - - if (options.content) { - textElement.innerHTML = options.content; - } else { - textElement.textContent = options.text; - - if (options.icon) { - var whitespace = elementTemplates.whitespace.cloneNode(false); - - // need to use for icons in the button to prevent a breaking change - iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false); - iconElement.className = this.options.iconBase + ' ' + options.icon; - - elementTemplates.fragment.appendChild(iconElement); - elementTemplates.fragment.appendChild(whitespace); - } - - if (options.subtext) { - subtextElement = elementTemplates.subtext.cloneNode(false); - subtextElement.textContent = options.subtext; - textElement.appendChild(subtextElement); - } - } - - if (useFragment === true) { - while (textElement.childNodes.length > 0) { - elementTemplates.fragment.appendChild(textElement.childNodes[0]); - } - } else { - elementTemplates.fragment.appendChild(textElement); - } - - return elementTemplates.fragment; - }, - - label: function (options) { - var textElement = elementTemplates.text.cloneNode(false), - subtextElement, - iconElement; - - textElement.innerHTML = options.display; - - if (options.icon) { - var whitespace = elementTemplates.whitespace.cloneNode(false); - - iconElement = elementTemplates.span.cloneNode(false); - iconElement.className = this.options.iconBase + ' ' + options.icon; - - elementTemplates.fragment.appendChild(iconElement); - elementTemplates.fragment.appendChild(whitespace); - } - - if (options.subtext) { - subtextElement = elementTemplates.subtext.cloneNode(false); - subtextElement.textContent = options.subtext; - textElement.appendChild(subtextElement); - } - - elementTemplates.fragment.appendChild(textElement); - - return elementTemplates.fragment; - } -}; - -var getOptionData = { - fromOption: function (option, type) { - var value; - - switch (type) { - case 'divider': - value = option.getAttribute('data-divider') === 'true'; - break; - - case 'text': - value = option.textContent; - break; - - case 'label': - value = option.label; - break; - - case 'style': - value = option.style.cssText; - break; - - case 'title': - value = option.title; - break; - - default: - value = option.getAttribute('data-' + toKebabCase(type)); - break; - } - - return value; - }, - fromDataSource: function (option, type) { - var value; - - switch (type) { - case 'text': - case 'label': - value = option.text || option.value || ''; - break; - - default: - value = option[type]; - break; - } - - return value; - } -}; - -function showNoResults (searchMatch, searchValue) { - if (!searchMatch.length) { - elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"'); - this.menuInner.firstChild.appendChild(elementTemplates.noResults); - } -} - -function filterHidden (item) { - return !(item.hidden || this.options.hideDisabled && item.disabled); -} - -function getSelectedOptions () { - var options = this.selectpicker.main.data; - - if (this.options.source.data || this.options.source.search) { - options = Object.values(this.selectpicker.optionValuesDataMap); - } - - var selectedOptions = options.filter(function (item) { - if (item.selected) { - if (this.options.hideDisabled && item.disabled) return false; - return true; - } - - return false; - }, this); - - // ensure only 1 option is selected if multiple are set in the data source - if (this.options.source.data && !this.multiple && selectedOptions.length > 1) { - for (var i = 0; i < selectedOptions.length - 1; i++) { - selectedOptions[i].selected = false; - } - - selectedOptions = [ selectedOptions[selectedOptions.length - 1] ]; - } - - return selectedOptions; -} - -function getSelectValues (selectedOptions) { - var value = [], - options = selectedOptions || getSelectedOptions.call(this), - opt; - - for (var i = 0, len = options.length; i < len; i++) { - opt = options[i]; - - if (!opt.disabled) { - value.push(opt.value === undefined ? opt.text : opt.value); - } - } - - if (!this.multiple) { - return !value.length ? null : value[0]; - } - - return value; -} -// - -var changedArguments = null; - -// shared flag for spacebar selection handling (mirrors original document data flag) -var spaceSelectFlag = false; - -var REMOVED_OPTIONS = ['container', 'display', 'mobile', 'styleBase', 'windowPadding']; - -function stripRemovedOptions (source) { - if (!source || typeof source !== 'object') return source; - - var result = Object.assign({}, source); - - for (var i = 0; i < REMOVED_OPTIONS.length; i++) { - delete result[REMOVED_OPTIONS[i]]; - } - - return result; -} - -class Selectpicker { - constructor (element, options) { - if (typeof element === 'string') { - element = document.querySelector(element); - } - - if (!element || element.tagName !== 'SELECT') { - throw new TypeError('Selectpicker requires a select element or selector.'); - } - - this.element = element; - this.newElement = null; - this.button = null; - this.menu = null; - this.options = Selectpicker._buildConfig(element, options || {}); - - // tracked event listeners for clean teardown - this._listeners = []; - this._named = {}; - - this.selectpicker = { - main: { - data: [], - optionQueue: elementTemplates.fragment.cloneNode(false), - hasMore: false - }, - search: { - data: [], - hasMore: false - }, - current: {}, // current is either equal to main or search depending on if a search is in progress - view: {}, - // map of option values and their respective data (only used in conjunction with options.source) - optionValuesDataMap: {}, - createdOptions: [], - openOption: { - isCreating: false - }, - isSearching: false, - keydown: { - keyHistory: '', - resetKeyHistory: { - start: () => { - return setTimeout(() => { - this.selectpicker.keydown.keyHistory = ''; - }, 800); - } - } - } - }; - - this.sizeInfo = {}; - - this.init(); - - instanceMap.set(element, this); - } - - // - _on (el, type, handler, options) { - el.addEventListener(type, handler, options); - this._listeners.push({ el: el, type: type, handler: handler, options: options }); - return handler; - } - - _delegate (el, type, selector, handler, options) { - var listener = function (e) { - var target = e.target.closest(selector); - if (target && el.contains(target)) { - handler.call(target, e); - } - }; - return this._on(el, type, listener, options); - } - - _emit (name, detail) { - var event = new CustomEvent(name + EVENT_KEY, { - bubbles: true, - cancelable: true, - detail: detail || null - }); - this.element.dispatchEvent(event); - return event; - } - - // adds an event listener that replaces any previously-registered listener under `key` - _replace (key, el, type, handler, options) { - this._removeNamed(key); - el.addEventListener(type, handler, options); - this._named[key] = { el: el, type: type, handler: handler, options: options }; - } - - _removeNamed (key) { - var prev = this._named[key]; - if (prev) { - prev.el.removeEventListener(prev.type, prev.handler, prev.options); - delete this._named[key]; - } - } - // - - init () { - var that = this, - id = this.element.getAttribute('id'), - element = this.element, - form = element.form; - - selectId++; - this.selectId = 'bs-select-' + selectId; - - element.classList.add('bs-select-hidden'); - - this.multiple = this.element.multiple; - this.autofocus = this.element.autofocus; - - if (element.classList.contains('show-tick')) { - this.options.showTick = true; - } - - this.newElement = this.createDropdown(); - - // insert newElement after element, then move element to be the first child of newElement - element.parentNode.insertBefore(this.newElement, element.nextSibling); - this.newElement.insertBefore(element, this.newElement.firstChild); - - // ensure select is associated with form element if it got unlinked after moving it inside newElement - if (form && element.form === null) { - if (!form.id) form.id = 'form-' + this.selectId; - element.setAttribute('form', form.id); - } - - this.button = this.newElement.querySelector(':scope > button'); - if (this.options.allowClear) this.clearButton = this.button.querySelector('.bs-select-clear-selected'); - this.menu = this.newElement.querySelector(':scope > ' + Selector.MENU); - this.menuInner = this.menu.querySelector('.inner'); - this.searchbox = this.menu.querySelector('input'); - this.selectedItems = this.newElement.querySelector(':scope > .bs-selected-items-external') || this.menu.querySelector('.bs-selected-items'); - this.createOptionButton = this.menu.querySelector('.bs-create-option'); - - element.classList.remove('bs-select-hidden'); - - this.fetchData(function () { - that.render(true); - that.buildList(); - - requestAnimationFrame(function () { - that._emit('loaded'); - }); - }); - - if (this.options.dropdownAlignRight === true) this.menu.classList.add(classNames.MENUEND); - - if (typeof id !== 'undefined' && id !== null) { - this.button.setAttribute('data-id', id); - } - - this.checkDisabled(); - this.clickListener(); - - var Dropdown = getDropdown(); - this.dropdown = new Dropdown(this.button); - - // store a reference to the instance for delegated handlers - this.newElement.bootstrapSelectInstance = this; - this.menu.bootstrapSelectInstance = this; - - if (this.options.liveSearch) { - this.liveSearchListener(); - this.focusedParent = this.searchbox; - } else { - this.focusedParent = this.menuInner; - } - - this.setStyle(); - this.setWidth(); - this._on(this.element, 'hide' + EVENT_KEY, function () { - if (that.isVirtual()) { - // empty menu on close - var menuInner = that.menuInner, - emptyMenu = menuInner.firstChild.cloneNode(false); - - // replace the existing UL with an empty one - this is faster than emptying it - menuInner.replaceChild(emptyMenu, menuInner.firstChild); - menuInner.scrollTop = 0; - } - }); - - // re-emit Bootstrap dropdown events as bootstrap-select events - this._on(this.newElement, 'hide.bs.dropdown', function (e) { - that._emit('hide', { bsEvent: e }); - }); - this._on(this.newElement, 'hidden.bs.dropdown', function (e) { - that._emit('hidden', { bsEvent: e }); - }); - this._on(this.newElement, 'show.bs.dropdown', function (e) { - that.onShow(e); - that._emit('show', { bsEvent: e }); - }); - this._on(this.newElement, 'shown.bs.dropdown', function (e) { - that._emit('shown', { bsEvent: e }); - }); - - if (element.hasAttribute('required')) { - this._on(this.element, 'invalid', function () { - that.button.classList.add('bs-invalid'); - - var onShownInvalid = function () { - // set the value to hide the validation message in Chrome when menu is opened - triggerNative(that.element, 'change'); - that.element.removeEventListener('shown' + EVENT_KEY, onShownInvalid); - }; - that._on(that.element, 'shown' + EVENT_KEY, onShownInvalid); - - var onRendered = function () { - // if select is no longer invalid, remove the bs-invalid class - if (that.element.validity.valid) that.button.classList.remove('bs-invalid'); - that.element.removeEventListener('rendered' + EVENT_KEY, onRendered); - }; - that._on(that.element, 'rendered' + EVENT_KEY, onRendered); - - var onBlur = function () { - that.element.focus(); - that.element.blur(); - that.button.removeEventListener('blur' + EVENT_KEY, onBlur); - }; - that._on(that.button, 'blur' + EVENT_KEY, onBlur); - }); - } - - if (form) { - this._on(form, 'reset', function () { - requestAnimationFrame(function () { - that.render(); - }); - }); - } - } - - createDropdown () { - // If we are multiple or showTick option is set, then add the show-tick class - var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '', - showSelectedTags = this.options.showSelectedTags ? ' show-selected-tags' : '', - selectedItemsStyle = this.options.selectedItemsStyle === 'list' ? ' selected-items-style-list' : '', - selectionIndicator = this.options.selectionIndicator === 'checkbox' ? ' selection-indicator-checkbox' : '', - multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', - autofocus = this.autofocus ? ' autofocus' : '', - liveSearchPlaceholder = this.options.liveSearchPlaceholder; - - if (liveSearchPlaceholder === null && (this.options.showSelectedTags || this.options.openOptions)) { - liveSearchPlaceholder = this.options.placeholder || 'Search'; - } - - // Elements - var drop, - header = '', - searchbox = '', - actionsbox = '', - donebutton = '', - clearButton = ''; - - if (this.options.header) { - header = - '
' + - '' + - this.options.header + - '
'; - } - - if (this.options.liveSearch) { - searchbox = - ''; - } - - if (this.multiple && this.options.actionsBox) { - actionsbox = - '
' + - '
' + - '' + - '' + - '
' + - '
'; - } - - if (this.multiple && this.options.doneButton) { - donebutton = - '
' + - '
' + - '' + - '
' + - '
'; - } - - if (this.options.allowClear) { - clearButton = '×'; - } - - drop = - ''; - - return createFromHTML(drop); - } - - // runs when the dropdown is about to be shown - onShow () { - if (this.options.liveSearch && this.searchbox.value) { - this.searchbox.value = ''; - this.selectpicker.search.previousValue = undefined; - } - - if (!this.newElement.classList.contains(classNames.SHOW)) { - this.setSize(); - } - } - - setPositionData () { - this.selectpicker.view.canHighlight = []; - this.selectpicker.view.size = 0; - this.selectpicker.view.firstHighlightIndex = false; - - for (var i = 0; i < this.selectpicker.current.data.length; i++) { - var li = this.selectpicker.current.data[i], - canHighlight = true; - - if (li.type === 'divider') { - canHighlight = false; - li.height = this.sizeInfo.dividerHeight; - } else if (li.type === 'optgroup-label') { - canHighlight = false; - li.height = this.sizeInfo.dropdownHeaderHeight; - } else { - li.height = this.sizeInfo.liHeight; - } - - if (li.disabled) canHighlight = false; - - this.selectpicker.view.canHighlight.push(canHighlight); - - if (canHighlight) { - this.selectpicker.view.size++; - li.posinset = this.selectpicker.view.size; - if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i; - } - - li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height; - } - } - - isVirtual () { - return (this.options.virtualScroll !== false) && (this.selectpicker.main.data.length >= this.options.virtualScroll) || this.options.virtualScroll === true; - } - - createView (isSearching, setSize, refresh) { - var that = this, - scrollTop = 0; - - this.selectpicker.isSearching = isSearching; - this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main; - - this.setPositionData(); - - if (setSize) { - if (refresh) { - scrollTop = this.menuInner.scrollTop; - } else if (!that.multiple) { - var element = that.element, - selectedIndex = (element.options[element.selectedIndex] || {}).liIndex; - - if (typeof selectedIndex === 'number' && that.options.size !== false) { - var selectedData = that.selectpicker.main.data[selectedIndex], - position = selectedData && selectedData.position; - - if (position) { - scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2); - } - } - } - } - - scroll(scrollTop, true); - - this._replace('createViewScroll', this.menuInner, 'scroll', function () { - if (!that.noScroll) scroll(that.menuInner.scrollTop); - that.noScroll = false; - }); - - function scroll (scrollTop, init) { - var size = that.selectpicker.current.data.length, - chunks = [], - chunkSize, - chunkCount, - firstChunk, - lastChunk, - currentChunk, - prevPositions, - positionIsDifferent, - previousElements, - menuIsDifferent = true, - isVirtual = that.isVirtual(); - - that.selectpicker.view.scrollTop = scrollTop; - - chunkSize = that.options.chunkSize; // number of options in a chunk - chunkCount = Math.ceil(size / chunkSize) || 1; // number of chunks - - for (var i = 0; i < chunkCount; i++) { - var endOfChunk = (i + 1) * chunkSize; - - if (i === chunkCount - 1) { - endOfChunk = size; - } - - chunks[i] = [ - (i) * chunkSize + (!i ? 0 : 1), - endOfChunk - ]; - - if (!size) break; - - if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) { - currentChunk = i; - } - } - - if (currentChunk === undefined) currentChunk = 0; - - prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1]; - - // always display previous, current, and next chunks - firstChunk = Math.max(0, currentChunk - 1); - lastChunk = Math.min(chunkCount - 1, currentChunk + 1); - - that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0); - that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0); - - positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1; - - if (that.activeElement !== undefined) { - if (init) { - if (that.activeElement !== that.selectedElement) { - that.defocusItem(that.activeElement); - } - that.activeElement = undefined; - } - - if (that.activeElement !== that.selectedElement) { - that.defocusItem(that.selectedElement); - } - } - - if (that.prevActiveElement !== undefined && that.prevActiveElement !== that.activeElement && that.prevActiveElement !== that.selectedElement) { - that.defocusItem(that.prevActiveElement); - } - - if (init || positionIsDifferent || that.selectpicker.current.hasMore) { - previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : []; - - if (isVirtual === false) { - that.selectpicker.view.visibleElements = that.selectpicker.current.elements; - } else { - that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1); - } - - that.setOptionStatus(); - - // if searching, check to make sure the list has actually been updated before updating DOM - // this prevents unnecessary repaints - if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements); - - // if virtual scroll is disabled and not searching, - // menu should never need to be updated more than once - if ((init || isVirtual === true) && menuIsDifferent) { - var menuInner = that.menuInner, - menuFragment = document.createDocumentFragment(), - emptyMenu = menuInner.firstChild.cloneNode(false), - marginTop, - marginBottom, - elements = that.selectpicker.view.visibleElements, - toSanitize = []; - - // replace the existing UL with an empty one - this is faster than emptying it - menuInner.replaceChild(emptyMenu, menuInner.firstChild); - - for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) { - var element = elements[i], - elText, - elementData; - - if (that.options.sanitize) { - elText = element.lastChild; - - if (elText) { - elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0]; - - if (elementData && elementData.content && !elementData.sanitized) { - toSanitize.push(elText); - elementData.sanitized = true; - } - } - } - - menuFragment.appendChild(element); - } - - if (that.options.sanitize && toSanitize.length) { - sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn); - } - - if (isVirtual === true) { - marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position); - marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position); - - menuInner.firstChild.style.marginTop = marginTop + 'px'; - menuInner.firstChild.style.marginBottom = marginBottom + 'px'; - } else { - menuInner.firstChild.style.marginTop = 0; - menuInner.firstChild.style.marginBottom = 0; - } - - menuInner.firstChild.appendChild(menuFragment); - - // if an option is encountered that is wider than the current menu width, update the menu width accordingly - if (isVirtual === true && that.sizeInfo.hasScrollBar) { - var menuInnerInnerWidth = menuInner.firstChild.offsetWidth; - - if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) { - menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; - } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) { - // set to 0 to get actual width of menu - that.menu.style.minWidth = 0; - - var actualMenuWidth = menuInner.firstChild.offsetWidth; - - if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) { - that.sizeInfo.menuInnerInnerWidth = actualMenuWidth; - menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; - } - - // reset to default CSS styling - that.menu.style.minWidth = ''; - } - } - } - - if ((!isSearching && that.options.source.data || isSearching && that.options.source.search) && that.selectpicker.current.hasMore && currentChunk === chunkCount - 1) { - // Don't load the next chunk until scrolling has started - // This prevents unnecessary requests while the user is typing if pageSize is <= chunkSize - if (scrollTop > 0) { - // Chunks use 0-based indexing, but pages use 1-based. Add 1 to convert and add 1 again to get next page - var page = Math.floor((currentChunk * that.options.chunkSize) / that.options.source.pageSize) + 2; - - that.fetchData(function () { - that.render(); - that.buildList(size, isSearching); - that.setPositionData(); - scroll(scrollTop); - }, isSearching ? 'search' : 'data', page, isSearching ? that.selectpicker.search.previousValue : undefined); - } - } - } - - that.prevActiveElement = that.activeElement; - - if (!that.options.liveSearch) { - that.menuInner.focus(); - } else if (isSearching && init) { - var index = 0, - newActive; - - if (!that.selectpicker.view.canHighlight[index]) { - index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true); - } - - newActive = that.selectpicker.view.visibleElements[index]; - - that.defocusItem(that.selectpicker.view.currentActive); - - that.activeElement = (that.selectpicker.current.data[index] || {}).element; - - that.focusItem(newActive); - } - } - - this._replace('createViewResize', window, 'resize', function () { - var isActive = that.newElement.classList.contains(classNames.SHOW); - - if (isActive) scroll(that.menuInner.scrollTop); - }); - } - - focusItem (li, liData, noStyle) { - if (li) { - liData = liData || this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)]; - var a = li.firstChild; - - if (a) { - a.setAttribute('aria-setsize', this.selectpicker.view.size); - a.setAttribute('aria-posinset', liData.posinset); - - if (noStyle !== true) { - this.focusedParent.setAttribute('aria-activedescendant', a.id); - li.classList.add('active'); - a.classList.add('active'); - } - } - } - } - - defocusItem (li) { - if (li) { - li.classList.remove('active'); - if (li.firstChild) li.firstChild.classList.remove('active'); - } - } - - setPlaceholder () { - var that = this, - updateIndex = false; - - if ((this.options.placeholder || this.options.allowClear) && !this.multiple) { - if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option'); - - // this option doesn't create a new
  • element, but does add a new option at the start, - // so startIndex should increase to prevent having to check every option for the bs-title-option class - updateIndex = true; - - var element = this.element, - selectTitleOption = false, - titleNotAppended = !this.selectpicker.view.titleOption.parentNode, - selectedIndex = element.selectedIndex, - selectedOption = element.options[selectedIndex], - firstSelectable = element.querySelector('select > *:not(:disabled)'), - firstSelectableIndex = firstSelectable ? firstSelectable.index : 0, - navigation = window.performance && window.performance.getEntriesByType('navigation'), - // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation - isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2; - - if (titleNotAppended) { - // Use native JS to prepend option (faster) - this.selectpicker.view.titleOption.className = 'bs-title-option'; - this.selectpicker.view.titleOption.value = ''; - - // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. - selectTitleOption = !selectedOption || (selectedIndex === firstSelectableIndex && selectedOption.defaultSelected === false); - } - - if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) { - element.insertBefore(this.selectpicker.view.titleOption, element.firstChild); - } - - // Set selected *after* appending to select - if (selectTitleOption && isNotBackForward) { - element.selectedIndex = 0; - } else if (document.readyState !== 'complete') { - // if navigation type is back_forward, there's a chance the select will have its value set by BFCache - // wait for that value to be set, then run render again - window.addEventListener('pageshow', function () { - if (that.selectpicker.view.displayedValue !== element.value) that.render(); - }); - } - } - - return updateIndex; - } - - fetchData (callback, type, page, searchValue) { - page = page || 1; - type = type || 'data'; - - var that = this, - data = this.options.source[type], - builtData; - - if (data) { - this.options.virtualScroll = true; - - if (typeof data === 'function') { - data.call( - this, - function (data, more, totalItems) { - var current = that.selectpicker[type === 'search' ? 'search' : 'main']; - current.hasMore = more; - current.totalItems = totalItems; - builtData = that.buildData(data, type); - callback.call(that, builtData); - that._emit('fetched'); - }, - page, - searchValue - ); - } else if (Array.isArray(data)) { - builtData = that.buildData(data, type); - callback.call(that, builtData); - } - } else { - builtData = this.buildData(false, type); - callback.call(that, builtData); - } - } - - buildData (data, type) { - var that = this; - var dataGetter = data === false ? getOptionData.fromOption : getOptionData.fromDataSource; - - var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([style*="display: none"])', - mainData = [], - startLen = this.selectpicker.main.data ? this.selectpicker.main.data.length : 0, - optID = 0, - startIndex = this.setPlaceholder() && !data ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop - - if (type === 'search') { - startLen = this.selectpicker.search.data.length; - } - - if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; - - var selectOptions = data ? data.filter(filterHidden, this) : this.element.querySelectorAll('select > *' + optionSelector); - - function addDivider (config) { - var previousData = mainData[mainData.length - 1]; - - // ensure optgroup doesn't create back-to-back dividers - if ( - previousData && - previousData.type === 'divider' && - (previousData.optID || config.optID) - ) { - return; - } - - config = config || {}; - config.type = 'divider'; - - mainData.push(config); - } - - function addOption (item, config) { - config = config || {}; - - config.divider = dataGetter(item, 'divider'); - - if (config.divider === true) { - addDivider({ - optID: config.optID - }); - } else { - var liIndex = mainData.length + startLen, - cssText = dataGetter(item, 'style'), - inlineStyle = cssText ? htmlEscape(cssText) : '', - optionClass = (item.className || '') + (config.optgroupClass || ''); - - if (config.optID) optionClass = 'opt ' + optionClass; - - config.optionClass = optionClass.trim(); - config.inlineStyle = inlineStyle; - - config.text = dataGetter(item, 'text'); - config.title = dataGetter(item, 'title'); - config.content = dataGetter(item, 'content'); - config.tokens = dataGetter(item, 'tokens'); - config.subtext = dataGetter(item, 'subtext'); - config.icon = dataGetter(item, 'icon'); - - config.display = config.content || config.text; - config.value = item.value === undefined ? item.text : item.value; - config.type = 'option'; - config.index = liIndex; - - config.option = !item.option ? item : item.option; // reference option element if it exists - config.option.liIndex = liIndex; - config.selected = !!item.selected; - config.disabled = config.disabled || !!item.disabled; - - if (data !== false) { - if (that.selectpicker.optionValuesDataMap[config.value]) { - config = Object.assign(that.selectpicker.optionValuesDataMap[config.value], config); - } else { - that.selectpicker.optionValuesDataMap[config.value] = config; - } - } - - mainData.push(config); - } - } - - function addOptgroup (index, selectOptions) { - var optgroup = selectOptions[index], - // skip placeholder option - previous = index - 1 < startIndex ? false : selectOptions[index - 1], - next = selectOptions[index + 1], - options = data ? optgroup.children.filter(filterHidden, this) : optgroup.querySelectorAll('option' + optionSelector); - - if (!options.length) return; - - var config = { - display: htmlEscape(dataGetter(item, 'label')), - subtext: dataGetter(optgroup, 'subtext'), - icon: dataGetter(optgroup, 'icon'), - type: 'optgroup-label', - optgroupClass: ' ' + (optgroup.className || ''), - optgroup: optgroup - }, - headerIndex, - lastIndex; - - optID++; - - if (previous) { - addDivider({ optID: optID }); - } - - config.optID = optID; - - mainData.push(config); - - for (var j = 0, len = options.length; j < len; j++) { - var option = options[j]; - - if (j === 0) { - headerIndex = mainData.length - 1; - lastIndex = headerIndex + len; - } - - addOption(option, { - headerIndex: headerIndex, - lastIndex: lastIndex, - optID: config.optID, - optgroupClass: config.optgroupClass, - disabled: optgroup.disabled - }); - } - - if (next) { - addDivider({ optID: optID }); - } - } - - var item; - - for (var len = selectOptions.length, i = startIndex; i < len; i++) { - item = selectOptions[i]; - var children = item.children; - - if (children && children.length) { - addOptgroup.call(this, i, selectOptions); - } else { - addOption.call(this, item, {}); - } - } - - switch (type) { - case 'data': { - if (!this.selectpicker.main.data) { - this.selectpicker.main.data = []; - } - Array.prototype.push.apply(this.selectpicker.main.data, mainData); - this.selectpicker.current.data = this.selectpicker.main.data; - break; - } - case 'search': { - Array.prototype.push.apply(this.selectpicker.search.data, mainData); - break; - } - } - - return mainData; - } - - buildList (size, searching) { - var that = this, - selectData = searching ? this.selectpicker.search.data : this.selectpicker.main.data, - mainElements = [], - widestOptionLength = 0; - - if (that.options.showTick || that.multiple) { - elementTemplates.checkMark.className = this.options.selectionIndicator === 'checkbox' - ? 'check-mark bs-selection-indicator' - : this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark'; - - if (!elementTemplates.checkMark.parentNode) { - elementTemplates.a.appendChild(elementTemplates.checkMark); - } - } - - function buildElement (mainElements, item) { - var liElement, - combinedLength = 0; - - switch (item.type) { - case 'divider': - liElement = generateOption.li( - false, - classNames.DIVIDER, - (item.optID ? item.optID + 'div' : undefined) - ); - - break; - - case 'option': - liElement = generateOption.li( - generateOption.a( - generateOption.text.call(that, item), - item.optionClass, - item.inlineStyle - ), - '', - item.optID - ); - - if (liElement.firstChild) { - liElement.firstChild.id = that.selectId + '-' + item.index; - } - - break; - - case 'optgroup-label': - liElement = generateOption.li( - generateOption.label.call(that, item), - 'dropdown-header' + item.optgroupClass, - item.optID - ); - - break; - } - - if (item.content) item.sanitized = false; - - if (!item.element) { - item.element = liElement; - } else { - item.element.innerHTML = liElement.innerHTML; - } - mainElements.push(item.element); - - // count the number of characters in the option - not perfect, but should work in most cases - if (item.display) combinedLength += item.display.length; - if (item.subtext) combinedLength += item.subtext.length; - // if there is an icon, ensure this option's width is checked - if (item.icon) combinedLength += 1; - - if (combinedLength > widestOptionLength) { - widestOptionLength = combinedLength; - - // guess which option is the widest - that.selectpicker.view.widestOption = mainElements[mainElements.length - 1]; - } - } - - var startIndex = size || 0; - - for (var len = selectData.length, i = startIndex; i < len; i++) { - var item = selectData[i]; - - buildElement(mainElements, item); - } - - if (size) { - if (searching) { - Array.prototype.push.apply(this.selectpicker.search.elements, mainElements); - } else { - Array.prototype.push.apply(this.selectpicker.main.elements, mainElements); - this.selectpicker.current.elements = this.selectpicker.main.elements; - } - } else { - if (searching) { - this.selectpicker.search.elements = mainElements; - } else { - this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements; - } - } - } - - findLis () { - return this.menuInner.querySelectorAll('.inner > li'); - } - - render (init) { - var that = this, - element = this.element, - // ensure titleOption is appended and selected (if necessary) before getting selectedOptions - placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0, - selectedOptions = getSelectedOptions.call(this), - selectedCount = selectedOptions.length, - selectedValues = getSelectValues.call(this, selectedOptions), - button = this.button, - buttonInner = button.querySelector('.filter-option-inner-inner'), - multipleSeparator = document.createTextNode(this.options.multipleSeparator), - titleFragment = elementTemplates.fragment.cloneNode(false), - forceCount = this.multiple && this.options.showSelectedTags && selectedCount > 0, - showCount, - countMax, - hasContent = false; - - function createSelected (item) { - if (item.selected) { - that.createOption(item, true); - } else if (item.children && item.children.length) { - item.children.map(createSelected); - } - } - - // create selected option elements to ensure select value is correct - if (this.options.source.data && init) { - selectedOptions.map(createSelected); - element.appendChild(this.selectpicker.main.optionQueue); - - if (placeholderSelected) placeholderSelected = element.selectedIndex === 0; - } - - button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !selectedValues && selectedValues !== 0); - - if (!that.multiple && selectedOptions.length === 1) { - that.selectpicker.view.displayedValue = selectedValues; - } - - if (this.options.selectedTextFormat === 'static') { - titleFragment = generateOption.text.call(this, { text: this.options.placeholder }, true); - } else { - showCount = forceCount || this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 0; - - // determine if the number of selected options will be shown (showCount === true) - if (showCount && !forceCount) { - countMax = this.options.selectedTextFormat.split('>'); - showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2); - } - - // only loop through all selected options if the count won't be shown - if (showCount === false) { - if (!placeholderSelected) { - for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) { - if (selectedIndex < 50) { - var option = selectedOptions[selectedIndex], - titleOptions = {}; - - if (option) { - if (this.multiple && selectedIndex > 0) { - titleFragment.appendChild(multipleSeparator.cloneNode(false)); - } - - if (option.title) { - titleOptions.text = option.title; - } else if (option.content && that.options.showContent) { - titleOptions.content = option.content.toString(); - hasContent = true; - } else { - if (that.options.showIcon) { - titleOptions.icon = option.icon; - } - if (that.options.showSubtext && !that.multiple && option.subtext) titleOptions.subtext = ' ' + option.subtext; - titleOptions.text = option.text.trim(); - } - - titleFragment.appendChild(generateOption.text.call(this, titleOptions, true)); - } - } else { - break; - } - } - - // add ellipsis - if (selectedCount > 49) { - titleFragment.appendChild(document.createTextNode('...')); - } - } - } else { - var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"]):not([style*="display: none"])'; - if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; - - // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc. - var totalCount = this.element.querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length, - tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText; - - titleFragment = generateOption.text.call(this, { - text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString()) - }, true); - } - } - - // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText - if (!titleFragment.childNodes.length) { - titleFragment = generateOption.text.call(this, { - text: this.options.placeholder ? this.options.placeholder : this.options.noneSelectedText - }, true); - } - - // if the select has a title, apply it to the button, and if not, apply titleFragment text - button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim(); - - if (this.options.sanitize && hasContent) { - sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn); - } - - buttonInner.innerHTML = ''; - buttonInner.appendChild(titleFragment); - - this.syncTagEditor(); - - this._emit('rendered'); - } - - usesTagEditor () { - return this.options.liveSearch && (this.options.showSelectedTags || this.options.openOptions); - } - - syncTagEditor () { - if (!this.usesTagEditor()) return; - - if (this.selectedItems) { - var selectedOptions = getSelectedOptions.call(this), - useListStyle = this.options.selectedItemsStyle === 'list'; - - this.selectedItems.innerHTML = ''; - this.selectedItems.hidden = !selectedOptions.length; - this.selectedItems.classList.toggle('list-group', useListStyle); - - for (var i = 0; i < selectedOptions.length; i++) { - var item = selectedOptions[i], - selectedTag = document.createElement('button'), - removeText = this.options.selectedTagRemoveLabel + ' ' + getOptionLabelText(item), - content = document.createElement('span'), - label = document.createElement('span'), - remove = document.createElement('span'), - icon; - - selectedTag.type = 'button'; - selectedTag.className = useListStyle - ? 'bs-selected-item list-group-item list-group-item-action' - : 'bs-selected-item'; - selectedTag.setAttribute('data-option-value', item.value); - selectedTag.setAttribute('aria-label', removeText); - selectedTag.title = removeText; - - content.className = 'bs-selected-item-content'; - - if (item.icon && this.options.showIcon) { - icon = document.createElement('span'); - icon.className = 'bs-selected-item-icon ' + this.options.iconBase + ' ' + item.icon; - icon.setAttribute('aria-hidden', 'true'); - content.appendChild(icon); - } - - label.className = 'bs-selected-item-label'; - label.textContent = getOptionLabelText(item); - content.appendChild(label); - - remove.className = 'bs-selected-item-remove'; - remove.setAttribute('aria-hidden', 'true'); - remove.textContent = '\u00d7'; - - selectedTag.appendChild(content); - selectedTag.appendChild(remove); - this.selectedItems.appendChild(selectedTag); - } - } - - this.syncOpenOptionButton(); - - if (this.newElement && this.newElement.classList.contains(classNames.SHOW)) { - this.setSize(true); - } - } - - syncOpenOptionButton () { - if (!this.createOptionButton) return; - - var searchValue = this.searchbox ? this.searchbox.value : '', - normalizedValue = searchValue.toString().trim(), - shouldShow = !!normalizedValue && - !this.selectpicker.openOption.isCreating && - !this.findOptionBySearchValue(normalizedValue); - - this.createOptionButton.hidden = !shouldShow; - this.createOptionButton.disabled = this.selectpicker.openOption.isCreating; - - if (shouldShow) { - this.createOptionButton.textContent = this.options.openOptionsText.replace('{0}', normalizedValue); - this.createOptionButton.setAttribute('data-search-value', normalizedValue); - } else { - this.createOptionButton.textContent = ''; - this.createOptionButton.removeAttribute('data-search-value'); - } - } - - findOptionByValue (value, dataSet) { - var options = dataSet || this.selectpicker.main.data, - stringValue = String(value); - - for (var i = 0; i < options.length; i++) { - var option = options[i]; - - if (option.type === 'option' && String(option.value) === stringValue) { - return option; - } - } - - return null; - } - - findOptionBySearchValue (searchValue) { - var options = this.options.source.data || this.options.source.search - ? Object.values(this.selectpicker.optionValuesDataMap) - : this.selectpicker.main.data, - normalizedSearch = normalizeSearchInput(searchValue, this.options.liveSearchNormalize); - - for (var i = 0; i < options.length; i++) { - var option = options[i]; - - if (option.type !== 'option') continue; - - if ( - normalizeSearchInput(option.text, this.options.liveSearchNormalize) === normalizedSearch || - normalizeSearchInput(option.value, this.options.liveSearchNormalize) === normalizedSearch || - normalizeSearchInput(option.title, this.options.liveSearchNormalize) === normalizedSearch - ) { - return option; - } - } - - return null; - } - - createOptionElement (optionData) { - var option = document.createElement('option'); - - option.value = optionData.value === undefined ? optionData.text : optionData.value; - option.textContent = optionData.text === undefined ? option.value : optionData.text; - - if (optionData.className) option.className = optionData.className; - if (optionData.title) option.title = optionData.title; - if (optionData.content) option.setAttribute('data-content', optionData.content); - if (optionData.tokens) option.setAttribute('data-tokens', optionData.tokens); - if (optionData.subtext) option.setAttribute('data-subtext', optionData.subtext); - if (optionData.icon) option.setAttribute('data-icon', optionData.icon); - if (optionData.disabled) option.disabled = true; - if (optionData.hidden) option.hidden = true; - - return option; - } - - appendCreatedSearchResults (searchValue) { - if (!this.selectpicker.createdOptions.length) return; - - var matches = []; - - for (var i = 0; i < this.selectpicker.createdOptions.length; i++) { - var option = this.selectpicker.createdOptions[i]; - - if ( - stringSearch(option, normalizeSearchInput(searchValue, this.options.liveSearchNormalize), this._searchStyle(), this.options.liveSearchNormalize) && - !this.findOptionByValue(option.value, this.selectpicker.search.data) - ) { - matches.push(option); - } - } - - if (matches.length) this.buildData(matches, 'search'); - } - - addCreatedOption (optionData) { - optionData = Object.assign({}, optionData); - optionData.value = optionData.value === undefined ? optionData.text : optionData.value; - optionData.text = optionData.text === undefined ? optionData.value : optionData.text; - - var size = this.selectpicker.main.elements ? this.selectpicker.main.elements.length : 0, - option = this.createOptionElement(optionData); - optionData.option = option; - - this.element.appendChild(option); - var builtOptions = this.buildData([optionData], 'data'), - builtOption = builtOptions[0]; - - this.buildList(size); - this.selectpicker.createdOptions.push(builtOption); - - return builtOption; - } - - removeSelectedTag (value) { - var option = this.findOptionByValue(value); - - if (!option || !option.selected) return; - - var prevValue = getSelectValues.call(this); - - this.setSelected(option, false); - changedArguments = [option.index, false, prevValue]; - triggerNative(this.element, 'change'); - - if (this.options.liveSearch) this.searchbox.focus(); - } - - createOpenOption (searchValue) { - searchValue = searchValue === undefined || searchValue === null ? '' : searchValue.toString().trim(); - - if (!searchValue || this.selectpicker.openOption.isCreating) return; - - var existingOption = this.findOptionBySearchValue(searchValue); - - if (existingOption) { - if (!existingOption.selected) { - var prevSelectedValue = getSelectValues.call(this); - - this.setSelected(existingOption, true); - changedArguments = [existingOption.index, true, prevSelectedValue]; - triggerNative(this.element, 'change'); - } - - if (this.options.liveSearch) this.searchbox.focus(); - return; - } - - var that = this, - prevValue = getSelectValues.call(this), - createHandler = this.options.source.create; - - this.selectpicker.openOption.isCreating = true; - this.syncOpenOptionButton(); - - function finalize (createdOption) { - that.selectpicker.openOption.isCreating = false; - - if (createdOption === undefined || createdOption === null || createdOption === false) { - that.syncOpenOptionButton(); - return; - } - - if (Array.isArray(createdOption)) createdOption = createdOption[0]; - if (typeof createdOption !== 'object') { - createdOption = { - text: createdOption, - value: createdOption - }; - } - - if (!createdOption.text && !createdOption.value) { - createdOption.text = searchValue; - } - - if (createdOption.value === undefined) createdOption.value = createdOption.text; - if (createdOption.text === undefined) createdOption.text = createdOption.value; - - var option = that.findOptionByValue(createdOption.value) || that.findOptionBySearchValue(createdOption.text); - - if (!option) { - option = that.addCreatedOption(createdOption); - } - - that.setSelected(option, true); - - if (that.options.source.data) that.element.appendChild(that.selectpicker.main.optionQueue); - - if (that.searchbox) { - that.searchbox.value = ''; - } - - that.selectpicker.search.previousValue = ''; - that.selectpicker.search.data = []; - that.selectpicker.search.elements = []; - that.createView(false); - - changedArguments = [option.index, true, prevValue]; - triggerNative(that.element, 'change'); - - if (that.options.liveSearch) that.searchbox.focus(); - } - - if (typeof createHandler === 'function') { - var returnedOption = createHandler.call(this, finalize, searchValue); - - if (returnedOption && typeof returnedOption.then === 'function') { - returnedOption.then(finalize); - } else if (returnedOption !== undefined) { - finalize(returnedOption); - } - } else { - finalize({ - text: searchValue, - value: searchValue - }); - } - } - - /** - * @param [newStyle] - * @param [status] - */ - setStyle (newStyle, status) { - var button = this.button, - newElement = this.newElement, - style = this.options.style.trim(), - buttonClass; - - if (this.element.getAttribute('class')) { - var extra = this.element.getAttribute('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '').trim(); - if (extra) newElement.classList.add.apply(newElement.classList, extra.split(/\s+/)); - } - - if (newStyle) { - buttonClass = newStyle.trim(); - } else { - buttonClass = style; - } - - if (status === 'add') { - if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); - } else if (status === 'remove') { - if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' ')); - } else { - if (style) button.classList.remove.apply(button.classList, style.split(' ')); - if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); - } - } - - liHeight (refresh) { - if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return; - - var newElement = elementTemplates.div.cloneNode(false), - menu = elementTemplates.div.cloneNode(false), - menuInner = elementTemplates.div.cloneNode(false), - menuInnerInner = document.createElement('ul'), - divider = elementTemplates.li.cloneNode(false), - dropdownHeader = elementTemplates.li.cloneNode(false), - li, - a = elementTemplates.a.cloneNode(false), - text = elementTemplates.span.cloneNode(false), - header = this.options.header && this.menu.querySelectorAll('.' + classNames.POPOVERHEADER).length > 0 ? this.menu.querySelector('.' + classNames.POPOVERHEADER).cloneNode(true) : null, - search = this.options.liveSearch && this.menu.querySelector('.bs-searchbox') - ? this.menu.querySelector('.bs-searchbox').cloneNode(true) - : null, - actions = this.options.actionsBox && this.multiple && this.menu.querySelectorAll('.bs-actionsbox').length > 0 ? this.menu.querySelector('.bs-actionsbox').cloneNode(true) : null, - doneButton = this.options.doneButton && this.multiple && this.menu.querySelectorAll('.bs-donebutton').length > 0 ? this.menu.querySelector('.bs-donebutton').cloneNode(true) : null, - firstOption = this.element.options[0]; - - this.sizeInfo.selectWidth = this.newElement.offsetWidth; - - text.className = 'text'; - a.className = 'dropdown-item ' + (firstOption ? firstOption.className : ''); - newElement.className = this.menu.parentNode.className + ' ' + classNames.SHOW; - newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating - menu.className = classNames.MENU + ' ' + classNames.SHOW; - menuInner.className = 'inner ' + classNames.SHOW; - menuInnerInner.className = classNames.MENU + ' inner ' + classNames.SHOW; - divider.className = classNames.DIVIDER; - dropdownHeader.className = 'dropdown-header'; - - text.appendChild(document.createTextNode('\u200b')); - - if (this.selectpicker.current.data.length) { - for (var i = 0; i < this.selectpicker.current.data.length; i++) { - var data = this.selectpicker.current.data[i]; - if (data.type === 'option' && window.getComputedStyle(data.element.firstChild).display !== 'none') { - li = data.element; - break; - } - } - } else { - li = elementTemplates.li.cloneNode(false); - a.appendChild(text); - li.appendChild(a); - } - - dropdownHeader.appendChild(text.cloneNode(true)); - - if (this.selectpicker.view.widestOption) { - menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true)); - } - - menuInnerInner.appendChild(li); - menuInnerInner.appendChild(divider); - menuInnerInner.appendChild(dropdownHeader); - if (header) menu.appendChild(header); - if (search) menu.appendChild(search); - if (actions) menu.appendChild(actions); - menuInner.appendChild(menuInnerInner); - menu.appendChild(menuInner); - if (doneButton) menu.appendChild(doneButton); - newElement.appendChild(menu); - - document.body.appendChild(newElement); - - var liHeight = li.offsetHeight, - dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0, - headerHeight = header ? header.offsetHeight : 0, - searchHeight = search ? search.offsetHeight : 0, - actionsHeight = actions ? actions.offsetHeight : 0, - doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, - dividerHeight = outerHeight(divider, true), - menuStyle = window.getComputedStyle(menu), - menuWidth = menu.offsetWidth, - menuPadding = { - vert: toInteger(menuStyle.paddingTop) + - toInteger(menuStyle.paddingBottom) + - toInteger(menuStyle.borderTopWidth) + - toInteger(menuStyle.borderBottomWidth), - horiz: toInteger(menuStyle.paddingLeft) + - toInteger(menuStyle.paddingRight) + - toInteger(menuStyle.borderLeftWidth) + - toInteger(menuStyle.borderRightWidth) - }, - menuExtras = { - vert: menuPadding.vert + - toInteger(menuStyle.marginTop) + - toInteger(menuStyle.marginBottom) + 2, - horiz: menuPadding.horiz + - toInteger(menuStyle.marginLeft) + - toInteger(menuStyle.marginRight) + 2 - }, - scrollBarWidth; - - menuInner.style.overflowY = 'scroll'; - - scrollBarWidth = menu.offsetWidth - menuWidth; - - document.body.removeChild(newElement); - - this.sizeInfo.liHeight = liHeight; - this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight; - this.sizeInfo.headerHeight = headerHeight; - this.sizeInfo.searchHeight = searchHeight; - this.sizeInfo.actionsHeight = actionsHeight; - this.sizeInfo.doneButtonHeight = doneButtonHeight; - this.sizeInfo.dividerHeight = dividerHeight; - this.sizeInfo.menuPadding = menuPadding; - this.sizeInfo.menuExtras = menuExtras; - this.sizeInfo.menuWidth = menuWidth; - this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz; - this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth; - this.sizeInfo.scrollBarWidth = scrollBarWidth; - this.sizeInfo.selectHeight = this.newElement.offsetHeight; - - this.setPositionData(); - } - - getSelectPosition () { - var that = this, - winScrollTop = window.pageYOffset, - winScrollLeft = window.pageXOffset, - winHeight = document.documentElement.clientHeight, - winWidth = document.documentElement.clientWidth, - pos = offset(that.newElement); - - this.sizeInfo.selectOffsetTop = pos.top - winScrollTop; - this.sizeInfo.selectOffsetBot = winHeight - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight; - this.sizeInfo.selectOffsetLeft = pos.left - winScrollLeft; - this.sizeInfo.selectOffsetRight = winWidth - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth; - } - - setMenuSize (isAuto) { - this.getSelectPosition(); - - var selectWidth = this.sizeInfo.selectWidth, - liHeight = this.sizeInfo.liHeight, - headerHeight = this.sizeInfo.headerHeight, - searchHeight = this.sizeInfo.searchHeight, - actionsHeight = this.sizeInfo.actionsHeight, - doneButtonHeight = this.sizeInfo.doneButtonHeight, - divHeight = this.sizeInfo.dividerHeight, - menuPadding = this.sizeInfo.menuPadding, - menuInnerHeight, - menuHeight, - divLength = 0, - minHeight, - _minHeight, - maxHeight, - menuInnerMinHeight, - estimate, - isDropup; - - if (this.options.dropupAuto) { - // Get the estimated height of the menu without scrollbars. - estimate = liHeight * this.selectpicker.current.data.length + menuPadding.vert; - - isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot; - - // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth) - if (this.selectpicker.isSearching === true) { - isDropup = this.selectpicker.dropup; - } - - this.newElement.classList.toggle(classNames.DROPUP, isDropup); - this.selectpicker.dropup = isDropup; - } - - if (this.options.size === 'auto') { - _minHeight = this.selectpicker.current.data.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0; - menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert; - minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; - menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0); - - if (this.newElement.classList.contains(classNames.DROPUP)) { - menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert; - } - - maxHeight = menuHeight; - menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert; - } else if (this.options.size && this.options.size !== 'auto' && this.selectpicker.current.elements.length > this.options.size) { - for (var i = 0; i < this.options.size; i++) { - if (this.selectpicker.current.data[i].type === 'divider') divLength++; - } - - menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; - menuInnerHeight = menuHeight - menuPadding.vert; - maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; - minHeight = menuInnerMinHeight = ''; - } - - setStyles(this.menu, { - maxHeight: maxHeight + 'px', - overflow: 'hidden', - minHeight: minHeight + 'px' - }); - - setStyles(this.menuInner, { - maxHeight: menuInnerHeight + 'px', - overflow: 'hidden auto', - minHeight: menuInnerMinHeight + 'px' - }); - - // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView - this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1); - - if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) { - this.sizeInfo.hasScrollBar = true; - this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth; - } - - if (this.options.dropdownAlignRight === 'auto') { - this.menu.classList.toggle(classNames.MENUEND, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth)); - } - - if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update(); - } - - setSize (refresh) { - this.liHeight(refresh); - - if (this.options.header) this.menu.style.paddingTop = 0; - - if (this.options.size !== false) { - var that = this; - - this.setMenuSize(); - - if (this.options.liveSearch) { - this._replace('setMenuSizeInput', this.searchbox, 'input', function () { - return that.setMenuSize(); - }); - } - - if (this.options.size === 'auto') { - var windowSizeHandler = function () { - return that.setMenuSize(); - }; - this._replace('setMenuSizeResize', window, 'resize', windowSizeHandler); - this._replace('setMenuSizeScroll', window, 'scroll', windowSizeHandler); - } else if (this.options.size && this.options.size !== 'auto' && this.selectpicker.current.elements.length > this.options.size) { - this._removeNamed('setMenuSizeResize'); - this._removeNamed('setMenuSizeScroll'); - } - } - - this.createView(false, true, refresh); - } - - setWidth () { - this.menu.style.minWidth = ''; - this.newElement.style.width = ''; - this.newElement.classList.remove('fit-width'); - - if (this.options.width === 'fit') { - this.newElement.classList.add('fit-width'); - return; - } - - if (this.options.width && this.options.width !== 'auto') { - this.newElement.style.width = this.options.width; - } - } - - selectPosition () { - this.bsContainer = createFromHTML('
    '); - - var that = this, - container = resolveContainer(this.options.container), - pos, - containerPos, - actualHeight, - getPlacement = function (element) { - var Dropdown = getDropdown(), - containerPosition = {}, - // fall back to dropdown's default display setting if display is not manually set - display = that.options.display || (Dropdown.Default ? Dropdown.Default.display : false); - - var extraClass = element.getAttribute('class').replace(/form-control|fit-width/gi, '').trim(); - if (extraClass) that.bsContainer.classList.add.apply(that.bsContainer.classList, extraClass.split(/\s+/)); - that.bsContainer.classList.toggle(classNames.DROPUP, element.classList.contains(classNames.DROPUP)); - pos = offset(element); - - if (container !== document.body) { - containerPos = offset(container); - var containerStyle = window.getComputedStyle(container); - containerPos.top += toInteger(containerStyle.borderTopWidth) - container.scrollTop; - containerPos.left += toInteger(containerStyle.borderLeftWidth) - container.scrollLeft; - } else { - containerPos = { top: 0, left: 0 }; - } - - actualHeight = element.classList.contains(classNames.DROPUP) ? 0 : element.offsetHeight; - - // Bootstrap 5 uses Popper for menu positioning - if (display === 'static') { - containerPosition.top = pos.top - containerPos.top + actualHeight; - containerPosition.left = pos.left - containerPos.left; - } - - containerPosition.width = element.offsetWidth; - - setStyles(that.bsContainer, { - top: containerPosition.top !== undefined ? containerPosition.top + 'px' : '', - left: containerPosition.left !== undefined ? containerPosition.left + 'px' : '', - width: containerPosition.width + 'px' - }); - }; - - this._on(this.button, 'click', function () { - if (that.isDisabled()) { - return; - } - - getPlacement(that.newElement); - - container.appendChild(that.bsContainer); - that.bsContainer.classList.toggle(classNames.SHOW, !that.button.classList.contains(classNames.SHOW)); - that.bsContainer.appendChild(that.menu); - }); - - var windowHandler = function () { - var isActive = that.newElement.classList.contains(classNames.SHOW); - - if (isActive) getPlacement(that.newElement); - }; - this._replace('selectPositionResize', window, 'resize', windowHandler); - this._replace('selectPositionScroll', window, 'scroll', windowHandler); - - this._on(this.element, 'hide' + EVENT_KEY, function () { - that._menuHeight = outerHeight(that.menu); - if (that.bsContainer.parentNode) that.bsContainer.parentNode.removeChild(that.bsContainer); - }); - } - - createOption (data, init) { - var optionData = !data.option ? data : data.option; - - if (optionData && optionData.nodeType !== 1) { - var option = (init ? elementTemplates.selectedOption : elementTemplates.option).cloneNode(true); - if (optionData.value !== undefined) option.value = optionData.value; - option.textContent = optionData.text; - - option.selected = true; - - if (optionData.liIndex !== undefined) { - option.liIndex = optionData.liIndex; - } else if (!init) { - option.liIndex = data.index; - } - - data.option = option; - - this.selectpicker.main.optionQueue.appendChild(option); - } - } - - setOptionStatus (selectedOnly) { - var that = this; - - that.noScroll = false; - - if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) { - for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) { - var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0], - option = liData.option; - - if (option) { - if (selectedOnly !== true) { - that.setDisabled(liData); - } - - that.setSelected(liData); - } - } - - // append optionQueue (documentFragment with option elements for select options) - if (this.options.source.data) this.element.appendChild(this.selectpicker.main.optionQueue); - } - } - - /** - * @param {Object} liData - the option object that is being changed - * @param {boolean} selected - true if the option is being selected, false if being deselected - */ - setSelected (liData, selected) { - selected = selected === undefined ? liData.selected : selected; - - var li = liData.element, - activeElementIsSet = this.activeElement !== undefined, - thisIsActive = this.activeElement === li, - prevActive, - a, - keepActive = thisIsActive || (selected && !this.multiple && !activeElementIsSet); - - if (selected !== undefined) { - liData.selected = selected; - if (liData.option) liData.option.selected = selected; - } - - if (selected && this.options.source.data) { - this.createOption(liData, false); - } - - if (!li) return; - - a = li.firstChild; - - if (selected) { - this.selectedElement = li; - } - - li.classList.toggle('selected', selected); - - if (keepActive) { - this.focusItem(li, liData); - this.selectpicker.view.currentActive = li; - this.activeElement = li; - } else { - this.defocusItem(li); - } - - if (a) { - a.classList.toggle('selected', selected); - - if (selected) { - a.setAttribute('aria-selected', true); - } else { - if (this.multiple) { - a.setAttribute('aria-selected', false); - } else { - a.removeAttribute('aria-selected'); - } - } - } - - if (!keepActive && !activeElementIsSet && selected && this.prevActiveElement !== undefined) { - prevActive = this.prevActiveElement; - - this.defocusItem(prevActive); - } - } - - /** - * @param {Object} liData - the option that is being disabled - */ - setDisabled (liData) { - var disabled = liData.disabled, - li = liData.element, - a; - - if (!li) return; - - a = li.firstChild; - - li.classList.toggle(classNames.DISABLED, disabled); - - if (a) { - a.classList.toggle(classNames.DISABLED, disabled); - - if (disabled) { - a.setAttribute('aria-disabled', disabled); - a.setAttribute('tabindex', -1); - } else { - a.removeAttribute('aria-disabled'); - a.setAttribute('tabindex', 0); - } - } - } - - isDisabled () { - return this.element.disabled; - } - - checkDisabled () { - if (this.isDisabled()) { - this.newElement.classList.add(classNames.DISABLED); - this.button.classList.add(classNames.DISABLED); - this.button.setAttribute('aria-disabled', true); - } else { - if (this.button.classList.contains(classNames.DISABLED)) { - this.newElement.classList.remove(classNames.DISABLED); - this.button.classList.remove(classNames.DISABLED); - this.button.setAttribute('aria-disabled', false); - } - } - } - - clickListener () { - var that = this; - - spaceSelectFlag = false; - - this._on(this.button, 'keyup', function (e) { - if (/(32)/.test(e.keyCode.toString(10)) && spaceSelectFlag) { - e.preventDefault(); - spaceSelectFlag = false; - } - }); - - function clearSelection (e) { - if (that.multiple) { - that.deselectAll(); - } else { - var element = that.element, - prevValue = element.value, - prevIndex = element.selectedIndex, - prevOption = element.options[prevIndex], - prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false; - - if (prevData) { - that.setSelected(prevData, false); - } - - element.selectedIndex = 0; - - changedArguments = [prevIndex, false, prevValue]; - triggerNative(that.element, 'change'); - } - - // remove selected styling if menu is open - if (that.newElement.classList.contains(classNames.SHOW)) { - if (that.options.liveSearch) { - that.searchbox.focus(); - } - - that.createView(false); - } - } - - if (this.options.allowClear) { - this._on(this.button, 'click', function (e) { - var target = e.target, - clearButton = that.clearButton; - - if (target === clearButton || target.parentElement === clearButton) { - e.stopImmediatePropagation(); - clearSelection(e); - } - }); - } - - function setFocus () { - if (that.options.liveSearch) { - that.searchbox.focus(); - } else { - that.menuInner.focus(); - } - } - - function checkPopperExists () { - if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state) { - setFocus(); - } else { - requestAnimationFrame(checkPopperExists); - } - } - - this._on(this.element, 'shown' + EVENT_KEY, function () { - if (that.menuInner.scrollTop !== that.selectpicker.view.scrollTop) { - that.menuInner.scrollTop = that.selectpicker.view.scrollTop; - } - - requestAnimationFrame(checkPopperExists); - }); - - // ensure posinset and setsize are correct before selecting an option via a click - this._delegate(this.menuInner, 'mouseover', 'li a', function () { - var hoverLi = this.parentElement, - position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, - index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi), - hoverData = that.selectpicker.current.data[index + position0]; - - that.focusItem(hoverLi, hoverData, true); - }); - - this._delegate(this.menuInner, 'click', 'li a', function (e) { - that.onOptionClick(this, e); - }); - - this._delegate(this.menu, 'click', 'li.' + classNames.DISABLED + ' a, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.btn-close):not(.close)', function (e) { - if (e.currentTarget === this || e.target === this) { - e.preventDefault(); - e.stopPropagation(); - if (that.options.liveSearch && !e.target.classList.contains('btn-close') && !e.target.classList.contains('close')) { - that.searchbox.focus(); - } else { - that.button.focus(); - } - } - }); - - this._delegate(this.menuInner, 'click', '.divider, .dropdown-header', function (e) { - e.preventDefault(); - e.stopPropagation(); - if (that.options.liveSearch) { - that.searchbox.focus(); - } else { - that.button.focus(); - } - }); - - this._delegate(this.menu, 'click', '.' + classNames.POPOVERHEADER + ' .btn-close, .' + classNames.POPOVERHEADER + ' .close', function () { - that.dropdown.hide(); - }); - - this._delegate(this.newElement, 'click', '.bs-selected-item', function (e) { - e.preventDefault(); - e.stopPropagation(); - that.removeSelectedTag(this.getAttribute('data-option-value')); - }); - - this._delegate(this.menu, 'click', '.bs-create-option', function (e) { - e.preventDefault(); - e.stopPropagation(); - that.createOpenOption(this.getAttribute('data-search-value')); - }); - - if (this.searchbox) { - this._on(this.searchbox, 'click', function (e) { - e.stopPropagation(); - }); - } - - this._delegate(this.menu, 'click', '.actions-btn', function (e) { - if (that.options.liveSearch) { - that.searchbox.focus(); - } else { - that.button.focus(); - } - - e.preventDefault(); - e.stopPropagation(); - - if (this.classList.contains('bs-select-all')) { - that.selectAll(); - } else { - that.deselectAll(); - } - }); - - this._on(this.button, 'focus', function (e) { - var tabindex = that.element.getAttribute('tabindex'); - - // only change when button is actually focused - if (tabindex !== undefined && tabindex !== null && e.isTrusted) { - // apply select element's tabindex to ensure correct order is followed when tabbing to the next element - this.setAttribute('tabindex', tabindex); - // set element's tabindex to -1 to allow for reverse tabbing - that.element.setAttribute('tabindex', -1); - that.selectpicker.view.tabindex = tabindex; - } - }); - - this._on(this.button, 'blur', function (e) { - // revert everything to original tabindex - if (that.selectpicker.view.tabindex !== undefined && e.isTrusted) { - that.element.setAttribute('tabindex', that.selectpicker.view.tabindex); - this.setAttribute('tabindex', -1); - that.selectpicker.view.tabindex = undefined; - } - }); - - this._on(this.element, 'change', function () { - that.render(); - that._emit('changed', changedArguments ? { - clickedIndex: changedArguments[0], - isSelected: changedArguments[1], - previousValue: changedArguments[2] - } : null); - changedArguments = null; - }); - - this._on(this.element, 'focus', function () { - if (!that.options.mobile) that.button.focus(); - }); - } - - onOptionClick (clickedAnchor, e, retainActive) { - var that = this, - element = that.element, - li = clickedAnchor.parentElement, - position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, - clickedData = that.selectpicker.current.data[Array.prototype.indexOf.call(li.parentElement.children, li) + position0], - clickedElement = clickedData.element, - prevValue = getSelectValues.call(that), - prevIndex = element.selectedIndex, - prevOption = element.options[prevIndex], - prevData = prevOption ? that.selectpicker.main.data[prevOption.liIndex] : false, - triggerChange = true; - - // Don't close on multi choice menu - if (that.multiple && that.options.maxOptions !== 1) { - e.stopPropagation(); - } - - e.preventDefault(); - - // Don't run if the select is disabled - if (!that.isDisabled() && !li.classList.contains(classNames.DISABLED)) { - var option = clickedData.option, - state = option.selected, - optgroupData = that.selectpicker.current.data.find(function (datum) { - return datum.optID === clickedData.optID && datum.type === 'optgroup-label'; - }), - optgroup = optgroupData ? optgroupData.optgroup : undefined, - dataGetter = optgroup instanceof Element ? getOptionData.fromOption : getOptionData.fromDataSource, - optgroupOptions = optgroup && optgroup.children, - maxOptions = parseInt(that.options.maxOptions), - maxOptionsGrp = optgroup && parseInt(dataGetter(optgroup, 'maxOptions')) || false; - - if (clickedElement === that.activeElement) retainActive = true; - - if (!retainActive) { - that.prevActiveElement = that.activeElement; - that.activeElement = undefined; - } - - if (!that.multiple || maxOptions === 1) { // Deselect previous option if not multi select - if (prevData) that.setSelected(prevData, false); - that.setSelected(clickedData, true); - } else { // Toggle the clicked option if multi select. - that.setSelected(clickedData, !state); - that.focusedParent.focus(); - - if (maxOptions !== false || maxOptionsGrp !== false) { - var maxReached = maxOptions < getSelectedOptions.call(that).length, - selectedGroupOptions = 0; - - if (optgroup && optgroup.children) { - for (var i = 0; i < optgroup.children.length; i++) { - if (optgroup.children[i].selected) selectedGroupOptions++; - } - } - - var maxReachedGrp = maxOptionsGrp < selectedGroupOptions; - - if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { - if (maxOptions && maxOptions === 1) { - element.selectedIndex = -1; - that.setOptionStatus(true); - } else if (maxOptionsGrp && maxOptionsGrp === 1) { - for (var j = 0; j < optgroupOptions.length; j++) { - var _option = optgroupOptions[j]; - that.setSelected(that.selectpicker.current.data[_option.liIndex], false); - } - - that.setSelected(clickedData, true); - } else { - var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, - maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, - maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), - maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), - notify = createFromHTML('
    '); - - that.menu.appendChild(notify); - - if (maxOptions && maxReached) { - notify.appendChild(createFromHTML('
    ' + maxTxt + '
    ')); - triggerChange = false; - that._emit('maxReached'); - } - - if (maxOptionsGrp && maxReachedGrp) { - notify.appendChild(createFromHTML('
    ' + maxTxtGrp + '
    ')); - triggerChange = false; - that._emit('maxReachedGrp'); - } - - setTimeout(function () { - that.setSelected(clickedData, false); - }, 10); - - notify.classList.add('fadeOut'); - - setTimeout(function () { - notify.remove(); - }, 1050); - } - } - } - } - - if (that.options.source.data) that.element.appendChild(that.selectpicker.main.optionQueue); - - if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { - that.button.focus(); - } else if (that.options.liveSearch) { - that.searchbox.focus(); - } - - // Trigger select 'change' - if (triggerChange) { - if (that.multiple || prevIndex !== element.selectedIndex) { - changedArguments = [option.index, option.selected, prevValue]; - triggerNative(that.element, 'change'); - } - } - } - } - - liveSearchListener () { - var that = this; - - this._on(this.searchbox, 'click', function (e) { - e.stopPropagation(); - }); - this._on(this.searchbox, 'focus', function (e) { - e.stopPropagation(); - }); - this._on(this.searchbox, 'touchend', function (e) { - e.stopPropagation(); - }); - this._on(this.searchbox, 'keydown', function (e) { - if (e.key === 'Enter' && that.createOptionButton && !that.createOptionButton.hidden && !that.selectpicker.current.data.length) { - e.preventDefault(); - e.stopPropagation(); - that.createOpenOption(that.searchbox.value); - } - }); - - this._on(this.searchbox, 'input', function () { - var searchValue = that.searchbox.value; - - that.selectpicker.search.elements = []; - that.selectpicker.search.data = []; - - if (searchValue) { - that.selectpicker.search.previousValue = searchValue; - - if (that.options.source.search) { - that.fetchData(function () { - that.appendCreatedSearchResults(searchValue); - that.render(); - that.buildList(undefined, true); - that.noScroll = true; - that.menuInner.scrollTop = 0; - that.createView(true); - showNoResults.call(that, that.selectpicker.search.data, searchValue); - }, 'search', 0, searchValue); - } else { - var searchMatch = [], - q = searchValue.toUpperCase(), - cache = {}, - cacheArr = [], - searchStyle = that._searchStyle(), - normalizeSearch = that.options.liveSearchNormalize; - - if (normalizeSearch) q = normalizeToBase(q); - - for (var i = 0; i < that.selectpicker.main.data.length; i++) { - var li = that.selectpicker.main.data[i]; - - if (!cache[i]) { - cache[i] = stringSearch(li, q, searchStyle, normalizeSearch); - } - - if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) { - if (li.headerIndex > 0) { - cache[li.headerIndex - 1] = true; - cacheArr.push(li.headerIndex - 1); - } - - cache[li.headerIndex] = true; - cacheArr.push(li.headerIndex); - - cache[li.lastIndex + 1] = true; - } - - if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i); - } - - for (var j = 0, cacheLen = cacheArr.length; j < cacheLen; j++) { - var index = cacheArr[j], - prevIndex = cacheArr[j - 1], - liData = that.selectpicker.main.data[index], - liPrev = that.selectpicker.main.data[prevIndex]; - - if (liData.type !== 'divider' || (liData.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== j)) { - that.selectpicker.search.data.push(liData); - searchMatch.push(that.selectpicker.main.elements[index]); - } - } - - that.activeElement = undefined; - that.noScroll = true; - that.menuInner.scrollTop = 0; - that.selectpicker.search.elements = searchMatch; - that.createView(true); - showNoResults.call(that, searchMatch, searchValue); - } - } else if (that.selectpicker.search.previousValue) { - that.menuInner.scrollTop = 0; - that.createView(false); - } - - that.syncOpenOptionButton(); - }); - } - - _searchStyle () { - return this.options.liveSearchStyle || 'contains'; - } - - getValue () { - var element = this.element; - - if (this.multiple) { - var values = []; - for (var i = 0; i < element.options.length; i++) { - if (element.options[i].selected) values.push(element.options[i].value); - } - return values; - } - - return element.value; - } - - val (value) { - var element = this.element; - - if (typeof value !== 'undefined') { - var selectedOptions = getSelectedOptions.call(this), - prevValue = getSelectValues.call(this, selectedOptions); - - changedArguments = [null, null, prevValue]; - - if (!Array.isArray(value)) value = [ value ]; - - value.map(String); - - for (var i = 0; i < selectedOptions.length; i++) { - var item = selectedOptions[i]; - - if (item && value.indexOf(String(item.value)) === -1) { - this.setSelected(item, false); - } - } - - // only update selected value if it matches an existing option - this.selectpicker.main.data.filter(function (item) { - if (value.indexOf(String(item.value)) !== -1) { - this.setSelected(item, true); - return true; - } - - return false; - }, this); - - if (this.options.source.data) element.appendChild(this.selectpicker.main.optionQueue); - - this._emit('changed', changedArguments ? { - clickedIndex: changedArguments[0], - isSelected: changedArguments[1], - previousValue: changedArguments[2] - } : null); - - if (this.newElement.classList.contains(classNames.SHOW)) { - if (this.multiple) { - this.setOptionStatus(true); - } else { - var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex; - - if (typeof liSelectedIndex === 'number') { - this.setSelected(this.selectpicker.current.data[liSelectedIndex], true); - } - } - } - - this.render(); - - changedArguments = null; - - return this.element; - } else { - return this.getValue(); - } - } - - changeAll (status) { - if (!this.multiple) return; - if (typeof status === 'undefined') status = true; - - var element = this.element, - previousSelected = 0, - currentSelected = 0, - prevValue = getSelectValues.call(this); - - element.classList.add('bs-select-hidden'); - - for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) { - var liData = data[i], - option = liData.option; - - if (option && !liData.disabled && liData.type !== 'divider') { - if (liData.selected) previousSelected++; - option.selected = status; - liData.selected = status; - if (status === true) currentSelected++; - } - } - - element.classList.remove('bs-select-hidden'); - - if (previousSelected === currentSelected) return; - - this.setOptionStatus(); - - changedArguments = [null, null, prevValue]; - - triggerNative(this.element, 'change'); - } - - selectAll () { - return this.changeAll(true); - } - - deselectAll () { - return this.changeAll(false); - } - - toggle (e, state) { - var isActive, - triggerToggle = state === undefined; - - if (e && e.stopPropagation) e.stopPropagation(); - - if (triggerToggle === false) { - isActive = this.newElement.classList.contains(classNames.SHOW); - triggerToggle = (state === true && isActive === false) || (state === false && isActive === true); - } - - if (triggerToggle) this.dropdown.toggle(); - } - - open (e) { - this.toggle(e, true); - } - - close (e) { - this.toggle(e, false); - } - - _keydown (e, el) { - var that = this, - which = e.which || e.keyCode, - isToggle = el.classList.contains('dropdown-toggle'), - items = that.findLis(), - index, - isActive, - liActive, - activeLi, - offsetVal, - updateScroll = false, - downOnTab = which === keyCodes.TAB && !isToggle && !that.options.selectOnTab, - isArrowKey = REGEXP_ARROW.test(which) || downOnTab, - scrollTop = that.menuInner.scrollTop, - isVirtual = that.isVirtual(), - position0 = isVirtual === true ? that.selectpicker.view.position0 : 0; - - // do nothing if a function key is pressed - if (which >= 112 && which <= 123) return; - - isActive = that.menu.classList.contains(classNames.SHOW); - - if ( - !isActive && - ( - isArrowKey || - (which >= 48 && which <= 57) || - (which >= 96 && which <= 105) || - (which >= 65 && which <= 90) - ) - ) { - that.dropdown.show(); - - if (that.options.liveSearch) { - that.searchbox.focus(); - return; - } - } - - if (which === keyCodes.ESCAPE && isActive) { - e.preventDefault(); - that.dropdown.hide(); - that.button.focus(); - } - - if (isArrowKey) { // if up or down - if (!items.length) return; - - liActive = that.activeElement; - index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1; - - if (index !== -1) { - that.defocusItem(liActive); - } - - if (which === keyCodes.ARROW_UP) { // up - if (index !== -1) index--; - if (index + position0 < 0) index += items.length; - - if (!that.selectpicker.view.canHighlight[index + position0]) { - index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0; - if (index === -1) index = items.length - 1; - } - } else if (which === keyCodes.ARROW_DOWN || downOnTab) { // down - index++; - if (index + position0 >= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex; - - if (!that.selectpicker.view.canHighlight[index + position0]) { - index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true); - } - } - - e.preventDefault(); - - var liActiveIndex = position0 + index; - - if (which === keyCodes.ARROW_UP) { // up - // scroll to bottom and highlight last option - if (position0 === 0 && index === items.length - 1) { - that.menuInner.scrollTop = that.menuInner.scrollHeight; - - liActiveIndex = that.selectpicker.current.elements.length - 1; - } else { - activeLi = that.selectpicker.current.data[liActiveIndex]; - - // could be undefined if no results exist - if (activeLi) { - offsetVal = activeLi.position - activeLi.height; - - updateScroll = offsetVal < scrollTop; - } - } - } else if (which === keyCodes.ARROW_DOWN || downOnTab) { // down - // scroll to top and highlight first option - if (index === that.selectpicker.view.firstHighlightIndex) { - that.menuInner.scrollTop = 0; - - liActiveIndex = that.selectpicker.view.firstHighlightIndex; - } else { - activeLi = that.selectpicker.current.data[liActiveIndex]; - - // could be undefined if no results exist - if (activeLi) { - offsetVal = activeLi.position - that.sizeInfo.menuInnerHeight; - - updateScroll = offsetVal > scrollTop; - } - } - } - - liActive = that.selectpicker.current.elements[liActiveIndex]; - - that.activeElement = (that.selectpicker.current.data[liActiveIndex] || {}).element; - - that.focusItem(liActive); - - that.selectpicker.view.currentActive = liActive; - - if (updateScroll) that.menuInner.scrollTop = offsetVal; - - if (that.options.liveSearch) { - that.searchbox.focus(); - } else { - el.focus(); - } - } else if ( - (!el.matches('input') && !REGEXP_TAB_OR_ESCAPE.test(which)) || - (which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory) - ) { - var matches = [], - keyHistory; - - e.preventDefault(); - - that.selectpicker.keydown.keyHistory += keyCodeMap[which]; - - if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel); - that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start(); - - keyHistory = that.selectpicker.keydown.keyHistory; - - // if all letters are the same, set keyHistory to just the first character when searching - if (/^(.)\1+$/.test(keyHistory)) { - keyHistory = keyHistory.charAt(0); - } - - // find matches - for (var i = 0; i < that.selectpicker.current.data.length; i++) { - var li = that.selectpicker.current.data[i], - hasMatch; - - hasMatch = stringSearch(li, keyHistory, 'startsWith', true); - - if (hasMatch && that.selectpicker.view.canHighlight[i]) { - matches.push(li.element); - } - } - - if (matches.length) { - var matchIndex = 0; - - Array.prototype.forEach.call(items, function (item) { - item.classList.remove('active'); - if (item.firstChild) item.firstChild.classList.remove('active'); - }); - - // either only one key has been pressed or they are all the same key - if (keyHistory.length === 1) { - matchIndex = matches.indexOf(that.activeElement); - - if (matchIndex === -1 || matchIndex === matches.length - 1) { - matchIndex = 0; - } else { - matchIndex++; - } - } - - activeLi = that.selectpicker.main.data[that.selectpicker.main.elements.indexOf(matches[matchIndex])]; - - if (activeLi) { - if (scrollTop - activeLi.position > 0) { - offsetVal = activeLi.position - activeLi.height; - updateScroll = true; - } else { - offsetVal = activeLi.position - that.sizeInfo.menuInnerHeight; - // if the option is already visible at the current scroll position, just keep it the same - updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight; - } - } - - liActive = matches[matchIndex]; - - that.activeElement = liActive; - - that.focusItem(liActive); - - if (liActive) liActive.firstChild.focus(); - - if (updateScroll) that.menuInner.scrollTop = offsetVal; - - el.focus(); - } - } - - // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. - if ( - isActive && - ( - (which === keyCodes.SPACE && !that.selectpicker.keydown.keyHistory) || - which === keyCodes.ENTER || - (which === keyCodes.TAB && that.options.selectOnTab) - ) - ) { - if (which !== keyCodes.SPACE) e.preventDefault(); - - if (!that.options.liveSearch || which !== keyCodes.SPACE) { - var activeAnchor = that.menuInner.querySelector('.active a'); - if (activeAnchor) that.onOptionClick(activeAnchor, e, true); // retain active class - el.focus(); - - if (!that.options.liveSearch) { - // Prevent screen from scrolling if the user hits the spacebar - e.preventDefault(); - // Fixes spacebar selection of dropdown items in FF & IE - spaceSelectFlag = true; - } - } - } - } - - mobile () { - // ensure mobile is set to true if mobile function is called after init - this.options.mobile = true; - this.element.classList.add('mobile-device'); - } - - resetMenuData () { - this.selectpicker.main.data = []; - this.selectpicker.main.elements = []; - this.selectpicker.main.hasMore = false; - this.selectpicker.search.data = []; - this.selectpicker.search.elements = []; - this.selectpicker.search.hasMore = false; - this.selectpicker.current.data = this.selectpicker.main.data; - this.selectpicker.current.elements = this.selectpicker.main.elements; - this.selectpicker.current.hasMore = false; - this.selectpicker.isSearching = false; - } - - refresh () { - var that = this; - // update options if data attributes have been changed - var config = stripRemovedOptions(Object.assign({}, this.options, getAttributesObject(this.element), getDataset(this.element))); - this.options = config; - - if (this.options.source.data) { - this.render(); - this.buildList(); - } else { - this.resetMenuData(); - this.fetchData(function () { - that.render(); - that.buildList(); - }); - } - - this.checkDisabled(); - this.setStyle(); - this.setWidth(); - - this.setSize(true); - - this._emit('refreshed'); - } - - hide () { - this.newElement.style.display = 'none'; - } - - show () { - this.newElement.style.display = ''; - } - - remove () { - if (this.newElement.parentNode) this.newElement.parentNode.removeChild(this.newElement); - instanceMap.delete(this.element); - } - - destroy () { - // move the select back out of newElement, then remove newElement - if (this.newElement.parentNode) { - this.newElement.parentNode.insertBefore(this.element, this.newElement); - this.newElement.parentNode.removeChild(this.newElement); - } - - if (this.bsContainer) { - if (this.bsContainer.parentNode) this.bsContainer.parentNode.removeChild(this.bsContainer); - } else if (this.menu && this.menu.parentNode) { - this.menu.parentNode.removeChild(this.menu); - } - - if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) { - this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption); - } - - // remove all tracked event listeners - for (var i = 0; i < this._listeners.length; i++) { - var l = this._listeners[i]; - l.el.removeEventListener(l.type, l.handler, l.options); - } - this._listeners = []; - - for (var key in this._named) { - if (Object.prototype.hasOwnProperty.call(this._named, key)) { - this._removeNamed(key); - } - } - - if (this.dropdown && typeof this.dropdown.dispose === 'function') { - this.dropdown.dispose(); - } - - this.element.classList.remove('bs-select-hidden', 'selectpicker', 'mobile-device'); - - instanceMap.delete(this.element); - } -} - -// stores element -> Selectpicker instance -var instanceMap = new WeakMap(); - -Selectpicker.NAME = 'selectpicker'; -Selectpicker.VERSION = '1.1.2'; - -// user-provided global defaults (set via Selectpicker.setDefaults, used by i18n files) -Selectpicker.defaults = null; - -// part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both. -Selectpicker.DEFAULTS = { - noneSelectedText: 'Nothing selected', - noneResultsText: 'No results matched {0}', - countSelectedText: function (numSelected) { - return (numSelected == 1) ? '{0} item selected' : '{0} items selected'; - }, - maxOptionsText: function (numAll, numGroup) { - return [ - (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', - (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' - ]; - }, - selectAllText: 'Select All', - deselectAllText: 'Deselect All', - source: { - pageSize: 40, - create: null - }, - chunkSize: 40, - doneButton: false, - doneButtonText: 'Close', - multipleSeparator: ', ', - style: classNames.BUTTONCLASS, - size: 'auto', - placeholder: null, - allowClear: false, - selectedTextFormat: 'values', - width: false, - hideDisabled: false, - showSubtext: false, - showIcon: true, - showContent: true, - dropupAuto: true, - header: false, - liveSearch: false, - liveSearchPlaceholder: null, - liveSearchNormalize: false, - liveSearchStyle: 'contains', - openOptions: false, - openOptionsText: 'Create "{0}"', - selectionIndicator: 'checkmark', - actionsBox: false, - iconBase: classNames.ICONBASE, - tickIcon: classNames.TICKICON, - showTick: false, - showSelectedTags: false, - selectedItemsStyle: 'tags', - selectedTagRemoveLabel: 'Remove', - template: { - caret: '' - }, - maxOptions: false, - selectOnTab: true, - dropdownAlignRight: false, - virtualScroll: 600, - sanitize: true, - sanitizeFn: null, - whiteList: DefaultWhitelist -}; - -Selectpicker._buildConfig = function (element, options) { - options = stripRemovedOptions(options || {}); - - var dataAttributes = stripRemovedOptions(getDataset(element)); - - for (var dataAttr in dataAttributes) { - if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { - delete dataAttributes[dataAttr]; - } - } - - var userDefaults = stripRemovedOptions(Selectpicker.defaults || {}); - - var config = Object.assign({}, Selectpicker.DEFAULTS, userDefaults, getAttributesObject(element), dataAttributes, options); - config.template = Object.assign({}, Selectpicker.DEFAULTS.template, userDefaults.template || {}, dataAttributes.template, options.template); - config.source = Object.assign({}, Selectpicker.DEFAULTS.source, userDefaults.source || {}, options.source); - - return applyLegacyOptions(element, config); -}; - -Selectpicker.setDefaults = function (newDefaults) { - Selectpicker.defaults = stripRemovedOptions(Object.assign({}, Selectpicker.defaults, newDefaults)); -}; - -Selectpicker.getInstance = function (element) { - if (typeof element === 'string') element = document.querySelector(element); - return instanceMap.get(element) || null; -}; - -Selectpicker.getOrCreateInstance = function (element, options) { - if (typeof element === 'string') element = document.querySelector(element); - if (!element || element.tagName !== 'SELECT') return null; - - var instance = instanceMap.get(element); - - if (instance) { - options = stripRemovedOptions(options); - - if (options && typeof options === 'object') { - for (var i in options) { - if (Object.prototype.hasOwnProperty.call(options, i)) { - instance.options[i] = options[i]; - } - } - } - - return instance; - } - - return new Selectpicker(element, typeof options === 'object' ? options : {}); -}; - -// -var KEYDOWN_SELECTOR = '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input'; - -// Handle keyboard navigation ourselves. This listener runs in the capture -// phase on `window` so it executes before Bootstrap's `document`-level -// (capture-phase, delegated) dropdown keydown handler and prevents it from -// processing bootstrap-select's custom menu (which would otherwise error on -// relocated/container menus and conflict with our own navigation). This -// replaces the upstream approach of unbinding Bootstrap's global handler. -window.addEventListener('keydown', function (e) { - var target = e.target; - if (!target || !target.closest) return; - - // Any keydown originating inside a bootstrap-select widget (or its relocated - // menu container) must not reach Bootstrap's dropdown keydown handler. - var widget = target.closest('.bootstrap-select, .bs-container'); - if (!widget) return; - - e.stopImmediatePropagation(); - - var trigger = target.closest(KEYDOWN_SELECTOR); - if (!trigger) return; - - var instance; - for (var node = trigger; node; node = node.parentElement) { - if (node.bootstrapSelectInstance) { - instance = node.bootstrapSelectInstance; - break; - } - } - - if (instance) instance._keydown(e, trigger); -}, true); - -document.addEventListener('focusin', function (e) { - var target = e.target; - if (target && target.closest && target.closest(KEYDOWN_SELECTOR)) { - e.stopPropagation(); - } -}); - -function initAll () { - var selects = document.querySelectorAll('.selectpicker'); - Array.prototype.forEach.call(selects, function (select) { - Selectpicker.getOrCreateInstance(select); - }); -} - -if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', initAll); -} else { - initAll(); -} -// - -if (typeof window !== 'undefined') { - window.Selectpicker = Selectpicker; -} - -return Selectpicker; diff --git a/js/bootstrap-select.render.js b/js/bootstrap-select.render.js new file mode 100644 index 00000000..519fa67a --- /dev/null +++ b/js/bootstrap-select.render.js @@ -0,0 +1,443 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + findLis () { + return this.menuInner.querySelectorAll('.inner > li'); + } + + render (init) { + var that = this, + element = this.element, + // ensure titleOption is appended and selected (if necessary) before getting selectedOptions + placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0, + selectedOptions = getSelectedOptions.call(this), + selectedCount = selectedOptions.length, + selectedValues = getSelectValues.call(this, selectedOptions), + button = this.button, + buttonInner = button.querySelector('.filter-option-inner-inner'), + multipleSeparator = document.createTextNode(this.options.multipleSeparator), + titleFragment = elementTemplates.fragment.cloneNode(false), + forceCount = this.multiple && this.options.showSelectedTags && selectedCount > 0, + showCount, + countMax, + hasContent = false; + + function createSelected (item) { + if (item.selected) { + that.createOption(item, true); + } else if (item.children && item.children.length) { + item.children.map(createSelected); + } + } + + // create selected option elements to ensure select value is correct + if (this.options.source.data && init) { + selectedOptions.map(createSelected); + element.appendChild(this.selectpicker.main.optionQueue); + + if (placeholderSelected) placeholderSelected = element.selectedIndex === 0; + } + + button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !selectedValues && selectedValues !== 0); + + if (!that.multiple && selectedOptions.length === 1) { + that.selectpicker.view.displayedValue = selectedValues; + } + + if (this.options.selectedTextFormat === 'static') { + titleFragment = generateOption.text.call(this, { text: this.options.placeholder }, true); + } else { + showCount = forceCount || this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 0; + + // determine if the number of selected options will be shown (showCount === true) + if (showCount && !forceCount) { + countMax = this.options.selectedTextFormat.split('>'); + showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2); + } + + // only loop through all selected options if the count won't be shown + if (showCount === false) { + if (!placeholderSelected) { + for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) { + if (selectedIndex < 50) { + var option = selectedOptions[selectedIndex], + titleOptions = {}; + + if (option) { + if (this.multiple && selectedIndex > 0) { + titleFragment.appendChild(multipleSeparator.cloneNode(false)); + } + + if (option.title) { + titleOptions.text = option.title; + } else if (option.content && that.options.showContent) { + titleOptions.content = option.content.toString(); + hasContent = true; + } else { + if (that.options.showIcon) { + titleOptions.icon = option.icon; + } + if (that.options.showSubtext && !that.multiple && option.subtext) titleOptions.subtext = ' ' + option.subtext; + titleOptions.text = option.text.trim(); + } + + titleFragment.appendChild(generateOption.text.call(this, titleOptions, true)); + } + } else { + break; + } + } + + // add ellipsis + if (selectedCount > 49) { + titleFragment.appendChild(document.createTextNode('...')); + } + } + } else { + var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"]):not([style*="display: none"])'; + if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; + + // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc. + var totalCount = this.element.querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length, + tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText; + + titleFragment = generateOption.text.call(this, { + text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString()) + }, true); + } + } + + // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText + if (!titleFragment.childNodes.length) { + titleFragment = generateOption.text.call(this, { + text: this.options.placeholder ? this.options.placeholder : this.options.noneSelectedText + }, true); + } + + // if the select has a title, apply it to the button, and if not, apply titleFragment text + button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim(); + + if (this.options.sanitize && hasContent) { + sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn); + } + + buttonInner.innerHTML = ''; + buttonInner.appendChild(titleFragment); + + this.syncTagEditor(); + + this._emit('rendered'); + } + + usesTagEditor () { + return this.options.liveSearch && (this.options.showSelectedTags || this.options.openOptions); + } + + syncTagEditor () { + if (!this.usesTagEditor()) return; + + if (this.selectedItems) { + var selectedOptions = getSelectedOptions.call(this), + useListStyle = this.options.selectedItemsStyle === 'list'; + + this.selectedItems.innerHTML = ''; + this.selectedItems.hidden = !selectedOptions.length; + this.selectedItems.classList.toggle('list-group', useListStyle); + + for (var i = 0; i < selectedOptions.length; i++) { + var item = selectedOptions[i], + selectedTag = document.createElement('button'), + removeText = this.options.selectedTagRemoveLabel + ' ' + getOptionLabelText(item), + content = document.createElement('span'), + label = document.createElement('span'), + remove = document.createElement('span'), + icon; + + selectedTag.type = 'button'; + selectedTag.className = useListStyle + ? 'bs-selected-item list-group-item list-group-item-action' + : 'bs-selected-item'; + selectedTag.setAttribute('data-option-value', item.value); + selectedTag.setAttribute('aria-label', removeText); + selectedTag.title = removeText; + + content.className = 'bs-selected-item-content'; + + if (item.icon && this.options.showIcon) { + icon = document.createElement('span'); + icon.className = 'bs-selected-item-icon ' + this.options.iconBase + ' ' + item.icon; + icon.setAttribute('aria-hidden', 'true'); + content.appendChild(icon); + } + + label.className = 'bs-selected-item-label'; + label.textContent = getOptionLabelText(item); + content.appendChild(label); + + remove.className = 'bs-selected-item-remove'; + remove.setAttribute('aria-hidden', 'true'); + remove.textContent = '\u00d7'; + + selectedTag.appendChild(content); + selectedTag.appendChild(remove); + this.selectedItems.appendChild(selectedTag); + } + } + + this.syncOpenOptionButton(); + + if (this.newElement && this.newElement.classList.contains(classNames.SHOW)) { + this.setSize(true); + } + } + + syncOpenOptionButton () { + if (!this.createOptionButton) return; + + var searchValue = this.searchbox ? this.searchbox.value : '', + normalizedValue = searchValue.toString().trim(), + shouldShow = !!normalizedValue && + !this.selectpicker.openOption.isCreating && + !this.findOptionBySearchValue(normalizedValue); + + this.createOptionButton.hidden = !shouldShow; + this.createOptionButton.disabled = this.selectpicker.openOption.isCreating; + + if (shouldShow) { + this.createOptionButton.textContent = this.options.openOptionsText.replace('{0}', normalizedValue); + this.createOptionButton.setAttribute('data-search-value', normalizedValue); + } else { + this.createOptionButton.textContent = ''; + this.createOptionButton.removeAttribute('data-search-value'); + } + } + + findOptionByValue (value, dataSet) { + var options = dataSet || this.selectpicker.main.data, + stringValue = String(value); + + for (var i = 0; i < options.length; i++) { + var option = options[i]; + + if (option.type === 'option' && String(option.value) === stringValue) { + return option; + } + } + + return null; + } + + findOptionBySearchValue (searchValue) { + var options = this.options.source.data || this.options.source.search + ? Object.values(this.selectpicker.optionValuesDataMap) + : this.selectpicker.main.data, + normalizedSearch = normalizeSearchInput(searchValue, this.options.liveSearchNormalize); + + for (var i = 0; i < options.length; i++) { + var option = options[i]; + + if (option.type !== 'option') continue; + + if ( + normalizeSearchInput(option.text, this.options.liveSearchNormalize) === normalizedSearch || + normalizeSearchInput(option.value, this.options.liveSearchNormalize) === normalizedSearch || + normalizeSearchInput(option.title, this.options.liveSearchNormalize) === normalizedSearch + ) { + return option; + } + } + + return null; + } + + createOptionElement (optionData) { + var option = document.createElement('option'); + + option.value = optionData.value === undefined ? optionData.text : optionData.value; + option.textContent = optionData.text === undefined ? option.value : optionData.text; + + if (optionData.className) option.className = optionData.className; + if (optionData.title) option.title = optionData.title; + if (optionData.content) option.setAttribute('data-content', optionData.content); + if (optionData.tokens) option.setAttribute('data-tokens', optionData.tokens); + if (optionData.subtext) option.setAttribute('data-subtext', optionData.subtext); + if (optionData.icon) option.setAttribute('data-icon', optionData.icon); + if (optionData.disabled) option.disabled = true; + if (optionData.hidden) option.hidden = true; + + return option; + } + + appendCreatedSearchResults (searchValue) { + if (!this.selectpicker.createdOptions.length) return; + + var matches = []; + + for (var i = 0; i < this.selectpicker.createdOptions.length; i++) { + var option = this.selectpicker.createdOptions[i]; + + if ( + stringSearch(option, normalizeSearchInput(searchValue, this.options.liveSearchNormalize), this._searchStyle(), this.options.liveSearchNormalize) && + !this.findOptionByValue(option.value, this.selectpicker.search.data) + ) { + matches.push(option); + } + } + + if (matches.length) this.buildData(matches, 'search'); + } + + addCreatedOption (optionData) { + optionData = Object.assign({}, optionData); + optionData.value = optionData.value === undefined ? optionData.text : optionData.value; + optionData.text = optionData.text === undefined ? optionData.value : optionData.text; + + var size = this.selectpicker.main.elements ? this.selectpicker.main.elements.length : 0, + option = this.createOptionElement(optionData); + optionData.option = option; + + this.element.appendChild(option); + var builtOptions = this.buildData([optionData], 'data'), + builtOption = builtOptions[0]; + + this.buildList(size); + this.selectpicker.createdOptions.push(builtOption); + + return builtOption; + } + + removeSelectedTag (value) { + var option = this.findOptionByValue(value); + + if (!option || !option.selected) return; + + var prevValue = getSelectValues.call(this); + + this.setSelected(option, false); + changedArguments = [option.index, false, prevValue]; + triggerNative(this.element, 'change'); + + if (this.options.liveSearch) this.searchbox.focus(); + } + + createOpenOption (searchValue) { + searchValue = searchValue === undefined || searchValue === null ? '' : searchValue.toString().trim(); + + if (!searchValue || this.selectpicker.openOption.isCreating) return; + + var existingOption = this.findOptionBySearchValue(searchValue); + + if (existingOption) { + if (!existingOption.selected) { + var prevSelectedValue = getSelectValues.call(this); + + this.setSelected(existingOption, true); + changedArguments = [existingOption.index, true, prevSelectedValue]; + triggerNative(this.element, 'change'); + } + + if (this.options.liveSearch) this.searchbox.focus(); + return; + } + + var that = this, + prevValue = getSelectValues.call(this), + createHandler = this.options.source.create; + + this.selectpicker.openOption.isCreating = true; + this.syncOpenOptionButton(); + + function finalize (createdOption) { + that.selectpicker.openOption.isCreating = false; + + if (createdOption === undefined || createdOption === null || createdOption === false) { + that.syncOpenOptionButton(); + return; + } + + if (Array.isArray(createdOption)) createdOption = createdOption[0]; + if (typeof createdOption !== 'object') { + createdOption = { + text: createdOption, + value: createdOption + }; + } + + if (!createdOption.text && !createdOption.value) { + createdOption.text = searchValue; + } + + if (createdOption.value === undefined) createdOption.value = createdOption.text; + if (createdOption.text === undefined) createdOption.text = createdOption.value; + + var option = that.findOptionByValue(createdOption.value) || that.findOptionBySearchValue(createdOption.text); + + if (!option) { + option = that.addCreatedOption(createdOption); + } + + that.setSelected(option, true); + + if (that.options.source.data) that.element.appendChild(that.selectpicker.main.optionQueue); + + if (that.searchbox) { + that.searchbox.value = ''; + } + + that.selectpicker.search.previousValue = ''; + that.selectpicker.search.data = []; + that.selectpicker.search.elements = []; + that.createView(false); + + changedArguments = [option.index, true, prevValue]; + triggerNative(that.element, 'change'); + + if (that.options.liveSearch) that.searchbox.focus(); + } + + if (typeof createHandler === 'function') { + var returnedOption = createHandler.call(this, finalize, searchValue); + + if (returnedOption && typeof returnedOption.then === 'function') { + returnedOption.then(finalize); + } else if (returnedOption !== undefined) { + finalize(returnedOption); + } + } else { + finalize({ + text: searchValue, + value: searchValue + }); + } + } + + /** + * @param [newStyle] + * @param [status] + */ + setStyle (newStyle, status) { + var button = this.button, + newElement = this.newElement, + style = this.options.style.trim(), + buttonClass; + + if (this.element.getAttribute('class')) { + var extra = this.element.getAttribute('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '').trim(); + if (extra) newElement.classList.add.apply(newElement.classList, extra.split(/\s+/)); + } + + if (newStyle) { + buttonClass = newStyle.trim(); + } else { + buttonClass = style; + } + + if (status === 'add') { + if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); + } else if (status === 'remove') { + if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' ')); + } else { + if (style) button.classList.remove.apply(button.classList, style.split(' ')); + if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); + } + } + diff --git a/js/bootstrap-select.runtime.js b/js/bootstrap-select.runtime.js new file mode 100644 index 00000000..3f64a387 --- /dev/null +++ b/js/bootstrap-select.runtime.js @@ -0,0 +1,72 @@ +/* global Selector, __SELECTPICKER_EXPOSE_GLOBAL__ */ + +// +var KEYDOWN_SELECTOR = '.bootstrap-select [' + Selector.DATA_TOGGLE + '], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input'; + +function initSelectpickerRuntime (Selectpicker, exposeGlobal) { + if (typeof window === 'undefined' || typeof document === 'undefined') return; + + // Handle keyboard navigation ourselves. This listener runs in the capture + // phase on `window` so it executes before Bootstrap's `document`-level + // (capture-phase, delegated) dropdown keydown handler and prevents it from + // processing bootstrap-select's custom menu (which would otherwise error on + // relocated/container menus and conflict with our own navigation). This + // replaces the upstream approach of unbinding Bootstrap's global handler. + window.addEventListener('keydown', function (e) { + var target = e.target; + if (!target || !target.closest) return; + + // Any keydown originating inside a bootstrap-select widget (or its + // relocated menu container) must not reach Bootstrap's dropdown keydown + // handler. + var widget = target.closest('.bootstrap-select, .bs-container'); + if (!widget) return; + + e.stopImmediatePropagation(); + + var trigger = target.closest(KEYDOWN_SELECTOR); + if (!trigger) return; + + var instance; + for (var node = trigger; node; node = node.parentElement) { + if (node.bootstrapSelectInstance) { + instance = node.bootstrapSelectInstance; + break; + } + } + + if (instance) instance._keydown(e, trigger); + }, true); + + document.addEventListener('focusin', function (e) { + var target = e.target; + if (target && target.closest && target.closest(KEYDOWN_SELECTOR)) { + e.stopPropagation(); + } + }); + + function initAll () { + var selects = document.querySelectorAll('.selectpicker'); + Array.prototype.forEach.call(selects, function (select) { + Selectpicker.getOrCreateInstance(select); + }); + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', initAll); + } else { + initAll(); + } + + if (exposeGlobal) { + window.Selectpicker = Selectpicker; + } +} + +initSelectpickerRuntime( + Selectpicker, + typeof __SELECTPICKER_EXPOSE_GLOBAL__ === 'undefined' ? true : __SELECTPICKER_EXPOSE_GLOBAL__ +); +// + +return Selectpicker; diff --git a/js/bootstrap-select.search.js b/js/bootstrap-select.search.js new file mode 100644 index 00000000..afecc87a --- /dev/null +++ b/js/bootstrap-select.search.js @@ -0,0 +1,166 @@ +/* eslint-disable no-unused-vars */ +// Shared ordered source fragment consumed by the Grunt JS build. + +// +function stringSearch (li, searchString, method, normalize) { + var stringTypes = [ + 'display', + 'subtext', + 'tokens' + ], + searchSuccess = false; + + for (var i = 0; i < stringTypes.length; i++) { + var stringType = stringTypes[i], + string = li[stringType]; + + if (string) { + string = string.toString(); + + // Strip HTML tags. This isn't perfect, but it's much faster than any other method + if (stringType === 'display') { + string = string.replace(/<[^>]+>/g, ''); + } + + if (normalize) string = normalizeToBase(string); + string = string.toUpperCase(); + + if (typeof method === 'function') { + searchSuccess = method(string, searchString); + } else if (method === 'contains') { + searchSuccess = string.indexOf(searchString) >= 0; + } else { + searchSuccess = string.startsWith(searchString); + } + + if (searchSuccess) break; + } + } + + return searchSuccess; +} + +function normalizeSearchInput (value, normalize) { + if (value === undefined || value === null) value = ''; + value = value.toString().trim(); + + if (normalize && value) value = normalizeToBase(value); + + return value.toUpperCase(); +} + +function getOptionLabelText (option) { + if (!option) return ''; + + return option.title || option.text || option.value || ''; +} + +// Borrowed from Lodash (_.deburr) +/** Used to map Latin Unicode letters to basic Latin letters. */ +var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' +}; + +/** Used to match Latin Unicode letters (excluding mathematical operators). */ +var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + +/** Used to compose unicode character classes. */ +var rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboMarksExtendedRange = '\\u1ab0-\\u1aff', + rsComboMarksSupplementRange = '\\u1dc0-\\u1dff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange; + +/** Used to compose unicode capture groups. */ +var rsCombo = '[' + rsComboRange + ']'; + +var reComboMark = RegExp(rsCombo, 'g'); + +function deburrLetter (key) { + return deburredLetters[key]; +} + +function normalizeToBase (string) { + string = string.toString(); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); +} + +// List of HTML entities for escaping. +var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' +}; + +var createEscaper = function (map) { + var escaper = function (match) { + return map[match]; + }; + var source = '(?:' + Object.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function (string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; +}; + +var htmlEscape = createEscaper(escapeMap); +// diff --git a/js/bootstrap-select.sizing.js b/js/bootstrap-select.sizing.js new file mode 100644 index 00000000..49509fcc --- /dev/null +++ b/js/bootstrap-select.sizing.js @@ -0,0 +1,492 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + liHeight (refresh) { + if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return; + + var newElement = elementTemplates.div.cloneNode(false), + menu = elementTemplates.div.cloneNode(false), + menuInner = elementTemplates.div.cloneNode(false), + menuInnerInner = document.createElement('ul'), + divider = elementTemplates.li.cloneNode(false), + dropdownHeader = elementTemplates.li.cloneNode(false), + li, + a = elementTemplates.a.cloneNode(false), + text = elementTemplates.span.cloneNode(false), + header = this.options.header && this.menu.querySelectorAll('.' + classNames.POPOVERHEADER).length > 0 ? this.menu.querySelector('.' + classNames.POPOVERHEADER).cloneNode(true) : null, + search = this.options.liveSearch && this.menu.querySelector('.bs-searchbox') + ? this.menu.querySelector('.bs-searchbox').cloneNode(true) + : null, + actions = this.options.actionsBox && this.multiple && this.menu.querySelectorAll('.bs-actionsbox').length > 0 ? this.menu.querySelector('.bs-actionsbox').cloneNode(true) : null, + doneButton = this.options.doneButton && this.multiple && this.menu.querySelectorAll('.bs-donebutton').length > 0 ? this.menu.querySelector('.bs-donebutton').cloneNode(true) : null, + firstOption = this.element.options[0]; + + this.sizeInfo.selectWidth = this.newElement.offsetWidth; + + text.className = 'text'; + a.className = 'dropdown-item ' + (firstOption ? firstOption.className : ''); + newElement.className = this.menu.parentNode.className + ' ' + classNames.SHOW; + newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating + menu.className = classNames.MENU + ' ' + classNames.SHOW; + menuInner.className = 'inner ' + classNames.SHOW; + menuInnerInner.className = classNames.MENU + ' inner ' + classNames.SHOW; + divider.className = classNames.DIVIDER; + dropdownHeader.className = 'dropdown-header'; + + text.appendChild(document.createTextNode('\u200b')); + + if (this.selectpicker.current.data.length) { + for (var i = 0; i < this.selectpicker.current.data.length; i++) { + var data = this.selectpicker.current.data[i]; + if (data.type === 'option' && window.getComputedStyle(data.element.firstChild).display !== 'none') { + li = data.element; + break; + } + } + } else { + li = elementTemplates.li.cloneNode(false); + a.appendChild(text); + li.appendChild(a); + } + + dropdownHeader.appendChild(text.cloneNode(true)); + + if (this.selectpicker.view.widestOption) { + menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true)); + } + + menuInnerInner.appendChild(li); + menuInnerInner.appendChild(divider); + menuInnerInner.appendChild(dropdownHeader); + if (header) menu.appendChild(header); + if (search) menu.appendChild(search); + if (actions) menu.appendChild(actions); + menuInner.appendChild(menuInnerInner); + menu.appendChild(menuInner); + if (doneButton) menu.appendChild(doneButton); + newElement.appendChild(menu); + + document.body.appendChild(newElement); + + var liHeight = li.offsetHeight, + dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0, + headerHeight = header ? header.offsetHeight : 0, + searchHeight = search ? search.offsetHeight : 0, + actionsHeight = actions ? actions.offsetHeight : 0, + doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, + dividerHeight = outerHeight(divider, true), + menuStyle = window.getComputedStyle(menu), + menuWidth = menu.offsetWidth, + menuPadding = { + vert: toInteger(menuStyle.paddingTop) + + toInteger(menuStyle.paddingBottom) + + toInteger(menuStyle.borderTopWidth) + + toInteger(menuStyle.borderBottomWidth), + horiz: toInteger(menuStyle.paddingLeft) + + toInteger(menuStyle.paddingRight) + + toInteger(menuStyle.borderLeftWidth) + + toInteger(menuStyle.borderRightWidth) + }, + menuExtras = { + vert: menuPadding.vert + + toInteger(menuStyle.marginTop) + + toInteger(menuStyle.marginBottom) + 2, + horiz: menuPadding.horiz + + toInteger(menuStyle.marginLeft) + + toInteger(menuStyle.marginRight) + 2 + }, + scrollBarWidth; + + menuInner.style.overflowY = 'scroll'; + + scrollBarWidth = menu.offsetWidth - menuWidth; + + document.body.removeChild(newElement); + + this.sizeInfo.liHeight = liHeight; + this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight; + this.sizeInfo.headerHeight = headerHeight; + this.sizeInfo.searchHeight = searchHeight; + this.sizeInfo.actionsHeight = actionsHeight; + this.sizeInfo.doneButtonHeight = doneButtonHeight; + this.sizeInfo.dividerHeight = dividerHeight; + this.sizeInfo.menuPadding = menuPadding; + this.sizeInfo.menuExtras = menuExtras; + this.sizeInfo.menuWidth = menuWidth; + this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz; + this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth; + this.sizeInfo.scrollBarWidth = scrollBarWidth; + this.sizeInfo.selectHeight = this.newElement.offsetHeight; + + this.setPositionData(); + } + + getSelectPosition () { + var that = this, + winScrollTop = window.pageYOffset, + winScrollLeft = window.pageXOffset, + winHeight = document.documentElement.clientHeight, + winWidth = document.documentElement.clientWidth, + pos = offset(that.newElement); + + this.sizeInfo.selectOffsetTop = pos.top - winScrollTop; + this.sizeInfo.selectOffsetBot = winHeight - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight; + this.sizeInfo.selectOffsetLeft = pos.left - winScrollLeft; + this.sizeInfo.selectOffsetRight = winWidth - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth; + } + + setMenuSize (isAuto) { + this.getSelectPosition(); + + var selectWidth = this.sizeInfo.selectWidth, + liHeight = this.sizeInfo.liHeight, + headerHeight = this.sizeInfo.headerHeight, + searchHeight = this.sizeInfo.searchHeight, + actionsHeight = this.sizeInfo.actionsHeight, + doneButtonHeight = this.sizeInfo.doneButtonHeight, + divHeight = this.sizeInfo.dividerHeight, + menuPadding = this.sizeInfo.menuPadding, + menuInnerHeight, + menuHeight, + divLength = 0, + minHeight, + _minHeight, + maxHeight, + menuInnerMinHeight, + estimate, + isDropup; + + if (this.options.dropupAuto) { + // Get the estimated height of the menu without scrollbars. + estimate = liHeight * this.selectpicker.current.data.length + menuPadding.vert; + + isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot; + + // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth) + if (this.selectpicker.isSearching === true) { + isDropup = this.selectpicker.dropup; + } + + this.newElement.classList.toggle(classNames.DROPUP, isDropup); + this.selectpicker.dropup = isDropup; + } + + if (this.options.size === 'auto') { + _minHeight = this.selectpicker.current.data.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0; + menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert; + minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; + menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0); + + if (this.newElement.classList.contains(classNames.DROPUP)) { + menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert; + } + + maxHeight = menuHeight; + menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert; + } else if (this.options.size && this.options.size !== 'auto' && this.selectpicker.current.elements.length > this.options.size) { + for (var i = 0; i < this.options.size; i++) { + if (this.selectpicker.current.data[i].type === 'divider') divLength++; + } + + menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; + menuInnerHeight = menuHeight - menuPadding.vert; + maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; + minHeight = menuInnerMinHeight = ''; + } + + setStyles(this.menu, { + maxHeight: maxHeight + 'px', + overflow: 'hidden', + minHeight: minHeight + 'px' + }); + + setStyles(this.menuInner, { + maxHeight: menuInnerHeight + 'px', + overflow: 'hidden auto', + minHeight: menuInnerMinHeight + 'px' + }); + + // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView + this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1); + + if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) { + this.sizeInfo.hasScrollBar = true; + this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth; + } + + if (this.options.dropdownAlignRight === 'auto') { + this.menu.classList.toggle(classNames.MENUEND, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth)); + } + + if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update(); + } + + setSize (refresh) { + this.liHeight(refresh); + + if (this.options.header) this.menu.style.paddingTop = 0; + + if (this.options.size !== false) { + var that = this; + + this.setMenuSize(); + + if (this.options.liveSearch) { + this._replace('setMenuSizeInput', this.searchbox, 'input', function () { + return that.setMenuSize(); + }); + } + + if (this.options.size === 'auto') { + var windowSizeHandler = function () { + return that.setMenuSize(); + }; + this._replace('setMenuSizeResize', window, 'resize', windowSizeHandler); + this._replace('setMenuSizeScroll', window, 'scroll', windowSizeHandler); + } else if (this.options.size && this.options.size !== 'auto' && this.selectpicker.current.elements.length > this.options.size) { + this._removeNamed('setMenuSizeResize'); + this._removeNamed('setMenuSizeScroll'); + } + } + + this.createView(false, true, refresh); + } + + setWidth () { + this.menu.style.minWidth = ''; + this.newElement.style.width = ''; + this.newElement.classList.remove('fit-width'); + + if (this.options.width === 'fit') { + this.newElement.classList.add('fit-width'); + return; + } + + if (this.options.width && this.options.width !== 'auto') { + this.newElement.style.width = this.options.width; + } + } + + selectPosition () { + this.bsContainer = createFromHTML('
    '); + + var that = this, + container = resolveContainer(this.options.container), + pos, + containerPos, + actualHeight, + getPlacement = function (element) { + var Dropdown = getDropdown(), + containerPosition = {}, + // fall back to dropdown's default display setting if display is not manually set + display = that.options.display || (Dropdown.Default ? Dropdown.Default.display : false); + + var extraClass = element.getAttribute('class').replace(/form-control|fit-width/gi, '').trim(); + if (extraClass) that.bsContainer.classList.add.apply(that.bsContainer.classList, extraClass.split(/\s+/)); + that.bsContainer.classList.toggle(classNames.DROPUP, element.classList.contains(classNames.DROPUP)); + pos = offset(element); + + if (container !== document.body) { + containerPos = offset(container); + var containerStyle = window.getComputedStyle(container); + containerPos.top += toInteger(containerStyle.borderTopWidth) - container.scrollTop; + containerPos.left += toInteger(containerStyle.borderLeftWidth) - container.scrollLeft; + } else { + containerPos = { top: 0, left: 0 }; + } + + actualHeight = element.classList.contains(classNames.DROPUP) ? 0 : element.offsetHeight; + + // Bootstrap 5 uses Popper for menu positioning + if (display === 'static') { + containerPosition.top = pos.top - containerPos.top + actualHeight; + containerPosition.left = pos.left - containerPos.left; + } + + containerPosition.width = element.offsetWidth; + + setStyles(that.bsContainer, { + top: containerPosition.top !== undefined ? containerPosition.top + 'px' : '', + left: containerPosition.left !== undefined ? containerPosition.left + 'px' : '', + width: containerPosition.width + 'px' + }); + }; + + this._on(this.button, 'click', function () { + if (that.isDisabled()) { + return; + } + + getPlacement(that.newElement); + + container.appendChild(that.bsContainer); + that.bsContainer.classList.toggle(classNames.SHOW, !that.button.classList.contains(classNames.SHOW)); + that.bsContainer.appendChild(that.menu); + }); + + var windowHandler = function () { + var isActive = that.newElement.classList.contains(classNames.SHOW); + + if (isActive) getPlacement(that.newElement); + }; + this._replace('selectPositionResize', window, 'resize', windowHandler); + this._replace('selectPositionScroll', window, 'scroll', windowHandler); + + this._on(this.element, 'hide' + EVENT_KEY, function () { + that._menuHeight = outerHeight(that.menu); + if (that.bsContainer.parentNode) that.bsContainer.parentNode.removeChild(that.bsContainer); + }); + } + + createOption (data, init) { + var optionData = !data.option ? data : data.option; + + if (optionData && optionData.nodeType !== 1) { + var option = (init ? elementTemplates.selectedOption : elementTemplates.option).cloneNode(true); + if (optionData.value !== undefined) option.value = optionData.value; + option.textContent = optionData.text; + + option.selected = true; + + if (optionData.liIndex !== undefined) { + option.liIndex = optionData.liIndex; + } else if (!init) { + option.liIndex = data.index; + } + + data.option = option; + + this.selectpicker.main.optionQueue.appendChild(option); + } + } + + setOptionStatus (selectedOnly) { + var that = this; + + that.noScroll = false; + + if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) { + for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) { + var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0], + option = liData.option; + + if (option) { + if (selectedOnly !== true) { + that.setDisabled(liData); + } + + that.setSelected(liData); + } + } + + // append optionQueue (documentFragment with option elements for select options) + if (this.options.source.data) this.element.appendChild(this.selectpicker.main.optionQueue); + } + } + + /** + * @param {Object} liData - the option object that is being changed + * @param {boolean} selected - true if the option is being selected, false if being deselected + */ + setSelected (liData, selected) { + selected = selected === undefined ? liData.selected : selected; + + var li = liData.element, + activeElementIsSet = this.activeElement !== undefined, + thisIsActive = this.activeElement === li, + prevActive, + a, + keepActive = thisIsActive || (selected && !this.multiple && !activeElementIsSet); + + if (selected !== undefined) { + liData.selected = selected; + if (liData.option) liData.option.selected = selected; + } + + if (selected && this.options.source.data) { + this.createOption(liData, false); + } + + if (!li) return; + + a = li.firstChild; + + if (selected) { + this.selectedElement = li; + } + + li.classList.toggle('selected', selected); + + if (keepActive) { + this.focusItem(li, liData); + this.selectpicker.view.currentActive = li; + this.activeElement = li; + } else { + this.defocusItem(li); + } + + if (a) { + a.classList.toggle('selected', selected); + + if (selected) { + a.setAttribute('aria-selected', true); + } else { + if (this.multiple) { + a.setAttribute('aria-selected', false); + } else { + a.removeAttribute('aria-selected'); + } + } + } + + if (!keepActive && !activeElementIsSet && selected && this.prevActiveElement !== undefined) { + prevActive = this.prevActiveElement; + + this.defocusItem(prevActive); + } + } + + /** + * @param {Object} liData - the option that is being disabled + */ + setDisabled (liData) { + var disabled = liData.disabled, + li = liData.element, + a; + + if (!li) return; + + a = li.firstChild; + + li.classList.toggle(classNames.DISABLED, disabled); + + if (a) { + a.classList.toggle(classNames.DISABLED, disabled); + + if (disabled) { + a.setAttribute('aria-disabled', disabled); + a.setAttribute('tabindex', -1); + } else { + a.removeAttribute('aria-disabled'); + a.setAttribute('tabindex', 0); + } + } + } + + isDisabled () { + return this.element.disabled; + } + + checkDisabled () { + if (this.isDisabled()) { + this.newElement.classList.add(classNames.DISABLED); + this.button.classList.add(classNames.DISABLED); + this.button.setAttribute('aria-disabled', true); + } else { + if (this.button.classList.contains(classNames.DISABLED)) { + this.newElement.classList.remove(classNames.DISABLED); + this.button.classList.remove(classNames.DISABLED); + this.button.setAttribute('aria-disabled', false); + } + } + } + diff --git a/js/bootstrap-select.virtual-scroll.js b/js/bootstrap-select.virtual-scroll.js new file mode 100644 index 00000000..2f7ac9f6 --- /dev/null +++ b/js/bootstrap-select.virtual-scroll.js @@ -0,0 +1,364 @@ +/* eslint-disable no-undef */ +// Shared ordered source fragment consumed by the Grunt JS build. + // runs when the dropdown is about to be shown + onShow () { + if (this.options.liveSearch && this.searchbox.value) { + this.searchbox.value = ''; + this.selectpicker.search.previousValue = undefined; + } + + if (!this.newElement.classList.contains(classNames.SHOW)) { + this.setSize(); + } + } + + setPositionData () { + this.selectpicker.view.canHighlight = []; + this.selectpicker.view.size = 0; + this.selectpicker.view.firstHighlightIndex = false; + + for (var i = 0; i < this.selectpicker.current.data.length; i++) { + var li = this.selectpicker.current.data[i], + canHighlight = true; + + if (li.type === 'divider') { + canHighlight = false; + li.height = this.sizeInfo.dividerHeight; + } else if (li.type === 'optgroup-label') { + canHighlight = false; + li.height = this.sizeInfo.dropdownHeaderHeight; + } else { + li.height = this.sizeInfo.liHeight; + } + + if (li.disabled) canHighlight = false; + + this.selectpicker.view.canHighlight.push(canHighlight); + + if (canHighlight) { + this.selectpicker.view.size++; + li.posinset = this.selectpicker.view.size; + if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i; + } + + li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height; + } + } + + isVirtual () { + return (this.options.virtualScroll !== false) && (this.selectpicker.main.data.length >= this.options.virtualScroll) || this.options.virtualScroll === true; + } + + createView (isSearching, setSize, refresh) { + var that = this, + scrollTop = 0; + + this.selectpicker.isSearching = isSearching; + this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main; + + this.setPositionData(); + + if (setSize) { + if (refresh) { + scrollTop = this.menuInner.scrollTop; + } else if (!that.multiple) { + var element = that.element, + selectedIndex = (element.options[element.selectedIndex] || {}).liIndex; + + if (typeof selectedIndex === 'number' && that.options.size !== false) { + var selectedData = that.selectpicker.main.data[selectedIndex], + position = selectedData && selectedData.position; + + if (position) { + scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2); + } + } + } + } + + scroll(scrollTop, true); + + this._replace('createViewScroll', this.menuInner, 'scroll', function () { + if (!that.noScroll) scroll(that.menuInner.scrollTop); + that.noScroll = false; + }); + + function scroll (scrollTop, init) { + var size = that.selectpicker.current.data.length, + chunks = [], + chunkSize, + chunkCount, + firstChunk, + lastChunk, + currentChunk, + prevPositions, + positionIsDifferent, + previousElements, + menuIsDifferent = true, + isVirtual = that.isVirtual(); + + that.selectpicker.view.scrollTop = scrollTop; + + chunkSize = that.options.chunkSize; // number of options in a chunk + chunkCount = Math.ceil(size / chunkSize) || 1; // number of chunks + + for (var i = 0; i < chunkCount; i++) { + var endOfChunk = (i + 1) * chunkSize; + + if (i === chunkCount - 1) { + endOfChunk = size; + } + + chunks[i] = [ + (i) * chunkSize + (!i ? 0 : 1), + endOfChunk + ]; + + if (!size) break; + + if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) { + currentChunk = i; + } + } + + if (currentChunk === undefined) currentChunk = 0; + + prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1]; + + // always display previous, current, and next chunks + firstChunk = Math.max(0, currentChunk - 1); + lastChunk = Math.min(chunkCount - 1, currentChunk + 1); + + that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0); + that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0); + + positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1; + + if (that.activeElement !== undefined) { + if (init) { + if (that.activeElement !== that.selectedElement) { + that.defocusItem(that.activeElement); + } + that.activeElement = undefined; + } + + if (that.activeElement !== that.selectedElement) { + that.defocusItem(that.selectedElement); + } + } + + if (that.prevActiveElement !== undefined && that.prevActiveElement !== that.activeElement && that.prevActiveElement !== that.selectedElement) { + that.defocusItem(that.prevActiveElement); + } + + if (init || positionIsDifferent || that.selectpicker.current.hasMore) { + previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : []; + + if (isVirtual === false) { + that.selectpicker.view.visibleElements = that.selectpicker.current.elements; + } else { + that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1); + } + + that.setOptionStatus(); + + // if searching, check to make sure the list has actually been updated before updating DOM + // this prevents unnecessary repaints + if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements); + + // if virtual scroll is disabled and not searching, + // menu should never need to be updated more than once + if ((init || isVirtual === true) && menuIsDifferent) { + var menuInner = that.menuInner, + menuFragment = document.createDocumentFragment(), + emptyMenu = menuInner.firstChild.cloneNode(false), + marginTop, + marginBottom, + elements = that.selectpicker.view.visibleElements, + toSanitize = []; + + // replace the existing UL with an empty one - this is faster than emptying it + menuInner.replaceChild(emptyMenu, menuInner.firstChild); + + for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) { + var element = elements[i], + elText, + elementData; + + if (that.options.sanitize) { + elText = element.lastChild; + + if (elText) { + elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0]; + + if (elementData && elementData.content && !elementData.sanitized) { + toSanitize.push(elText); + elementData.sanitized = true; + } + } + } + + menuFragment.appendChild(element); + } + + if (that.options.sanitize && toSanitize.length) { + sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn); + } + + if (isVirtual === true) { + marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position); + marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position); + + menuInner.firstChild.style.marginTop = marginTop + 'px'; + menuInner.firstChild.style.marginBottom = marginBottom + 'px'; + } else { + menuInner.firstChild.style.marginTop = 0; + menuInner.firstChild.style.marginBottom = 0; + } + + menuInner.firstChild.appendChild(menuFragment); + + // if an option is encountered that is wider than the current menu width, update the menu width accordingly + if (isVirtual === true && that.sizeInfo.hasScrollBar) { + var menuInnerInnerWidth = menuInner.firstChild.offsetWidth; + + if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) { + menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; + } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) { + // set to 0 to get actual width of menu + that.menu.style.minWidth = 0; + + var actualMenuWidth = menuInner.firstChild.offsetWidth; + + if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) { + that.sizeInfo.menuInnerInnerWidth = actualMenuWidth; + menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; + } + + // reset to default CSS styling + that.menu.style.minWidth = ''; + } + } + } + + if ((!isSearching && that.options.source.data || isSearching && that.options.source.search) && that.selectpicker.current.hasMore && currentChunk === chunkCount - 1) { + // Don't load the next chunk until scrolling has started + // This prevents unnecessary requests while the user is typing if pageSize is <= chunkSize + if (scrollTop > 0) { + // Chunks use 0-based indexing, but pages use 1-based. Add 1 to convert and add 1 again to get next page + var page = Math.floor((currentChunk * that.options.chunkSize) / that.options.source.pageSize) + 2; + + that.fetchData(function () { + that.render(); + that.buildList(size, isSearching); + that.setPositionData(); + scroll(scrollTop); + }, isSearching ? 'search' : 'data', page, isSearching ? that.selectpicker.search.previousValue : undefined); + } + } + } + + that.prevActiveElement = that.activeElement; + + if (!that.options.liveSearch) { + that.menuInner.focus(); + } else if (isSearching && init) { + var index = 0, + newActive; + + if (!that.selectpicker.view.canHighlight[index]) { + index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true); + } + + newActive = that.selectpicker.view.visibleElements[index]; + + that.defocusItem(that.selectpicker.view.currentActive); + + that.activeElement = (that.selectpicker.current.data[index] || {}).element; + + that.focusItem(newActive); + } + } + + this._replace('createViewResize', window, 'resize', function () { + var isActive = that.newElement.classList.contains(classNames.SHOW); + + if (isActive) scroll(that.menuInner.scrollTop); + }); + } + + focusItem (li, liData, noStyle) { + if (li) { + liData = liData || this.selectpicker.current.data[this.selectpicker.current.elements.indexOf(this.activeElement)]; + var a = li.firstChild; + + if (a) { + a.setAttribute('aria-setsize', this.selectpicker.view.size); + a.setAttribute('aria-posinset', liData.posinset); + + if (noStyle !== true) { + this.focusedParent.setAttribute('aria-activedescendant', a.id); + li.classList.add('active'); + a.classList.add('active'); + } + } + } + } + + defocusItem (li) { + if (li) { + li.classList.remove('active'); + if (li.firstChild) li.firstChild.classList.remove('active'); + } + } + + setPlaceholder () { + var that = this, + updateIndex = false; + + if ((this.options.placeholder || this.options.allowClear) && !this.multiple) { + if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option'); + + // this option doesn't create a new
  • element, but does add a new option at the start, + // so startIndex should increase to prevent having to check every option for the bs-title-option class + updateIndex = true; + + var element = this.element, + selectTitleOption = false, + titleNotAppended = !this.selectpicker.view.titleOption.parentNode, + selectedIndex = element.selectedIndex, + selectedOption = element.options[selectedIndex], + firstSelectable = element.querySelector('select > *:not(:disabled)'), + firstSelectableIndex = firstSelectable ? firstSelectable.index : 0, + navigation = window.performance && window.performance.getEntriesByType('navigation'), + // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation + isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2; + + if (titleNotAppended) { + // Use native JS to prepend option (faster) + this.selectpicker.view.titleOption.className = 'bs-title-option'; + this.selectpicker.view.titleOption.value = ''; + + // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. + selectTitleOption = !selectedOption || (selectedIndex === firstSelectableIndex && selectedOption.defaultSelected === false); + } + + if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) { + element.insertBefore(this.selectpicker.view.titleOption, element.firstChild); + } + + // Set selected *after* appending to select + if (selectTitleOption && isNotBackForward) { + element.selectedIndex = 0; + } else if (document.readyState !== 'complete') { + // if navigation type is back_forward, there's a chance the select will have its value set by BFCache + // wait for that value to be set, then run render again + window.addEventListener('pageshow', function () { + if (that.selectpicker.view.displayedValue !== element.value) that.render(); + }); + } + } + + return updateIndex; + } + diff --git a/js/cjs-intro.js b/js/cjs-intro.js new file mode 100644 index 00000000..4beaf196 --- /dev/null +++ b/js/cjs-intro.js @@ -0,0 +1,13 @@ +'use strict'; + +var bootstrap; + +try { + bootstrap = require('bootstrap'); +} catch (error) { + bootstrap = undefined; +} + +var __SELECTPICKER_EXPOSE_GLOBAL__ = false; + +var Selectpicker = (function (bootstrap) { diff --git a/js/cjs-outro.js b/js/cjs-outro.js new file mode 100644 index 00000000..7f5e0e75 --- /dev/null +++ b/js/cjs-outro.js @@ -0,0 +1,5 @@ +}(bootstrap)); + +module.exports = Selectpicker; +module.exports.Selectpicker = Selectpicker; +module.exports.default = Selectpicker; diff --git a/js/esm-intro.js b/js/esm-intro.js index c970e6d4..2f520119 100644 --- a/js/esm-intro.js +++ b/js/esm-intro.js @@ -1,3 +1,5 @@ import * as Bootstrap from 'bootstrap'; +var __SELECTPICKER_EXPOSE_GLOBAL__ = false; + var Selectpicker = (function (bootstrap) { diff --git a/js/umd-intro.js b/js/umd-intro.js index c6e9fa14..2f4321bd 100644 --- a/js/umd-intro.js +++ b/js/umd-intro.js @@ -16,3 +16,4 @@ factory(typeof window !== 'undefined' ? window.bootstrap : undefined); } }(function (bootstrap) { + var __SELECTPICKER_EXPOSE_GLOBAL__ = true; diff --git a/package.json b/package.json index 353b35ca..d3715bd1 100644 --- a/package.json +++ b/package.json @@ -1,17 +1,18 @@ { "name": "@crestapps/bootstrap-select", "title": "bootstrap-select", - "main": "dist/js/bootstrap-select.js", + "main": "dist/js/bootstrap-select.cjs", "module": "dist/js/bootstrap-select.esm.mjs", "style": "dist/css/bootstrap-select.min.css", "exports": { ".": { "import": "./dist/js/bootstrap-select.esm.mjs", - "require": "./dist/js/bootstrap-select.js", + "require": "./dist/js/bootstrap-select.cjs", "default": "./dist/js/bootstrap-select.js" }, "./dist/css/bootstrap-select.css": "./dist/css/bootstrap-select.css", "./dist/css/bootstrap-select.min.css": "./dist/css/bootstrap-select.min.css", + "./dist/js/bootstrap-select.cjs": "./dist/js/bootstrap-select.cjs", "./dist/js/bootstrap-select.js": "./dist/js/bootstrap-select.js", "./dist/js/bootstrap-select.min.js": "./dist/js/bootstrap-select.min.js", "./dist/js/bootstrap-select.esm.mjs": "./dist/js/bootstrap-select.esm.mjs" diff --git a/tests/e2e/module-import.spec.js b/tests/e2e/module-import.spec.js index aedb1c30..0224152a 100644 --- a/tests/e2e/module-import.spec.js +++ b/tests/e2e/module-import.spec.js @@ -1,7 +1,7 @@ const { test, expect } = require('@playwright/test'); test('ES module build can be imported and initialized', async ({ page }) => { - await page.goto('/tests/index.html'); + await page.goto('/tests/packaging.html'); await page.evaluate(() => { document.body.innerHTML = ''; @@ -27,6 +27,7 @@ test('ES module build can be imported and initialized', async ({ page }) => { window.esmChecks = { defaultIsFunction: typeof Selectpicker === 'function', namedMatches: Selectpicker === NamedSelectpicker, + globalExposed: typeof window.Selectpicker !== 'undefined', value: picker.val(), instance: Selectpicker.getInstance('#esm-select') === picker, buttonCount: document.querySelectorAll('.bootstrap-select > button').length @@ -39,8 +40,83 @@ test('ES module build can be imported and initialized', async ({ page }) => { await expect.poll(() => page.evaluate(() => window.esmChecks)).toEqual({ defaultIsFunction: true, namedMatches: true, + globalExposed: false, value: 'One', instance: true, buttonCount: 1 }); }); + +test('CommonJS build can be loaded through a require-style shim', async ({ page }) => { + await page.goto('/tests/packaging.html'); + + await page.evaluate(() => { + document.body.innerHTML = ''; + }); + + await page.addScriptTag({ + url: '/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js' + }); + + await page.evaluate(async () => { + const source = await fetch('/dist/js/bootstrap-select.cjs').then(response => response.text()); + const module = { exports: {} }; + const exports = module.exports; + const require = function (name) { + if (name === 'bootstrap') return window.bootstrap; + throw new Error('Unsupported module: ' + name); + }; + const loadCommonJs = new Function('module', 'exports', 'require', source); + loadCommonJs(module, exports, require); + window.cjsModule = module; + }); + + await page.evaluate(() => { + const Selectpicker = window.cjsModule.exports; + const picker = new Selectpicker('#cjs-select'); + + window.cjsChecks = { + defaultMatches: Selectpicker.default === Selectpicker, + namedMatches: Selectpicker.Selectpicker === Selectpicker, + globalExposed: typeof window.Selectpicker !== 'undefined', + value: picker.val(), + instance: Selectpicker.getInstance('#cjs-select') === picker, + buttonCount: document.querySelectorAll('.bootstrap-select > button').length + }; + }); + + await expect.poll(() => page.evaluate(() => window.cjsChecks)).toEqual({ + defaultMatches: true, + namedMatches: true, + globalExposed: false, + value: 'One', + instance: true, + buttonCount: 1 + }); +}); + +test('UMD build still exposes the browser global', async ({ page }) => { + await page.goto('/tests/packaging.html'); + + await page.evaluate(() => { + document.body.innerHTML = ''; + }); + + await page.addScriptTag({ + url: '/node_modules/bootstrap/dist/js/bootstrap.bundle.min.js' + }); + + await page.addScriptTag({ + url: '/dist/js/bootstrap-select.js' + }); + + await page.waitForFunction(() => typeof window.Selectpicker === 'function'); + + await expect.poll(() => page.evaluate(() => ({ + globalIsFunction: typeof window.Selectpicker === 'function', + autoInitialized: document.querySelectorAll('.bootstrap-select > button').length + }))).toEqual({ + globalIsFunction: true, + autoInitialized: 1 + }); +}); diff --git a/tests/packaging.html b/tests/packaging.html new file mode 100644 index 00000000..435119c3 --- /dev/null +++ b/tests/packaging.html @@ -0,0 +1,13 @@ + + + + Bootstrap-select packaging tests + + + + + + + + + From 0493e0e29cfe927c611c0d82a8cb78fc425d9b8e Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Tue, 16 Jun 2026 10:08:15 -0700 Subject: [PATCH 2/3] Use ESM --- README.md | 55 ++++-- docs/content/events.mdx | 53 +++++ docs/content/examples.mdx | 193 +++++++++++-------- docs/content/index.md | 43 ++--- docs/content/options.mdx | 81 +------- docs/sidebars.js | 5 + docs/src/components/LiveExample.js | 34 ++++ docs/versioned_docs/version-1.1/examples.mdx | 193 +++++++++++-------- docs/versioned_docs/version-1.1/options.mdx | 81 +------- js/bootstrap-select.api.js | 2 +- js/bootstrap-select.class.js | 13 +- js/bootstrap-select.data.js | 3 +- less/bootstrap-select.less | 46 ++++- package.json | 4 +- sass/bootstrap-select.scss | 39 +++- tests/e2e/single-select.spec.js | 100 ++++++++++ 16 files changed, 570 insertions(+), 375 deletions(-) create mode 100644 docs/content/events.mdx diff --git a/README.md b/README.md index 5d3df761..bfdffad1 100644 --- a/README.md +++ b/README.md @@ -74,11 +74,11 @@ jsDelivr. Prefer pinning an explicit package version in production: - - + + ``` -You can replace `@1.1.2` with the version you want to consume. During +You can replace `@1.2.0` with the version you want to consume. During development, `@latest` also works, but a fixed version is safer for production deployments. @@ -87,11 +87,11 @@ deployments. The package now ships three first-class JavaScript entry styles from the same source code: -| Style | Entry | Use when | -| --- | --- | --- | -| ESM | `@crestapps/bootstrap-select` via `import` | You use native modules or a bundler that prefers ESM | -| CommonJS | `@crestapps/bootstrap-select` via `require()` | You use a bundler or toolchain that still consumes CommonJS | -| Browser global / UMD | `dist/js/bootstrap-select.js` or `.min.js` | You load the plugin directly from a ` - - + + - - + + ``` -You can replace `@1.1.2` with the version you want to consume. During development, +You can replace `@1.2.0` with the version you want to consume. During development, `@latest` also works, but a fixed version is safer for production deployments. ## Package formats @@ -59,11 +59,11 @@ You can replace `@1.1.2` with the version you want to consume. During developmen bootstrap-select now ships three JavaScript consumption styles from the same shared source code: -| Style | Entry | Use when | -| --- | --- | --- | -| ESM | `@crestapps/bootstrap-select` via `import` | Your app uses native modules or an ESM-first bundler | -| CommonJS | `@crestapps/bootstrap-select` via `require()` | Your bundler or app still prefers CommonJS | -| Browser global / UMD | `dist/js/bootstrap-select.js` or `.min.js` | You load the plugin directly from a ` - - + + - - + + -

    Page Not Found

    We could not find what you were looking for.

    Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

    +

    Page Not Found

    We could not find what you were looking for.

    Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

    \ No newline at end of file diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 00000000..45701c30 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,62 @@ +# Documentation site development + +This repository ships the public docs site at +[bootstrap-select.crestapps.com](https://bootstrap-select.crestapps.com) using +**Docusaurus 3.10**. + +## Requirements + +- Node.js 20.19 or newer + +## Build the package first + +Most docs workflows depend on the generated plugin assets being available under +`docs/static/dist/`. + +```sh +npm install +npm run build +``` + +## Run the docs site locally + +The easiest local workflow is: + +```sh +npm install +npm run docs:start +``` + +`docs:start`: + +1. builds the plugin into `dist/` +2. copies the generated assets into `docs/static/dist/` +3. starts the Docusaurus dev server + +Open `http://localhost:3000/` after startup. The examples are available from +the docs UI and directly at: + +- `http://localhost:3000/examples/basic.html` +- `http://localhost:3000/examples/live-search.html` +- `http://localhost:3000/examples/multiple.html` + +## Other documentation commands + +```sh +npm run docs:prepare # build plugin assets and copy them into docs/static/dist/ +npm run docs:build # build the static Docusaurus site into .pages-build/ +npm run docs:serve # serve the built Docusaurus site locally +npm run docs:pages # copy the built site into docs/ for branch-based Pages +npm run docs:clear # clear Docusaurus caches +``` + +## Docs source layout + +- `docs/content/` - current Docusaurus source content +- `docs/src/` - Docusaurus theme components +- `docs/static/` - static assets copied directly into the site +- `docs/versioned_docs/` - versioned documentation snapshots + +GitHub Pages publishes from the repository's `docs/` output, so the deploy +workflow builds the site and syncs the generated static files back into this +directory. diff --git a/docs/assets/js/11b43341.c645ef13.js b/docs/assets/js/11b43341.c645ef13.js new file mode 100644 index 00000000..91c3c95c --- /dev/null +++ b/docs/assets/js/11b43341.c645ef13.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_crestapps_bootstrap_select=self.webpackChunk_crestapps_bootstrap_select||[]).push([[256],{3401(e){e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Latest","banner":null,"badge":true,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"docs":[{"type":"link","href":"/docs/","label":"Getting Started","docId":"index","unlisted":false},{"type":"link","href":"/docs/examples","label":"Examples","docId":"examples","unlisted":false},{"type":"link","href":"/docs/options","label":"Options","docId":"options","unlisted":false},{"type":"link","href":"/docs/methods","label":"Methods","docId":"methods","unlisted":false},{"type":"link","href":"/docs/events","label":"Events","docId":"events","unlisted":false}]},"docs":{"events":{"id":"events","title":"Events","description":"bootstrap-select browser events such as changed.bs.select, show.bs.select, and refreshed.bs.select.","sidebar":"docs"},"examples":{"id":"examples","title":"Examples","description":"Live bootstrap-select examples hosted by the Docusaurus docs site.","sidebar":"docs"},"index":{"id":"index","title":"Getting Started","description":"Install and use the CrestApps bootstrap-select fork with Bootstrap 5+.","sidebar":"docs"},"methods":{"id":"methods","title":"Methods","description":"bootstrap-select instance and static methods.","sidebar":"docs"},"options":{"id":"options","title":"Options","description":"bootstrap-select options, events, and sanitizer settings.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/11b43341.e445e340.js b/docs/assets/js/11b43341.e445e340.js deleted file mode 100644 index 574439cf..00000000 --- a/docs/assets/js/11b43341.e445e340.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunk_crestapps_bootstrap_select=self.webpackChunk_crestapps_bootstrap_select||[]).push([[256],{3401(e){e.exports=JSON.parse('{"version":{"pluginId":"default","version":"current","label":"Latest","banner":null,"badge":true,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"docs":[{"type":"link","href":"/docs/","label":"Getting Started","docId":"index","unlisted":false},{"type":"link","href":"/docs/examples","label":"Examples","docId":"examples","unlisted":false},{"type":"link","href":"/docs/options","label":"Options","docId":"options","unlisted":false},{"type":"link","href":"/docs/methods","label":"Methods","docId":"methods","unlisted":false}]},"docs":{"examples":{"id":"examples","title":"Examples","description":"Live bootstrap-select examples hosted by the Docusaurus docs site.","sidebar":"docs"},"index":{"id":"index","title":"Getting Started","description":"Install and use the CrestApps bootstrap-select fork with Bootstrap 5+.","sidebar":"docs"},"methods":{"id":"methods","title":"Methods","description":"bootstrap-select instance and static methods.","sidebar":"docs"},"options":{"id":"options","title":"Options","description":"bootstrap-select options, events, and sanitizer settings.","sidebar":"docs"}}}}')}}]); \ No newline at end of file diff --git a/docs/assets/js/20e3dd10.265d8c2f.js b/docs/assets/js/20e3dd10.70047a2f.js similarity index 51% rename from docs/assets/js/20e3dd10.265d8c2f.js rename to docs/assets/js/20e3dd10.70047a2f.js index f231cd1b..f3bf58e4 100644 --- a/docs/assets/js/20e3dd10.265d8c2f.js +++ b/docs/assets/js/20e3dd10.70047a2f.js @@ -1,4 +1,4 @@ -"use strict";(self.webpackChunk_crestapps_bootstrap_select=self.webpackChunk_crestapps_bootstrap_select||[]).push([[674],{7810(e,t,o){o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>d});const n=JSON.parse('{"id":"examples","title":"Examples","description":"Live bootstrap-select examples hosted by the Docusaurus docs site.","source":"@site/content/examples.mdx","sourceDirName":".","slug":"/examples","permalink":"/docs/examples","draft":false,"unlisted":false,"editUrl":"https://github.com/CrestApps/crestapps-bootstrap-select/tree/main/docs/content/examples.mdx","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"sidebar_position":2,"title":"Examples","description":"Live bootstrap-select examples hosted by the Docusaurus docs site."},"sidebar":"docs","previous":{"title":"Getting Started","permalink":"/docs/"},"next":{"title":"Options","permalink":"/docs/options"}}');var s=o(4848),i=o(8453),l=o(5194);const a={sidebar_position:2,title:"Examples",description:"Live bootstrap-select examples hosted by the Docusaurus docs site."},c="Basic examples",p={},d=[{value:"Standard select boxes",id:"standard-select-boxes",level:2},{value:"Select boxes with optgroups",id:"select-boxes-with-optgroups",level:2},{value:"Multiple select boxes",id:"multiple-select-boxes",level:2},{value:"Live search",id:"live-search",level:2},{value:"Key words",id:"key-words",level:2},{value:"Tags-style live search with open options",id:"tags-style-live-search-with-open-options",level:2},{value:"List-style menu",id:"list-style-menu",level:2},{value:"Floating labels with visible tags",id:"floating-labels-with-visible-tags",level:2},{value:"Placeholder",id:"placeholder",level:2},{value:"Selected text",id:"selected-text",level:2},{value:"Selected text format",id:"selected-text-format",level:2},{value:"Button classes",id:"button-classes",level:2},{value:"Checkmark on selected option",id:"checkmark-on-selected-option",level:2},{value:"Menu arrow",id:"menu-arrow",level:2},{value:"Style individual options",id:"style-individual-options",level:2},{value:"Width",id:"width",level:2},{value:"Font Awesome icons",id:"font-awesome-icons",level:2},{value:"Custom content",id:"custom-content",level:2},{value:"Subtext",id:"subtext",level:2},{value:"Menu size",id:"menu-size",level:2},{value:"Select/deselect all options",id:"selectdeselect-all-options",level:2},{value:"Divider",id:"divider",level:2},{value:"Menu header",id:"menu-header",level:2},{value:"Dropup menu",id:"dropup-menu",level:2},{value:"Disabled select box",id:"disabled-select-box",level:2},{value:"Disabled options",id:"disabled-options",level:2},{value:"Disabled option groups",id:"disabled-option-groups",level:2}];function r(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"basic-examples",children:"Basic examples"})}),"\n",(0,s.jsx)(t.admonition,{title:"CrestApps fork",type:"info",children:(0,s.jsxs)(t.p,{children:["The examples use the vanilla JavaScript / Bootstrap 5+ API: ",(0,s.jsx)(t.code,{children:"new Selectpicker(el)"})," or the ",(0,s.jsx)(t.code,{children:"selectpicker"})," class, which auto-initializes. jQuery is not required."]})}),"\n",(0,s.jsxs)(t.p,{children:["The main examples now live directly on this docs page so they inherit the docs theme, including light and dark mode. The standalone HTML files are still kept under ",(0,s.jsx)(t.code,{children:"docs/static/examples/"})," for quick smoke-testing outside Docusaurus."]}),"\n",(0,s.jsx)(t.h2,{id:"standard-select-boxes",children:"Standard select boxes"}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +"use strict";(self.webpackChunk_crestapps_bootstrap_select=self.webpackChunk_crestapps_bootstrap_select||[]).push([[674],{7810(e,t,o){o.r(t),o.d(t,{assets:()=>p,contentTitle:()=>c,default:()=>h,frontMatter:()=>a,metadata:()=>n,toc:()=>r});const n=JSON.parse('{"id":"examples","title":"Examples","description":"Live bootstrap-select examples hosted by the Docusaurus docs site.","source":"@site/content/examples.mdx","sourceDirName":".","slug":"/examples","permalink":"/docs/examples","draft":false,"unlisted":false,"editUrl":"https://github.com/CrestApps/bootstrap-select/tree/main/docs/content/examples.mdx","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"sidebar_position":2,"title":"Examples","description":"Live bootstrap-select examples hosted by the Docusaurus docs site."},"sidebar":"docs","previous":{"title":"Getting Started","permalink":"/docs/"},"next":{"title":"Options","permalink":"/docs/options"}}');var i=o(4848),s=o(8453),l=o(5194);const a={sidebar_position:2,title:"Examples",description:"Live bootstrap-select examples hosted by the Docusaurus docs site."},c="Basic examples",p={},r=[{value:"Browse by topic",id:"browse-by-topic",level:2},{value:"Core selection patterns",id:"core-selection-patterns",level:2},{value:"Standard select boxes",id:"standard-select-boxes",level:3},{value:"Single select with checkmark indicator",id:"single-select-with-checkmark-indicator",level:3},{value:"Single select with radio indicators",id:"single-select-with-radio-indicators",level:3},{value:"Select boxes with optgroups",id:"select-boxes-with-optgroups",level:3},{value:"Multiple select boxes",id:"multiple-select-boxes",level:3},{value:"Multiple select with checkbox indicators",id:"multiple-select-with-checkbox-indicators",level:3},{value:"Search and multi-select workflows",id:"search-and-multi-select-workflows",level:2},{value:"Live search",id:"live-search",level:3},{value:"Key words",id:"key-words",level:3},{value:"Tags-style live search with open options",id:"tags-style-live-search-with-open-options",level:3},{value:"List-style menu",id:"list-style-menu",level:3},{value:"Floating labels with visible tags",id:"floating-labels-with-visible-tags",level:3},{value:"Limit the number of selections",id:"limit-the-number-of-selections",level:3},{value:"Selection text and summaries",id:"selection-text-and-summaries",level:2},{value:"Placeholder",id:"placeholder",level:3},{value:"Selected text",id:"selected-text",level:3},{value:"Selected text format",id:"selected-text-format",level:3},{value:"Styling and layout",id:"styling-and-layout",level:2},{value:"Button classes",id:"button-classes",level:3},{value:"Menu arrow",id:"menu-arrow",level:3},{value:"Style individual options",id:"style-individual-options",level:3},{value:"Width",id:"width",level:3},{value:"Rich option content",id:"rich-option-content",level:2},{value:"Font Awesome icons",id:"font-awesome-icons",level:3},{value:"Custom content",id:"custom-content",level:3},{value:"Subtext",id:"subtext",level:3},{value:"Menu behavior",id:"menu-behavior",level:2},{value:"Menu size",id:"menu-size",level:3},{value:"Select/deselect all options",id:"selectdeselect-all-options",level:3},{value:"Divider",id:"divider",level:3},{value:"Menu header",id:"menu-header",level:3},{value:"Dropup menu",id:"dropup-menu",level:3},{value:"Disabled states",id:"disabled-states",level:2},{value:"Disabled select box",id:"disabled-select-box",level:3},{value:"Disabled options",id:"disabled-options",level:3},{value:"Disabled option groups",id:"disabled-option-groups",level:3}];function d(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.header,{children:(0,i.jsx)(t.h1,{id:"basic-examples",children:"Basic examples"})}),"\n",(0,i.jsx)(t.admonition,{title:"CrestApps fork",type:"info",children:(0,i.jsxs)(t.p,{children:["The examples use the vanilla JavaScript / Bootstrap 5+ API: ",(0,i.jsx)(t.code,{children:"new Selectpicker(el)"})," or the ",(0,i.jsx)(t.code,{children:"selectpicker"})," class, which auto-initializes. jQuery is not required."]})}),"\n",(0,i.jsxs)(t.p,{children:["The main examples now live directly on this docs page so they inherit the docs theme, including light and dark mode. The standalone HTML files are still kept under ",(0,i.jsx)(t.code,{children:"docs/static/examples/"})," for quick smoke-testing outside Docusaurus."]}),"\n",(0,i.jsx)(t.h2,{id:"browse-by-topic",children:"Browse by topic"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#core-selection-patterns",children:"Core selection patterns"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#search-and-multi-select-workflows",children:"Search and multi-select workflows"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#selection-text-and-summaries",children:"Selection text and summaries"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#styling-and-layout",children:"Styling and layout"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#rich-option-content",children:"Rich option content"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#menu-behavior",children:"Menu behavior"})}),"\n",(0,i.jsx)(t.li,{children:(0,i.jsx)(t.a,{href:"#disabled-states",children:"Disabled states"})}),"\n"]}),"\n",(0,i.jsx)(t.h2,{id:"core-selection-patterns",children:"Core selection patterns"}),"\n",(0,i.jsx)(t.h3,{id:"standard-select-boxes",children:"Standard select boxes"}),"\n",(0,i.jsx)(l.A,{html:String.raw`

    Native select:

    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)("span",{id:"optgroup"}),"\n",(0,s.jsx)(t.h2,{id:"select-boxes-with-optgroups",children:"Select boxes with optgroups"}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n \n \n \n\n'})}),"\n",(0,i.jsx)(t.h3,{id:"single-select-with-checkmark-indicator",children:"Single select with checkmark indicator"}),"\n",(0,i.jsxs)(t.p,{children:["Use the ",(0,i.jsx)(t.code,{children:"show-tick"})," class when you want the default checkmark indicator on a single-select menu:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"single-select-with-radio-indicators",children:"Single select with radio indicators"}),"\n",(0,i.jsxs)(t.p,{children:["If you set ",(0,i.jsx)(t.code,{children:"selectionIndicator"})," to ",(0,i.jsx)(t.code,{children:"checkbox"})," on a single select, bootstrap-select renders radio-style indicators automatically:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)("span",{id:"optgroup"}),"\n",(0,i.jsx)(t.h3,{id:"select-boxes-with-optgroups",children:"Select boxes with optgroups"}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"multiple-select-boxes",children:"Multiple select boxes"}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"multiple-select-boxes",children:"Multiple select boxes"}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"live-search",children:"Live search"}),"\n",(0,s.jsxs)(t.p,{children:["You can add a search input by passing ",(0,s.jsx)(t.code,{children:'data-live-search="true"'})," attribute:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"multiple-select-with-checkbox-indicators",children:"Multiple select with checkbox indicators"}),"\n",(0,i.jsxs)(t.p,{children:["Use ",(0,i.jsx)(t.code,{children:'data-selection-indicator="checkbox"'})," on multiselects when you want a checkbox column instead of the floating checkmark:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h2,{id:"search-and-multi-select-workflows",children:"Search and multi-select workflows"}),"\n",(0,i.jsx)(t.h3,{id:"live-search",children:"Live search"}),"\n",(0,i.jsxs)(t.p,{children:["You can add a search input by passing ",(0,i.jsx)(t.code,{children:'data-live-search="true"'})," attribute:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `,className:"no-code"}),"\n",(0,s.jsx)(t.h2,{id:"key-words",children:"Key words"}),"\n",(0,s.jsxs)(t.p,{children:["Add key words to options to improve their searchability using ",(0,s.jsx)(t.code,{children:"data-tokens"}),"."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `,className:"no-code"}),"\n",(0,i.jsx)(t.h3,{id:"key-words",children:"Key words"}),"\n",(0,i.jsxs)(t.p,{children:["Add key words to options to improve their searchability using ",(0,i.jsx)(t.code,{children:"data-tokens"}),"."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"tags-style-live-search-with-open-options",children:"Tags-style live search with open options"}),"\n",(0,s.jsxs)(t.p,{children:["Use ",(0,s.jsx)(t.code,{children:"showSelectedTags"})," to keep selections visible as removable tags above the search box, while the button switches to a compact summary instead of repeating the same values."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n \n \n \n\n'})}),"\n",(0,i.jsx)(t.h3,{id:"tags-style-live-search-with-open-options",children:"Tags-style live search with open options"}),"\n",(0,i.jsxs)(t.p,{children:["Use ",(0,i.jsx)(t.code,{children:"showSelectedTags"})," to keep selections visible as removable tags above the search box, while the button switches to a compact summary instead of repeating the same values."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n \n \n \n \n \n \n\n'})}),"\n",(0,s.jsxs)(t.p,{children:["If you prefer a Bootstrap-style checkbox instead of the floating checkmark, set ",(0,s.jsx)(t.code,{children:"selectionIndicator"})," to ",(0,s.jsx)(t.code,{children:"checkbox"}),":"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n \n \n \n \n\n'})}),"\n",(0,s.jsx)(t.h2,{id:"list-style-menu",children:"List-style menu"}),"\n",(0,s.jsxs)(t.p,{children:["Set ",(0,s.jsx)(t.code,{children:"selectedItemsStyle"})," to ",(0,s.jsx)(t.code,{children:"list"})," to render the removable selections as a stacked Bootstrap list group:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n'})}),"\n",(0,i.jsx)(t.h3,{id:"list-style-menu",children:"List-style menu"}),"\n",(0,i.jsxs)(t.p,{children:["Set ",(0,i.jsx)(t.code,{children:"selectedItemsStyle"})," to ",(0,i.jsx)(t.code,{children:"list"})," to render the removable selections as a stacked Bootstrap list group:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n \n \n \n\n'})}),"\n",(0,s.jsx)(t.h2,{id:"floating-labels-with-visible-tags",children:"Floating labels with visible tags"}),"\n",(0,s.jsxs)(t.p,{children:["When a tags-style picker is placed inside a Bootstrap 5 ",(0,s.jsx)(t.code,{children:"form-floating"})," wrapper, the selected tags stay visible inside the control after the menu closes, with balanced top and bottom spacing around the tags."]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +`}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n \n \n \n\n'})}),"\n",(0,i.jsx)(t.h3,{id:"floating-labels-with-visible-tags",children:"Floating labels with visible tags"}),"\n",(0,i.jsxs)(t.p,{children:["When a tags-style picker is placed inside a Bootstrap 5 ",(0,i.jsx)(t.code,{children:"form-floating"})," wrapper, the selected tags stay visible inside the control after the menu closes, with balanced top and bottom spacing around the tags."]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'
    \n \n \n \n \n \n \n
    \n'})}),"\n",(0,s.jsxs)(t.p,{children:["For remote-backed pickers, initialize with JavaScript and provide ",(0,s.jsx)(t.code,{children:"source.create(callback, searchValue)"})," to save the new item before selecting it:"]}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-js",children:"new Selectpicker('#tag-editor', {\n liveSearch: true,\n showSelectedTags: true,\n openOptions: true,\n source: {\n data: function (callback) {\n callback(existingTags);\n },\n search: function (callback, page, searchValue) {\n callback(filterTags(searchValue));\n },\n create: function (callback, searchValue) {\n saveTag(searchValue).then(function (tag) {\n callback({\n text: tag.displayText,\n value: tag.id\n });\n });\n }\n }\n});\n"})}),"\n",(0,s.jsx)(t.h1,{id:"limit-the-number-of-selections",children:"Limit the number of selections"}),"\n",(0,s.jsxs)(t.p,{children:["Limit the number of options that can be selected via the ",(0,s.jsx)(t.code,{children:"data-max-options"})," attribute. It also works for option groups. Customize the message displayed when the limit is reached with ",(0,s.jsx)(t.code,{children:"maxOptionsText"}),"."]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +
    `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'
    \n \n \n \n \n \n \n
    \n'})}),"\n",(0,i.jsxs)(t.p,{children:["For remote-backed pickers, initialize with JavaScript and provide ",(0,i.jsx)(t.code,{children:"source.create(callback, searchValue)"})," to save the new item before selecting it:"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"new Selectpicker('#tag-editor', {\n liveSearch: true,\n showSelectedTags: true,\n openOptions: true,\n source: {\n data: function (callback) {\n callback(existingTags);\n },\n search: function (callback, page, searchValue) {\n callback(filterTags(searchValue));\n },\n create: function (callback, searchValue) {\n saveTag(searchValue).then(function (tag) {\n callback({\n text: tag.displayText,\n value: tag.id\n });\n });\n }\n }\n});\n"})}),"\n",(0,i.jsx)(t.h3,{id:"limit-the-number-of-selections",children:"Limit the number of selections"}),"\n",(0,i.jsxs)(t.p,{children:["Limit the number of options that can be selected via the ",(0,i.jsx)(t.code,{children:"data-max-options"})," attribute. It also works for option groups. Customize the message displayed when the limit is reached with ",(0,i.jsx)(t.code,{children:"maxOptionsText"}),"."]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'
    \n
    \n \n \n
    \n\n
    \n \n \n
    \n
    \n'})}),"\n",(0,s.jsx)(t.h1,{id:"custom-button-text",children:"Custom button text"}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"placeholder",children:"Placeholder"}),"\n",(0,s.jsx)("p",{id:"titleMultiples"}),"\n",(0,s.jsxs)(t.p,{children:["Use the ",(0,s.jsx)(t.code,{children:"placeholder"})," attribute to set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +
    `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'
    \n
    \n \n \n
    \n\n
    \n \n \n
    \n
    \n'})}),"\n",(0,i.jsx)(t.h2,{id:"selection-text-and-summaries",children:"Selection text and summaries"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.h3,{id:"placeholder",children:"Placeholder"}),"\n",(0,i.jsx)("p",{id:"titleMultiples"}),"\n",(0,i.jsxs)(t.p,{children:["Use the ",(0,i.jsx)(t.code,{children:"placeholder"})," attribute to set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsxs)(t.p,{children:["Legacy bootstrap-select markup that uses the select element's ",(0,s.jsx)(t.code,{children:"title"})," attribute for placeholder text is also supported on single selects:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n \n \n \n\n'})}),"\n",(0,i.jsxs)(t.p,{children:["Legacy bootstrap-select markup that uses the select element's ",(0,i.jsx)(t.code,{children:"title"})," attribute for placeholder text is also supported on single selects:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"selected-text",children:"Selected text"}),"\n",(0,s.jsx)("p",{id:"title"}),"\n",(0,s.jsxs)(t.p,{children:["Set the ",(0,s.jsx)(t.code,{children:"title"})," attribute on individual options to display alternative text when the option is selected:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"selected-text",children:"Selected text"}),"\n",(0,i.jsx)("p",{id:"title"}),"\n",(0,i.jsxs)(t.p,{children:["Set the ",(0,i.jsx)(t.code,{children:"title"})," attribute on individual options to display alternative text when the option is selected:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `,className:"no-code"}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"selected-text-format",children:"Selected text format"}),"\n",(0,s.jsx)("p",{id:"titleMultiplesFormat"}),"\n",(0,s.jsxs)(t.p,{children:["Specify how the selection is displayed with the ",(0,s.jsx)(t.code,{children:"data-selected-text-format"})," attribute on a multiple select."]}),"\n",(0,s.jsx)(t.p,{children:"The supported values are:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"values"}),": A comma delimited list of selected values (default)"]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"count"}),": If one item is selected, then the option value is shown. If more than one is selected then the number of selected items is displayed, e.g. ",(0,s.jsx)(t.code,{children:"2 of 6 selected"})]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"count > x"}),": Where ",(0,s.jsx)(t.code,{children:"x"})," is the number of items selected when the display format changes from ",(0,s.jsx)(t.code,{children:"values"})," to ",(0,s.jsx)(t.code,{children:"count"})]}),"\n",(0,s.jsxs)(t.li,{children:[(0,s.jsx)(t.code,{children:"static"}),": Always show the placeholder, regardless of selection"]}),"\n"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `,className:"no-code"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"selected-text-format",children:"Selected text format"}),"\n",(0,i.jsx)("p",{id:"titleMultiplesFormat"}),"\n",(0,i.jsxs)(t.p,{children:["Specify how the selection is displayed with the ",(0,i.jsx)(t.code,{children:"data-selected-text-format"})," attribute on a multiple select."]}),"\n",(0,i.jsx)(t.p,{children:"The supported values are:"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"values"}),": A comma delimited list of selected values (default)"]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"count"}),": If one item is selected, then the option value is shown. If more than one is selected then the number of selected items is displayed, e.g. ",(0,i.jsx)(t.code,{children:"2 of 6 selected"})]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"count > x"}),": Where ",(0,i.jsx)(t.code,{children:"x"})," is the number of items selected when the display format changes from ",(0,i.jsx)(t.code,{children:"values"})," to ",(0,i.jsx)(t.code,{children:"count"})]}),"\n",(0,i.jsxs)(t.li,{children:[(0,i.jsx)(t.code,{children:"static"}),": Always show the placeholder, regardless of selection"]}),"\n"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h1,{id:"styling",children:"Styling"}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"button-classes",children:"Button classes"}),"\n",(0,s.jsxs)(t.p,{children:["You can set the button classes via the ",(0,s.jsx)(t.code,{children:"data-style"})," attribute:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +`}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h2,{id:"styling-and-layout",children:"Styling and layout"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.h3,{id:"button-classes",children:"Button classes"}),"\n",(0,i.jsxs)(t.p,{children:["You can set the button classes via the ",(0,i.jsx)(t.code,{children:"data-style"})," attribute:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n\n\n\n\n\n\n\n\n\n\n'})}),"\n",(0,s.jsx)(t.h2,{id:"checkmark-on-selected-option",children:"Checkmark on selected option"}),"\n",(0,s.jsxs)(t.p,{children:["You can also show the checkmark icon on standard select boxes with the ",(0,s.jsx)(t.code,{children:"show-tick"})," class:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"menu-arrow",children:"Menu arrow"}),"\n",(0,s.jsxs)(t.p,{children:["The Bootstrap menu arrow can be added with the ",(0,s.jsx)(t.code,{children:"show-menu-arrow"})," class:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n ...\n\n\n\n\n\n\n\n\n\n\n\n'})}),"\n",(0,i.jsx)(t.h3,{id:"menu-arrow",children:"Menu arrow"}),"\n",(0,i.jsxs)(t.p,{children:["The Bootstrap menu arrow can be added with the ",(0,i.jsx)(t.code,{children:"show-menu-arrow"})," class:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"style-individual-options",children:"Style individual options"}),"\n",(0,s.jsx)("p",{id:"classes"}),"\n",(0,s.jsx)(t.p,{children:"Classes and styles added to options are transferred to the select box:"}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"style-individual-options",children:"Style individual options"}),"\n",(0,i.jsx)("p",{id:"classes"}),"\n",(0,i.jsx)(t.p,{children:"Classes and styles added to options are transferred to the select box:"}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-css",children:".special {\n font-weight: bold !important;\n color: #fff !important;\n background: #bc0000 !important;\n text-transform: uppercase;\n}\n"})}),"\n",(0,s.jsx)(t.h2,{id:"width",children:"Width"}),"\n",(0,s.jsx)("p",{id:"grid"}),"\n",(0,s.jsx)(t.p,{children:"Wrap selects in grid columns, or any custom parent element, to easily enforce desired widths."}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +`}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-css",children:".special {\n font-weight: bold !important;\n color: #fff !important;\n background: #bc0000 !important;\n text-transform: uppercase;\n}\n"})}),"\n",(0,i.jsx)(t.h3,{id:"width",children:"Width"}),"\n",(0,i.jsx)("p",{id:"grid"}),"\n",(0,i.jsx)(t.p,{children:"Wrap selects in grid columns, or any custom parent element, to easily enforce desired widths."}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'
    \n
    \n
    \n \n
    \n
    \n
    \n'})}),"\n",(0,s.jsx)("div",{id:"data-width"}),"\n",(0,s.jsxs)(t.p,{children:["Alternatively, use the ",(0,s.jsx)(t.code,{children:"data-width"})," attribute to set the width of the select. Set ",(0,s.jsx)(t.code,{children:"data-width"})," to ",(0,s.jsx)(t.code,{children:"'auto'"})," to automatically adjust the width of the select to its widest option. ",(0,s.jsx)(t.code,{children:"'fit'"})," automatically adjusts the width of the select to the width of its currently selected option. An exact value can also be specified, e.g., ",(0,s.jsx)(t.code,{children:"300px"})," or ",(0,s.jsx)(t.code,{children:"50%"}),"."]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +
    `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'
    \n
    \n
    \n \n
    \n
    \n
    \n'})}),"\n",(0,i.jsx)("div",{id:"data-width"}),"\n",(0,i.jsxs)(t.p,{children:["Alternatively, use the ",(0,i.jsx)(t.code,{children:"data-width"})," attribute to set the width of the select. Set ",(0,i.jsx)(t.code,{children:"data-width"})," to ",(0,i.jsx)(t.code,{children:"'auto'"})," to automatically adjust the width of the select to its widest option. ",(0,i.jsx)(t.code,{children:"'fit'"})," automatically adjusts the width of the select to the width of its currently selected option. An exact value can also be specified, e.g., ",(0,i.jsx)(t.code,{children:"300px"})," or ",(0,i.jsx)(t.code,{children:"50%"}),"."]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    @@ -321,18 +318,18 @@
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n\n\n\n'})}),"\n",(0,s.jsx)(t.h1,{id:"customize-options",children:"Customize options"}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"font-awesome-icons",children:"Font Awesome icons"}),"\n",(0,s.jsxs)(t.p,{children:["This example uses Font Awesome. Add an icon to an option or optgroup with the ",(0,s.jsx)(t.code,{children:"data-icon"})," attribute:"]}),"\n",(0,s.jsx)(t.admonition,{title:"Bootstrap 5 icons",type:"info",children:(0,s.jsxs)(t.p,{children:["Bootstrap 5 does not include an icon font. To use Font Awesome or another icon library, set ",(0,s.jsx)(t.code,{children:"iconBase"})," and ",(0,s.jsx)(t.code,{children:"tickIcon"})," to match that library."]})}),"\n",(0,s.jsx)(t.p,{children:"The selected option renders its icon in the button, and the menu shows the icons for the remaining options as well."}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n ...\n\n\n\n\n'})}),"\n",(0,i.jsx)(t.h2,{id:"rich-option-content",children:"Rich option content"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.h3,{id:"font-awesome-icons",children:"Font Awesome icons"}),"\n",(0,i.jsxs)(t.p,{children:["This example uses Font Awesome. Add an icon to an option or optgroup with the ",(0,i.jsx)(t.code,{children:"data-icon"})," attribute:"]}),"\n",(0,i.jsx)(t.admonition,{title:"Bootstrap 5 icons",type:"info",children:(0,i.jsxs)(t.p,{children:["Bootstrap 5 does not include an icon font. To use Font Awesome or another icon library, set ",(0,i.jsx)(t.code,{children:"iconBase"})," and ",(0,i.jsx)(t.code,{children:"tickIcon"})," to match that library."]})}),"\n",(0,i.jsx)(t.p,{children:"The selected option renders its icon in the button, and the menu shows the icons for the remaining options as well."}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"custom-content",children:"Custom content"}),"\n",(0,s.jsxs)(t.p,{children:["Insert custom HTML into the option with the ",(0,s.jsx)(t.code,{children:"data-content"})," attribute:"]}),"\n",(0,s.jsx)(t.admonition,{title:"Custom content is sanitized",type:"warning",children:(0,s.jsxs)(t.p,{children:["This feature inserts HTML into the DOM. By default, it is sanitized using our built-in ",(0,s.jsx)(t.a,{href:"../options#sanitizer",children:"sanitizer"}),"."]})}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"custom-content",children:"Custom content"}),"\n",(0,i.jsxs)(t.p,{children:["Insert custom HTML into the option with the ",(0,i.jsx)(t.code,{children:"data-content"})," attribute:"]}),"\n",(0,i.jsx)(t.admonition,{title:"Custom content is sanitized",type:"warning",children:(0,i.jsxs)(t.p,{children:["This feature inserts HTML into the DOM. By default, it is sanitized using our built-in ",(0,i.jsx)(t.a,{href:"../options#sanitizer",children:"sanitizer"}),"."]})}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"subtext",children:"Subtext"}),"\n",(0,s.jsxs)(t.p,{children:["Add subtext to an option or optgroup with the ",(0,s.jsx)(t.code,{children:"data-subtext"})," attribute:"]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +`}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"subtext",children:"Subtext"}),"\n",(0,i.jsxs)(t.p,{children:["Add subtext to an option or optgroup with the ",(0,i.jsx)(t.code,{children:"data-subtext"})," attribute:"]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    With showSubtext set to true. -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h1,{id:"customize-menu",children:"Customize menu"}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"menu-size",children:"Menu size"}),"\n",(0,s.jsxs)(t.p,{children:["The ",(0,s.jsx)(t.code,{children:"size"})," option is set to ",(0,s.jsx)(t.code,{children:"'auto'"})," by default. When ",(0,s.jsx)(t.code,{children:"size"})," is set to ",(0,s.jsx)(t.code,{children:"'auto'"}),", the menu always opens up to show as many items as the window will allow without being cut off. Set ",(0,s.jsx)(t.code,{children:"size"})," to ",(0,s.jsx)(t.code,{children:"false"})," to always show all items. The size of the menu can also be specifed using the ",(0,s.jsx)(t.code,{children:"data-size"})," attribute."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n \n\n'})}),"\n",(0,i.jsx)(t.h2,{id:"menu-behavior",children:"Menu behavior"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.h3,{id:"menu-size",children:"Menu size"}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"size"})," option is set to ",(0,i.jsx)(t.code,{children:"'auto'"})," by default. When ",(0,i.jsx)(t.code,{children:"size"})," is set to ",(0,i.jsx)(t.code,{children:"'auto'"}),", the menu always opens up to show as many items as the window will allow without being cut off. Set ",(0,i.jsx)(t.code,{children:"size"})," to ",(0,i.jsx)(t.code,{children:"false"})," to always show all items. The size of the menu can also be specifed using the ",(0,i.jsx)(t.code,{children:"data-size"})," attribute."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)("p",{id:"data-size"}),"\n",(0,s.jsxs)(t.p,{children:["Specify a number for ",(0,s.jsx)(t.code,{children:"data-size"})," to choose the maximum number of items to show in the menu."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)("p",{id:"data-size"}),"\n",(0,i.jsxs)(t.p,{children:["Specify a number for ",(0,i.jsx)(t.code,{children:"data-size"})," to choose the maximum number of items to show in the menu."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"selectdeselect-all-options",children:"Select/deselect all options"}),"\n",(0,s.jsxs)(t.p,{children:["Adds two buttons to the top of the menu - ",(0,s.jsx)(t.strong,{children:"Select All"})," & ",(0,s.jsx)(t.strong,{children:"Deselect All"})," with ",(0,s.jsx)(t.code,{children:'data-actions-box="true"'}),"."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"selectdeselect-all-options",children:"Select/deselect all options"}),"\n",(0,i.jsxs)(t.p,{children:["Adds two buttons to the top of the menu - ",(0,i.jsx)(t.strong,{children:"Select All"})," & ",(0,i.jsx)(t.strong,{children:"Deselect All"})," with ",(0,i.jsx)(t.code,{children:'data-actions-box="true"'}),"."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"divider",children:"Divider"}),"\n",(0,s.jsxs)(t.p,{children:["Add ",(0,s.jsx)(t.code,{children:'data-divider="true"'})," to an option to turn it into a divider."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"divider",children:"Divider"}),"\n",(0,i.jsxs)(t.p,{children:["Add ",(0,i.jsx)(t.code,{children:'data-divider="true"'})," to an option to turn it into a divider."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"menu-header",children:"Menu header"}),"\n",(0,s.jsxs)(t.p,{children:["Add a header to the dropdown menu, e.g. ",(0,s.jsx)(t.code,{children:"header: 'Select a condiment'"})," or ",(0,s.jsx)(t.code,{children:'data-header="Select a condiment"'})]}),"\n",(0,s.jsx)(l.A,{html:String.raw`
    +`}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"menu-header",children:"Menu header"}),"\n",(0,i.jsxs)(t.p,{children:["Add a header to the dropdown menu, e.g. ",(0,i.jsx)(t.code,{children:"header: 'Select a condiment'"})," or ",(0,i.jsx)(t.code,{children:'data-header="Select a condiment"'})]}),"\n",(0,i.jsx)(l.A,{html:String.raw`
    -
    `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"dropup-menu",children:"Dropup menu"}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.code,{children:"dropupAuto"})," is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If ",(0,s.jsx)(t.code,{children:"dropupAuto"})," is set to false, manually make the select a dropup menu by adding the ",(0,s.jsx)(t.code,{children:".dropup"})," class to the select."]}),"\n",(0,s.jsx)(l.A,{html:String.raw` \n ...\n\n'})}),"\n",(0,i.jsx)(t.h3,{id:"dropup-menu",children:"Dropup menu"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"dropupAuto"})," is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If ",(0,i.jsx)(t.code,{children:"dropupAuto"})," is set to false, manually make the select a dropup menu by adding the ",(0,i.jsx)(t.code,{children:".dropup"})," class to the select."]}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h1,{id:"disabled",children:"Disabled"}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h2,{id:"disabled-select-box",children:"Disabled select box"}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h2,{id:"disabled-states",children:"Disabled states"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.h3,{id:"disabled-select-box",children:"Disabled select box"}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"disabled-options",children:"Disabled options"}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"disabled-options",children:"Disabled options"}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,s.jsx)(t.h2,{id:"disabled-option-groups",children:"Disabled option groups"}),"\n",(0,s.jsx)(l.A,{html:String.raw` `}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})}),"\n",(0,i.jsx)(t.h3,{id:"disabled-option-groups",children:"Disabled option groups"}),"\n",(0,i.jsx)(l.A,{html:String.raw` `}),"\n",(0,s.jsx)(t.pre,{children:(0,s.jsx)(t.code,{className:"language-html",children:'\n'})})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(r,{...e})}):r(e)}},5194(e,t,o){o.d(t,{A:()=>a});var n=o(6540),s=o(8478),i=o(4848);function l(e){let t=e.html,o=e.className,s=void 0===o?"":o,l=e.style;const a=(0,n.useRef)(null);return(0,n.useEffect)(function(){let e,t=!1,o=[];const n=[],s=[];function i(t){window.clearTimeout(e),e=window.setTimeout(c,t)}function l(e,t){window.addEventListener(e,t),s.push(function(){window.removeEventListener(e,t)})}function c(){!t&&a.current&&("undefined"!=typeof window&&window.bootstrap&&window.bootstrap.Dropdown&&window.Selectpicker?(o=Array.from(a.current.querySelectorAll("select.selectpicker")).map(function(e){return window.Selectpicker.getOrCreateInstance(e)}),window.requestAnimationFrame(function(){t||o.forEach(function(e){e&&"function"==typeof e.refresh&&e.refresh()})})):i(100))}return l("load",c),l("hashchange",function(){i(0),i(100)}),l("resize",function(){i(0)}),Array.from(document.querySelectorAll("script[src]")).forEach(function(e){/bootstrap(?:\.bundle)?(?:\.min)?\.js|bootstrap-select(?:\.min)?\.js/i.test(e.src)&&function(e){const t=function(){i(0)};e.addEventListener("load",t),n.push(function(){e.removeEventListener("load",t)})}(e)}),c(),function(){t=!0,window.clearTimeout(e),s.forEach(function(e){e()}),n.forEach(function(e){e()}),o.forEach(function(e){e&&"function"==typeof e.destroy&&e.destroy()}),o=[]}},[t]),(0,i.jsx)("div",{className:"bs-docs-example "+s,dangerouslySetInnerHTML:{__html:t},ref:a,style:l})}function a(e){return(0,i.jsx)(s.A,{fallback:(0,i.jsx)("div",{className:"bs-docs-example "+(e.className||""),style:e.style}),children:function(){return(0,i.jsx)(l,{...e})}})}},8478(e,t,o){o.d(t,{A:()=>i});o(6540);var n=o(2303),s=o(4848);function i(e){let t=e.children,o=e.fallback;return(0,n.A)()?(0,s.jsx)(s.Fragment,{children:null==t?void 0:t()}):null!=o?o:null}},8453(e,t,o){o.d(t,{R:()=>l,x:()=>a});var n=o(6540);const s={},i=n.createContext(s);function l(e){const t=n.useContext(i);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:l(e.components),n.createElement(i.Provider,{value:t},e.children)}}}]); \ No newline at end of file +`}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-html",children:'\n'})})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},5194(e,t,o){o.d(t,{A:()=>a});var n=o(6540),i=o(8478),s=o(4848);function l(e){let t=e.html,o=e.className,i=void 0===o?"":o,l=e.style;const a=(0,n.useRef)(null);return(0,n.useEffect)(function(){let e,t=!1,o=[];const n=[],i=[];let s;function l(e){return!(!e||1!==e.nodeType||!("MARK"===e.tagName||"function"==typeof e.querySelector&&e.querySelector("mark")))}function c(t){window.clearTimeout(e),e=window.setTimeout(r,t)}function p(e,t){window.addEventListener(e,t),i.push(function(){window.removeEventListener(e,t)})}function r(){!t&&a.current&&("undefined"!=typeof window&&window.bootstrap&&window.bootstrap.Dropdown&&window.Selectpicker?(o=Array.from(a.current.querySelectorAll("select.selectpicker")).map(function(e){return window.Selectpicker.getOrCreateInstance(e)}),window.requestAnimationFrame(function(){t||o.forEach(function(e){e&&"function"==typeof e.refresh&&e.refresh()})})):c(100))}if(p("load",r),p("hashchange",function(){c(0),c(100)}),p("resize",function(){c(0)}),Array.from(document.querySelectorAll("script[src]")).forEach(function(e){/bootstrap(?:\.bundle)?(?:\.min)?\.js|bootstrap-select(?:\.min)?\.js/i.test(e.src)&&function(e){const t=function(){c(0)};e.addEventListener("load",t),n.push(function(){e.removeEventListener("load",t)})}(e)}),"undefined"!=typeof MutationObserver){const e=a.current&&a.current.closest("article");e&&(s=new MutationObserver(function(e){e.some(function(e){return Array.from(e.addedNodes||[]).some(l)||Array.from(e.removedNodes||[]).some(l)})&&c(150)}),s.observe(e,{childList:!0,subtree:!0}))}return r(),function(){t=!0,window.clearTimeout(e),s&&s.disconnect(),i.forEach(function(e){e()}),n.forEach(function(e){e()}),o.forEach(function(e){e&&"function"==typeof e.destroy&&e.destroy()}),o=[]}},[t]),(0,s.jsx)("div",{className:"bs-docs-example "+i,dangerouslySetInnerHTML:{__html:t},ref:a,style:l})}function a(e){return(0,s.jsx)(i.A,{fallback:(0,s.jsx)("div",{className:"bs-docs-example "+(e.className||""),style:e.style}),children:function(){return(0,s.jsx)(l,{...e})}})}},8478(e,t,o){o.d(t,{A:()=>s});o(6540);var n=o(2303),i=o(4848);function s(e){let t=e.children,o=e.fallback;return(0,n.A)()?(0,i.jsx)(i.Fragment,{children:null==t?void 0:t()}):null!=o?o:null}},8453(e,t,o){o.d(t,{R:()=>l,x:()=>a});var n=o(6540);const i={},s=n.createContext(i);function l(e){const t=n.useContext(s);return n.useMemo(function(){return"function"==typeof e?e(t):{...t,...e}},[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:l(e.components),n.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/docs/assets/js/32db8e2e.d0aca040.js b/docs/assets/js/32db8e2e.5d3fb493.js similarity index 64% rename from docs/assets/js/32db8e2e.d0aca040.js rename to docs/assets/js/32db8e2e.5d3fb493.js index e9c5f801..ba95c8bc 100644 --- a/docs/assets/js/32db8e2e.d0aca040.js +++ b/docs/assets/js/32db8e2e.5d3fb493.js @@ -1,4 +1,4 @@ -"use strict";(self.webpackChunk_crestapps_bootstrap_select=self.webpackChunk_crestapps_bootstrap_select||[]).push([[12],{7458(e,t,d){d.r(t),d.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>o,toc:()=>l});const o=JSON.parse('{"id":"options","title":"Options","description":"bootstrap-select options, events, and sanitizer settings.","source":"@site/versioned_docs/version-1.1/options.mdx","sourceDirName":".","slug":"/options","permalink":"/docs/1.1/options","draft":false,"unlisted":false,"editUrl":"https://github.com/CrestApps/crestapps-bootstrap-select/tree/main/docs/versioned_docs/version-1.1/options.mdx","tags":[],"version":"1.1","sidebarPosition":3,"frontMatter":{"sidebar_position":3,"title":"Options","description":"bootstrap-select options, events, and sanitizer settings."},"sidebar":"docs","previous":{"title":"Examples","permalink":"/docs/1.1/examples"},"next":{"title":"Methods","permalink":"/docs/1.1/methods"}}');var n=d(4848),s=d(8453),a=d(9069);const i={sidebar_position:3,title:"Options",description:"bootstrap-select options, events, and sanitizer settings."},c="Core options",r={},l=[{value:"Tags-style live search and open options",id:"tags-style-live-search-and-open-options",level:2},{value:"Sanitizer",id:"sanitizer",level:2}];function h(e){const t={admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{title:"CrestApps fork",type:"info",children:(0,n.jsxs)(t.p,{children:["The options and data attributes documented on this page are part of the current forward-only API. Initialize with ",(0,n.jsx)(t.code,{children:"new Selectpicker('#sel', options)"})," or add the ",(0,n.jsx)(t.code,{children:"selectpicker"})," class for automatic initialization. Global defaults are set with ",(0,n.jsx)(t.code,{children:"Selectpicker.setDefaults({ ... })"}),"."]})}),"\n",(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"core-options",children:"Core options"})}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:["Options can be passed via data attributes or JavaScript. For data attributes, append the option name to ",(0,n.jsx)(t.code,{children:"data-"}),", as in\n",(0,n.jsx)(t.code,{children:'data-style=""'})," or ",(0,n.jsx)(t.code,{children:'data-selected-text-format="count"'}),"."]}),"\n",(0,n.jsx)(t.admonition,{title:"Data attributes",type:"warning",children:(0,n.jsxs)(t.p,{children:["For security reasons, the ",(0,n.jsx)(t.code,{children:"sanitize"}),", ",(0,n.jsx)(t.code,{children:"sanitizeFn"}),", and ",(0,n.jsx)(t.code,{children:"whiteList"})," options cannot be supplied using data attributes."]})}),"\n",(0,n.jsx)(a.A,{html:String.raw` +"use strict";(self.webpackChunk_crestapps_bootstrap_select=self.webpackChunk_crestapps_bootstrap_select||[]).push([[12],{7458(e,t,o){o.r(t),o.d(t,{assets:()=>r,contentTitle:()=>c,default:()=>p,frontMatter:()=>i,metadata:()=>d,toc:()=>l});const d=JSON.parse('{"id":"options","title":"Options","description":"bootstrap-select options, events, and sanitizer settings.","source":"@site/versioned_docs/version-1.1/options.mdx","sourceDirName":".","slug":"/options","permalink":"/docs/1.1/options","draft":false,"unlisted":false,"editUrl":"https://github.com/CrestApps/bootstrap-select/tree/main/docs/versioned_docs/version-1.1/options.mdx","tags":[],"version":"1.1","sidebarPosition":3,"frontMatter":{"sidebar_position":3,"title":"Options","description":"bootstrap-select options, events, and sanitizer settings."},"sidebar":"docs","previous":{"title":"Examples","permalink":"/docs/1.1/examples"},"next":{"title":"Methods","permalink":"/docs/1.1/methods"}}');var n=o(4848),s=o(8453),a=o(9069);const i={sidebar_position:3,title:"Options",description:"bootstrap-select options, events, and sanitizer settings."},c="Core options",r={},l=[{value:"Tags-style live search and open options",id:"tags-style-live-search-and-open-options",level:2},{value:"Sanitizer",id:"sanitizer",level:2}];function h(e){const t={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",hr:"hr",li:"li",ol:"ol",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(t.admonition,{title:"CrestApps fork",type:"info",children:(0,n.jsxs)(t.p,{children:["The options and data attributes documented on this page are part of the current forward-only API. Initialize with ",(0,n.jsx)(t.code,{children:"new Selectpicker('#sel', options)"})," or add the ",(0,n.jsx)(t.code,{children:"selectpicker"})," class for automatic initialization. Global defaults are set with ",(0,n.jsx)(t.code,{children:"Selectpicker.setDefaults({ ... })"}),"."]})}),"\n",(0,n.jsx)(t.header,{children:(0,n.jsx)(t.h1,{id:"core-options",children:"Core options"})}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:["Options can be passed via data attributes or JavaScript. For data attributes, append the option name to ",(0,n.jsx)(t.code,{children:"data-"}),", as in\n",(0,n.jsx)(t.code,{children:'data-style=""'})," or ",(0,n.jsx)(t.code,{children:'data-selected-text-format="count"'}),"."]}),"\n",(0,n.jsx)(t.admonition,{title:"Data attributes",type:"warning",children:(0,n.jsxs)(t.p,{children:["For security reasons, the ",(0,n.jsx)(t.code,{children:"sanitize"}),", ",(0,n.jsx)(t.code,{children:"sanitizeFn"}),", and ",(0,n.jsx)(t.code,{children:"whiteList"})," options cannot be supplied using data attributes."]})}),"\n",(0,n.jsx)(a.A,{html:String.raw`
    @@ -246,7 +246,7 @@ @@ -270,7 +270,7 @@ @@ -345,60 +345,4 @@ -
    Nameboolean false -

    Show checkmark on selected option (for items without multiple attribute).

    +

    Shows the default checkmark indicator on single-select menus. Multiselect menus already render a selection indicator by default.

    'checkmark' | 'checkbox' 'checkmark' -

    Controls how selected items are indicated in the dropdown. Use 'checkbox' to render a Bootstrap-style checkbox column instead of the default floating checkmark.

    +

    Controls how selected items are indicated in the dropdown. Use 'checkbox' to render a Bootstrap-style checkbox column on multiselects, or radio-style indicators automatically on single selects, instead of the default floating checkmark.

    `}),"\n",(0,n.jsx)(t.admonition,{title:"Bootstrap 5 runtime defaults",type:"info",children:(0,n.jsxs)(t.p,{children:["This Bootstrap 5 build no longer supports the legacy ",(0,n.jsx)(t.code,{children:"container"}),", ",(0,n.jsx)(t.code,{children:"mobile"}),", ",(0,n.jsx)(t.code,{children:"styleBase"}),", or ",(0,n.jsx)(t.code,{children:"windowPadding"})," options. When ",(0,n.jsx)(t.code,{children:"width"})," is not set, the picker follows normal Bootstrap sizing and fills its container by default."]})}),"\n",(0,n.jsx)(t.h2,{id:"tags-style-live-search-and-open-options",children:"Tags-style live search and open options"}),"\n",(0,n.jsxs)(t.p,{children:["The ",(0,n.jsx)(t.code,{children:"showSelectedTags"})," and ",(0,n.jsx)(t.code,{children:"openOptions"})," settings are intended for taxonomy-style editors where authors need to keep selected values visible while continuing to search."]}),"\n",(0,n.jsx)(t.p,{children:"When both are enabled on a multiple select:"}),"\n",(0,n.jsxs)(t.ol,{children:["\n",(0,n.jsx)(t.li,{children:"Selected values stay visible as removable tags on the control while the search UI stays available."}),"\n",(0,n.jsx)(t.li,{children:"Typing a value that does not exactly match an existing option shows a create action."}),"\n",(0,n.jsx)(t.li,{children:"Choosing that action creates and selects the option immediately."}),"\n"]}),"\n",(0,n.jsx)(t.p,{children:"Use data attributes when local in-browser creation is enough:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-html",children:'\n \n \n \n\n'})}),"\n",(0,n.jsx)(t.p,{children:"Use JavaScript when the picker is backed by a remote source and new terms must be saved first:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-js",children:"new Selectpicker('#tag-editor', {\n liveSearch: true,\n showSelectedTags: true,\n openOptions: true,\n openOptionsText: 'Create tag \"{0}\"',\n selectedTagRemoveLabel: 'Remove tag',\n selectionIndicator: 'checkbox',\n source: {\n data: function (callback) {\n callback(existingTags);\n },\n search: function (callback, page, searchValue) {\n callback(findMatchingTags(searchValue));\n },\n create: function (callback, searchValue) {\n createTag(searchValue).then(function (tag) {\n callback({\n text: tag.displayText,\n value: tag.id\n });\n });\n }\n }\n});\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"source.create"})," can return the created option synchronously, invoke the provided callback later, or resolve a Promise. In each case, the picker adds the returned option and selects it automatically."]}),"\n",(0,n.jsx)(t.h1,{id:"default-settings",children:"Default settings"}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:["You can change the default settings for bootstrap-select by modifying its ",(0,n.jsx)(t.code,{children:"DEFAULTS"})," object (or by calling ",(0,n.jsx)(t.code,{children:"Selectpicker.setDefaults({ \u2026 })"}),"):"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-js",children:"Selectpicker.DEFAULTS.multipleSeparator = ' | ';\n"})}),"\n",(0,n.jsx)(t.h1,{id:"events",children:"Events"}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:["bootstrap-select emits native ",(0,n.jsx)(t.code,{children:"CustomEvent"}),"s on the original ",(0,n.jsx)(t.code,{children:"\n'})}),"\n",(0,n.jsx)(t.p,{children:"Use JavaScript when the picker is backed by a remote source and new terms must be saved first:"}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-js",children:"new Selectpicker('#tag-editor', {\n liveSearch: true,\n showSelectedTags: true,\n openOptions: true,\n openOptionsText: 'Create tag \"{0}\"',\n selectedTagRemoveLabel: 'Remove tag',\n selectionIndicator: 'checkbox',\n source: {\n data: function (callback) {\n callback(existingTags);\n },\n search: function (callback, page, searchValue) {\n callback(findMatchingTags(searchValue));\n },\n create: function (callback, searchValue) {\n createTag(searchValue).then(function (tag) {\n callback({\n text: tag.displayText,\n value: tag.id\n });\n });\n }\n }\n});\n"})}),"\n",(0,n.jsxs)(t.p,{children:[(0,n.jsx)(t.code,{children:"source.create"})," can return the created option synchronously, invoke the provided callback later, or resolve a Promise. In each case, the picker adds the returned option and selects it automatically."]}),"\n",(0,n.jsx)(t.h1,{id:"default-settings",children:"Default settings"}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:["You can change the default settings for bootstrap-select by modifying its ",(0,n.jsx)(t.code,{children:"DEFAULTS"})," object (or by calling ",(0,n.jsx)(t.code,{children:"Selectpicker.setDefaults({ \u2026 })"}),"):"]}),"\n",(0,n.jsx)(t.pre,{children:(0,n.jsx)(t.code,{className:"language-js",children:"Selectpicker.DEFAULTS.multipleSeparator = ' | ';\n"})}),"\n",(0,n.jsx)(t.h1,{id:"events",children:"Events"}),"\n",(0,n.jsx)(t.hr,{}),"\n",(0,n.jsxs)(t.p,{children:["bootstrap-select emits native ",(0,n.jsx)(t.code,{children:"CustomEvent"}),"s on the original ",(0,n.jsx)(t.code,{children:"
    Version: 1.0

    Basic examples

    +
    Version: 1.0

    Basic examples

    CrestApps fork

    The examples use the vanilla JavaScript / Bootstrap 5+ API: new Selectpicker(el) or the selectpicker class, which auto-initializes. jQuery is not required.

    Standalone basic

    Open the local plugin build on a plain HTML page.

    Open basic example

    Live search

    Test search filtering against hosted example markup.

    Open live search

    Multiple select

    Verify multiselect and action-box behavior.

    Open multiselect

    Standard select boxes

    @@ -152,6 +152,6 @@

    Disabled
    <select class="selectpicker">
    <option>Mustard</option>
    <option disabled>Ketchup</option>
    <option>Relish</option>
    </select>

    Disabled option groups

    -
    <select class="selectpicker test">
    <optgroup label="Picnic" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    +
    <select class="selectpicker test">
    <optgroup label="Picnic" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    \ No newline at end of file diff --git a/docs/docs/1.0/index.html b/docs/docs/1.0/index.html index 7781a08b..131ba9ad 100644 --- a/docs/docs/1.0/index.html +++ b/docs/docs/1.0/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: 1.0

    Getting Started

    +
    Version: 1.0

    Getting Started

    CrestApps fork

    This is the CrestApps fork of snapappointments/bootstrap-select. It removes the jQuery dependency entirely, uses plain vanilla JavaScript, and supports Bootstrap 5+ only. Older Bootstrap and jQuery compatibility paths are intentionally out of scope so the library can stay small and forward-focused.

    Quick start

    bootstrap-select requires Bootstrap 5+ (CSS and JS, including its bundled Popper). @@ -47,6 +47,6 @@

    Via JavaScr

    If calling bootstrap-select via JavaScript, run your code after the elements exist — either place the script at the bottom of the page (after the last <select>) or wrap it in a DOMContentLoaded listener:

    -
    document.addEventListener('DOMContentLoaded', function () {
    document.querySelectorAll('select').forEach(function (el) {
    new Selectpicker(el);
    });
    });

    +
    document.addEventListener('DOMContentLoaded', function () {
    document.querySelectorAll('select').forEach(function (el) {
    new Selectpicker(el);
    });
    });
    \ No newline at end of file diff --git a/docs/docs/1.0/methods/index.html b/docs/docs/1.0/methods/index.html index dffcded3..849d251c 100644 --- a/docs/docs/1.0/methods/index.html +++ b/docs/docs/1.0/methods/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: 1.0

    Methods

    +
    Version: 1.0

    Methods

    Interface with bootstrap-select.

    In this fork, methods are called directly on the Selectpicker instance (there is no jQuery $.fn.selectpicker). Obtain an instance with @@ -94,6 +94,6 @@

    .destroy()
    Selectpicker.getInstance('#my-select').destroy();


    Static methods

    -
    MethodDescription
    new Selectpicker(elementOrSelector, options)Create a new instance.
    Selectpicker.getInstance(elementOrSelector)Return the existing instance for an element, or null.
    Selectpicker.getOrCreateInstance(elementOrSelector, options)Return the existing instance, creating one if needed.
    Selectpicker.setDefaults(options)Set global default options (used by the i18n translation files).
    Selectpicker.VERSIONThe plugin version.
    +
    MethodDescription
    new Selectpicker(elementOrSelector, options)Create a new instance.
    Selectpicker.getInstance(elementOrSelector)Return the existing instance for an element, or null.
    Selectpicker.getOrCreateInstance(elementOrSelector, options)Return the existing instance, creating one if needed.
    Selectpicker.setDefaults(options)Set global default options (used by the i18n translation files).
    Selectpicker.VERSIONThe plugin version.
    \ No newline at end of file diff --git a/docs/docs/1.0/options/index.html b/docs/docs/1.0/options/index.html index 970afd1f..55fc903e 100644 --- a/docs/docs/1.0/options/index.html +++ b/docs/docs/1.0/options/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: 1.0
    CrestApps fork

    The options and data attributes documented on this page are part of the current forward-only API. Initialize with new Selectpicker('#sel', options) or add the selectpicker class for automatic initialization. Global defaults are set with Selectpicker.setDefaults({ ... }).

    +
    +

    For performance reasons, our built-in sanitizer accepts an array of DOM nodes as its first argument, rather than an HTML string. Keep that in mind if deciding to use your own sanitizeFn.

    \ No newline at end of file diff --git a/docs/docs/1.0/search-index.json b/docs/docs/1.0/search-index.json index 89744c22..af8caf49 100644 --- a/docs/docs/1.0/search-index.json +++ b/docs/docs/1.0/search-index.json @@ -1 +1 @@ -[{"documents":[{"i":91,"t":"Getting Started","u":"/docs/1.0/","b":["Docs"]},{"i":102,"t":"Basic examples","u":"/docs/1.0/examples/","b":["Docs"]},{"i":168,"t":"Methods","u":"/docs/1.0/methods/","b":["Docs"]},{"i":172,"t":"Core options","u":"/docs/1.0/options/","b":["Docs"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/91",[0,1.137,1,1.137]],["t/102",[2,1.137,3,1.137]],["t/168",[4,1.46]],["t/172",[5,1.137,6,1.137]]],"invertedIndex":[["basic",{"_index":2,"t":{"102":{"position":[[0,5]]}}}],["core",{"_index":5,"t":{"172":{"position":[[0,4]]}}}],["exampl",{"_index":3,"t":{"102":{"position":[[6,8]]}}}],["get",{"_index":0,"t":{"91":{"position":[[0,7]]}}}],["method",{"_index":4,"t":{"168":{"position":[[0,7]]}}}],["option",{"_index":6,"t":{"172":{"position":[[5,7]]}}}],["start",{"_index":1,"t":{"91":{"position":[[8,7]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":93,"t":"Quick start","u":"/docs/1.0/","h":"#quick-start","p":91},{"i":95,"t":"Using the CDN build","u":"/docs/1.0/","h":"#using-the-cdn-build","p":91},{"i":97,"t":"Usage","u":"/docs/1.0/","h":"","p":91},{"i":98,"t":"Via selectpicker class","u":"/docs/1.0/","h":"#via-selectpicker-class","p":91},{"i":100,"t":"Via JavaScript","u":"/docs/1.0/","h":"#via-javascript","p":91},{"i":104,"t":"Standalone basic","u":"/docs/1.0/examples/","h":"","p":102},{"i":106,"t":"Live search","u":"/docs/1.0/examples/","h":"","p":102},{"i":108,"t":"Multiple select","u":"/docs/1.0/examples/","h":"","p":102},{"i":110,"t":"Standard select boxes","u":"/docs/1.0/examples/","h":"#standard-select-boxes","p":102},{"i":112,"t":"Select boxes with optgroups","u":"/docs/1.0/examples/","h":"#select-boxes-with-optgroups","p":102},{"i":114,"t":"Multiple select boxes","u":"/docs/1.0/examples/","h":"#multiple-select-boxes","p":102},{"i":116,"t":"Live search","u":"/docs/1.0/examples/","h":"","p":102},{"i":117,"t":"Live search","u":"/docs/1.0/examples/","h":"#live-search-1","p":102},{"i":119,"t":"Key words","u":"/docs/1.0/examples/","h":"#key-words","p":102},{"i":121,"t":"Limit the number of selections","u":"/docs/1.0/examples/","h":"","p":102},{"i":123,"t":"Custom button text","u":"/docs/1.0/examples/","h":"","p":102},{"i":124,"t":"Placeholder","u":"/docs/1.0/examples/","h":"#placeholder","p":102},{"i":126,"t":"Selected text","u":"/docs/1.0/examples/","h":"#selected-text","p":102},{"i":128,"t":"Selected text format","u":"/docs/1.0/examples/","h":"#selected-text-format","p":102},{"i":130,"t":"Styling","u":"/docs/1.0/examples/","h":"","p":102},{"i":131,"t":"Button classes","u":"/docs/1.0/examples/","h":"#button-classes","p":102},{"i":133,"t":"Checkmark on selected option","u":"/docs/1.0/examples/","h":"#checkmark-on-selected-option","p":102},{"i":135,"t":"Menu arrow","u":"/docs/1.0/examples/","h":"#menu-arrow","p":102},{"i":137,"t":"Style individual options","u":"/docs/1.0/examples/","h":"#style-individual-options","p":102},{"i":139,"t":"Width","u":"/docs/1.0/examples/","h":"#width","p":102},{"i":141,"t":"Customize options","u":"/docs/1.0/examples/","h":"","p":102},{"i":142,"t":"Icons","u":"/docs/1.0/examples/","h":"#icons","p":102},{"i":144,"t":"Custom content","u":"/docs/1.0/examples/","h":"#custom-content","p":102},{"i":146,"t":"Subtext","u":"/docs/1.0/examples/","h":"#subtext","p":102},{"i":148,"t":"Customize menu","u":"/docs/1.0/examples/","h":"","p":102},{"i":149,"t":"Menu size","u":"/docs/1.0/examples/","h":"#menu-size","p":102},{"i":151,"t":"Select/deselect all options","u":"/docs/1.0/examples/","h":"#selectdeselect-all-options","p":102},{"i":153,"t":"Divider","u":"/docs/1.0/examples/","h":"#divider","p":102},{"i":155,"t":"Menu header","u":"/docs/1.0/examples/","h":"#menu-header","p":102},{"i":157,"t":"Container","u":"/docs/1.0/examples/","h":"#container","p":102},{"i":159,"t":"Dropup menu","u":"/docs/1.0/examples/","h":"#dropup-menu","p":102},{"i":161,"t":"Disabled","u":"/docs/1.0/examples/","h":"","p":102},{"i":162,"t":"Disabled select box","u":"/docs/1.0/examples/","h":"#disabled-select-box","p":102},{"i":164,"t":"Disabled options","u":"/docs/1.0/examples/","h":"#disabled-options","p":102},{"i":166,"t":"Disabled option groups","u":"/docs/1.0/examples/","h":"#disabled-option-groups","p":102},{"i":170,"t":"Static methods","u":"/docs/1.0/methods/","h":"#static-methods","p":168},{"i":174,"t":"Default settings","u":"/docs/1.0/options/","h":"","p":172},{"i":176,"t":"Events","u":"/docs/1.0/options/","h":"","p":172},{"i":178,"t":"Sanitizer","u":"/docs/1.0/options/","h":"#sanitizer","p":172}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/93",[0,3.417,1,3.417]],["t/95",[2,2.84,3,2.84,4,2.84]],["t/97",[5,4.288]],["t/98",[6,2.413,7,2.84,8,2.413]],["t/100",[6,2.904,9,3.417]],["t/104",[10,3.417,11,3.417]],["t/106",[12,2.566,13,2.566]],["t/108",[14,2.904,15,1.563]],["t/110",[15,1.299,16,2.84,17,1.923]],["t/112",[15,1.299,17,1.923,18,2.84]],["t/114",[14,2.413,15,1.299,17,1.923]],["t/116",[12,2.566,13,2.566]],["t/117",[12,2.566,13,2.566]],["t/119",[19,3.417,20,3.417]],["t/121",[15,1.299,21,2.84,22,2.84]],["t/123",[23,1.923,24,2.413,25,2.132]],["t/124",[26,4.288]],["t/126",[15,1.563,25,2.566]],["t/128",[15,1.299,25,2.132,27,2.84]],["t/130",[28,3.644]],["t/131",[8,2.904,24,2.904]],["t/133",[15,1.299,29,2.84,30,1.616]],["t/135",[31,2.112,32,3.417]],["t/137",[28,2.413,30,1.616,33,2.84]],["t/139",[34,4.288]],["t/141",[23,2.313,30,1.944]],["t/142",[35,4.288]],["t/144",[23,2.313,36,3.417]],["t/146",[37,4.288]],["t/148",[23,2.313,31,2.112]],["t/149",[31,2.112,38,3.417]],["t/151",[30,1.944,39,3.417]],["t/153",[40,4.288]],["t/155",[31,2.112,41,3.417]],["t/157",[42,4.288]],["t/159",[31,2.112,43,3.417]],["t/161",[44,2.903]],["t/162",[15,1.299,17,1.923,44,1.923]],["t/164",[30,1.944,44,2.313]],["t/166",[30,1.616,44,1.923,45,2.84]],["t/170",[46,3.417,47,3.417]],["t/174",[48,3.417,49,3.417]],["t/176",[50,4.288]],["t/178",[51,4.288]]],"invertedIndex":[["arrow",{"_index":32,"t":{"135":{"position":[[5,5]]}}}],["basic",{"_index":11,"t":{"104":{"position":[[11,5]]}}}],["box",{"_index":17,"t":{"110":{"position":[[16,5]]},"112":{"position":[[7,5]]},"114":{"position":[[16,5]]},"162":{"position":[[16,3]]}}}],["build",{"_index":4,"t":{"95":{"position":[[14,5]]}}}],["button",{"_index":24,"t":{"123":{"position":[[7,6]]},"131":{"position":[[0,6]]}}}],["cdn",{"_index":3,"t":{"95":{"position":[[10,3]]}}}],["checkmark",{"_index":29,"t":{"133":{"position":[[0,9]]}}}],["class",{"_index":8,"t":{"98":{"position":[[17,5]]},"131":{"position":[[7,7]]}}}],["contain",{"_index":42,"t":{"157":{"position":[[0,9]]}}}],["content",{"_index":36,"t":{"144":{"position":[[7,7]]}}}],["custom",{"_index":23,"t":{"123":{"position":[[0,6]]},"141":{"position":[[0,9]]},"144":{"position":[[0,6]]},"148":{"position":[[0,9]]}}}],["default",{"_index":48,"t":{"174":{"position":[[0,7]]}}}],["disabl",{"_index":44,"t":{"161":{"position":[[0,8]]},"162":{"position":[[0,8]]},"164":{"position":[[0,8]]},"166":{"position":[[0,8]]}}}],["divid",{"_index":40,"t":{"153":{"position":[[0,7]]}}}],["dropup",{"_index":43,"t":{"159":{"position":[[0,6]]}}}],["event",{"_index":50,"t":{"176":{"position":[[0,6]]}}}],["format",{"_index":27,"t":{"128":{"position":[[14,6]]}}}],["group",{"_index":45,"t":{"166":{"position":[[16,6]]}}}],["header",{"_index":41,"t":{"155":{"position":[[5,6]]}}}],["icon",{"_index":35,"t":{"142":{"position":[[0,5]]}}}],["individu",{"_index":33,"t":{"137":{"position":[[6,10]]}}}],["javascript",{"_index":9,"t":{"100":{"position":[[4,10]]}}}],["key",{"_index":19,"t":{"119":{"position":[[0,3]]}}}],["limit",{"_index":21,"t":{"121":{"position":[[0,5]]}}}],["live",{"_index":12,"t":{"106":{"position":[[0,4]]},"116":{"position":[[0,4]]},"117":{"position":[[0,4]]}}}],["menu",{"_index":31,"t":{"135":{"position":[[0,4]]},"148":{"position":[[10,4]]},"149":{"position":[[0,4]]},"155":{"position":[[0,4]]},"159":{"position":[[7,4]]}}}],["method",{"_index":47,"t":{"170":{"position":[[7,7]]}}}],["multipl",{"_index":14,"t":{"108":{"position":[[0,8]]},"114":{"position":[[0,8]]}}}],["number",{"_index":22,"t":{"121":{"position":[[10,6]]}}}],["optgroup",{"_index":18,"t":{"112":{"position":[[18,9]]}}}],["option",{"_index":30,"t":{"133":{"position":[[22,6]]},"137":{"position":[[17,7]]},"141":{"position":[[10,7]]},"151":{"position":[[20,7]]},"164":{"position":[[9,7]]},"166":{"position":[[9,6]]}}}],["placehold",{"_index":26,"t":{"124":{"position":[[0,11]]}}}],["quick",{"_index":0,"t":{"93":{"position":[[0,5]]}}}],["sanit",{"_index":51,"t":{"178":{"position":[[0,9]]}}}],["search",{"_index":13,"t":{"106":{"position":[[5,6]]},"116":{"position":[[5,6]]},"117":{"position":[[5,6]]}}}],["select",{"_index":15,"t":{"108":{"position":[[9,6]]},"110":{"position":[[9,6]]},"112":{"position":[[0,6]]},"114":{"position":[[9,6]]},"121":{"position":[[20,10]]},"126":{"position":[[0,8]]},"128":{"position":[[0,8]]},"133":{"position":[[13,8]]},"162":{"position":[[9,6]]}}}],["select/deselect",{"_index":39,"t":{"151":{"position":[[0,15]]}}}],["selectpick",{"_index":7,"t":{"98":{"position":[[4,12]]}}}],["set",{"_index":49,"t":{"174":{"position":[[8,8]]}}}],["size",{"_index":38,"t":{"149":{"position":[[5,4]]}}}],["standalon",{"_index":10,"t":{"104":{"position":[[0,10]]}}}],["standard",{"_index":16,"t":{"110":{"position":[[0,8]]}}}],["start",{"_index":1,"t":{"93":{"position":[[6,5]]}}}],["static",{"_index":46,"t":{"170":{"position":[[0,6]]}}}],["style",{"_index":28,"t":{"130":{"position":[[0,7]]},"137":{"position":[[0,5]]}}}],["subtext",{"_index":37,"t":{"146":{"position":[[0,7]]}}}],["text",{"_index":25,"t":{"123":{"position":[[14,4]]},"126":{"position":[[9,4]]},"128":{"position":[[9,4]]}}}],["us",{"_index":2,"t":{"95":{"position":[[0,5]]}}}],["usag",{"_index":5,"t":{"97":{"position":[[0,5]]}}}],["via",{"_index":6,"t":{"98":{"position":[[0,3]]},"100":{"position":[[0,3]]}}}],["width",{"_index":34,"t":{"139":{"position":[[0,5]]}}}],["word",{"_index":20,"t":{"119":{"position":[[4,5]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":91,"t":"Install and use the CrestApps bootstrap-select fork with Bootstrap 5+.","s":"Getting Started","u":"/docs/1.0/","p":91},{"i":102,"t":"Live bootstrap-select examples hosted by the Docusaurus docs site.","s":"Basic examples","u":"/docs/1.0/examples/","p":102},{"i":168,"t":"bootstrap-select instance and static methods.","s":"Methods","u":"/docs/1.0/methods/","p":168},{"i":172,"t":"bootstrap-select options, events, and sanitizer settings.","s":"Core options","u":"/docs/1.0/options/","p":172}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/91",[0,1.119,1,1.119,2,1.119,3,0.138,4,0.098,5,1.119,6,1.119]],["t/102",[3,0.098,4,0.098,7,1.119,8,1.119,9,1.119,10,1.119,11,1.119,12,1.119]],["t/168",[3,0.118,4,0.118,13,1.347,14,1.347,15,1.347]],["t/172",[3,0.11,4,0.11,16,1.261,17,1.261,18,1.261,19,1.261]]],"invertedIndex":[["5",{"_index":6,"t":{"91":{"position":[[67,3]]}}}],["bootstrap",{"_index":3,"t":{"91":{"position":[[30,9],[57,9]]},"102":{"position":[[5,9]]},"168":{"position":[[0,9]]},"172":{"position":[[0,9]]}}}],["crestapp",{"_index":2,"t":{"91":{"position":[[20,9]]}}}],["doc",{"_index":11,"t":{"102":{"position":[[56,4]]}}}],["docusauru",{"_index":10,"t":{"102":{"position":[[45,10]]}}}],["event",{"_index":17,"t":{"172":{"position":[[26,7]]}}}],["exampl",{"_index":8,"t":{"102":{"position":[[22,8]]}}}],["fork",{"_index":5,"t":{"91":{"position":[[47,4]]}}}],["host",{"_index":9,"t":{"102":{"position":[[31,6]]}}}],["instal",{"_index":0,"t":{"91":{"position":[[0,7]]}}}],["instanc",{"_index":13,"t":{"168":{"position":[[17,8]]}}}],["live",{"_index":7,"t":{"102":{"position":[[0,4]]}}}],["method",{"_index":15,"t":{"168":{"position":[[37,8]]}}}],["option",{"_index":16,"t":{"172":{"position":[[17,8]]}}}],["sanit",{"_index":18,"t":{"172":{"position":[[38,9]]}}}],["select",{"_index":4,"t":{"91":{"position":[[40,6]]},"102":{"position":[[15,6]]},"168":{"position":[[10,6]]},"172":{"position":[[10,6]]}}}],["set",{"_index":19,"t":{"172":{"position":[[48,9]]}}}],["site",{"_index":12,"t":{"102":{"position":[[61,5]]}}}],["static",{"_index":14,"t":{"168":{"position":[[30,6]]}}}],["us",{"_index":1,"t":{"91":{"position":[[12,3]]}}}]],"pipeline":["stemmer"]}},{"documents":[],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[],"invertedIndex":[],"pipeline":["stemmer"]}},{"documents":[{"i":92,"t":"CrestApps fork This is the CrestApps fork of snapappointments/bootstrap-select. It removes the jQuery dependency entirely, uses plain vanilla JavaScript, and supports Bootstrap 5+ only. Older Bootstrap and jQuery compatibility paths are intentionally out of scope so the library can stay small and forward-focused.","s":"Getting Started","u":"/docs/1.0/","h":"","p":91},{"i":94,"t":"bootstrap-select requires Bootstrap 5+ (CSS and JS, including its bundled Popper). jQuery is not required. Install with npm: npm install crestapps-bootstrap-select bootstrap Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript): ","s":"Quick start","u":"/docs/1.0/","h":"#quick-start","p":91},{"i":96,"t":"After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production: You can replace @1.0.0 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments. When loaded via a ","s":"Quick start","u":"/docs/1.0/","h":"#quick-start","p":113},{"i":118,"t":"After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production: You can replace @1.0.0 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments. When loaded via a - - + + -
    Version: 1.1

    Basic examples

    +
    Version: 1.1

    Basic examples

    CrestApps fork

    The examples use the vanilla JavaScript / Bootstrap 5+ API: new Selectpicker(el) or the selectpicker class, which auto-initializes. jQuery is not required.

    The main examples now live directly on this docs page so they inherit the docs theme, including light and dark mode. The standalone HTML files are still kept under docs/static/examples/ for quick smoke-testing outside Docusaurus.

    -

    Standard select boxes

    +

    Browse by topic

    + +

    Core selection patterns

    +

    Standard select boxes

    <select class="selectpicker">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    +

    Single select with checkmark indicator

    +

    Use the show-tick class when you want the default checkmark indicator on a single-select menu:

    +
    +
    <select class="selectpicker show-tick">
    <option>Mustard</option>
    <option selected>Ketchup</option>
    <option>Relish</option>
    </select>
    +

    Single select with radio indicators

    +

    If you set selectionIndicator to checkbox on a single select, bootstrap-select renders radio-style indicators automatically:

    +
    +
    <select class="selectpicker" data-selection-indicator="checkbox">
    <option>Article</option>
    <option selected>Blog Post</option>
    <option>Landing Page</option>
    </select>
    -

    Select boxes with optgroups

    +

    Select boxes with optgroups

    <select class="selectpicker">
    <optgroup label="Picnic">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    -

    Multiple select boxes

    +

    Multiple select boxes

    <select class="selectpicker" multiple>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    - +

    Multiple select with checkbox indicators

    +

    Use data-selection-indicator="checkbox" on multiselects when you want a checkbox column instead of the floating checkmark:

    +
    +
    <select class="selectpicker" multiple data-selection-indicator="checkbox">
    <option selected>Bootstrap 5</option>
    <option>Vue</option>
    <option>React</option>
    <option>Svelte</option>
    </select>
    +

    Search and multi-select workflows

    +

    You can add a search input by passing data-live-search="true" attribute:

    -

    Key words

    +

    Key words

    Add key words to options to improve their searchability using data-tokens.

    <select class="selectpicker" data-live-search="true">
    <option data-tokens="ketchup mustard">Hot Dog, Fries and a Soda</option>
    <option data-tokens="mustard">Burger, Shake and a Smile</option>
    <option data-tokens="frosting">Sugar, Spice and all things nice</option>
    </select>
    -

    Tags-style live search with open options

    +

    Tags-style live search with open options

    Use showSelectedTags to keep selections visible as removable tags above the search box, while the button switches to a compact summary instead of repeating the same values.

    <select
    class="selectpicker"
    multiple
    data-icon-base="fa-solid"
    data-tick-icon="fa-check"
    data-live-search="true"
    data-show-selected-tags="true"
    data-open-options="true"
    data-live-search-placeholder="Search or create tags"
    placeholder="Search or create tags">
    <option selected data-icon="fa-seedling">Orchard Core</option>
    <option selected data-icon="fa-cubes">Bootstrap 5</option>
    <option data-icon="fa-code">Vue</option>
    <option data-icon="fa-tags">Taxonomy</option>
    <option data-icon="fa-circle-plus">Open option</option>
    <option data-icon="fa-wand-magic-sparkles">Editor UX</option>
    </select>
    -

    If you prefer a Bootstrap-style checkbox instead of the floating checkmark, set selectionIndicator to checkbox:

    -
    -
    <select
    class="selectpicker"
    multiple
    data-live-search="true"
    data-show-selected-tags="true"
    data-selection-indicator="checkbox"
    placeholder="Choose frameworks">
    <option selected>Bootstrap 5</option>
    <option>Vue</option>
    <option>React</option>
    <option>Svelte</option>
    </select>
    -

    List-style menu

    +

    List-style menu

    Set selectedItemsStyle to list to render the removable selections as a stacked Bootstrap list group:

    <select
    class="selectpicker"
    multiple
    data-live-search="true"
    data-show-selected-tags="true"
    data-selected-items-style="list">
    <option selected>Orchard Core</option>
    <option selected>Bootstrap 5</option>
    <option>Vue</option>
    </select>
    -

    Floating labels with visible tags

    +

    Floating labels with visible tags

    When a tags-style picker is placed inside a Bootstrap 5 form-floating wrapper, the selected tags stay visible inside the control after the menu closes, with balanced top and bottom spacing around the tags.

    <div class="form-floating">
    <select
    id="floating-tags-example"
    class="selectpicker"
    multiple
    data-live-search="true"
    data-show-selected-tags="true"
    data-open-options="true"
    placeholder="Years">
    <option selected>2026</option>
    <option selected>2023</option>
    <option selected>2021</option>
    </select>
    <label for="floating-tags-example">Years</label>
    </div>

    For remote-backed pickers, initialize with JavaScript and provide source.create(callback, searchValue) to save the new item before selecting it:

    new Selectpicker('#tag-editor', {
    liveSearch: true,
    showSelectedTags: true,
    openOptions: true,
    source: {
    data: function (callback) {
    callback(existingTags);
    },
    search: function (callback, page, searchValue) {
    callback(filterTags(searchValue));
    },
    create: function (callback, searchValue) {
    saveTag(searchValue).then(function (tag) {
    callback({
    text: tag.displayText,
    value: tag.id
    });
    });
    }
    }
    });
    -

    Limit the number of selections

    +

    Limit the number of selections

    Limit the number of options that can be selected via the data-max-options attribute. It also works for option groups. Customize the message displayed when the limit is reached with maxOptionsText.

    <div class="row g-3">
    <div class="col-md-6">
    <label for="max-options-example">Overall limit</label>
    <select id="max-options-example" class="selectpicker" multiple data-max-options="2" data-width="100%">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    </div>

    <div class="col-md-6">
    <label for="max-options-groups-example">Per-group limit</label>
    <select id="max-options-groups-example" class="selectpicker" multiple data-width="100%">
    <optgroup label="Condiments" data-max-options="2">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Breads" data-max-options="2">
    <option>Plain</option>
    <option>Steamed</option>
    <option>Toasted</option>
    </optgroup>
    </select>
    </div>
    </div>
    -

    Custom button text

    +

    Selection text and summaries


    -

    Placeholder

    +

    Placeholder

    Use the placeholder attribute to set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes:

    @@ -67,12 +88,12 @@

    PlaceholderLegacy bootstrap-select markup that uses the select element's title attribute for placeholder text is also supported on single selects:

    <select class="selectpicker" title="Choose a content type">
    <option>Article</option>
    <option>Blog Post</option>
    <option>Landing Page</option>
    </select>
    -

    Selected text

    +

    Selected text

    Set the title attribute on individual options to display alternative text when the option is selected:

    <select class="selectpicker">
    <option title="Combo 1">Hot Dog, Fries and a Soda</option>
    <option title="Combo 2">Burger, Shake and a Smile</option>
    <option title="Combo 3">Sugar, Spice and all things nice</option>
    </select>
    -

    Selected text format

    +

    Selected text format

    Specify how the selection is displayed with the data-selected-text-format attribute on a multiple select.

    The supported values are:

    @@ -86,27 +107,23 @@

    Selec
    <select class="selectpicker" multiple data-selected-text-format="count">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    <select class="selectpicker" multiple data-selected-text-format="count > 3">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    <option>Onions</option>
    </select>
    -

    Styling

    +

    Styling and layout


    -

    Button classes

    +

    Button classes

    You can set the button classes via the data-style attribute:

    <select class="selectpicker" data-style="btn-primary">
    ...
    </select>

    <select class="selectpicker" data-style="btn-secondary">
    ...
    </select>

    <select class="selectpicker" data-style="btn-success">
    ...
    </select>

    <select class="selectpicker" data-style="btn-dark">
    ...
    </select>

    <select class="selectpicker" data-style="btn-light">
    ...
    </select>

    <select class="selectpicker" data-style="btn-danger">
    ...
    </select>
    -

    Checkmark on selected option

    -

    You can also show the checkmark icon on standard select boxes with the show-tick class:

    -
    -
    <select class="selectpicker show-tick">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    - +

    The Bootstrap menu arrow can be added with the show-menu-arrow class:

    <select class="selectpicker show-menu-arrow">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Style individual options

    +

    Style individual options

    Classes and styles added to options are transferred to the select box:

    <select class="selectpicker">
    <option>Mustard</option>
    <option class="special">Ketchup</option>
    <option style="background: #5cb85c; color: #fff;">Relish</option>
    </select>
    .special {
    font-weight: bold !important;
    color: #fff !important;
    background: #bc0000 !important;
    text-transform: uppercase;
    }
    -

    Width

    +

    Width

    Wrap selects in grid columns, or any custom parent element, to easily enforce desired widths.

    @@ -115,58 +132,58 @@

    Width

    <select class="selectpicker" data-width="auto">
    ...
    </select>
    <select class="selectpicker" data-width="fit">
    ...
    </select>
    <select class="selectpicker" data-width="100px">
    ...
    </select>
    <select class="selectpicker" data-width="75%">
    ...
    </select>
    -

    Customize options

    +

    Rich option content


    -

    Font Awesome icons

    +

    Font Awesome icons

    This example uses Font Awesome. Add an icon to an option or optgroup with the data-icon attribute:

    Bootstrap 5 icons

    Bootstrap 5 does not include an icon font. To use Font Awesome or another icon library, set iconBase and tickIcon to match that library.

    The selected option renders its icon in the button, and the menu shows the icons for the remaining options as well.

    <select class="selectpicker" data-icon-base="fa-solid" data-tick-icon="fa-check">
    <option selected data-icon="fa-heart">Ketchup</option>
    </select>
    -

    Custom content

    +

    Custom content

    Insert custom HTML into the option with the data-content attribute:

    Custom content is sanitized

    This feature inserts HTML into the DOM. By default, it is sanitized using our built-in sanitizer.

    <select class="selectpicker">
    <option data-content="<span class='badge text-bg-success'>Relish</span>">Relish</option>
    </select>
    -

    Subtext

    +

    Subtext

    Add subtext to an option or optgroup with the data-subtext attribute:

    <select class="selectpicker" data-size="5">
    <option data-subtext="Heinz">Ketchup</option>
    </select>
    -

    Customize menu

    +
    - +

    The size option is set to 'auto' by default. When size is set to 'auto', the menu always opens up to show as many items as the window will allow without being cut off. Set size to false to always show all items. The size of the menu can also be specifed using the data-size attribute.

    Specify a number for data-size to choose the maximum number of items to show in the menu.

    <select class="selectpicker" data-size="5">
    ...
    </select>
    -

    Select/deselect all options

    +

    Select/deselect all options

    Adds two buttons to the top of the menu - Select All & Deselect All with data-actions-box="true".

    <select class="selectpicker" multiple data-actions-box="true">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Divider

    +

    Divider

    Add data-divider="true" to an option to turn it into a divider.

    <select class="selectpicker" data-size="5">
    <option data-divider="true"></option>
    </select>
    - +

    Add a header to the dropdown menu, e.g. header: 'Select a condiment' or data-header="Select a condiment"

    <select class="selectpicker" data-header="Select a condiment">
    ...
    </select>
    -

    Dropup menu

    +

    Dropup menu

    dropupAuto is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If dropupAuto is set to false, manually make the select a dropup menu by adding the .dropup class to the select.

    <select class="selectpicker dropup" data-dropup-auto="false">
    ...
    </select>
    -

    Disabled

    +

    Disabled states


    -

    Disabled select box

    +

    Disabled select box

    <select class="selectpicker" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Disabled options

    +

    Disabled options

    <select class="selectpicker">
    <option>Mustard</option>
    <option disabled>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Disabled option groups

    +

    Disabled option groups

    -
    <select class="selectpicker test">
    <optgroup label="Picnic" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    +
    <select class="selectpicker test">
    <optgroup label="Picnic" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    \ No newline at end of file diff --git a/docs/docs/1.1/index.html b/docs/docs/1.1/index.html index 08d7e6aa..d90cb1ce 100644 --- a/docs/docs/1.1/index.html +++ b/docs/docs/1.1/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: 1.1

    Getting Started

    +
    Version: 1.1

    Getting Started

    CrestApps fork

    This is the CrestApps fork of snapappointments/bootstrap-select. It removes the jQuery dependency entirely, uses plain vanilla JavaScript, and supports Bootstrap 5+ only. Older Bootstrap and jQuery compatibility paths are intentionally out of scope so the library can stay small and forward-focused.

    Quick start

    bootstrap-select requires Bootstrap 5+ (CSS and JS, including its bundled Popper). @@ -51,6 +51,6 @@

    Via JavaScr

    Tags-style editor pattern

    For taxonomy-style experiences, combine live search, removable selected tags, and open-option creation so selections stay visible as tags without repeating the full list in the button:

    new Selectpicker('#tag-editor', {
    liveSearch: true,
    showSelectedTags: true,
    openOptions: true,
    selectionIndicator: 'checkbox'
    });
    -

    See Examples for a live demo and Options for the full source.create(callback, searchValue) flow used by remote-backed editors.

    +

    See Examples for a live demo and Options for the full source.create(callback, searchValue) flow used by remote-backed editors.

    \ No newline at end of file diff --git a/docs/docs/1.1/methods/index.html b/docs/docs/1.1/methods/index.html index 18c8ec37..69c0319b 100644 --- a/docs/docs/1.1/methods/index.html +++ b/docs/docs/1.1/methods/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: 1.1

    Methods

    +
    Version: 1.1

    Methods

    Interface with bootstrap-select.

    In this fork, methods are called directly on the Selectpicker instance (there is no jQuery $.fn.selectpicker). Obtain an instance with @@ -94,6 +94,6 @@

    .destroy()
    Selectpicker.getInstance('#my-select').destroy();


    Static methods

    -
    MethodDescription
    new Selectpicker(elementOrSelector, options)Create a new instance.
    Selectpicker.getInstance(elementOrSelector)Return the existing instance for an element, or null.
    Selectpicker.getOrCreateInstance(elementOrSelector, options)Return the existing instance, creating one if needed.
    Selectpicker.setDefaults(options)Set global default options (used by the i18n translation files).
    Selectpicker.VERSIONThe plugin version.
    +
    MethodDescription
    new Selectpicker(elementOrSelector, options)Create a new instance.
    Selectpicker.getInstance(elementOrSelector)Return the existing instance for an element, or null.
    Selectpicker.getOrCreateInstance(elementOrSelector, options)Return the existing instance, creating one if needed.
    Selectpicker.setDefaults(options)Set global default options (used by the i18n translation files).
    Selectpicker.VERSIONThe plugin version.
    \ No newline at end of file diff --git a/docs/docs/1.1/options/index.html b/docs/docs/1.1/options/index.html index 791021cf..d329c33c 100644 --- a/docs/docs/1.1/options/index.html +++ b/docs/docs/1.1/options/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: 1.1
    CrestApps fork

    The options and data attributes documented on this page are part of the current forward-only API. Initialize with new Selectpicker('#sel', options) or add the selectpicker class for automatic initialization. Global defaults are set with Selectpicker.setDefaults({ ... }).

    +
    Version: 1.1
    CrestApps fork

    The options and data attributes documented on this page are part of the current forward-only API. Initialize with new Selectpicker('#sel', options) or add the selectpicker class for automatic initialization. Global defaults are set with Selectpicker.setDefaults({ ... }).

    Core options


    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in @@ -270,7 +270,7 @@ boolean false -

    Show checkmark on selected option (for items without multiple attribute).

    +

    Shows the default checkmark indicator on single-select menus. Multiselect menus already render a selection indicator by default.

    @@ -294,7 +294,7 @@ 'checkmark' | 'checkbox' 'checkmark' -

    Controls how selected items are indicated in the dropdown. Use 'checkbox' to render a Bootstrap-style checkbox column instead of the default floating checkmark.

    +

    Controls how selected items are indicated in the dropdown. Use 'checkbox' to render a Bootstrap-style checkbox column on multiselects, or radio-style indicators automatically on single selects, instead of the default floating checkmark.

    @@ -390,66 +390,10 @@

    Default settings

    Selectpicker.DEFAULTS.multipleSeparator = ' | ';

    Events


    -

    bootstrap-select emits native CustomEvents on the original <select> element.

    -

    For show.bs.select, shown.bs.select, hide.bs.select, and hidden.bs.select, the original Bootstrap dropdown event is exposed as event.detail.bsEvent. Its relatedTarget property is the toggling button element.

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Event TypeDescription
    show.bs.selectThis event fires immediately when the menu starts opening.
    shown.bs.selectThis event is fired when the menu has been made visible to the user (after CSS transitions complete).
    hide.bs.selectThis event is fired immediately when the menu starts closing.
    hidden.bs.selectThis event is fired when the menu has finished being hidden from the user (after CSS transitions complete).
    loaded.bs.selectThis event fires after the select has been initialized.
    rendered.bs.selectThis event fires after the render instance has been called.
    refreshed.bs.selectThis event fires after the refresh instance has been called.
    changed.bs.select -

    This event fires after the select's value has been changed. The detail object passes clickedIndex, isSelected, and previousValue via event.detail.

    -

    previousValue is the value of the select prior to being changed. If the select's value has been changed either via the val(), selectAll(), or deselectAll() methods, clickedIndex and isSelected will be null.

    -
    maxReached.bs.selectThis event fires when a multi-select tries to exceed the configured maxOptions limit on the select.
    maxReachedGrp.bs.selectThis event fires when a multi-select tries to exceed the configured data-max-options limit on an <optgroup>.
    fetched.bs.selectThis event fires after async or callback-backed source data has been fetched and applied to the picker.
    -
    document.querySelector('#mySelect').addEventListener('changed.bs.select', function (e) {
    const { clickedIndex, isSelected, previousValue } = e.detail;
    // do something...
    });

    document.querySelector('#mySelect').addEventListener('show.bs.select', function (e) {
    const bootstrapEvent = e.detail.bsEvent;
    const button = bootstrapEvent.relatedTarget;
    });
    +

    bootstrap-select emits native CustomEvents on the original <select> element. +See the dedicated Events page for the full event reference, event +payload details, and examples for changed.bs.select, show.bs.select, and +the rest of the public event surface.

    Sanitizer


    HTML added via the data-content attribute on individual options is sanitized using our built-in sanitizer.

    @@ -459,6 +403,6 @@

    Sanitizer
    var myDefaultWhiteList = Selectpicker.DEFAULTS.whiteList;

    // To allow table elements
    myDefaultWhiteList.table = [];

    // To allow td elements and data-option attributes on td elements
    myDefaultWhiteList.td = ['data-option'];

    // You can push your custom regex to validate your attributes.
    // Be careful about your regular expressions being too lax
    var myCustomRegex = /^data-my-app-[\w-]+/;
    myDefaultWhiteList['*'].push(myCustomRegex);

    If you want to bypass our sanitizer because you prefer to use a dedicated library, you should do the following:

    new Selectpicker('#yourSelect', {
    sanitizeFn: function (domNodes) {
    return DOMPurify.sanitize(domNodes)
    }
    });
    -

    For performance reasons, our built-in sanitizer accepts an array of DOM nodes as its first argument, rather than an HTML string. Keep that in mind if deciding to use your own sanitizeFn.

    +

    For performance reasons, our built-in sanitizer accepts an array of DOM nodes as its first argument, rather than an HTML string. Keep that in mind if deciding to use your own sanitizeFn.

    \ No newline at end of file diff --git a/docs/docs/1.1/search-index.json b/docs/docs/1.1/search-index.json index a1e4c513..9bc418ff 100644 --- a/docs/docs/1.1/search-index.json +++ b/docs/docs/1.1/search-index.json @@ -1 +1 @@ -[{"documents":[{"i":180,"t":"Getting Started","u":"/docs/1.1/","b":["Docs"]},{"i":193,"t":"Basic examples","u":"/docs/1.1/examples/","b":["Docs"]},{"i":256,"t":"Methods","u":"/docs/1.1/methods/","b":["Docs"]},{"i":260,"t":"Core options","u":"/docs/1.1/options/","b":["Docs"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/180",[0,1.137,1,1.137]],["t/193",[2,1.137,3,1.137]],["t/256",[4,1.46]],["t/260",[5,1.137,6,1.137]]],"invertedIndex":[["basic",{"_index":2,"t":{"193":{"position":[[0,5]]}}}],["core",{"_index":5,"t":{"260":{"position":[[0,4]]}}}],["exampl",{"_index":3,"t":{"193":{"position":[[6,8]]}}}],["get",{"_index":0,"t":{"180":{"position":[[0,7]]}}}],["method",{"_index":4,"t":{"256":{"position":[[0,7]]}}}],["option",{"_index":6,"t":{"260":{"position":[[5,7]]}}}],["start",{"_index":1,"t":{"180":{"position":[[8,7]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":182,"t":"Quick start","u":"/docs/1.1/","h":"#quick-start","p":180},{"i":184,"t":"Using the CDN build","u":"/docs/1.1/","h":"#using-the-cdn-build","p":180},{"i":186,"t":"Usage","u":"/docs/1.1/","h":"","p":180},{"i":187,"t":"Via selectpicker class","u":"/docs/1.1/","h":"#via-selectpicker-class","p":180},{"i":189,"t":"Via JavaScript","u":"/docs/1.1/","h":"#via-javascript","p":180},{"i":191,"t":"Tags-style editor pattern","u":"/docs/1.1/","h":"#tags-style-editor-pattern","p":180},{"i":195,"t":"Standard select boxes","u":"/docs/1.1/examples/","h":"#standard-select-boxes","p":193},{"i":197,"t":"Select boxes with optgroups","u":"/docs/1.1/examples/","h":"#select-boxes-with-optgroups","p":193},{"i":199,"t":"Multiple select boxes","u":"/docs/1.1/examples/","h":"#multiple-select-boxes","p":193},{"i":201,"t":"Live search","u":"/docs/1.1/examples/","h":"#live-search","p":193},{"i":203,"t":"Key words","u":"/docs/1.1/examples/","h":"#key-words","p":193},{"i":205,"t":"Tags-style live search with open options","u":"/docs/1.1/examples/","h":"#tags-style-live-search-with-open-options","p":193},{"i":207,"t":"List-style menu","u":"/docs/1.1/examples/","h":"#list-style-menu","p":193},{"i":209,"t":"Floating labels with visible tags","u":"/docs/1.1/examples/","h":"#floating-labels-with-visible-tags","p":193},{"i":211,"t":"Limit the number of selections","u":"/docs/1.1/examples/","h":"","p":193},{"i":213,"t":"Custom button text","u":"/docs/1.1/examples/","h":"","p":193},{"i":214,"t":"Placeholder","u":"/docs/1.1/examples/","h":"#placeholder","p":193},{"i":216,"t":"Selected text","u":"/docs/1.1/examples/","h":"#selected-text","p":193},{"i":218,"t":"Selected text format","u":"/docs/1.1/examples/","h":"#selected-text-format","p":193},{"i":220,"t":"Styling","u":"/docs/1.1/examples/","h":"","p":193},{"i":221,"t":"Button classes","u":"/docs/1.1/examples/","h":"#button-classes","p":193},{"i":223,"t":"Checkmark on selected option","u":"/docs/1.1/examples/","h":"#checkmark-on-selected-option","p":193},{"i":225,"t":"Menu arrow","u":"/docs/1.1/examples/","h":"#menu-arrow","p":193},{"i":227,"t":"Style individual options","u":"/docs/1.1/examples/","h":"#style-individual-options","p":193},{"i":229,"t":"Width","u":"/docs/1.1/examples/","h":"#width","p":193},{"i":231,"t":"Customize options","u":"/docs/1.1/examples/","h":"","p":193},{"i":232,"t":"Font Awesome icons","u":"/docs/1.1/examples/","h":"#font-awesome-icons","p":193},{"i":234,"t":"Custom content","u":"/docs/1.1/examples/","h":"#custom-content","p":193},{"i":236,"t":"Subtext","u":"/docs/1.1/examples/","h":"#subtext","p":193},{"i":238,"t":"Customize menu","u":"/docs/1.1/examples/","h":"","p":193},{"i":239,"t":"Menu size","u":"/docs/1.1/examples/","h":"#menu-size","p":193},{"i":241,"t":"Select/deselect all options","u":"/docs/1.1/examples/","h":"#selectdeselect-all-options","p":193},{"i":243,"t":"Divider","u":"/docs/1.1/examples/","h":"#divider","p":193},{"i":245,"t":"Menu header","u":"/docs/1.1/examples/","h":"#menu-header","p":193},{"i":247,"t":"Dropup menu","u":"/docs/1.1/examples/","h":"#dropup-menu","p":193},{"i":249,"t":"Disabled","u":"/docs/1.1/examples/","h":"","p":193},{"i":250,"t":"Disabled select box","u":"/docs/1.1/examples/","h":"#disabled-select-box","p":193},{"i":252,"t":"Disabled options","u":"/docs/1.1/examples/","h":"#disabled-options","p":193},{"i":254,"t":"Disabled option groups","u":"/docs/1.1/examples/","h":"#disabled-option-groups","p":193},{"i":258,"t":"Static methods","u":"/docs/1.1/methods/","h":"#static-methods","p":256},{"i":262,"t":"Tags-style live search and open options","u":"/docs/1.1/options/","h":"#tags-style-live-search-and-open-options","p":260},{"i":264,"t":"Default settings","u":"/docs/1.1/options/","h":"","p":260},{"i":266,"t":"Events","u":"/docs/1.1/options/","h":"","p":260},{"i":268,"t":"Sanitizer","u":"/docs/1.1/options/","h":"#sanitizer","p":260}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/182",[0,3.642,1,3.642]],["t/184",[2,3.077,3,3.077,4,3.077]],["t/186",[5,4.462]],["t/187",[6,2.615,7,3.077,8,2.615]],["t/189",[6,3.095,9,3.642]],["t/191",[10,1.804,11,1.516,12,2.664,13,2.664]],["t/195",[14,3.077,15,1.508,16,2.083]],["t/197",[15,1.508,16,2.083,17,3.077]],["t/199",[15,1.508,16,2.083,18,3.077]],["t/201",[19,2.735,20,2.735]],["t/203",[21,3.642,22,3.642]],["t/205",[10,1.422,11,1.195,19,1.577,20,1.577,23,1.785,24,1.029]],["t/207",[11,1.751,25,3.077,26,1.751]],["t/209",[10,1.804,27,2.664,28,2.664,29,2.664]],["t/211",[15,1.508,30,3.077,31,3.077]],["t/213",[32,2.083,33,2.615,34,2.311]],["t/214",[35,4.462]],["t/216",[15,1.785,34,2.735]],["t/218",[15,1.508,34,2.311,36,3.077]],["t/220",[11,2.538]],["t/221",[8,3.095,33,3.095]],["t/223",[15,1.508,24,1.508,37,3.077]],["t/225",[26,2.072,38,3.642]],["t/227",[11,1.751,24,1.508,39,3.077]],["t/229",[40,4.462]],["t/231",[24,1.785,32,2.466]],["t/232",[41,3.077,42,3.077,43,3.077]],["t/234",[32,2.466,44,3.642]],["t/236",[45,4.462]],["t/238",[26,2.072,32,2.466]],["t/239",[26,2.072,46,3.642]],["t/241",[24,1.785,47,3.642]],["t/243",[48,4.462]],["t/245",[26,2.072,49,3.642]],["t/247",[26,2.072,50,3.642]],["t/249",[51,3.02]],["t/250",[15,1.508,16,2.083,51,2.083]],["t/252",[24,1.785,51,2.466]],["t/254",[24,1.508,51,2.083,52,3.077]],["t/258",[53,3.642,54,3.642]],["t/262",[10,1.422,11,1.195,19,1.577,20,1.577,23,1.785,24,1.029]],["t/264",[55,3.642,56,3.642]],["t/266",[57,4.462]],["t/268",[58,4.462]]],"invertedIndex":[["arrow",{"_index":38,"t":{"225":{"position":[[5,5]]}}}],["awesom",{"_index":42,"t":{"232":{"position":[[5,7]]}}}],["box",{"_index":16,"t":{"195":{"position":[[16,5]]},"197":{"position":[[7,5]]},"199":{"position":[[16,5]]},"250":{"position":[[16,3]]}}}],["build",{"_index":4,"t":{"184":{"position":[[14,5]]}}}],["button",{"_index":33,"t":{"213":{"position":[[7,6]]},"221":{"position":[[0,6]]}}}],["cdn",{"_index":3,"t":{"184":{"position":[[10,3]]}}}],["checkmark",{"_index":37,"t":{"223":{"position":[[0,9]]}}}],["class",{"_index":8,"t":{"187":{"position":[[17,5]]},"221":{"position":[[7,7]]}}}],["content",{"_index":44,"t":{"234":{"position":[[7,7]]}}}],["custom",{"_index":32,"t":{"213":{"position":[[0,6]]},"231":{"position":[[0,9]]},"234":{"position":[[0,6]]},"238":{"position":[[0,9]]}}}],["default",{"_index":55,"t":{"264":{"position":[[0,7]]}}}],["disabl",{"_index":51,"t":{"249":{"position":[[0,8]]},"250":{"position":[[0,8]]},"252":{"position":[[0,8]]},"254":{"position":[[0,8]]}}}],["divid",{"_index":48,"t":{"243":{"position":[[0,7]]}}}],["dropup",{"_index":50,"t":{"247":{"position":[[0,6]]}}}],["editor",{"_index":12,"t":{"191":{"position":[[11,6]]}}}],["event",{"_index":57,"t":{"266":{"position":[[0,6]]}}}],["float",{"_index":27,"t":{"209":{"position":[[0,8]]}}}],["font",{"_index":41,"t":{"232":{"position":[[0,4]]}}}],["format",{"_index":36,"t":{"218":{"position":[[14,6]]}}}],["group",{"_index":52,"t":{"254":{"position":[[16,6]]}}}],["header",{"_index":49,"t":{"245":{"position":[[5,6]]}}}],["icon",{"_index":43,"t":{"232":{"position":[[13,5]]}}}],["individu",{"_index":39,"t":{"227":{"position":[[6,10]]}}}],["javascript",{"_index":9,"t":{"189":{"position":[[4,10]]}}}],["key",{"_index":21,"t":{"203":{"position":[[0,3]]}}}],["label",{"_index":28,"t":{"209":{"position":[[9,6]]}}}],["limit",{"_index":30,"t":{"211":{"position":[[0,5]]}}}],["list",{"_index":25,"t":{"207":{"position":[[0,4]]}}}],["live",{"_index":19,"t":{"201":{"position":[[0,4]]},"205":{"position":[[11,4]]},"262":{"position":[[11,4]]}}}],["menu",{"_index":26,"t":{"207":{"position":[[11,4]]},"225":{"position":[[0,4]]},"238":{"position":[[10,4]]},"239":{"position":[[0,4]]},"245":{"position":[[0,4]]},"247":{"position":[[7,4]]}}}],["method",{"_index":54,"t":{"258":{"position":[[7,7]]}}}],["multipl",{"_index":18,"t":{"199":{"position":[[0,8]]}}}],["number",{"_index":31,"t":{"211":{"position":[[10,6]]}}}],["open",{"_index":23,"t":{"205":{"position":[[28,4]]},"262":{"position":[[27,4]]}}}],["optgroup",{"_index":17,"t":{"197":{"position":[[18,9]]}}}],["option",{"_index":24,"t":{"205":{"position":[[33,7]]},"223":{"position":[[22,6]]},"227":{"position":[[17,7]]},"231":{"position":[[10,7]]},"241":{"position":[[20,7]]},"252":{"position":[[9,7]]},"254":{"position":[[9,6]]},"262":{"position":[[32,7]]}}}],["pattern",{"_index":13,"t":{"191":{"position":[[18,7]]}}}],["placehold",{"_index":35,"t":{"214":{"position":[[0,11]]}}}],["quick",{"_index":0,"t":{"182":{"position":[[0,5]]}}}],["sanit",{"_index":58,"t":{"268":{"position":[[0,9]]}}}],["search",{"_index":20,"t":{"201":{"position":[[5,6]]},"205":{"position":[[16,6]]},"262":{"position":[[16,6]]}}}],["select",{"_index":15,"t":{"195":{"position":[[9,6]]},"197":{"position":[[0,6]]},"199":{"position":[[9,6]]},"211":{"position":[[20,10]]},"216":{"position":[[0,8]]},"218":{"position":[[0,8]]},"223":{"position":[[13,8]]},"250":{"position":[[9,6]]}}}],["select/deselect",{"_index":47,"t":{"241":{"position":[[0,15]]}}}],["selectpick",{"_index":7,"t":{"187":{"position":[[4,12]]}}}],["set",{"_index":56,"t":{"264":{"position":[[8,8]]}}}],["size",{"_index":46,"t":{"239":{"position":[[5,4]]}}}],["standard",{"_index":14,"t":{"195":{"position":[[0,8]]}}}],["start",{"_index":1,"t":{"182":{"position":[[6,5]]}}}],["static",{"_index":53,"t":{"258":{"position":[[0,6]]}}}],["style",{"_index":11,"t":{"191":{"position":[[5,5]]},"205":{"position":[[5,5]]},"207":{"position":[[5,5]]},"220":{"position":[[0,7]]},"227":{"position":[[0,5]]},"262":{"position":[[5,5]]}}}],["subtext",{"_index":45,"t":{"236":{"position":[[0,7]]}}}],["tag",{"_index":10,"t":{"191":{"position":[[0,4]]},"205":{"position":[[0,4]]},"209":{"position":[[29,4]]},"262":{"position":[[0,4]]}}}],["text",{"_index":34,"t":{"213":{"position":[[14,4]]},"216":{"position":[[9,4]]},"218":{"position":[[9,4]]}}}],["us",{"_index":2,"t":{"184":{"position":[[0,5]]}}}],["usag",{"_index":5,"t":{"186":{"position":[[0,5]]}}}],["via",{"_index":6,"t":{"187":{"position":[[0,3]]},"189":{"position":[[0,3]]}}}],["visibl",{"_index":29,"t":{"209":{"position":[[21,7]]}}}],["width",{"_index":40,"t":{"229":{"position":[[0,5]]}}}],["word",{"_index":22,"t":{"203":{"position":[[4,5]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":180,"t":"Install and use the CrestApps bootstrap-select fork with Bootstrap 5+.","s":"Getting Started","u":"/docs/1.1/","p":180},{"i":193,"t":"Live bootstrap-select examples hosted by the Docusaurus docs site.","s":"Basic examples","u":"/docs/1.1/examples/","p":193},{"i":256,"t":"bootstrap-select instance and static methods.","s":"Methods","u":"/docs/1.1/methods/","p":256},{"i":260,"t":"bootstrap-select options, events, and sanitizer settings.","s":"Core options","u":"/docs/1.1/options/","p":260}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/180",[0,1.119,1,1.119,2,1.119,3,0.138,4,0.098,5,1.119,6,1.119]],["t/193",[3,0.098,4,0.098,7,1.119,8,1.119,9,1.119,10,1.119,11,1.119,12,1.119]],["t/256",[3,0.118,4,0.118,13,1.347,14,1.347,15,1.347]],["t/260",[3,0.11,4,0.11,16,1.261,17,1.261,18,1.261,19,1.261]]],"invertedIndex":[["5",{"_index":6,"t":{"180":{"position":[[67,3]]}}}],["bootstrap",{"_index":3,"t":{"180":{"position":[[30,9],[57,9]]},"193":{"position":[[5,9]]},"256":{"position":[[0,9]]},"260":{"position":[[0,9]]}}}],["crestapp",{"_index":2,"t":{"180":{"position":[[20,9]]}}}],["doc",{"_index":11,"t":{"193":{"position":[[56,4]]}}}],["docusauru",{"_index":10,"t":{"193":{"position":[[45,10]]}}}],["event",{"_index":17,"t":{"260":{"position":[[26,7]]}}}],["exampl",{"_index":8,"t":{"193":{"position":[[22,8]]}}}],["fork",{"_index":5,"t":{"180":{"position":[[47,4]]}}}],["host",{"_index":9,"t":{"193":{"position":[[31,6]]}}}],["instal",{"_index":0,"t":{"180":{"position":[[0,7]]}}}],["instanc",{"_index":13,"t":{"256":{"position":[[17,8]]}}}],["live",{"_index":7,"t":{"193":{"position":[[0,4]]}}}],["method",{"_index":15,"t":{"256":{"position":[[37,8]]}}}],["option",{"_index":16,"t":{"260":{"position":[[17,8]]}}}],["sanit",{"_index":18,"t":{"260":{"position":[[38,9]]}}}],["select",{"_index":4,"t":{"180":{"position":[[40,6]]},"193":{"position":[[15,6]]},"256":{"position":[[10,6]]},"260":{"position":[[10,6]]}}}],["set",{"_index":19,"t":{"260":{"position":[[48,9]]}}}],["site",{"_index":12,"t":{"193":{"position":[[61,5]]}}}],["static",{"_index":14,"t":{"256":{"position":[[30,6]]}}}],["us",{"_index":1,"t":{"180":{"position":[[12,3]]}}}]],"pipeline":["stemmer"]}},{"documents":[],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[],"invertedIndex":[],"pipeline":["stemmer"]}},{"documents":[{"i":181,"t":"CrestApps fork This is the CrestApps fork of snapappointments/bootstrap-select. It removes the jQuery dependency entirely, uses plain vanilla JavaScript, and supports Bootstrap 5+ only. Older Bootstrap and jQuery compatibility paths are intentionally out of scope so the library can stay small and forward-focused.","s":"Getting Started","u":"/docs/1.1/","h":"","p":180},{"i":183,"t":"bootstrap-select requires Bootstrap 5+ (CSS and JS, including its bundled Popper). jQuery is not required. Install with npm: npm install @crestapps/bootstrap-select bootstrap Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript): ","s":"Quick start","u":"/docs/1.1/","h":"#quick-start","p":180},{"i":185,"t":"After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production: You can replace @1.1.2 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments. When loaded via a ","s":"Quick start","u":"/docs/1.1/","h":"#quick-start","p":202},{"i":207,"t":"After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production: You can replace @1.1.2 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments. When loaded via a + + + + + + + + + + + + +
    Version: Latest

    Events

    +

    bootstrap-select emits native CustomEvents on the original <select> +element.

    +

    Listening for events

    +
    const select = document.querySelector('#mySelect');

    select.addEventListener('changed.bs.select', function (e) {
    const { clickedIndex, isSelected, previousValue } = e.detail;
    console.log('selection changed', { clickedIndex, isSelected, previousValue });
    });

    select.addEventListener('show.bs.select', function (e) {
    const bootstrapEvent = e.detail.bsEvent;
    const button = bootstrapEvent.relatedTarget;
    console.log('opening from button', button);
    });
    +

    Event detail

    +
      +
    • show.bs.select, shown.bs.select, hide.bs.select, and +hidden.bs.select expose the original Bootstrap dropdown event as +event.detail.bsEvent.
    • +
    • changed.bs.select exposes clickedIndex, isSelected, and +previousValue on event.detail.
    • +
    • If the value changed via val(), selectAll(), or deselectAll(), +clickedIndex and isSelected are null.
    • +
    +

    Event reference

    +
    Event typeDescription
    show.bs.selectFires immediately when the menu starts opening.
    shown.bs.selectFires after the menu is visible to the user.
    hide.bs.selectFires immediately when the menu starts closing.
    hidden.bs.selectFires after the menu has finished closing.
    loaded.bs.selectFires after the selectpicker has been initialized.
    rendered.bs.selectFires after render() updates the UI.
    refreshed.bs.selectFires after refresh() syncs the UI with the underlying <select>.
    changed.bs.selectFires after the value changes. event.detail contains clickedIndex, isSelected, and previousValue.
    maxReached.bs.selectFires when a multi-select exceeds the configured maxOptions limit.
    maxReachedGrp.bs.selectFires when an <optgroup> exceeds its configured data-max-options limit.
    fetched.bs.selectFires after async or callback-backed source data has been fetched and applied.
    + + \ No newline at end of file diff --git a/docs/docs/examples/index.html b/docs/docs/examples/index.html index 247aadc4..6a3815c1 100644 --- a/docs/docs/examples/index.html +++ b/docs/docs/examples/index.html @@ -9,57 +9,78 @@ - - + + -
    Version: Latest

    Basic examples

    +
    Version: Latest

    Basic examples

    CrestApps fork

    The examples use the vanilla JavaScript / Bootstrap 5+ API: new Selectpicker(el) or the selectpicker class, which auto-initializes. jQuery is not required.

    The main examples now live directly on this docs page so they inherit the docs theme, including light and dark mode. The standalone HTML files are still kept under docs/static/examples/ for quick smoke-testing outside Docusaurus.

    -

    Standard select boxes

    +

    Browse by topic

    + +

    Core selection patterns

    +

    Standard select boxes

    <select class="selectpicker">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    +

    Single select with checkmark indicator

    +

    Use the show-tick class when you want the default checkmark indicator on a single-select menu:

    +
    +
    <select class="selectpicker show-tick">
    <option>Mustard</option>
    <option selected>Ketchup</option>
    <option>Relish</option>
    </select>
    +

    Single select with radio indicators

    +

    If you set selectionIndicator to checkbox on a single select, bootstrap-select renders radio-style indicators automatically:

    +
    +
    <select class="selectpicker" data-selection-indicator="checkbox">
    <option>Article</option>
    <option selected>Blog Post</option>
    <option>Landing Page</option>
    </select>
    -

    Select boxes with optgroups

    +

    Select boxes with optgroups

    <select class="selectpicker">
    <optgroup label="Picnic">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    -

    Multiple select boxes

    +

    Multiple select boxes

    <select class="selectpicker" multiple>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    - +

    Multiple select with checkbox indicators

    +

    Use data-selection-indicator="checkbox" on multiselects when you want a checkbox column instead of the floating checkmark:

    +
    +
    <select class="selectpicker" multiple data-selection-indicator="checkbox">
    <option selected>Bootstrap 5</option>
    <option>Vue</option>
    <option>React</option>
    <option>Svelte</option>
    </select>
    +

    Search and multi-select workflows

    +

    You can add a search input by passing data-live-search="true" attribute:

    -

    Key words

    +

    Key words

    Add key words to options to improve their searchability using data-tokens.

    <select class="selectpicker" data-live-search="true">
    <option data-tokens="ketchup mustard">Hot Dog, Fries and a Soda</option>
    <option data-tokens="mustard">Burger, Shake and a Smile</option>
    <option data-tokens="frosting">Sugar, Spice and all things nice</option>
    </select>
    -

    Tags-style live search with open options

    +

    Tags-style live search with open options

    Use showSelectedTags to keep selections visible as removable tags above the search box, while the button switches to a compact summary instead of repeating the same values.

    <select
    class="selectpicker"
    multiple
    data-icon-base="fa-solid"
    data-tick-icon="fa-check"
    data-live-search="true"
    data-show-selected-tags="true"
    data-open-options="true"
    data-live-search-placeholder="Search or create tags"
    placeholder="Search or create tags">
    <option selected data-icon="fa-seedling">Orchard Core</option>
    <option selected data-icon="fa-cubes">Bootstrap 5</option>
    <option data-icon="fa-code">Vue</option>
    <option data-icon="fa-tags">Taxonomy</option>
    <option data-icon="fa-circle-plus">Open option</option>
    <option data-icon="fa-wand-magic-sparkles">Editor UX</option>
    </select>
    -

    If you prefer a Bootstrap-style checkbox instead of the floating checkmark, set selectionIndicator to checkbox:

    -
    -
    <select
    class="selectpicker"
    multiple
    data-live-search="true"
    data-show-selected-tags="true"
    data-selection-indicator="checkbox"
    placeholder="Choose frameworks">
    <option selected>Bootstrap 5</option>
    <option>Vue</option>
    <option>React</option>
    <option>Svelte</option>
    </select>
    -

    List-style menu

    +

    List-style menu

    Set selectedItemsStyle to list to render the removable selections as a stacked Bootstrap list group:

    <select
    class="selectpicker"
    multiple
    data-live-search="true"
    data-show-selected-tags="true"
    data-selected-items-style="list">
    <option selected>Orchard Core</option>
    <option selected>Bootstrap 5</option>
    <option>Vue</option>
    </select>
    -

    Floating labels with visible tags

    +

    Floating labels with visible tags

    When a tags-style picker is placed inside a Bootstrap 5 form-floating wrapper, the selected tags stay visible inside the control after the menu closes, with balanced top and bottom spacing around the tags.

    <div class="form-floating">
    <select
    id="floating-tags-example"
    class="selectpicker"
    multiple
    data-live-search="true"
    data-show-selected-tags="true"
    data-open-options="true"
    placeholder="Years">
    <option selected>2026</option>
    <option selected>2023</option>
    <option selected>2021</option>
    </select>
    <label for="floating-tags-example">Years</label>
    </div>

    For remote-backed pickers, initialize with JavaScript and provide source.create(callback, searchValue) to save the new item before selecting it:

    new Selectpicker('#tag-editor', {
    liveSearch: true,
    showSelectedTags: true,
    openOptions: true,
    source: {
    data: function (callback) {
    callback(existingTags);
    },
    search: function (callback, page, searchValue) {
    callback(filterTags(searchValue));
    },
    create: function (callback, searchValue) {
    saveTag(searchValue).then(function (tag) {
    callback({
    text: tag.displayText,
    value: tag.id
    });
    });
    }
    }
    });
    -

    Limit the number of selections

    +

    Limit the number of selections

    Limit the number of options that can be selected via the data-max-options attribute. It also works for option groups. Customize the message displayed when the limit is reached with maxOptionsText.

    <div class="row g-3">
    <div class="col-md-6">
    <label for="max-options-example">Overall limit</label>
    <select id="max-options-example" class="selectpicker" multiple data-max-options="2" data-width="100%">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    </div>

    <div class="col-md-6">
    <label for="max-options-groups-example">Per-group limit</label>
    <select id="max-options-groups-example" class="selectpicker" multiple data-width="100%">
    <optgroup label="Condiments" data-max-options="2">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Breads" data-max-options="2">
    <option>Plain</option>
    <option>Steamed</option>
    <option>Toasted</option>
    </optgroup>
    </select>
    </div>
    </div>
    -

    Custom button text

    +

    Selection text and summaries


    -

    Placeholder

    +

    Placeholder

    Use the placeholder attribute to set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes:

    @@ -67,12 +88,12 @@

    PlaceholderLegacy bootstrap-select markup that uses the select element's title attribute for placeholder text is also supported on single selects:

    <select class="selectpicker" title="Choose a content type">
    <option>Article</option>
    <option>Blog Post</option>
    <option>Landing Page</option>
    </select>
    -

    Selected text

    +

    Selected text

    Set the title attribute on individual options to display alternative text when the option is selected:

    <select class="selectpicker">
    <option title="Combo 1">Hot Dog, Fries and a Soda</option>
    <option title="Combo 2">Burger, Shake and a Smile</option>
    <option title="Combo 3">Sugar, Spice and all things nice</option>
    </select>
    -

    Selected text format

    +

    Selected text format

    Specify how the selection is displayed with the data-selected-text-format attribute on a multiple select.

    The supported values are:

    @@ -86,27 +107,23 @@

    Selec
    <select class="selectpicker" multiple data-selected-text-format="count">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    <select class="selectpicker" multiple data-selected-text-format="count > 3">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    <option>Onions</option>
    </select>
    -

    Styling

    +

    Styling and layout


    -

    Button classes

    +

    Button classes

    You can set the button classes via the data-style attribute:

    <select class="selectpicker" data-style="btn-primary">
    ...
    </select>

    <select class="selectpicker" data-style="btn-secondary">
    ...
    </select>

    <select class="selectpicker" data-style="btn-success">
    ...
    </select>

    <select class="selectpicker" data-style="btn-dark">
    ...
    </select>

    <select class="selectpicker" data-style="btn-light">
    ...
    </select>

    <select class="selectpicker" data-style="btn-danger">
    ...
    </select>
    -

    Checkmark on selected option

    -

    You can also show the checkmark icon on standard select boxes with the show-tick class:

    -
    -
    <select class="selectpicker show-tick">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    - +

    The Bootstrap menu arrow can be added with the show-menu-arrow class:

    <select class="selectpicker show-menu-arrow">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Style individual options

    +

    Style individual options

    Classes and styles added to options are transferred to the select box:

    <select class="selectpicker">
    <option>Mustard</option>
    <option class="special">Ketchup</option>
    <option style="background: #5cb85c; color: #fff;">Relish</option>
    </select>
    .special {
    font-weight: bold !important;
    color: #fff !important;
    background: #bc0000 !important;
    text-transform: uppercase;
    }
    -

    Width

    +

    Width

    Wrap selects in grid columns, or any custom parent element, to easily enforce desired widths.

    @@ -115,58 +132,58 @@

    Width

    <select class="selectpicker" data-width="auto">
    ...
    </select>
    <select class="selectpicker" data-width="fit">
    ...
    </select>
    <select class="selectpicker" data-width="100px">
    ...
    </select>
    <select class="selectpicker" data-width="75%">
    ...
    </select>
    -

    Customize options

    +

    Rich option content


    -

    Font Awesome icons

    +

    Font Awesome icons

    This example uses Font Awesome. Add an icon to an option or optgroup with the data-icon attribute:

    Bootstrap 5 icons

    Bootstrap 5 does not include an icon font. To use Font Awesome or another icon library, set iconBase and tickIcon to match that library.

    The selected option renders its icon in the button, and the menu shows the icons for the remaining options as well.

    <select class="selectpicker" data-icon-base="fa-solid" data-tick-icon="fa-check">
    <option selected data-icon="fa-heart">Ketchup</option>
    </select>
    -

    Custom content

    +

    Custom content

    Insert custom HTML into the option with the data-content attribute:

    Custom content is sanitized

    This feature inserts HTML into the DOM. By default, it is sanitized using our built-in sanitizer.

    <select class="selectpicker">
    <option data-content="<span class='badge text-bg-success'>Relish</span>">Relish</option>
    </select>
    -

    Subtext

    +

    Subtext

    Add subtext to an option or optgroup with the data-subtext attribute:

    <select class="selectpicker" data-size="5">
    <option data-subtext="Heinz">Ketchup</option>
    </select>
    -

    Customize menu

    +
    - +

    The size option is set to 'auto' by default. When size is set to 'auto', the menu always opens up to show as many items as the window will allow without being cut off. Set size to false to always show all items. The size of the menu can also be specifed using the data-size attribute.

    Specify a number for data-size to choose the maximum number of items to show in the menu.

    <select class="selectpicker" data-size="5">
    ...
    </select>
    -

    Select/deselect all options

    +

    Select/deselect all options

    Adds two buttons to the top of the menu - Select All & Deselect All with data-actions-box="true".

    <select class="selectpicker" multiple data-actions-box="true">
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Divider

    +

    Divider

    Add data-divider="true" to an option to turn it into a divider.

    <select class="selectpicker" data-size="5">
    <option data-divider="true"></option>
    </select>
    - +

    Add a header to the dropdown menu, e.g. header: 'Select a condiment' or data-header="Select a condiment"

    <select class="selectpicker" data-header="Select a condiment">
    ...
    </select>
    -

    Dropup menu

    +

    Dropup menu

    dropupAuto is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If dropupAuto is set to false, manually make the select a dropup menu by adding the .dropup class to the select.

    <select class="selectpicker dropup" data-dropup-auto="false">
    ...
    </select>
    -

    Disabled

    +

    Disabled states


    -

    Disabled select box

    +

    Disabled select box

    <select class="selectpicker" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Disabled options

    +

    Disabled options

    <select class="selectpicker">
    <option>Mustard</option>
    <option disabled>Ketchup</option>
    <option>Relish</option>
    </select>
    -

    Disabled option groups

    +

    Disabled option groups

    -
    <select class="selectpicker test">
    <optgroup label="Picnic" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    +
    <select class="selectpicker test">
    <optgroup label="Picnic" disabled>
    <option>Mustard</option>
    <option>Ketchup</option>
    <option>Relish</option>
    </optgroup>
    <optgroup label="Camping">
    <option>Tent</option>
    <option>Flashlight</option>
    <option>Toilet Paper</option>
    </optgroup>
    </select>
    \ No newline at end of file diff --git a/docs/docs/index.html b/docs/docs/index.html index 6e7f5534..0cc14112 100644 --- a/docs/docs/index.html +++ b/docs/docs/index.html @@ -9,31 +9,55 @@ - - + + -
    Version: Latest

    Getting Started

    +
    Version: Latest

    Getting Started

    CrestApps fork

    This is the CrestApps fork of snapappointments/bootstrap-select. It removes the jQuery dependency entirely, uses plain vanilla JavaScript, and supports Bootstrap 5+ only. Older Bootstrap and jQuery compatibility paths are intentionally out of scope so the library can stay small and forward-focused.

    Quick start

    bootstrap-select requires Bootstrap 5+ (CSS and JS, including its bundled Popper). jQuery is not required.

    Install with npm:

    npm install @crestapps/bootstrap-select bootstrap
    -

    Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript):

    +

    Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript when using the browser-global build):

    <!-- Bootstrap 5 (includes Popper) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>

    <!-- bootstrap-select -->
    <link rel="stylesheet" href="dist/css/bootstrap-select.min.css">
    <script src="dist/js/bootstrap-select.min.js"></script>

    <!-- (Optional) translation files -->
    <script src="dist/js/i18n/defaults-*.min.js"></script>

    Using the CDN build

    After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production:

    -
    <!-- Bootstrap 5 (includes Popper) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>

    <!-- @crestapps/bootstrap-select from jsDelivr -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/bootstrap-select@1.1.2/dist/css/bootstrap-select.min.css">
    <script src="https://cdn.jsdelivr.net/npm/@crestapps/bootstrap-select@1.1.2/dist/js/bootstrap-select.min.js"></script>
    -

    You can replace @1.1.2 with the version you want to consume. During development, +

    <!-- Bootstrap 5 (includes Popper) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>

    <!-- @crestapps/bootstrap-select from jsDelivr -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/bootstrap-select@1.2.0/dist/css/bootstrap-select.min.css">
    <script src="https://cdn.jsdelivr.net/npm/@crestapps/bootstrap-select@1.2.0/dist/js/bootstrap-select.min.js"></script>
    +

    You can replace @1.2.0 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments.

    -

    When loaded via a <script> tag, the plugin exposes a global Selectpicker class. -Modern JavaScript can import the ES module entry:

    -
    import Selectpicker from '@crestapps/bootstrap-select';
    +

    Package formats

    +

    bootstrap-select now ships three JavaScript consumption styles from the same +shared source code:

    +
    StylePackage entryDirect fileUse when
    ESMimport Selectpicker from '@crestapps/bootstrap-select'dist/js/bootstrap-select.esm.mjsYour app uses native modules or an ESM-first bundler
    CommonJSrequire('@crestapps/bootstrap-select')dist/js/bootstrap-select.cjsYour bundler or app still prefers CommonJS
    Browser global / UMDn/adist/js/bootstrap-select.js or .min.jsYou load the plugin directly from a <script> tag or CDN
    +

    bootstrap-select is still a browser plugin, so the ESM and CommonJS entries are +meant for browser bundles or browser-like runtimes with a DOM, not server-only +Node.js execution.

    +

    ESM

    +

    Use the package import entry or the direct .mjs file:

    +
    import 'bootstrap/dist/css/bootstrap.min.css';
    import '@crestapps/bootstrap-select/dist/css/bootstrap-select.css';
    import Selectpicker, { Selectpicker as NamedSelectpicker } from '@crestapps/bootstrap-select';

    const picker = new Selectpicker('#my-select', { liveSearch: true });

    console.log(Selectpicker === NamedSelectpicker); // true
    +

    The ESM build stays module-scoped and does not attach window.Selectpicker. +If you prefer a direct file import, use @crestapps/bootstrap-select/dist/js/bootstrap-select.esm.mjs.

    +

    CommonJS

    +

    Use the package require() entry or the direct .cjs file:

    +
    require('bootstrap');
    require('@crestapps/bootstrap-select/dist/css/bootstrap-select.css');

    const Selectpicker = require('@crestapps/bootstrap-select');
    // or: const { Selectpicker } = require('@crestapps/bootstrap-select');

    const picker = new Selectpicker('#my-select', { liveSearch: true });
    +

    The CommonJS entry exports:

    +
      +
    • module.exports = Selectpicker
    • +
    • module.exports.Selectpicker = Selectpicker
    • +
    • module.exports.default = Selectpicker
    • +
    +

    Like the ESM build, it does not attach window.Selectpicker. +If you prefer a direct file require, use @crestapps/bootstrap-select/dist/js/bootstrap-select.cjs.

    +

    Browser global / UMD

    +

    When loaded from a <script> tag, the UMD build exposes the global +window.Selectpicker / Selectpicker:

    +
    <!-- Bootstrap 5 (includes Popper) -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js"></script>

    <!-- @crestapps/bootstrap-select from jsDelivr -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@crestapps/bootstrap-select@1.2.0/dist/css/bootstrap-select.min.css">
    <script src="https://cdn.jsdelivr.net/npm/@crestapps/bootstrap-select@1.2.0/dist/js/bootstrap-select.min.js"></script>

    <script>
    const picker = new Selectpicker('#my-select', { liveSearch: true });
    </script>

    Usage


    Via selectpicker class

    @@ -50,10 +74,6 @@

    Via JavaScr

    If calling bootstrap-select via JavaScript, run your code after the elements exist — either place the script at the bottom of the page (after the last <select>) or wrap it in a DOMContentLoaded listener:

    -
    document.addEventListener('DOMContentLoaded', function () {
    document.querySelectorAll('select').forEach(function (el) {
    new Selectpicker(el);
    });
    });
    -

    Tags-style editor pattern

    -

    For taxonomy-style experiences, combine live search, removable selected tags, and open-option creation so selections stay visible as tags without repeating the full list in the button:

    -
    new Selectpicker('#tag-editor', {
    liveSearch: true,
    showSelectedTags: true,
    openOptions: true,
    selectionIndicator: 'checkbox'
    });
    -

    See Examples for a live demo and Options for the full source.create(callback, searchValue) flow used by remote-backed editors.

    +
    document.addEventListener('DOMContentLoaded', function () {
    document.querySelectorAll('select').forEach(function (el) {
    new Selectpicker(el);
    });
    });
    \ No newline at end of file diff --git a/docs/docs/methods/index.html b/docs/docs/methods/index.html index 50b62716..2c8bab23 100644 --- a/docs/docs/methods/index.html +++ b/docs/docs/methods/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: Latest

    Methods

    +
    Version: Latest

    Methods

    Interface with bootstrap-select.

    In this fork, methods are called directly on the Selectpicker instance (there is no jQuery $.fn.selectpicker). Obtain an instance with @@ -94,6 +94,6 @@

    .destroy()
    Selectpicker.getInstance('#my-select').destroy();


    Static methods

    -
    MethodDescription
    new Selectpicker(elementOrSelector, options)Create a new instance.
    Selectpicker.getInstance(elementOrSelector)Return the existing instance for an element, or null.
    Selectpicker.getOrCreateInstance(elementOrSelector, options)Return the existing instance, creating one if needed.
    Selectpicker.setDefaults(options)Set global default options (used by the i18n translation files).
    Selectpicker.VERSIONThe plugin version.
    +
    MethodDescription
    new Selectpicker(elementOrSelector, options)Create a new instance.
    Selectpicker.getInstance(elementOrSelector)Return the existing instance for an element, or null.
    Selectpicker.getOrCreateInstance(elementOrSelector, options)Return the existing instance, creating one if needed.
    Selectpicker.setDefaults(options)Set global default options (used by the i18n translation files).
    Selectpicker.VERSIONThe plugin version.
    \ No newline at end of file diff --git a/docs/docs/options/index.html b/docs/docs/options/index.html index 05ef7648..8e9d66c1 100644 --- a/docs/docs/options/index.html +++ b/docs/docs/options/index.html @@ -9,14 +9,14 @@ - - + + -
    Version: Latest
    CrestApps fork

    The options and data attributes documented on this page are part of the current forward-only API. Initialize with new Selectpicker('#sel', options) or add the selectpicker class for automatic initialization. Global defaults are set with Selectpicker.setDefaults({ ... }).

    +
    Version: Latest
    CrestApps fork

    The options and data attributes documented on this page are part of the current forward-only API. Initialize with new Selectpicker('#sel', options) or add the selectpicker class for automatic initialization. Global defaults are set with Selectpicker.setDefaults({ ... }).

    Core options


    Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-, as in @@ -270,7 +270,7 @@ boolean false -

    Show checkmark on selected option (for items without multiple attribute).

    +

    Shows the default checkmark indicator on single-select menus. Multiselect menus already render a selection indicator by default.

    @@ -294,7 +294,7 @@ 'checkmark' | 'checkbox' 'checkmark' -

    Controls how selected items are indicated in the dropdown. Use 'checkbox' to render a Bootstrap-style checkbox column instead of the default floating checkmark.

    +

    Controls how selected items are indicated in the dropdown. Use 'checkbox' to render a Bootstrap-style checkbox column on multiselects, or radio-style indicators automatically on single selects, instead of the default floating checkmark.

    @@ -390,66 +390,10 @@

    Default settings

    Selectpicker.DEFAULTS.multipleSeparator = ' | ';

    Events


    -

    bootstrap-select emits native CustomEvents on the original <select> element.

    -

    For show.bs.select, shown.bs.select, hide.bs.select, and hidden.bs.select, the original Bootstrap dropdown event is exposed as event.detail.bsEvent. Its relatedTarget property is the toggling button element.

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Event TypeDescription
    show.bs.selectThis event fires immediately when the menu starts opening.
    shown.bs.selectThis event is fired when the menu has been made visible to the user (after CSS transitions complete).
    hide.bs.selectThis event is fired immediately when the menu starts closing.
    hidden.bs.selectThis event is fired when the menu has finished being hidden from the user (after CSS transitions complete).
    loaded.bs.selectThis event fires after the select has been initialized.
    rendered.bs.selectThis event fires after the render instance has been called.
    refreshed.bs.selectThis event fires after the refresh instance has been called.
    changed.bs.select -

    This event fires after the select's value has been changed. The detail object passes clickedIndex, isSelected, and previousValue via event.detail.

    -

    previousValue is the value of the select prior to being changed. If the select's value has been changed either via the val(), selectAll(), or deselectAll() methods, clickedIndex and isSelected will be null.

    -
    maxReached.bs.selectThis event fires when a multi-select tries to exceed the configured maxOptions limit on the select.
    maxReachedGrp.bs.selectThis event fires when a multi-select tries to exceed the configured data-max-options limit on an <optgroup>.
    fetched.bs.selectThis event fires after async or callback-backed source data has been fetched and applied to the picker.
    -
    document.querySelector('#mySelect').addEventListener('changed.bs.select', function (e) {
    const { clickedIndex, isSelected, previousValue } = e.detail;
    // do something...
    });

    document.querySelector('#mySelect').addEventListener('show.bs.select', function (e) {
    const bootstrapEvent = e.detail.bsEvent;
    const button = bootstrapEvent.relatedTarget;
    });
    +

    bootstrap-select emits native CustomEvents on the original <select> element. +See the dedicated Events page for the full event reference, event +payload details, and examples for changed.bs.select, show.bs.select, and +the rest of the public event surface.

    Sanitizer


    HTML added via the data-content attribute on individual options is sanitized using our built-in sanitizer.

    @@ -459,6 +403,6 @@

    Sanitizer
    var myDefaultWhiteList = Selectpicker.DEFAULTS.whiteList;

    // To allow table elements
    myDefaultWhiteList.table = [];

    // To allow td elements and data-option attributes on td elements
    myDefaultWhiteList.td = ['data-option'];

    // You can push your custom regex to validate your attributes.
    // Be careful about your regular expressions being too lax
    var myCustomRegex = /^data-my-app-[\w-]+/;
    myDefaultWhiteList['*'].push(myCustomRegex);

    If you want to bypass our sanitizer because you prefer to use a dedicated library, you should do the following:

    new Selectpicker('#yourSelect', {
    sanitizeFn: function (domNodes) {
    return DOMPurify.sanitize(domNodes)
    }
    });
    -

    For performance reasons, our built-in sanitizer accepts an array of DOM nodes as its first argument, rather than an HTML string. Keep that in mind if deciding to use your own sanitizeFn.

    +

    For performance reasons, our built-in sanitizer accepts an array of DOM nodes as its first argument, rather than an HTML string. Keep that in mind if deciding to use your own sanitizeFn.

    \ No newline at end of file diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index ee00b274..c698958b 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -16,7 +16,7 @@ const config = { url: process.env.DOCUSAURUS_URL || 'https://bootstrap-select.crestapps.com', baseUrl: normalizedBaseUrl, organizationName: 'CrestApps', - projectName: 'crestapps-bootstrap-select', + projectName: 'bootstrap-select', trailingSlash: true, onBrokenLinks: 'throw', markdown: { @@ -70,7 +70,7 @@ const config = { docs: { path: 'content', sidebarPath: require.resolve('./sidebars.js'), - editUrl: 'https://github.com/CrestApps/crestapps-bootstrap-select/tree/main/docs/', + editUrl: 'https://github.com/CrestApps/bootstrap-select/tree/main/docs/', lastVersion: 'current', versions: { current: { @@ -119,7 +119,7 @@ const config = { dropdownActiveClassDisabled: true }, { - href: 'https://github.com/CrestApps/crestapps-bootstrap-select', + href: 'https://github.com/CrestApps/bootstrap-select/', label: 'GitHub', position: 'right' } @@ -154,7 +154,7 @@ const config = { items: [ { label: 'Issues', - href: 'https://github.com/CrestApps/crestapps-bootstrap-select/issues' + href: 'https://github.com/CrestApps/bootstrap-select/issues' } ] }, @@ -163,7 +163,7 @@ const config = { items: [ { label: 'GitHub', - href: 'https://github.com/CrestApps/crestapps-bootstrap-select' + href: 'https://github.com/CrestApps/bootstrap-select/' }, { label: 'CrestApps', diff --git a/docs/index.html b/docs/index.html index 30ed1eb2..e131ac13 100644 --- a/docs/index.html +++ b/docs/index.html @@ -9,13 +9,13 @@ - - + + -

    bootstrap-select for modern Bootstrap

    A dependency-free, vanilla JavaScript fork of bootstrap-select for Bootstrap 5+.

    Enhance native select elements with searchable menus, multiselects, custom text, sizing, and events while keeping jQuery out of your application.

    Vanilla JavaScript

    Use the Selectpicker class directly, with no jQuery dependency or legacy Bootstrap compatibility paths.

    Bootstrap 5+

    Built for modern Bootstrap projects and loaded alongside Bootstrap bundle assets in the docs examples.

    Hosted examples

    Exercise live selectpicker examples in the docs site or open standalone HTML examples served from the same Docusaurus app.

    +

    bootstrap-select for modern Bootstrap

    A dependency-free, vanilla JavaScript fork of bootstrap-select for Bootstrap 5+.

    Enhance native select elements with searchable menus, multiselects, custom text, sizing, and events while keeping jQuery out of your application.

    Vanilla JavaScript

    Use the Selectpicker class directly, with no jQuery dependency or legacy Bootstrap compatibility paths.

    Bootstrap 5+

    Built for modern Bootstrap projects and loaded alongside Bootstrap bundle assets in the docs examples.

    Hosted examples

    Exercise live selectpicker examples in the docs site or open standalone HTML examples served from the same Docusaurus app.

    \ No newline at end of file diff --git a/docs/search-index.json b/docs/search-index.json index f491a607..0a41f0df 100644 --- a/docs/search-index.json +++ b/docs/search-index.json @@ -1 +1 @@ -[{"documents":[{"i":1,"t":"Getting Started","u":"/docs/","b":["Docs"]},{"i":14,"t":"Basic examples","u":"/docs/examples/","b":["Docs"]},{"i":77,"t":"Methods","u":"/docs/methods/","b":["Docs"]},{"i":81,"t":"Core options","u":"/docs/options/","b":["Docs"]}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,1.137,1,1.137]],["t/14",[2,1.137,3,1.137]],["t/77",[4,1.46]],["t/81",[5,1.137,6,1.137]]],"invertedIndex":[["basic",{"_index":2,"t":{"14":{"position":[[0,5]]}}}],["core",{"_index":5,"t":{"81":{"position":[[0,4]]}}}],["exampl",{"_index":3,"t":{"14":{"position":[[6,8]]}}}],["get",{"_index":0,"t":{"1":{"position":[[0,7]]}}}],["method",{"_index":4,"t":{"77":{"position":[[0,7]]}}}],["option",{"_index":6,"t":{"81":{"position":[[5,7]]}}}],["start",{"_index":1,"t":{"1":{"position":[[8,7]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":3,"t":"Quick start","u":"/docs/","h":"#quick-start","p":1},{"i":5,"t":"Using the CDN build","u":"/docs/","h":"#using-the-cdn-build","p":1},{"i":7,"t":"Usage","u":"/docs/","h":"","p":1},{"i":8,"t":"Via selectpicker class","u":"/docs/","h":"#via-selectpicker-class","p":1},{"i":10,"t":"Via JavaScript","u":"/docs/","h":"#via-javascript","p":1},{"i":12,"t":"Tags-style editor pattern","u":"/docs/","h":"#tags-style-editor-pattern","p":1},{"i":16,"t":"Standard select boxes","u":"/docs/examples/","h":"#standard-select-boxes","p":14},{"i":18,"t":"Select boxes with optgroups","u":"/docs/examples/","h":"#select-boxes-with-optgroups","p":14},{"i":20,"t":"Multiple select boxes","u":"/docs/examples/","h":"#multiple-select-boxes","p":14},{"i":22,"t":"Live search","u":"/docs/examples/","h":"#live-search","p":14},{"i":24,"t":"Key words","u":"/docs/examples/","h":"#key-words","p":14},{"i":26,"t":"Tags-style live search with open options","u":"/docs/examples/","h":"#tags-style-live-search-with-open-options","p":14},{"i":28,"t":"List-style menu","u":"/docs/examples/","h":"#list-style-menu","p":14},{"i":30,"t":"Floating labels with visible tags","u":"/docs/examples/","h":"#floating-labels-with-visible-tags","p":14},{"i":32,"t":"Limit the number of selections","u":"/docs/examples/","h":"","p":14},{"i":34,"t":"Custom button text","u":"/docs/examples/","h":"","p":14},{"i":35,"t":"Placeholder","u":"/docs/examples/","h":"#placeholder","p":14},{"i":37,"t":"Selected text","u":"/docs/examples/","h":"#selected-text","p":14},{"i":39,"t":"Selected text format","u":"/docs/examples/","h":"#selected-text-format","p":14},{"i":41,"t":"Styling","u":"/docs/examples/","h":"","p":14},{"i":42,"t":"Button classes","u":"/docs/examples/","h":"#button-classes","p":14},{"i":44,"t":"Checkmark on selected option","u":"/docs/examples/","h":"#checkmark-on-selected-option","p":14},{"i":46,"t":"Menu arrow","u":"/docs/examples/","h":"#menu-arrow","p":14},{"i":48,"t":"Style individual options","u":"/docs/examples/","h":"#style-individual-options","p":14},{"i":50,"t":"Width","u":"/docs/examples/","h":"#width","p":14},{"i":52,"t":"Customize options","u":"/docs/examples/","h":"","p":14},{"i":53,"t":"Font Awesome icons","u":"/docs/examples/","h":"#font-awesome-icons","p":14},{"i":55,"t":"Custom content","u":"/docs/examples/","h":"#custom-content","p":14},{"i":57,"t":"Subtext","u":"/docs/examples/","h":"#subtext","p":14},{"i":59,"t":"Customize menu","u":"/docs/examples/","h":"","p":14},{"i":60,"t":"Menu size","u":"/docs/examples/","h":"#menu-size","p":14},{"i":62,"t":"Select/deselect all options","u":"/docs/examples/","h":"#selectdeselect-all-options","p":14},{"i":64,"t":"Divider","u":"/docs/examples/","h":"#divider","p":14},{"i":66,"t":"Menu header","u":"/docs/examples/","h":"#menu-header","p":14},{"i":68,"t":"Dropup menu","u":"/docs/examples/","h":"#dropup-menu","p":14},{"i":70,"t":"Disabled","u":"/docs/examples/","h":"","p":14},{"i":71,"t":"Disabled select box","u":"/docs/examples/","h":"#disabled-select-box","p":14},{"i":73,"t":"Disabled options","u":"/docs/examples/","h":"#disabled-options","p":14},{"i":75,"t":"Disabled option groups","u":"/docs/examples/","h":"#disabled-option-groups","p":14},{"i":79,"t":"Static methods","u":"/docs/methods/","h":"#static-methods","p":77},{"i":83,"t":"Tags-style live search and open options","u":"/docs/options/","h":"#tags-style-live-search-and-open-options","p":81},{"i":85,"t":"Default settings","u":"/docs/options/","h":"","p":81},{"i":87,"t":"Events","u":"/docs/options/","h":"","p":81},{"i":89,"t":"Sanitizer","u":"/docs/options/","h":"#sanitizer","p":81}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/3",[0,3.642,1,3.642]],["t/5",[2,3.077,3,3.077,4,3.077]],["t/7",[5,4.462]],["t/8",[6,2.615,7,3.077,8,2.615]],["t/10",[6,3.095,9,3.642]],["t/12",[10,1.804,11,1.516,12,2.664,13,2.664]],["t/16",[14,3.077,15,1.508,16,2.083]],["t/18",[15,1.508,16,2.083,17,3.077]],["t/20",[15,1.508,16,2.083,18,3.077]],["t/22",[19,2.735,20,2.735]],["t/24",[21,3.642,22,3.642]],["t/26",[10,1.422,11,1.195,19,1.577,20,1.577,23,1.785,24,1.029]],["t/28",[11,1.751,25,3.077,26,1.751]],["t/30",[10,1.804,27,2.664,28,2.664,29,2.664]],["t/32",[15,1.508,30,3.077,31,3.077]],["t/34",[32,2.083,33,2.615,34,2.311]],["t/35",[35,4.462]],["t/37",[15,1.785,34,2.735]],["t/39",[15,1.508,34,2.311,36,3.077]],["t/41",[11,2.538]],["t/42",[8,3.095,33,3.095]],["t/44",[15,1.508,24,1.508,37,3.077]],["t/46",[26,2.072,38,3.642]],["t/48",[11,1.751,24,1.508,39,3.077]],["t/50",[40,4.462]],["t/52",[24,1.785,32,2.466]],["t/53",[41,3.077,42,3.077,43,3.077]],["t/55",[32,2.466,44,3.642]],["t/57",[45,4.462]],["t/59",[26,2.072,32,2.466]],["t/60",[26,2.072,46,3.642]],["t/62",[24,1.785,47,3.642]],["t/64",[48,4.462]],["t/66",[26,2.072,49,3.642]],["t/68",[26,2.072,50,3.642]],["t/70",[51,3.02]],["t/71",[15,1.508,16,2.083,51,2.083]],["t/73",[24,1.785,51,2.466]],["t/75",[24,1.508,51,2.083,52,3.077]],["t/79",[53,3.642,54,3.642]],["t/83",[10,1.422,11,1.195,19,1.577,20,1.577,23,1.785,24,1.029]],["t/85",[55,3.642,56,3.642]],["t/87",[57,4.462]],["t/89",[58,4.462]]],"invertedIndex":[["arrow",{"_index":38,"t":{"46":{"position":[[5,5]]}}}],["awesom",{"_index":42,"t":{"53":{"position":[[5,7]]}}}],["box",{"_index":16,"t":{"16":{"position":[[16,5]]},"18":{"position":[[7,5]]},"20":{"position":[[16,5]]},"71":{"position":[[16,3]]}}}],["build",{"_index":4,"t":{"5":{"position":[[14,5]]}}}],["button",{"_index":33,"t":{"34":{"position":[[7,6]]},"42":{"position":[[0,6]]}}}],["cdn",{"_index":3,"t":{"5":{"position":[[10,3]]}}}],["checkmark",{"_index":37,"t":{"44":{"position":[[0,9]]}}}],["class",{"_index":8,"t":{"8":{"position":[[17,5]]},"42":{"position":[[7,7]]}}}],["content",{"_index":44,"t":{"55":{"position":[[7,7]]}}}],["custom",{"_index":32,"t":{"34":{"position":[[0,6]]},"52":{"position":[[0,9]]},"55":{"position":[[0,6]]},"59":{"position":[[0,9]]}}}],["default",{"_index":55,"t":{"85":{"position":[[0,7]]}}}],["disabl",{"_index":51,"t":{"70":{"position":[[0,8]]},"71":{"position":[[0,8]]},"73":{"position":[[0,8]]},"75":{"position":[[0,8]]}}}],["divid",{"_index":48,"t":{"64":{"position":[[0,7]]}}}],["dropup",{"_index":50,"t":{"68":{"position":[[0,6]]}}}],["editor",{"_index":12,"t":{"12":{"position":[[11,6]]}}}],["event",{"_index":57,"t":{"87":{"position":[[0,6]]}}}],["float",{"_index":27,"t":{"30":{"position":[[0,8]]}}}],["font",{"_index":41,"t":{"53":{"position":[[0,4]]}}}],["format",{"_index":36,"t":{"39":{"position":[[14,6]]}}}],["group",{"_index":52,"t":{"75":{"position":[[16,6]]}}}],["header",{"_index":49,"t":{"66":{"position":[[5,6]]}}}],["icon",{"_index":43,"t":{"53":{"position":[[13,5]]}}}],["individu",{"_index":39,"t":{"48":{"position":[[6,10]]}}}],["javascript",{"_index":9,"t":{"10":{"position":[[4,10]]}}}],["key",{"_index":21,"t":{"24":{"position":[[0,3]]}}}],["label",{"_index":28,"t":{"30":{"position":[[9,6]]}}}],["limit",{"_index":30,"t":{"32":{"position":[[0,5]]}}}],["list",{"_index":25,"t":{"28":{"position":[[0,4]]}}}],["live",{"_index":19,"t":{"22":{"position":[[0,4]]},"26":{"position":[[11,4]]},"83":{"position":[[11,4]]}}}],["menu",{"_index":26,"t":{"28":{"position":[[11,4]]},"46":{"position":[[0,4]]},"59":{"position":[[10,4]]},"60":{"position":[[0,4]]},"66":{"position":[[0,4]]},"68":{"position":[[7,4]]}}}],["method",{"_index":54,"t":{"79":{"position":[[7,7]]}}}],["multipl",{"_index":18,"t":{"20":{"position":[[0,8]]}}}],["number",{"_index":31,"t":{"32":{"position":[[10,6]]}}}],["open",{"_index":23,"t":{"26":{"position":[[28,4]]},"83":{"position":[[27,4]]}}}],["optgroup",{"_index":17,"t":{"18":{"position":[[18,9]]}}}],["option",{"_index":24,"t":{"26":{"position":[[33,7]]},"44":{"position":[[22,6]]},"48":{"position":[[17,7]]},"52":{"position":[[10,7]]},"62":{"position":[[20,7]]},"73":{"position":[[9,7]]},"75":{"position":[[9,6]]},"83":{"position":[[32,7]]}}}],["pattern",{"_index":13,"t":{"12":{"position":[[18,7]]}}}],["placehold",{"_index":35,"t":{"35":{"position":[[0,11]]}}}],["quick",{"_index":0,"t":{"3":{"position":[[0,5]]}}}],["sanit",{"_index":58,"t":{"89":{"position":[[0,9]]}}}],["search",{"_index":20,"t":{"22":{"position":[[5,6]]},"26":{"position":[[16,6]]},"83":{"position":[[16,6]]}}}],["select",{"_index":15,"t":{"16":{"position":[[9,6]]},"18":{"position":[[0,6]]},"20":{"position":[[9,6]]},"32":{"position":[[20,10]]},"37":{"position":[[0,8]]},"39":{"position":[[0,8]]},"44":{"position":[[13,8]]},"71":{"position":[[9,6]]}}}],["select/deselect",{"_index":47,"t":{"62":{"position":[[0,15]]}}}],["selectpick",{"_index":7,"t":{"8":{"position":[[4,12]]}}}],["set",{"_index":56,"t":{"85":{"position":[[8,8]]}}}],["size",{"_index":46,"t":{"60":{"position":[[5,4]]}}}],["standard",{"_index":14,"t":{"16":{"position":[[0,8]]}}}],["start",{"_index":1,"t":{"3":{"position":[[6,5]]}}}],["static",{"_index":53,"t":{"79":{"position":[[0,6]]}}}],["style",{"_index":11,"t":{"12":{"position":[[5,5]]},"26":{"position":[[5,5]]},"28":{"position":[[5,5]]},"41":{"position":[[0,7]]},"48":{"position":[[0,5]]},"83":{"position":[[5,5]]}}}],["subtext",{"_index":45,"t":{"57":{"position":[[0,7]]}}}],["tag",{"_index":10,"t":{"12":{"position":[[0,4]]},"26":{"position":[[0,4]]},"30":{"position":[[29,4]]},"83":{"position":[[0,4]]}}}],["text",{"_index":34,"t":{"34":{"position":[[14,4]]},"37":{"position":[[9,4]]},"39":{"position":[[9,4]]}}}],["us",{"_index":2,"t":{"5":{"position":[[0,5]]}}}],["usag",{"_index":5,"t":{"7":{"position":[[0,5]]}}}],["via",{"_index":6,"t":{"8":{"position":[[0,3]]},"10":{"position":[[0,3]]}}}],["visibl",{"_index":29,"t":{"30":{"position":[[21,7]]}}}],["width",{"_index":40,"t":{"50":{"position":[[0,5]]}}}],["word",{"_index":22,"t":{"24":{"position":[[4,5]]}}}]],"pipeline":["stemmer"]}},{"documents":[{"i":1,"t":"Install and use the CrestApps bootstrap-select fork with Bootstrap 5+.","s":"Getting Started","u":"/docs/","p":1},{"i":14,"t":"Live bootstrap-select examples hosted by the Docusaurus docs site.","s":"Basic examples","u":"/docs/examples/","p":14},{"i":77,"t":"bootstrap-select instance and static methods.","s":"Methods","u":"/docs/methods/","p":77},{"i":81,"t":"bootstrap-select options, events, and sanitizer settings.","s":"Core options","u":"/docs/options/","p":81}],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[["t/1",[0,1.119,1,1.119,2,1.119,3,0.138,4,0.098,5,1.119,6,1.119]],["t/14",[3,0.098,4,0.098,7,1.119,8,1.119,9,1.119,10,1.119,11,1.119,12,1.119]],["t/77",[3,0.118,4,0.118,13,1.347,14,1.347,15,1.347]],["t/81",[3,0.11,4,0.11,16,1.261,17,1.261,18,1.261,19,1.261]]],"invertedIndex":[["5",{"_index":6,"t":{"1":{"position":[[67,3]]}}}],["bootstrap",{"_index":3,"t":{"1":{"position":[[30,9],[57,9]]},"14":{"position":[[5,9]]},"77":{"position":[[0,9]]},"81":{"position":[[0,9]]}}}],["crestapp",{"_index":2,"t":{"1":{"position":[[20,9]]}}}],["doc",{"_index":11,"t":{"14":{"position":[[56,4]]}}}],["docusauru",{"_index":10,"t":{"14":{"position":[[45,10]]}}}],["event",{"_index":17,"t":{"81":{"position":[[26,7]]}}}],["exampl",{"_index":8,"t":{"14":{"position":[[22,8]]}}}],["fork",{"_index":5,"t":{"1":{"position":[[47,4]]}}}],["host",{"_index":9,"t":{"14":{"position":[[31,6]]}}}],["instal",{"_index":0,"t":{"1":{"position":[[0,7]]}}}],["instanc",{"_index":13,"t":{"77":{"position":[[17,8]]}}}],["live",{"_index":7,"t":{"14":{"position":[[0,4]]}}}],["method",{"_index":15,"t":{"77":{"position":[[37,8]]}}}],["option",{"_index":16,"t":{"81":{"position":[[17,8]]}}}],["sanit",{"_index":18,"t":{"81":{"position":[[38,9]]}}}],["select",{"_index":4,"t":{"1":{"position":[[40,6]]},"14":{"position":[[15,6]]},"77":{"position":[[10,6]]},"81":{"position":[[10,6]]}}}],["set",{"_index":19,"t":{"81":{"position":[[48,9]]}}}],["site",{"_index":12,"t":{"14":{"position":[[61,5]]}}}],["static",{"_index":14,"t":{"77":{"position":[[30,6]]}}}],["us",{"_index":1,"t":{"1":{"position":[[12,3]]}}}]],"pipeline":["stemmer"]}},{"documents":[],"index":{"version":"2.3.9","fields":["t"],"fieldVectors":[],"invertedIndex":[],"pipeline":["stemmer"]}},{"documents":[{"i":2,"t":"CrestApps fork This is the CrestApps fork of snapappointments/bootstrap-select. It removes the jQuery dependency entirely, uses plain vanilla JavaScript, and supports Bootstrap 5+ only. Older Bootstrap and jQuery compatibility paths are intentionally out of scope so the library can stay small and forward-focused.","s":"Getting Started","u":"/docs/","h":"","p":1},{"i":4,"t":"bootstrap-select requires Bootstrap 5+ (CSS and JS, including its bundled Popper). jQuery is not required. Install with npm: npm install @crestapps/bootstrap-select bootstrap Load Bootstrap 5 first, then bootstrap-select's CSS and JS (after Bootstrap's JavaScript): ","s":"Quick start","u":"/docs/","h":"#quick-start","p":1},{"i":6,"t":"After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production: You can replace @1.1.2 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments. When loaded via a ","s":"Quick start","u":"/docs/","h":"#quick-start","p":1},{"i":6,"t":"After the package is published to npm, it will also be available through jsDelivr. Prefer pinning an explicit package version in production: You can replace @1.2.0 with the version you want to consume. During development, @latest also works, but a fixed version is safer for production deployments.","s":"Using the CDN build","u":"/docs/","h":"#using-the-cdn-build","p":1},{"i":8,"t":"bootstrap-select now ships three JavaScript consumption styles from the same shared source code: Style Package entry Direct file Use when ESM import Selectpicker from '@crestapps/bootstrap-select' dist/js/bootstrap-select.esm.mjs Your app uses native modules or an ESM-first bundler CommonJS require('@crestapps/bootstrap-select') dist/js/bootstrap-select.cjs Your bundler or app still prefers CommonJS Browser global / UMD n/a dist/js/bootstrap-select.js or .min.js You load the plugin directly from a ","s":"Browser global / UMD","u":"/docs/","h":"#browser-global--umd","p":1},{"i":17,"t":"Add the selectpicker class to your select elements to auto-initialize bootstrap-select once the DOM is ready. Existing bootstrap-select markup that uses title=\"...\" placeholders or data-width=\"fit\" is also supported: ","s":"Via selectpicker class","u":"/docs/","h":"#via-selectpicker-class","p":1},{"i":19,"t":"// Initialize one select (accepts an element or a selector string) new Selectpicker('#my-select', { liveSearch: true }); or // Initialize several selects document.querySelectorAll('.my-select').forEach(function (el) { new Selectpicker(el); }); If calling bootstrap-select via JavaScript, run your code after the elements exist — either place the script at the bottom of the page (after the last element.","s":"Events","u":"/docs/events/","h":"","p":20},{"i":23,"t":"const select = document.querySelector('#mySelect'); select.addEventListener('changed.bs.select', function (e) { const { clickedIndex, isSelected, previousValue } = e.detail; console.log('selection changed', { clickedIndex, isSelected, previousValue }); }); select.addEventListener('show.bs.select', function (e) { const bootstrapEvent = e.detail.bsEvent; const button = bootstrapEvent.relatedTarget; console.log('opening from button', button); });","s":"Listening for events","u":"/docs/events/","h":"#listening-for-events","p":20},{"i":25,"t":"show.bs.select, shown.bs.select, hide.bs.select, and hidden.bs.select expose the original Bootstrap dropdown event as event.detail.bsEvent. changed.bs.select exposes clickedIndex, isSelected, and previousValue on event.detail. If the value changed via val(), selectAll(), or deselectAll(), clickedIndex and isSelected are null.","s":"Event detail","u":"/docs/events/","h":"#event-detail","p":20},{"i":27,"t":"Event type Description show.bs.select Fires immediately when the menu starts opening. shown.bs.select Fires after the menu is visible to the user. hide.bs.select Fires immediately when the menu starts closing. hidden.bs.select Fires after the menu has finished closing. loaded.bs.select Fires after the selectpicker has been initialized. rendered.bs.select Fires after render() updates the UI. refreshed.bs.select Fires after refresh() syncs the UI with the underlying ","s":"Standard select boxes","u":"/docs/examples/","h":"#standard-select-boxes","p":28},{"i":36,"t":"Use the show-tick class when you want the default checkmark indicator on a single-select menu: ","s":"Single select with checkmark indicator","u":"/docs/examples/","h":"#single-select-with-checkmark-indicator","p":28},{"i":38,"t":"If you set selectionIndicator to checkbox on a single select, bootstrap-select renders radio-style indicators automatically: ","s":"Single select with radio indicators","u":"/docs/examples/","h":"#single-select-with-radio-indicators","p":28},{"i":40,"t":"","s":"Select boxes with optgroups","u":"/docs/examples/","h":"#select-boxes-with-optgroups","p":28},{"i":42,"t":"","s":"Multiple select boxes","u":"/docs/examples/","h":"#multiple-select-boxes","p":28},{"i":44,"t":"Use data-selection-indicator=\"checkbox\" on multiselects when you want a checkbox column instead of the floating checkmark: ","s":"Multiple select with checkbox indicators","u":"/docs/examples/","h":"#multiple-select-with-checkbox-indicators","p":28},{"i":47,"t":"You can add a search input by passing data-live-search=\"true\" attribute:","s":"Live search","u":"/docs/examples/","h":"#live-search","p":28},{"i":49,"t":"Add key words to options to improve their searchability using data-tokens. ","s":"Key words","u":"/docs/examples/","h":"#key-words","p":28},{"i":51,"t":"Use showSelectedTags to keep selections visible as removable tags above the search box, while the button switches to a compact summary instead of repeating the same values. ","s":"Tags-style live search with open options","u":"/docs/examples/","h":"#tags-style-live-search-with-open-options","p":28},{"i":53,"t":"Set selectedItemsStyle to list to render the removable selections as a stacked Bootstrap list group: ","s":"List-style menu","u":"/docs/examples/","h":"#list-style-menu","p":28},{"i":55,"t":"When a tags-style picker is placed inside a Bootstrap 5 form-floating wrapper, the selected tags stay visible inside the control after the menu closes, with balanced top and bottom spacing around the tags.
    For remote-backed pickers, initialize with JavaScript and provide source.create(callback, searchValue) to save the new item before selecting it: new Selectpicker('#tag-editor', { liveSearch: true, showSelectedTags: true, openOptions: true, source: { data: function (callback) { callback(existingTags); }, search: function (callback, page, searchValue) { callback(filterTags(searchValue)); }, create: function (callback, searchValue) { saveTag(searchValue).then(function (tag) { callback({ text: tag.displayText, value: tag.id }); }); } } });","s":"Floating labels with visible tags","u":"/docs/examples/","h":"#floating-labels-with-visible-tags","p":28},{"i":57,"t":"Limit the number of options that can be selected via the data-max-options attribute. It also works for option groups. Customize the message displayed when the limit is reached with maxOptionsText.
    ","s":"Limit the number of selections","u":"/docs/examples/","h":"#limit-the-number-of-selections","p":28},{"i":60,"t":"Use the placeholder attribute to set the default placeholder text when nothing is selected. This works for both multiple and standard select boxes: Legacy bootstrap-select markup that uses the select element's title attribute for placeholder text is also supported on single selects: ","s":"Placeholder","u":"/docs/examples/","h":"#placeholder","p":28},{"i":62,"t":"Set the title attribute on individual options to display alternative text when the option is selected: ","s":"Selected text","u":"/docs/examples/","h":"#selected-text","p":28},{"i":64,"t":"Specify how the selection is displayed with the data-selected-text-format attribute on a multiple select. The supported values are: values: A comma delimited list of selected values (default) count: If one item is selected, then the option value is shown. If more than one is selected then the number of selected items is displayed, e.g. 2 of 6 selected count > x: Where x is the number of items selected when the display format changes from values to count static: Always show the placeholder, regardless of selection ","s":"Selected text format","u":"/docs/examples/","h":"#selected-text-format","p":28},{"i":67,"t":"You can set the button classes via the data-style attribute: ","s":"Button classes","u":"/docs/examples/","h":"#button-classes","p":28},{"i":69,"t":"The Bootstrap menu arrow can be added with the show-menu-arrow class: ","s":"Menu arrow","u":"/docs/examples/","h":"#menu-arrow","p":28},{"i":71,"t":"Classes and styles added to options are transferred to the select box: .special { font-weight: bold !important; color: #fff !important; background: #bc0000 !important; text-transform: uppercase; }","s":"Style individual options","u":"/docs/examples/","h":"#style-individual-options","p":28},{"i":73,"t":"Wrap selects in grid columns, or any custom parent element, to easily enforce desired widths.
    Alternatively, use the data-width attribute to set the width of the select. Set data-width to 'auto' to automatically adjust the width of the select to its widest option. 'fit' automatically adjusts the width of the select to the width of its currently selected option. An exact value can also be specified, e.g., 300px or 50%. ","s":"Width","u":"/docs/examples/","h":"#width","p":28},{"i":76,"t":"This example uses Font Awesome. Add an icon to an option or optgroup with the data-icon attribute: Bootstrap 5 icons Bootstrap 5 does not include an icon font. To use Font Awesome or another icon library, set iconBase and tickIcon to match that library. The selected option renders its icon in the button, and the menu shows the icons for the remaining options as well. ","s":"Font Awesome icons","u":"/docs/examples/","h":"#font-awesome-icons","p":28},{"i":78,"t":"Insert custom HTML into the option with the data-content attribute: Custom content is sanitized This feature inserts HTML into the DOM. By default, it is sanitized using our built-in sanitizer. ","s":"Custom content","u":"/docs/examples/","h":"#custom-content","p":28},{"i":80,"t":"Add subtext to an option or optgroup with the data-subtext attribute: ","s":"Subtext","u":"/docs/examples/","h":"#subtext","p":28},{"i":83,"t":"The size option is set to 'auto' by default. When size is set to 'auto', the menu always opens up to show as many items as the window will allow without being cut off. Set size to false to always show all items. The size of the menu can also be specifed using the data-size attribute. Specify a number for data-size to choose the maximum number of items to show in the menu. ","s":"Menu size","u":"/docs/examples/","h":"#menu-size","p":28},{"i":85,"t":"Adds two buttons to the top of the menu - Select All & Deselect All with data-actions-box=\"true\". ","s":"Select/deselect all options","u":"/docs/examples/","h":"#selectdeselect-all-options","p":28},{"i":87,"t":"Add data-divider=\"true\" to an option to turn it into a divider. ","s":"Divider","u":"/docs/examples/","h":"#divider","p":28},{"i":89,"t":"Add a header to the dropdown menu, e.g. header: 'Select a condiment' or data-header=\"Select a condiment\" ","s":"Menu header","u":"/docs/examples/","h":"#menu-header","p":28},{"i":91,"t":"dropupAuto is set to true by default, which automatically determines whether or not the menu should display above or below the select box. If dropupAuto is set to false, manually make the select a dropup menu by adding the .dropup class to the select. ","s":"Dropup menu","u":"/docs/examples/","h":"#dropup-menu","p":28},{"i":94,"t":"","s":"Disabled select box","u":"/docs/examples/","h":"#disabled-select-box","p":28},{"i":96,"t":"","s":"Disabled options","u":"/docs/examples/","h":"#disabled-options","p":28},{"i":98,"t":"","s":"Disabled option groups","u":"/docs/examples/","h":"#disabled-option-groups","p":28},{"i":100,"t":"Interface with bootstrap-select. In this fork, methods are called directly on the Selectpicker instance (there is no jQuery $.fn.selectpicker). Obtain an instance with Selectpicker.getInstance(elementOrSelector) (returns the existing instance) or Selectpicker.getOrCreateInstance(elementOrSelector, options). const picker = Selectpicker.getInstance('#my-select'); .val()​ You can set the selected value by calling the val method on the instance. Selectpicker.getInstance('#my-select').val('Mustard'); Selectpicker.getInstance('#my-select').val(['Mustard', 'Relish']); This is different to setting value directly on the select element. If you set value on the element directly, the bootstrap-select UI will not refresh (as the change event only fires from user interaction). You will have to call the UI render method yourself. const select = document.querySelector('#my-select'); select.value = 'Mustard'; Selectpicker.getInstance(select).render(); // this is the equivalent of the above Selectpicker.getInstance(select).val('Mustard'); Called with no argument, val() returns the current value (a string for single selects, or an array of strings for multiple selects). .selectAll()​ This will select all items in a multi-select. Selectpicker.getInstance('#my-select').selectAll(); .deselectAll()​ This will deselect all items in a multi-select. Selectpicker.getInstance('#my-select').deselectAll(); .render()​ You can force a re-render of the bootstrap-select UI with the render method. This is useful if you programmatically change any underlying values that affect the layout of the element. Selectpicker.getInstance('#my-select').render(); .mobile()​ Enable mobile scrolling by calling mobile(). This enables the device's native menu for select menus. The method for detecting the browser is left up to the user. if (/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) { Selectpicker.getInstance('#my-select').mobile(); } .setStyle()​ Modify the class(es) associated with either the button itself or its container. If changing the class on the container: const select = document.querySelector('#my-select'); select.closest('.bootstrap-select').classList.add('col-lg-12'); Selectpicker.getInstance(select).setStyle(); If changing the class(es) on the button (altering data-style): const picker = Selectpicker.getInstance('#my-select'); // Replace class picker.setStyle('btn-danger'); // Add class picker.setStyle('btn-lg', 'add'); // Remove class picker.setStyle('btn-lg', 'remove'); .refresh()​ To programmatically update a select with JavaScript, first manipulate the select, then use the refresh method to update the UI to match the new state. This is necessary when removing or adding options, or when disabling/enabling a select via JavaScript. Selectpicker.getInstance('#my-select').refresh(); For example, to remove an option then refresh: document.querySelector('.rm-mustard').addEventListener('click', function () { const select = document.querySelector('.remove-example'); const option = select.querySelector('[value=\"Mustard\"]'); if (option) option.remove(); Selectpicker.getInstance(select).refresh(); }); Or to disable/enable a select: const select = document.querySelector('.disable-example'); document.querySelector('.ex-disable').addEventListener('click', function () { select.disabled = true; Selectpicker.getInstance(select).refresh(); }); document.querySelector('.ex-enable').addEventListener('click', function () { select.disabled = false; Selectpicker.getInstance(select).refresh(); }); .toggle()​ Programmatically toggles the bootstrap-select menu open/closed. Selectpicker.getInstance('#my-select').toggle(); .open() and .close() are also available. .hide()​ To programmatically hide the bootstrap-select use the hide method (this only affects the visibility of the bootstrap-select itself). Selectpicker.getInstance('#my-select').hide(); .show()​ To programmatically show the bootstrap-select use the show method (this only affects the visibility of the bootstrap-select itself). Selectpicker.getInstance('#my-select').show(); .destroy()​ To programmatically destroy the bootstrap-select, use the destroy method. This removes the generated UI and restores the original Use JavaScript when the picker is backed by a remote source and new terms must be saved first: new Selectpicker('#tag-editor', { liveSearch: true, showSelectedTags: true, openOptions: true, openOptionsText: 'Create tag \"{0}\"', selectedTagRemoveLabel: 'Remove tag', selectionIndicator: 'checkbox', source: { data: function (callback) { callback(existingTags); }, search: function (callback, page, searchValue) { callback(findMatchingTags(searchValue)); }, create: function (callback, searchValue) { createTag(searchValue).then(function (tag) { callback({ text: tag.displayText, value: tag.id }); }); } } }); source.create can return the created option synchronously, invoke the provided callback later, or resolve a Promise. In each case, the picker adds the returned option and selects it automatically.","s":"Tags-style live search and open options","u":"/docs/options/","h":"#tags-style-live-search-and-open-options","p":103},{"i":108,"t":"You can change the default settings for bootstrap-select by modifying its DEFAULTS object (or by calling Selectpicker.setDefaults({ … })): Selectpicker.DEFAULTS.multipleSeparator = ' | ';","s":"Default settings","u":"/docs/options/","h":"","p":103},{"i":110,"t":"bootstrap-select emits native CustomEvents on the original

    Search the documentation

    +

    Search the documentation

    \ No newline at end of file diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 105a617f..a5a6a930 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -1 +1 @@ -https://bootstrap-select.crestapps.com/search/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/examples/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/methods/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/options/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/examples/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/methods/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/options/weekly0.5https://bootstrap-select.crestapps.com/docs/weekly0.5https://bootstrap-select.crestapps.com/docs/examples/weekly0.5https://bootstrap-select.crestapps.com/docs/methods/weekly0.5https://bootstrap-select.crestapps.com/docs/options/weekly0.5https://bootstrap-select.crestapps.com/weekly0.5 \ No newline at end of file +https://bootstrap-select.crestapps.com/search/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/examples/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/methods/weekly0.5https://bootstrap-select.crestapps.com/docs/1.0/options/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/examples/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/methods/weekly0.5https://bootstrap-select.crestapps.com/docs/1.1/options/weekly0.5https://bootstrap-select.crestapps.com/docs/weekly0.5https://bootstrap-select.crestapps.com/docs/events/weekly0.5https://bootstrap-select.crestapps.com/docs/examples/weekly0.5https://bootstrap-select.crestapps.com/docs/methods/weekly0.5https://bootstrap-select.crestapps.com/docs/options/weekly0.5https://bootstrap-select.crestapps.com/weekly0.5 \ No newline at end of file diff --git a/eslint.config.cjs b/eslint.config.cjs index b6679400..ae14ba06 100644 --- a/eslint.config.cjs +++ b/eslint.config.cjs @@ -157,7 +157,9 @@ module.exports = [ 'js/umd-intro.js', 'js/umd-outro.js', 'js/esm-intro.js', - 'js/esm-outro.js' + 'js/esm-outro.js', + 'js/cjs-intro.js', + 'js/cjs-outro.js' ] }, { @@ -182,10 +184,13 @@ module.exports = [ rules }, { - files: ['Gruntfile.js'], + files: ['rollup.config.js', 'scripts/**/*.js'], languageOptions: { ecmaVersion: 2022, - sourceType: 'commonjs' + sourceType: 'commonjs', + globals: { + ...globals.node + } }, rules } diff --git a/less/bootstrap-select.less b/less/bootstrap-select.less deleted file mode 100644 index c504ba82..00000000 --- a/less/bootstrap-select.less +++ /dev/null @@ -1,818 +0,0 @@ -@import "variables"; - -@keyframes bs-notify-fadeOut { - 0% {opacity: 0.9;} - 100% {opacity: 0;} -} - -// Mixins -.cursor-disabled() { - cursor: not-allowed; -} - -// Rules -select.bs-select-hidden, -.bootstrap-select > select.bs-select-hidden, -select.selectpicker { - display: none !important; -} - -.bootstrap-select { - width: 100%; - vertical-align: middle; - - // The selectpicker button - > .dropdown-toggle { - position: relative; - width: 100%; - // necessary for proper positioning of caret in Bootstrap 5 (pushes caret to the right) - text-align: right; - white-space: nowrap; - // force caret to be vertically centered for Bootstrap 5 multi-line buttons - display: inline-flex; - align-items: center; - justify-content: space-between; - - &:after { - margin-top: -1px; - } - - &.bs-placeholder { - &, - &:hover, - &:focus, - &:active { - color: @input-color-placeholder; - } - - &.btn-primary, - &.btn-secondary, - &.btn-success, - &.btn-danger, - &.btn-info, - &.btn-dark { - &, - &:hover, - &:focus, - &:active { - color: @input-alt-color-placeholder; - } - } - } - } - - > select { - position: absolute !important; - bottom: 0; - left: 50%; - display: block !important; - width: 0.5px !important; - height: 100% !important; - padding: 0 !important; - opacity: 0 !important; - border: none; - z-index: 0 !important; - - &.mobile-device { - top: 0; - left: 0; - display: block !important; - width: 100% !important; - z-index: 2 !important; - } - } - - // Error display - .has-error & .dropdown-toggle, - .error & .dropdown-toggle, - &.is-invalid .dropdown-toggle, - .was-validated & select:invalid + .dropdown-toggle { - border-color: @color-red-error; - } - - &.is-valid .dropdown-toggle, - .was-validated & select:valid + .dropdown-toggle { - border-color: @color-green-success; - } - - &:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { - width: @width-default; - } - - > select.mobile-device:focus + .dropdown-toggle, - .dropdown-toggle:focus { - outline: thin dotted #333333 !important; - outline: 5px auto -webkit-focus-ring-color !important; - outline-offset: -2px; - } -} - -// The selectpicker components -.bootstrap-select { - &.form-control { - margin-bottom: 0; - padding: 0; - border: none; - height: auto; - - :not(.input-group) > &:not([class*="col-"]) { - width: 100%; - } - - &.input-group-btn { - float: none; - z-index: auto; - } - } - - .form-inline &, - .form-inline &.form-control:not([class*="col-"]) { - width: auto; - } - - &:not(.input-group-btn), - &[class*="col-"] { - float: none; - display: inline-block; - margin-left: 0; - } - - // Forces the pull to the right, if necessary - &, - &[class*="col-"], - .row &[class*="col-"] { - &.dropdown-menu-end { - float: right; - } - } - - .form-inline &, - .form-horizontal &, - .form-group & { - margin-bottom: 0; - } - - .form-group-lg &.form-control, - .form-group-sm &.form-control { - padding: 0; - - .dropdown-toggle { - height: 100%; - font-size: inherit; - line-height: inherit; - border-radius: inherit; - } - } - - &.form-control-sm .dropdown-toggle, - &.form-control-lg .dropdown-toggle { - font-size: inherit; - line-height: inherit; - border-radius: inherit; - } - - &.form-control-sm .dropdown-toggle { - padding: @input-padding-y-sm @input-padding-x-sm; - } - - &.form-control-lg .dropdown-toggle { - padding: @input-padding-y-lg @input-padding-x-lg; - } - - // Set the width of the live search (and any other form control within an inline form) - // see https://github.com/silviomoreto/bootstrap-select/issues/685 - .form-inline & .form-control { - width: 100%; - } - - &.disabled, - > .disabled { - .cursor-disabled(); - - &:focus { - outline: none !important; - } - } - - &.bs-container { - position: absolute; - top: 0; - left: 0; - height: 0 !important; - padding: 0 !important; - - .dropdown-menu { - z-index: @zindex-select-dropdown; - } - } - - // The selectpicker button - .dropdown-toggle { - .filter-option { - position: static; - top: 0; - left: 0; - float: left; - height: 100%; - width: 100%; - text-align: left; - overflow: hidden; - flex: 0 1 auto; // for IE10 - } - - .filter-option-inner-inner { - overflow: hidden; - } - - // used to expand the height of the button when inside an input group - .filter-expand { - width: 0 !important; - float: left; - opacity: 0 !important; - overflow: hidden; - } - - .caret { - position: absolute; - top: 50%; - right: 12px; - margin-top: -2px; - vertical-align: middle; - } - - .bs-select-clear-selected { - position: relative; - display: block; - margin-right: 5px; - text-align: center; - - span { - position: relative; - top: calc(((-1em / 1.5) + 1ex) / 2); - pointer-events: none; - } - } - - &.bs-placeholder .bs-select-clear-selected { - display: none; - } - } - - .input-group &.form-control .dropdown-toggle { - border-radius: inherit; - } - - &[class*="col-"] .dropdown-toggle { - width: 100%; - } - - // The selectpicker dropdown - .dropdown-menu { - min-width: 100%; - box-sizing: border-box; - - > .inner:focus { - outline: none !important; - } - - &.inner { - position: static; - float: none; - border: 0; - padding: 0; - margin: 0; - border-radius: 0; - box-shadow: none; - } - - li { - position: relative; - - &.active small { - color: @input-alt-color-placeholder !important; - } - - &.disabled a { - .cursor-disabled(); - } - - a { - cursor: pointer; - user-select: none; - - &.opt { - position: relative; - padding-left: 2.25em; - } - - span.check-mark { - display: none; - } - - span.text { - display: inline-block; - } - } - - small { - padding-left: 0.5em; - } - } - - .notify { - position: absolute; - bottom: 5px; - width: 96%; - margin: 0 2%; - min-height: 26px; - padding: 3px 5px; - background: rgb(245, 245, 245); - border: 1px solid rgb(227, 227, 227); - box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%); - pointer-events: none; - opacity: 0.9; - box-sizing: border-box; - - &.fadeOut { - animation: 300ms linear 750ms forwards bs-notify-fadeOut; - } - } - } - - .no-results { - padding: 3px; - background: #f5f5f5; - margin: 0 5px; - white-space: nowrap; - } - - &.fit-width .dropdown-toggle { - .filter-option { - position: static; - display: inline; - padding: 0; - } - - .filter-option-inner, - .filter-option-inner-inner { - display: inline; - } - - .bs-caret:before { - content: '\00a0'; - } - - .caret { - position: static; - top: auto; - margin-top: -1px; - } - } - - &.show-tick .dropdown-menu { - .selected span.check-mark { - position: absolute; - display: inline-block; - right: 15px; - top: 50%; - margin-top: -0.55rem; - } - - li a span.text { - margin-right: 34px; - } - } - - &.selection-indicator-checkbox.show-tick .dropdown-menu, - &.selection-indicator-radio.show-tick .dropdown-menu { - li a { - padding-left: 2.5rem; - } - - li a span.text { - margin-right: 0; - } - - li a span.check-mark { - position: absolute; - display: inline-flex; - align-items: center; - justify-content: center; - left: 0.75rem; - right: auto; - top: 50%; - width: 1rem; - height: 1rem; - margin-top: -0.5rem; - border: 1px solid var(--bs-border-color, #ced4da); - border-radius: 0.25rem; - background: var(--bs-body-bg, #fff); - color: transparent; - transition: background-color .15s ease-in-out, border-color .15s ease-in-out, color .15s ease-in-out, box-shadow .15s ease-in-out; - } - } - - &.selection-indicator-checkbox.show-tick .dropdown-menu { - li a span.check-mark { - border-radius: 0.25rem; - } - - .selected span.check-mark { - background: var(--bs-primary, #0d6efd); - border-color: var(--bs-primary, #0d6efd); - color: var(--bs-white, #fff); - } - - .selected span.check-mark::after { - content: ''; - width: 0.3rem; - height: 0.55rem; - border: solid currentColor; - border-width: 0 0.14rem 0.14rem 0; - transform: rotate(45deg); - margin-top: -0.05rem; - } - } - - &.selection-indicator-radio.show-tick .dropdown-menu { - li a span.check-mark { - border-radius: 50%; - } - - .selected span.check-mark { - border-color: var(--bs-primary, #0d6efd); - color: var(--bs-primary, #0d6efd); - } - - .selected span.check-mark::after { - content: ''; - width: 0.5rem; - height: 0.5rem; - border-radius: 50%; - background: currentColor; - } - } - - // default check mark for use without an icon font - .bs-ok-default:after { - content: ''; - display: block; - width: 0.5em; - height: 1em; - border-style: solid; - border-width: 0 0.26em 0.26em 0; - transform-style: preserve-3d; - transform: rotate(45deg); - } -} - -.bootstrap-select.show-menu-arrow { - &.open > .dropdown-toggle, - &.show > .dropdown-toggle { - z-index: (@zindex-select-dropdown + 1); - } - - .dropdown-toggle .filter-option { - &:before { - content: ''; - border-left: 7px solid transparent; - border-right: 7px solid transparent; - border-bottom: 7px solid @color-grey-arrow; - position: absolute; - bottom: -4px; - left: 9px; - display: none; - } - - &:after { - content: ''; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid white; - position: absolute; - bottom: -4px; - left: 10px; - display: none; - } - } - - &.dropup .dropdown-toggle .filter-option { - &:before { - bottom: auto; - top: -4px; - border-top: 7px solid @color-grey-arrow; - border-bottom: 0; - } - - &:after { - bottom: auto; - top: -4px; - border-top: 6px solid white; - border-bottom: 0; - } - } - - &.pull-right .dropdown-toggle .filter-option { - &:before { - right: 12px; - left: auto; - } - - &:after { - right: 13px; - left: auto; - } - } - - &.open > .dropdown-toggle .filter-option, - &.show > .dropdown-toggle .filter-option { - &:before, - &:after { - display: block; - } - } -} - -.bs-searchbox, -.bs-actionsbox, -.bs-donebutton { - padding: 4px 8px; -} - -.popover-header { - display: flex; - align-items: center; - gap: 0.75rem; - padding: 0.625rem 0.875rem; - - .popover-header-text { - flex: 1 1 auto; - min-width: 0; - } - - .btn-close, - .close { - flex: 0 0 auto; - margin: 0; - margin-left: auto; - } - - .btn-close { - width: 0.875rem; - height: 0.875rem; - padding: 0.25rem; - background-size: 0.75rem; - } - - .close { - font-size: 0.875rem; - line-height: 1; - } -} - -.bs-actionsbox { - width: 100%; - box-sizing: border-box; - - & .btn-group { - display: block; - - & button { - width: 50%; - } - } -} - -.bs-donebutton { - float: left; - width: 100%; - box-sizing: border-box; - - & .btn-group { - display: block; - - & button { - width: 100%; - } - } -} - -.bs-searchbox { - display: flex; - flex-direction: column; - gap: 0.75rem; - padding: 0.75rem; - border-bottom: 1px solid var(--bs-border-color-translucent, rgba(0, 0, 0, 0.1)); - - & + .bs-actionsbox { - padding: 0 8px 4px; - } - - & .form-control { - margin-bottom: 0; - width: 100%; - float: none; - min-height: calc(1.5em + 0.75rem + 2px); - } - - & .bs-create-option { - display: block; - padding: 0.5rem 0.75rem; - border: 1px dashed rgba(13, 110, 253, 0.45); - border-radius: 0.375rem; - background: rgba(13, 110, 253, 0.06); - color: var(--bs-primary, #0d6efd); - white-space: normal; - text-align: left; - } - - & .bs-create-option:hover, - & .bs-create-option:focus { - background: rgba(13, 110, 253, 0.12); - color: var(--bs-primary-text-emphasis, var(--bs-primary, #0d6efd)); - } -} - -.bs-selected-items { - display: flex; - flex-wrap: wrap; - gap: 0.375rem 0.5rem; - margin-top: 0.5rem; -} - -.bs-selected-items-external { - padding: 0 0.125rem; -} - -.bs-selected-item { - display: inline-flex; - align-items: center; - justify-content: space-between; - gap: 0.375rem; - max-width: 100%; - min-height: calc(1.5em + 0.25rem + 2px); - padding: 0.1875rem 0.25rem 0.1875rem 0.625rem; - border: 1px solid var(--bs-border-color, #ced4da); - border-radius: 0.875rem; - background-color: var(--bs-tertiary-bg, #f8f9fa); - color: var(--bs-body-color, inherit); - font-size: 0.8125rem; - line-height: 1.125rem; - text-align: left; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); - transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - appearance: none; - -webkit-appearance: none; -} - -.bs-selected-item-content { - display: inline-flex; - align-items: center; - gap: 0.5rem; - min-width: 0; -} - -.bs-selected-item-icon { - flex: 0 0 auto; -} - -.bs-selected-item:hover, -.bs-selected-item:focus { - border-color: rgba(13, 110, 253, 0.35); - background-color: var(--bs-secondary-bg, #e9ecef); - box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.12); - outline: 0; -} - -.bs-selected-item-label { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} - -.bs-selected-item-remove { - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.125rem; - height: 1.125rem; - border-radius: 999px; - background: rgba(108, 117, 125, 0.14); - color: var(--bs-secondary-color, #6c757d); - font-size: 0.875rem; - font-weight: 900; - line-height: 1; - flex: 0 0 auto; - padding-bottom: 0; -} - -.bootstrap-select.selected-items-style-list .bs-selected-items { - display: block; - margin-top: 0.5rem; -} - -.bootstrap-select.selected-items-style-list .bs-selected-items-external { - padding: 0; -} - -.bootstrap-select.selected-items-style-list .bs-selected-item { - width: 100%; - min-height: 0; - padding: 0.75rem 1rem; - border: 1px solid var(--bs-list-group-border-color, rgba(0, 0, 0, 0.125)); - border-radius: 0; - background-color: var(--bs-list-group-bg, #fff); - color: var(--bs-list-group-color, inherit); - font-size: 1rem; - line-height: 1.5; - box-shadow: none; -} - -.bootstrap-select.selected-items-style-list .bs-selected-item:first-child { - border-top-left-radius: var(--bs-list-group-border-radius, 0.375rem); - border-top-right-radius: var(--bs-list-group-border-radius, 0.375rem); -} - -.bootstrap-select.selected-items-style-list .bs-selected-item:last-child { - border-bottom-left-radius: var(--bs-list-group-border-radius, 0.375rem); - border-bottom-right-radius: var(--bs-list-group-border-radius, 0.375rem); -} - -.bootstrap-select.selected-items-style-list .bs-selected-item + .bs-selected-item { - margin-top: -1px; -} - -.bootstrap-select.selected-items-style-list .bs-selected-item:hover, -.bootstrap-select.selected-items-style-list .bs-selected-item:focus { - border-color: var(--bs-list-group-border-color, rgba(0, 0, 0, 0.125)); - background-color: var(--bs-list-group-action-hover-bg, #f8f9fa); - color: var(--bs-list-group-action-hover-color, inherit); - box-shadow: none; -} - -.bootstrap-select.selected-items-style-list .bs-selected-item-content { - flex: 1 1 auto; -} - -.bootstrap-select.selected-items-style-list .bs-selected-item-label { - white-space: normal; -} - -.bootstrap-select.selected-items-style-list .bs-selected-item-remove { - width: auto; - height: auto; - margin-left: auto; - border-radius: 0; - background: transparent; - font-size: 1rem; - color: var(--bs-secondary-color, #6c757d); -} - -.form-floating > .bootstrap-select.show-selected-tags { - position: relative; - min-height: calc(3.5rem + 2px); - border: var(--bs-border-width, 1px) solid var(--bs-border-color, #ced4da); - border-radius: var(--bs-border-radius, 0.375rem); - background-color: var(--bs-body-bg, #fff); - transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; - - &:focus-within, - &.show { - border-color: #86b7fe; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); - } - - > .dropdown-toggle { - min-height: 0; - height: auto; - padding-top: 1.375rem; - padding-bottom: 0.25rem; - border: 0; - background-color: transparent; - box-shadow: none; - } - - > .dropdown-toggle:hover, - > .dropdown-toggle:focus, - > .dropdown-toggle:active { - background-color: transparent; - box-shadow: none; - } - - > .dropdown-toggle .filter-option-inner-inner { - opacity: 0; - } - - > .bs-selected-items-external { - position: relative; - z-index: 3; - margin: 0 2.25rem 0 0.75rem; - margin-top: 0; - margin-bottom: 0; - padding-bottom: 1.375rem; - } -} - -.form-floating > .bootstrap-select.show-selected-tags ~ label { - padding-top: 0.75rem; -} diff --git a/less/variables.less b/less/variables.less deleted file mode 100644 index 881ec962..00000000 --- a/less/variables.less +++ /dev/null @@ -1,17 +0,0 @@ -@color-red-error: rgb(185, 74, 72); -@color-green-success: #28a745; -@color-grey-arrow: rgba(204, 204, 204, 0.2); - -@width-default: 100%; - -@zindex-select-dropdown: 1060; // must be higher than a modal background (1050) - -//** Placeholder text color -@input-color-placeholder: #999; -@input-alt-color-placeholder: rgba(255, 255, 255, 0.5); - -@input-padding-y-sm: .25rem; -@input-padding-x-sm: .5rem; - -@input-padding-y-lg: 0.5rem; -@input-padding-x-lg: 1rem; \ No newline at end of file diff --git a/nuget/bootstrap-select.nuspec b/nuget/bootstrap-select.nuspec index 875d54f8..7c0d67c1 100644 --- a/nuget/bootstrap-select.nuspec +++ b/nuget/bootstrap-select.nuspec @@ -6,7 +6,7 @@ bootstrap-select CrestApps, Casey Holzer, Silvio Moreto, SnapAppointments LLC CrestApps - https://github.com/CrestApps/crestapps-bootstrap-select + https://github.com/CrestApps/bootstrap-select A dependency-free, vanilla JavaScript plugin that brings select elements into the 21st century with intuitive multiselection, searching, and much more. Supports Bootstrap 5+. javascript vanilla-js form bootstrap bootstrap-5 dropdown select replacement README.md diff --git a/package-lock.json b/package-lock.json index 00b54f04..0e71a362 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@crestapps/bootstrap-select", - "version": "1.1.2", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@crestapps/bootstrap-select", - "version": "1.1.2", + "version": "1.2.0", "license": "MIT", "devDependencies": { "@docusaurus/core": "^3.10.1", @@ -16,28 +16,21 @@ "@mdx-js/react": "^3.1.1", "@playwright/test": "^1.60.0", "@popperjs/core": "^2.11.8", + "@rollup/plugin-terser": "^0.4.4", "archiver": "^8.0.0", "autoprefixer": "^10.5.0", "bootstrap": "^5.3.8", - "chokidar": "^5.0.0", + "chokidar-cli": "^3.0.0", "clsx": "^2.1.1", + "cssnano": "^7.1.1", + "eslint": "^9.29.0", "globals": "^17.6.0", - "grunt": "^1.6.2", - "grunt-banner": "^0.6.0", - "grunt-contrib-clean": "^2.0.1", - "grunt-contrib-concat": "^2.1.0", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-csslint": "^2.0.0", - "grunt-contrib-cssmin": "^5.0.0", - "grunt-contrib-less": "^3.0.0", - "grunt-contrib-uglify": "^5.2.2", - "grunt-eslint": "^26.0.0", - "grunt-version": "^3.0.2", - "load-grunt-tasks": "^5.1.0", "postcss": "^8.5.15", "prism-react-renderer": "^2.4.1", "react": "^19.2.7", "react-dom": "^19.2.7", + "rollup": "^4.44.1", + "sass": "^1.89.2", "webpack": "^5.107.2" }, "engines": { @@ -2126,6 +2119,13 @@ "node": ">=6.9.0" } }, + "node_modules/@colordx/core": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@colordx/core/-/core-5.4.3.tgz", + "integrity": "sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -3683,6 +3683,27 @@ } } }, + "node_modules/@docusaurus/bundler/node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/@docusaurus/core": { "version": "3.10.1", "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.10.1.tgz", @@ -5933,6 +5954,348 @@ "node": ">= 8" } }, + "node_modules/@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@peculiar/asn1-cms": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.8.0.tgz", @@ -6181,6 +6544,418 @@ "url": "https://opencollective.com/popperjs" } }, + "node_modules/@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "serialize-javascript": "^6.0.1", + "smob": "^1.0.0", + "terser": "^5.17.4" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.0.tgz", + "integrity": "sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.0.tgz", + "integrity": "sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.0.tgz", + "integrity": "sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.0.tgz", + "integrity": "sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.0.tgz", + "integrity": "sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.0.tgz", + "integrity": "sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.0.tgz", + "integrity": "sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.0.tgz", + "integrity": "sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==", + "cpu": [ + "arm" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.0.tgz", + "integrity": "sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.0.tgz", + "integrity": "sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.0.tgz", + "integrity": "sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.0.tgz", + "integrity": "sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==", + "cpu": [ + "loong64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.0.tgz", + "integrity": "sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.0.tgz", + "integrity": "sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.0.tgz", + "integrity": "sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.0.tgz", + "integrity": "sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.0.tgz", + "integrity": "sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz", + "integrity": "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz", + "integrity": "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.0.tgz", + "integrity": "sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.0.tgz", + "integrity": "sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.0.tgz", + "integrity": "sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.0.tgz", + "integrity": "sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz", + "integrity": "sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz", + "integrity": "sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sinclair/typebox": { "version": "0.27.10", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", @@ -6723,12 +7498,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, "node_modules/@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -7098,12 +7867,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -7476,24 +8239,6 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -7501,15 +8246,6 @@ "dev": true, "license": "MIT" }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -7519,15 +8255,6 @@ "node": ">=8" } }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/asn1js": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", @@ -8428,6 +9155,76 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/chokidar-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chokidar-cli/-/chokidar-cli-3.0.0.tgz", + "integrity": "sha512-xVW+Qeh7z15uZRxHOkP93Ux8A0xbPzwK4GaqD8dQOYc34TlkqUhVSS59fK36DOp5WdJlrRzlYSy02Ht99FjZqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^3.5.2", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "yargs": "^13.3.0" + }, + "bin": { + "chokidar": "index.js" + }, + "engines": { + "node": ">= 8.10.0" + } + }, + "node_modules/chokidar-cli/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar-cli/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chokidar-cli/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -8538,13 +9335,116 @@ "node": ">=8" } }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.8" + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/cliui/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" } }, "node_modules/clone-deep": { @@ -8615,15 +9515,6 @@ "dev": true, "license": "MIT" }, - "node_modules/colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combine-promises": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", @@ -8863,22 +9754,6 @@ "dev": true, "license": "MIT" }, - "node_modules/copy-anything": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", - "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-what": "^4.1.8" - }, - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, "node_modules/copy-text-to-clipboard": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.2.tgz", @@ -9310,6 +10185,27 @@ } } }, + "node_modules/css-minimizer-webpack-plugin/node_modules/cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + }, + "engines": { + "node": "^14 || ^16 || >=18.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } + }, "node_modules/css-prefers-color-scheme": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", @@ -9407,41 +10303,25 @@ "node": ">=4" } }, - "node_modules/csslint": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/csslint/-/csslint-1.0.5.tgz", - "integrity": "sha1-Gcw+2jIhYP0/cjKvHLKjYOiYouk=", - "dev": true, - "dependencies": { - "clone": "~2.1.0", - "parserlib": "~1.1.1" - }, - "bin": { - "csslint": "dist/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.9.tgz", + "integrity": "sha512-uPR75+5Dk/WJ/YSPR1/YDHdwMM9c5FsaARljfKWgeCKLKOtJ0we21xy/RcCjn53fZnD/f6yYEIZ8pu18+GnbNQ==", "dev": true, "license": "MIT", "dependencies": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" + "cssnano-preset-default": "^7.0.17", + "lilconfig": "^3.1.3" }, "engines": { - "node": "^14 || ^16 || >=18.0" + "node": "^18.12.0 || ^20.9.0 || >=22.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/cssnano" }, "peerDependencies": { - "postcss": "^8.4.31" + "postcss": "^8.5.13" } }, "node_modules/cssnano-preset-advanced": { @@ -9524,6 +10404,592 @@ "postcss": "^8.4.31" } }, + "node_modules/cssnano/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/cssnano/node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssnano/node_modules/cssnano-preset-default": { + "version": "7.0.17", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.17.tgz", + "integrity": "sha512-11qO63A+czwguQFJCaTdICvbaxn0pJzz/XghLlv+OT7WyToDxAMR0Xb3/26/l0y0hQJywwNbj/SLSQlGBHE1OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.3", + "postcss-calc": "^10.1.1", + "postcss-colormin": "^7.0.10", + "postcss-convert-values": "^7.0.12", + "postcss-discard-comments": "^7.0.8", + "postcss-discard-duplicates": "^7.0.4", + "postcss-discard-empty": "^7.0.3", + "postcss-discard-overridden": "^7.0.3", + "postcss-merge-longhand": "^7.0.7", + "postcss-merge-rules": "^7.0.11", + "postcss-minify-font-values": "^7.0.3", + "postcss-minify-gradients": "^7.0.5", + "postcss-minify-params": "^7.0.9", + "postcss-minify-selectors": "^7.1.2", + "postcss-normalize-charset": "^7.0.3", + "postcss-normalize-display-values": "^7.0.3", + "postcss-normalize-positions": "^7.0.4", + "postcss-normalize-repeat-style": "^7.0.4", + "postcss-normalize-string": "^7.0.3", + "postcss-normalize-timing-functions": "^7.0.3", + "postcss-normalize-unicode": "^7.0.9", + "postcss-normalize-url": "^7.0.3", + "postcss-normalize-whitespace": "^7.0.3", + "postcss-ordered-values": "^7.0.4", + "postcss-reduce-initial": "^7.0.9", + "postcss-reduce-transforms": "^7.0.3", + "postcss-svgo": "^7.1.3", + "postcss-unique-selectors": "^7.0.7" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/cssnano-utils": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.3.tgz", + "integrity": "sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/cssnano/node_modules/postcss-calc": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz", + "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12 || ^20.9 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.4.38" + } + }, + "node_modules/cssnano/node_modules/postcss-colormin": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.10.tgz", + "integrity": "sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colordx/core": "^5.4.3", + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-convert-values": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.12.tgz", + "integrity": "sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-discard-comments": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.8.tgz", + "integrity": "sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-discard-duplicates": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.4.tgz", + "integrity": "sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-discard-empty": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.3.tgz", + "integrity": "sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-discard-overridden": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.3.tgz", + "integrity": "sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-merge-longhand": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.7.tgz", + "integrity": "sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.11" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-merge-rules": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.11.tgz", + "integrity": "sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.3", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-minify-font-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.3.tgz", + "integrity": "sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-minify-gradients": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.5.tgz", + "integrity": "sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colordx/core": "^5.4.3", + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-minify-params": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.9.tgz", + "integrity": "sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-minify-selectors": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.1.2.tgz", + "integrity": "sha512-aQtrEWKwqafNlExcKHQvPGsXR2+vlUqqJtf5XsCQcgsSb5PL4wlujWBYDJuWsP4UnQX1YHDHU8qRlD+1PzTQ+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.1", + "caniuse-api": "^3.0.0", + "cssesc": "^3.0.0", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-charset": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.3.tgz", + "integrity": "sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-display-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.3.tgz", + "integrity": "sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-positions": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.4.tgz", + "integrity": "sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-repeat-style": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.4.tgz", + "integrity": "sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-string": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.3.tgz", + "integrity": "sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-timing-functions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.3.tgz", + "integrity": "sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-unicode": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.9.tgz", + "integrity": "sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-url": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.3.tgz", + "integrity": "sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-normalize-whitespace": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.3.tgz", + "integrity": "sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-ordered-values": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.4.tgz", + "integrity": "sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-reduce-initial": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.9.tgz", + "integrity": "sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-reduce-transforms": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.3.tgz", + "integrity": "sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano/node_modules/postcss-svgo": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.3.tgz", + "integrity": "sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^4.0.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >= 18" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/postcss-unique-selectors": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.7.tgz", + "integrity": "sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/stylehacks": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.11.tgz", + "integrity": "sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.2", + "postcss-selector-parser": "^7.1.1" + }, + "engines": { + "node": "^18.12.0 || ^20.9.0 || >=22.0" + }, + "peerDependencies": { + "postcss": "^8.5.13" + } + }, + "node_modules/cssnano/node_modules/svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, "node_modules/csso": { "version": "5.0.5", "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", @@ -9567,16 +11033,6 @@ "dev": true, "license": "MIT" }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", @@ -9602,6 +11058,16 @@ } } }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/decode-named-character-reference": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", @@ -9789,13 +11255,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "dev": true, + "license": "Apache-2.0", + "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/detect-node": { @@ -10098,20 +11566,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "prr": "~1.0.1" - }, - "bin": { - "errno": "cli.js" - } - }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", @@ -10226,15 +11680,6 @@ "dev": true, "license": "MIT" }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/eslint": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", @@ -10721,27 +12166,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/express": { "version": "4.22.2", "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", @@ -10980,22 +12404,6 @@ "node": ">=0.4.0" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -11049,12 +12457,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/file-sync-cmp": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", - "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=", - "dev": true - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -11133,47 +12535,6 @@ "node": ">=6" } }, - "node_modules/findup-sync": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", - "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.3", - "micromatch": "^4.0.4", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -11226,27 +12587,6 @@ } } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -11315,12 +12655,6 @@ "node": ">=14.14" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, "node_modules/fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -11356,6 +12690,16 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -11415,15 +12759,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/getobject": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", - "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", @@ -11431,26 +12766,6 @@ "dev": true, "license": "ISC" }, - "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -11504,54 +12819,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "dependencies": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/global-prefix/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/globals": { "version": "17.6.0", "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", @@ -11661,478 +12928,6 @@ "node": ">=6.0" } }, - "node_modules/grunt": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.6.2.tgz", - "integrity": "sha512-bUzh5nA/P5L66ihXTDP6J5BGnMB/8lXJXejYWSbH4Y4TvWM9t2S39sggQDYYQlx06cYcCsmu63HMYHGCIzUVfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "dateformat": "~4.6.2", - "eventemitter2": "~0.4.13", - "exit": "~0.1.2", - "findup-sync": "~5.0.0", - "glob": "~7.1.6", - "grunt-cli": "^1.4.3", - "grunt-known-options": "~2.0.0", - "grunt-legacy-log": "~3.0.0", - "grunt-legacy-util": "~2.0.1", - "iconv-lite": "~0.6.3", - "js-yaml": "~3.14.0", - "minimatch": "^3.1.5", - "nopt": "^5.0.0" - }, - "bin": { - "grunt": "bin/grunt" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/grunt-banner": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/grunt-banner/-/grunt-banner-0.6.0.tgz", - "integrity": "sha512-50H/Wxydlf+ifve5Jzcz9oB4jr6oCGEPyfhEDUsl2NEMX80cWUJqVMXSHBr2n9Rb3nd+rRSKeQzqNxWrqoyQ1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "grunt": ">=0.4.0" - } - }, - "node_modules/grunt-banner/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-banner/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-banner/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-banner/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-banner/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/grunt-cli": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", - "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", - "dev": true, - "dependencies": { - "grunt-known-options": "~2.0.0", - "interpret": "~1.1.0", - "liftup": "~3.0.1", - "nopt": "~4.0.1", - "v8flags": "~3.2.0" - }, - "bin": { - "grunt": "bin/grunt" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-cli/node_modules/nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, - "dependencies": { - "abbrev": "1", - "osenv": "^0.1.4" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, - "node_modules/grunt-contrib-clean": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-2.0.1.tgz", - "integrity": "sha512-uRvnXfhiZt8akb/ZRDHJpQQtkkVkqc/opWO4Po/9ehC2hPxgptB9S6JHDC/Nxswo4CJSM0iFPT/Iym3cEMWzKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^3.2.3", - "rimraf": "^2.6.2" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "grunt": ">=0.4.5" - } - }, - "node_modules/grunt-contrib-clean/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/grunt-contrib-concat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-2.1.0.tgz", - "integrity": "sha512-Vnl95JIOxfhEN7bnYIlCgQz41kkbi7tsZ/9a4usZmxNxi1S2YAIOy8ysFmO8u4MN26Apal1O106BwARdaNxXQw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "source-map": "^0.5.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "grunt": ">=1.4.1" - } - }, - "node_modules/grunt-contrib-copy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz", - "integrity": "sha512-gFRFUB0ZbLcjKb67Magz1yOHGBkyU6uL29hiEW1tdQ9gQt72NuMKIy/kS6dsCbV0cZ0maNCb0s6y+uT1FKU7jA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.1.1", - "file-sync-cmp": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-copy/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-copy/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-copy/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-copy/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-copy/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/grunt-contrib-csslint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-csslint/-/grunt-contrib-csslint-2.0.0.tgz", - "integrity": "sha512-op9Adig+K90UyWGE4rQ6AWR5HOnOdtLDVizTueitvtSoIBcGm5OpQmKI9RcLfAn6x8IM4aKMkU15ITtXD6Aemg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.0.0", - "csslint": "^1.0.0", - "lodash": "^4.8.2", - "strip-json-comments": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-csslint/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-csslint/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-csslint/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-csslint/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-contrib-csslint/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/grunt-contrib-cssmin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-5.0.0.tgz", - "integrity": "sha512-SNp4H4+85mm2xaHYi83FBHuOXylpi5vcwgtNoYCZBbkgeXQXoeTAKa59VODRb0woTDBvxouP91Ff5PzCkikg6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "clean-css": "^5.3.2", - "maxmin": "^3.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/grunt-contrib-less": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-3.0.0.tgz", - "integrity": "sha512-fBB8MUDCo5EgT7WdOVQnZq4GF+XCeFdnkhaxI7uepp8P973sH1jdodjF87c6d9WSHKgArJAGP5JEtthhdKVovg==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^3.2.0", - "chalk": "^4.1.0", - "less": "^4.1.1", - "lodash": "^4.17.21" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-contrib-uglify": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-5.2.2.tgz", - "integrity": "sha512-ITxiWxrjjP+RZu/aJ5GLvdele+sxlznh+6fK9Qckio5ma8f7Iv8woZjRkGfafvpuygxNefOJNc+hfjjBayRn2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "maxmin": "^3.0.0", - "uglify-js": "^3.16.1", - "uri-path": "^1.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/grunt-eslint": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-26.0.0.tgz", - "integrity": "sha512-HP/Mu00nBtdLDk0i1V1gLplYBgce4nBjxwmtpo3Eit/h5OUzGxEsgBxprkT4I5bN1x79w6wDnrN+7CX29OZatg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "eslint": "^9.22.0" - }, - "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - }, - "peerDependencies": { - "grunt": ">=1" - } - }, - "node_modules/grunt-known-options": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", - "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/grunt-legacy-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", - "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", - "dev": true, - "dependencies": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.19" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/grunt-legacy-log-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", - "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", - "dev": true, - "dependencies": { - "chalk": "~4.1.0", - "lodash": "~4.17.19" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-legacy-util": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", - "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", - "dev": true, - "dependencies": { - "async": "~3.2.0", - "exit": "~0.1.2", - "getobject": "~1.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.21", - "underscore.string": "~3.3.5", - "which": "~2.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt-version": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/grunt-version/-/grunt-version-3.0.2.tgz", - "integrity": "sha512-tD/RCuwRaHnKa7Mdh9Hh0lA+Ia1ossIw0R5kVQ2g64KHKB8zT7huBsdkoJ5WHgkUHC7DPGbR6v2K/N0CGVsHZg==", - "dev": true, - "dependencies": { - "grunt": "^1.6.1", - "semver": "^7.6.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/grunt/node_modules/eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, - "node_modules/gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", @@ -12140,27 +12935,6 @@ "dev": true, "license": "MIT" }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -12427,27 +13201,6 @@ "react-is": "^16.7.0" } }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -12828,20 +13581,6 @@ "node": ">= 4" } }, - "node_modules/image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", - "dev": true, - "license": "MIT", - "optional": true, - "bin": { - "image-size": "bin/image-size.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", @@ -12849,6 +13588,13 @@ "dev": true, "license": "MIT" }, + "node_modules/immutable": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.6.tgz", + "integrity": "sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -12906,16 +13652,6 @@ "node": ">=12" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -12939,12 +13675,6 @@ "dev": true, "license": "MIT" }, - "node_modules/interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, "node_modules/invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -12965,19 +13695,6 @@ "node": ">= 10" } }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", @@ -13275,18 +13992,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", @@ -13307,40 +14012,6 @@ "dev": true, "license": "MIT" }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-what": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", - "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -13649,43 +14320,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/less": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/less/-/less-4.6.4.tgz", - "integrity": "sha512-OJmO5+HxZLLw0RLzkqaNHzcgEAQG7C0y3aMbwtCzIUFZsLMNNq/1IdAdHEycQ58CwUO3jPTHmoN+tE5I7FQxNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "copy-anything": "^3.0.5", - "parse-node-version": "^1.0.1" - }, - "bin": { - "lessc": "bin/lessc" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "source-map": "~0.6.0" - } - }, - "node_modules/less/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -13710,40 +14344,6 @@ "node": ">= 0.8.0" } }, - "node_modules/liftup": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", - "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", - "dev": true, - "dependencies": { - "extend": "^3.0.2", - "findup-sync": "^4.0.0", - "fined": "^1.2.0", - "flagged-respawn": "^1.0.1", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.1", - "rechoir": "^0.7.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/liftup/node_modules/findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "dev": true, - "dependencies": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -13764,25 +14364,6 @@ "dev": true, "license": "MIT" }, - "node_modules/load-grunt-tasks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-5.1.0.tgz", - "integrity": "sha512-oNj0Jlka1TsfDe+9He0kcA1cRln+TMoTsEByW7ij6kyktNLxBKJtslCFEvFrLC2Dj0S19IWJh3fOCIjLby2Xrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^2.0.1", - "multimatch": "^4.0.0", - "pkg-up": "^3.1.0", - "resolve-pkg": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "peerDependencies": { - "grunt": ">=1" - } - }, "node_modules/loader-runner": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", @@ -13853,6 +14434,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -13931,53 +14519,6 @@ "dev": true, "license": "MPL-1.1" }, - "node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "optional": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/mark.js": { "version": "8.11.1", "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", @@ -14019,25 +14560,6 @@ "node": ">= 0.4" } }, - "node_modules/maxmin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-3.0.0.tgz", - "integrity": "sha512-wcahMInmGtg/7c6a75fr21Ch/Ks1Tb+Jtoan5Ft4bAI0ZvJqyOw8kkM7e7p8hDSzY805vmxwHT50KcjGwKyJ0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "figures": "^3.2.0", - "gzip-size": "^5.1.1", - "pretty-bytes": "^5.3.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/mdast-util-directive": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", @@ -16580,22 +17102,6 @@ "multicast-dns": "cli.js" } }, - "node_modules/multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "dev": true, - "dependencies": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/nanoid": { "version": "3.3.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", @@ -16622,24 +17128,6 @@ "dev": true, "license": "MIT" }, - "node_modules/needle": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.5.0.tgz", - "integrity": "sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - }, - "bin": { - "needle": "bin/needle" - }, - "engines": { - "node": ">= 4.4.x" - } - }, "node_modules/negotiator": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", @@ -16668,6 +17156,14 @@ "tslib": "^2.0.3" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, "node_modules/node-emoji": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", @@ -16694,22 +17190,6 @@ "node": ">=18" } }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -16860,46 +17340,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -16930,15 +17370,6 @@ "node": ">= 0.8" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, "node_modules/onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -17001,34 +17432,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "node_modules/p-cancelable": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", @@ -17219,20 +17622,6 @@ "dev": true, "license": "MIT" }, - "node_modules/parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -17252,16 +17641,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/parse-numeric-range": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", @@ -17269,15 +17648,6 @@ "dev": true, "license": "ISC" }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -17331,12 +17701,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/parserlib": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-1.1.1.tgz", - "integrity": "sha1-pkz6ckBiQ0/fw1HJpOwtkrlMBvQ=", - "dev": true - }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -17367,15 +17731,6 @@ "node": ">=4" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", @@ -17399,27 +17754,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "dependencies": { - "path-root-regex": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-to-regexp": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", @@ -17467,16 +17801,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/pkg-dir": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", @@ -17581,18 +17905,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/pkijs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", @@ -19193,19 +19505,6 @@ "node": ">= 0.8.0" } }, - "node_modules/pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -19336,14 +19635,6 @@ "node": ">= 0.10" } }, - "node_modules/prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true, - "license": "MIT", - "optional": true - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -19752,18 +20043,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/recma-build-jsx": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", @@ -20214,6 +20493,16 @@ "entities": "^2.0.0" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -20233,6 +20522,13 @@ "node": "*" } }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -20269,19 +20565,6 @@ "dev": true, "license": "MIT" }, - "node_modules/resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "dependencies": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -20299,27 +20582,6 @@ "dev": true, "license": "MIT" }, - "node_modules/resolve-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", - "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-pkg/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/responselike": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", @@ -20357,6 +20619,51 @@ "node": ">=0.10.0" } }, + "node_modules/rollup": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz", + "integrity": "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.9" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.62.0", + "@rollup/rollup-android-arm64": "4.62.0", + "@rollup/rollup-darwin-arm64": "4.62.0", + "@rollup/rollup-darwin-x64": "4.62.0", + "@rollup/rollup-freebsd-arm64": "4.62.0", + "@rollup/rollup-freebsd-x64": "4.62.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.0", + "@rollup/rollup-linux-arm-musleabihf": "4.62.0", + "@rollup/rollup-linux-arm64-gnu": "4.62.0", + "@rollup/rollup-linux-arm64-musl": "4.62.0", + "@rollup/rollup-linux-loong64-gnu": "4.62.0", + "@rollup/rollup-linux-loong64-musl": "4.62.0", + "@rollup/rollup-linux-ppc64-gnu": "4.62.0", + "@rollup/rollup-linux-ppc64-musl": "4.62.0", + "@rollup/rollup-linux-riscv64-gnu": "4.62.0", + "@rollup/rollup-linux-riscv64-musl": "4.62.0", + "@rollup/rollup-linux-s390x-gnu": "4.62.0", + "@rollup/rollup-linux-x64-gnu": "4.62.0", + "@rollup/rollup-linux-x64-musl": "4.62.0", + "@rollup/rollup-openbsd-x64": "4.62.0", + "@rollup/rollup-openharmony-arm64": "4.62.0", + "@rollup/rollup-win32-arm64-msvc": "4.62.0", + "@rollup/rollup-win32-ia32-msvc": "4.62.0", + "@rollup/rollup-win32-x64-gnu": "4.62.0", + "@rollup/rollup-win32-x64-msvc": "4.62.0", + "fsevents": "~2.3.2" + } + }, "node_modules/rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -20454,6 +20761,27 @@ "dev": true, "license": "MIT" }, + "node_modules/sass": { + "version": "1.101.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", + "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^5.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=20.19.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, "node_modules/sax": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", @@ -20808,6 +21136,13 @@ "node": ">= 0.8.0" } }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -21044,6 +21379,16 @@ "node": ">=8" } }, + "node_modules/smob": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz", + "integrity": "sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -21077,15 +21422,6 @@ "node": ">= 6.3.0" } }, - "node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -21829,47 +22165,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/underscore.string": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", - "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", - "dev": true, - "dependencies": { - "sprintf-js": "^1.1.1", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/underscore.string/node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "node_modules/undici": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz", @@ -22203,15 +22498,6 @@ "punycode": "^2.1.0" } }, - "node_modules/uri-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", - "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/url-loader": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", @@ -22329,18 +22615,6 @@ "uuid": "dist/esm/bin/uuid" } }, - "node_modules/v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", @@ -22931,6 +23205,13 @@ "node": ">= 8" } }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, "node_modules/widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -23024,12 +23305,6 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -23123,6 +23398,13 @@ "xml-js": "bin/cli.js" } }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -23130,6 +23412,101 @@ "dev": true, "license": "ISC" }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -24516,6 +24893,12 @@ "@babel/helper-validator-identifier": "^7.29.7" } }, + "@colordx/core": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/@colordx/core/-/core-5.4.3.tgz", + "integrity": "sha512-kIxYSfA5T8HXjav55UaaH/o/cKivF6jCCGIb8eqtcsfI46wsvlSiT8jMDyrl779qLec3c2c2oHBZo4oAhvbjrQ==", + "dev": true + }, "@colors/colors": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", @@ -25161,6 +25544,18 @@ "url-loader": "^4.1.1", "webpack": "^5.95.0", "webpackbar": "^7.0.0" + }, + "dependencies": { + "cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dev": true, + "requires": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + } + } } }, "@docusaurus/core": { @@ -26580,6 +26975,132 @@ "fastq": "^1.6.0" } }, + "@parcel/watcher": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz", + "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==", + "dev": true, + "optional": true, + "requires": { + "@parcel/watcher-android-arm64": "2.5.6", + "@parcel/watcher-darwin-arm64": "2.5.6", + "@parcel/watcher-darwin-x64": "2.5.6", + "@parcel/watcher-freebsd-x64": "2.5.6", + "@parcel/watcher-linux-arm-glibc": "2.5.6", + "@parcel/watcher-linux-arm-musl": "2.5.6", + "@parcel/watcher-linux-arm64-glibc": "2.5.6", + "@parcel/watcher-linux-arm64-musl": "2.5.6", + "@parcel/watcher-linux-x64-glibc": "2.5.6", + "@parcel/watcher-linux-x64-musl": "2.5.6", + "@parcel/watcher-win32-arm64": "2.5.6", + "@parcel/watcher-win32-ia32": "2.5.6", + "@parcel/watcher-win32-x64": "2.5.6", + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "dependencies": { + "picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "optional": true + } + } + }, + "@parcel/watcher-android-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz", + "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==", + "dev": true, + "optional": true + }, + "@parcel/watcher-darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz", + "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz", + "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-freebsd-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz", + "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz", + "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz", + "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-arm64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz", + "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==", + "dev": true, + "optional": true + }, + "@parcel/watcher-linux-x64-musl": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz", + "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz", + "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-ia32": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz", + "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==", + "dev": true, + "optional": true + }, + "@parcel/watcher-win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz", + "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==", + "dev": true, + "optional": true + }, "@peculiar/asn1-cms": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.8.0.tgz", @@ -26789,6 +27310,192 @@ "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", "dev": true }, + "@rollup/plugin-terser": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", + "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", + "dev": true, + "requires": { + "serialize-javascript": "^7.0.5", + "smob": "^1.0.0", + "terser": "^5.17.4" + } + }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.0.tgz", + "integrity": "sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.0.tgz", + "integrity": "sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.0.tgz", + "integrity": "sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.0.tgz", + "integrity": "sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.0.tgz", + "integrity": "sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-freebsd-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.0.tgz", + "integrity": "sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.0.tgz", + "integrity": "sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.0.tgz", + "integrity": "sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.0.tgz", + "integrity": "sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.0.tgz", + "integrity": "sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loong64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.0.tgz", + "integrity": "sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-loong64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.0.tgz", + "integrity": "sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-ppc64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.0.tgz", + "integrity": "sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-ppc64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.0.tgz", + "integrity": "sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.0.tgz", + "integrity": "sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.0.tgz", + "integrity": "sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.0.tgz", + "integrity": "sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.0.tgz", + "integrity": "sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.0.tgz", + "integrity": "sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-openbsd-x64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.0.tgz", + "integrity": "sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-openharmony-arm64": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.0.tgz", + "integrity": "sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.0.tgz", + "integrity": "sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.0.tgz", + "integrity": "sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-gnu": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.0.tgz", + "integrity": "sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.0.tgz", + "integrity": "sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==", + "dev": true, + "optional": true + }, "@sinclair/typebox": { "version": "0.27.10", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", @@ -27156,12 +27863,6 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "dev": true }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, "@types/ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", @@ -27495,12 +28196,6 @@ "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "dev": true }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -27764,42 +28459,18 @@ "sprintf-js": "~1.0.2" } }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true - }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, "asn1js": { "version": "3.0.10", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.10.tgz", @@ -28350,6 +29021,54 @@ "readdirp": "^5.0.0" } }, + "chokidar-cli": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chokidar-cli/-/chokidar-cli-3.0.0.tgz", + "integrity": "sha512-xVW+Qeh7z15uZRxHOkP93Ux8A0xbPzwK4GaqD8dQOYc34TlkqUhVSS59fK36DOp5WdJlrRzlYSy02Ht99FjZqQ==", + "dev": true, + "requires": { + "chokidar": "^3.5.2", + "lodash.debounce": "^4.0.8", + "lodash.throttle": "^4.1.1", + "yargs": "^13.3.0" + }, + "dependencies": { + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + } + } + }, "chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -28420,11 +29139,91 @@ } } }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + } + } }, "clone-deep": { "version": "4.0.1", @@ -28476,12 +29275,6 @@ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, "combine-promises": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", @@ -28659,15 +29452,6 @@ "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "dev": true }, - "copy-anything": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.5.tgz", - "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", - "dev": true, - "requires": { - "is-what": "^4.1.8" - } - }, "copy-text-to-clipboard": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.2.tgz", @@ -28889,6 +29673,18 @@ "postcss": "^8.4.24", "schema-utils": "^4.0.1", "serialize-javascript": "^7.0.5" + }, + "dependencies": { + "cssnano": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", + "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "dev": true, + "requires": { + "cssnano-preset-default": "^6.1.2", + "lilconfig": "^3.1.1" + } + } } }, "css-prefers-color-scheme": { @@ -28939,24 +29735,373 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "csslint": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/csslint/-/csslint-1.0.5.tgz", - "integrity": "sha1-Gcw+2jIhYP0/cjKvHLKjYOiYouk=", - "dev": true, - "requires": { - "clone": "~2.1.0", - "parserlib": "~1.1.1" - } - }, "cssnano": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", + "version": "7.1.9", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-7.1.9.tgz", + "integrity": "sha512-uPR75+5Dk/WJ/YSPR1/YDHdwMM9c5FsaARljfKWgeCKLKOtJ0we21xy/RcCjn53fZnD/f6yYEIZ8pu18+GnbNQ==", "dev": true, "requires": { - "cssnano-preset-default": "^6.1.2", - "lilconfig": "^3.1.1" + "cssnano-preset-default": "^7.0.17", + "lilconfig": "^3.1.3" + }, + "dependencies": { + "commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true + }, + "css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "requires": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + } + }, + "cssnano-preset-default": { + "version": "7.0.17", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-7.0.17.tgz", + "integrity": "sha512-11qO63A+czwguQFJCaTdICvbaxn0pJzz/XghLlv+OT7WyToDxAMR0Xb3/26/l0y0hQJywwNbj/SLSQlGBHE1OA==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "css-declaration-sorter": "^7.2.0", + "cssnano-utils": "^5.0.3", + "postcss-calc": "^10.1.1", + "postcss-colormin": "^7.0.10", + "postcss-convert-values": "^7.0.12", + "postcss-discard-comments": "^7.0.8", + "postcss-discard-duplicates": "^7.0.4", + "postcss-discard-empty": "^7.0.3", + "postcss-discard-overridden": "^7.0.3", + "postcss-merge-longhand": "^7.0.7", + "postcss-merge-rules": "^7.0.11", + "postcss-minify-font-values": "^7.0.3", + "postcss-minify-gradients": "^7.0.5", + "postcss-minify-params": "^7.0.9", + "postcss-minify-selectors": "^7.1.2", + "postcss-normalize-charset": "^7.0.3", + "postcss-normalize-display-values": "^7.0.3", + "postcss-normalize-positions": "^7.0.4", + "postcss-normalize-repeat-style": "^7.0.4", + "postcss-normalize-string": "^7.0.3", + "postcss-normalize-timing-functions": "^7.0.3", + "postcss-normalize-unicode": "^7.0.9", + "postcss-normalize-url": "^7.0.3", + "postcss-normalize-whitespace": "^7.0.3", + "postcss-ordered-values": "^7.0.4", + "postcss-reduce-initial": "^7.0.9", + "postcss-reduce-transforms": "^7.0.3", + "postcss-svgo": "^7.1.3", + "postcss-unique-selectors": "^7.0.7" + } + }, + "cssnano-utils": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-5.0.3.tgz", + "integrity": "sha512-ynIREMICLxkxm7e9bCR9sh75s4Q5drICi0ua1yxo5jH2XPBqSKkl4dOh4EbFqtUmnTMhRffHgYL0EKKkMjtJTg==", + "dev": true, + "requires": {} + }, + "mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true + }, + "postcss-calc": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-10.1.1.tgz", + "integrity": "sha512-NYEsLHh8DgG/PRH2+G9BTuUdtf9ViS+vdoQ0YA5OQdGsfN4ztiwtDWNtBl9EKeqNMFnIu8IKZ0cLxEQ5r5KVMw==", + "dev": true, + "requires": { + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "7.0.10", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-7.0.10.tgz", + "integrity": "sha512-yFr6JezOolHLta/buLE71VKPh2mXursp4saVe98/ol8ZnEWhL+racShqPKlvd/DKWLre/39B6HhcMXf7RZ3hxg==", + "dev": true, + "requires": { + "@colordx/core": "^5.4.3", + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-7.0.12.tgz", + "integrity": "sha512-xurKu5qqk4viR3Cp3p4xBR4KfnZm4w4ys6+UBwBmeuBSNkH7+DtLnYOYnOffgtE4yx8sH9S1VZ6RAAvROXzP2Q==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-discard-comments": { + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.8.tgz", + "integrity": "sha512-CvvS5S9WrXblFXCEJ9nVo+4z+eA7zSC7Z88V1HEJuwlQhlFnYTIjg1xJY+BCUiG2bvICap2tXii4mP22BD108Q==", + "dev": true, + "requires": { + "postcss-selector-parser": "^7.1.1" + } + }, + "postcss-discard-duplicates": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-7.0.4.tgz", + "integrity": "sha512-VBNn1+EuMZkeGVVtz0gRfbNGtx9IFgAsAV+E2pHtXPrp4qfGBkhTIiAuE/wrb+Y6Pakg9NewAlfTpYIFAWODtw==", + "dev": true, + "requires": {} + }, + "postcss-discard-empty": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-7.0.3.tgz", + "integrity": "sha512-M2pyjQCU+/7cMHVtL6bKTHjv0lZnPLMpicgr67Dlth7AbuV9gjVTtUqaRwn6Pp6BwSDspUzhz8SaUrRykJU5Dw==", + "dev": true, + "requires": {} + }, + "postcss-discard-overridden": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-7.0.3.tgz", + "integrity": "sha512-aNovXo9UsZuRNLzHJtp13lHIvinDPfiXBPePpXkSjCbgp++iU2FqE+YxvjIsg6EdyPZsASFbfu+JcBFVsErXIQ==", + "dev": true, + "requires": {} + }, + "postcss-merge-longhand": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-7.0.7.tgz", + "integrity": "sha512-b3mfYUxR388u5Pt0HPcVIUtUDn/k15UfTY9M+ORW+meCR6JLNxoZffiYvXyOYQoRYQNZyX/UFkMCM/mNHxe1qA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^7.0.11" + } + }, + "postcss-merge-rules": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-7.0.11.tgz", + "integrity": "sha512-SJUPM18g2BmPhf8BVlbwqWz4aK3pLu6u6xjfwEzra7xL6IBR10sUaiB++EzqcVfadPHrKBSMlNdP+XieykhI+Q==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^5.0.3", + "postcss-selector-parser": "^7.1.1" + } + }, + "postcss-minify-font-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-7.0.3.tgz", + "integrity": "sha512-yilG/VOaNI74IylQvAQQxm3/wZVBkXyYUqNUAdxqwtbWUXPsbK1q8Ms0mL83v+f8YicgcyfYCRZtWACUdYajpA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-7.0.5.tgz", + "integrity": "sha512-YraROyQRg3BI1+Hg8E05B/JPdnTm8EDSVu4P2BxdM+CRiOyfmou809+chGIqo6fQqwjPGQ947nbGncSjmTU1WQ==", + "dev": true, + "requires": { + "@colordx/core": "^5.4.3", + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-7.0.9.tgz", + "integrity": "sha512-R8itbB8BhlpoYyBm1ou0dD+vJnQ3F6adQipR4UnkCHUwlo+S9WXJaDRg1RHjC8YVAtIdrQzSWvJl40HnGDTKjA==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-7.1.2.tgz", + "integrity": "sha512-aQtrEWKwqafNlExcKHQvPGsXR2+vlUqqJtf5XsCQcgsSb5PL4wlujWBYDJuWsP4UnQX1YHDHU8qRlD+1PzTQ+Q==", + "dev": true, + "requires": { + "browserslist": "^4.28.1", + "caniuse-api": "^3.0.0", + "cssesc": "^3.0.0", + "postcss-selector-parser": "^7.1.1" + } + }, + "postcss-normalize-charset": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-7.0.3.tgz", + "integrity": "sha512-NoBfZu8PR4c2NlmjvrqQTzCzLY79hwcSRgNQ3ZiNK0ABzf9kYKloE/jNj+/8GQY1wsm8pRRgANk6ydLH8cwo0Q==", + "dev": true, + "requires": {} + }, + "postcss-normalize-display-values": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-7.0.3.tgz", + "integrity": "sha512-ldsCX0QIt05pKIOobZtVQ48wXJecr+czw4+e1/YjVhLMqslShgpVxgPtI2CefURR8oyVoYaU/l829MMwExDMLw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-7.0.4.tgz", + "integrity": "sha512-VEvlpeGd3Ju1Hqa/oN4jaP3+ms4laYwkEL9N9u+B6k54PZjXbW1n6wI+aVprf1BQXlCYpS5+1pl/7/vHiKgARg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-7.0.4.tgz", + "integrity": "sha512-6mPKlY/8cSaDHxX502wERADarJsccwlky6yIrOapHH2ZgfoKAV94SbiTKfKEs4EEpdazuc3J72WsqeYk7hp9+Q==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-7.0.3.tgz", + "integrity": "sha512-HnEQPUchi1eznmDKEYrKUTqrprEq97SrpUYClgUkv7V2zRODD9DFoUsYU+m9ZOetmD5ku7fEMZB/lwy8IT6xVQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-7.0.3.tgz", + "integrity": "sha512-zmEzHdvpZBZu0OKlbJSfgASQvaayyAoVuWtvyr34IJ/LyS+DaOKvvR3EvFJ9RWWtNIx+CMvO125OVophaxNYew==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-7.0.9.tgz", + "integrity": "sha512-DRAdWfeh/TjmhLJsw91vdiWCnUod9iwvM7xyS02/nF/sLsCR3A8l3pztrSUrWG8DSBqfX7yEk9FM0USaVJ2mSg==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-7.0.3.tgz", + "integrity": "sha512-CL93wmloq5qsffmFv+bw24MIRbmhHrp53qoh1LDAb/5TtjWEXI/np4xcP/Gw9oWCb2XyWnqHYLDUwiKRoJBA1Q==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-7.0.3.tgz", + "integrity": "sha512-FdHjjn+Ht5Z2ZRjNOmeCbNq6lq09sUYKpmlF/Aq0XjVNSLTL6fmHlA/3swN2wP2caY9GV/tjSDcIIyS7aN7W0A==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-ordered-values": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-7.0.4.tgz", + "integrity": "sha512-nubSi49hDHQk4E8KIj+IbLY8Bg+8OcSUEhgyolgM+atnOvXjV7EjaR6bac4YGZoFyPa9mWoAF3EaYbWdFkKqVg==", + "dev": true, + "requires": { + "cssnano-utils": "^5.0.3", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-initial": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-7.0.9.tgz", + "integrity": "sha512-ztTNPdIxXTxtBcG03E9u8v44M4ElXbMIRT7pf2onlquGula0Y83nKKxqM22FA/hMgkfCjN7ohevkVlaNwI8iOQ==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-7.0.3.tgz", + "integrity": "sha512-FXsnN9ZwcZTT8Yf8cAHA8qIGUXcX6WfLd9JoYhrdDfmvsVhhfqkkv7m4AC3rwFOfz+GzkUa87OCKF9dUcicd+g==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-selector-parser": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.4.tgz", + "integrity": "sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-7.1.3.tgz", + "integrity": "sha512-2QfoFOYMcj8lwcVEf9WeTlkVIAm7u2QvOEhMzkQU3KUhhGX/l8hVV9EtjMv4iq3E9iI3OeeMN0YoMLbGusuigw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^4.0.1" + } + }, + "postcss-unique-selectors": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-7.0.7.tgz", + "integrity": "sha512-d+sCkaRnSefghOUdH8CMJZV9yUQhj2ojpe8Nw/lA+LV1UOfeleGkLTl6XdCFFSai9UJ+DJPb69FFuqthXYsY8w==", + "dev": true, + "requires": { + "postcss-selector-parser": "^7.1.1" + } + }, + "stylehacks": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-7.0.11.tgz", + "integrity": "sha512-iODNfhXVLqc5LADs+Y6Oh5wJuK5ZcHbVng8aiK3y9pjMQdc5hLrBW0eFU6FtnpNrE6PoEg/MmFTU4waotj5WNg==", + "dev": true, + "requires": { + "browserslist": "^4.28.2", + "postcss-selector-parser": "^7.1.1" + } + }, + "svgo": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.1.tgz", + "integrity": "sha512-XDpWUOPC6FEibaLzjfe0ucaV0YrOjYotGJO1WpF0Zd+n6ZGEQUsSugaoLq9QkEZtAfQIxT42UChcssDVPP3+/w==", + "dev": true, + "requires": { + "commander": "^11.1.0", + "css-select": "^5.1.0", + "css-tree": "^3.0.1", + "css-what": "^6.1.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "^1.5.0" + } + } } }, "cssnano-preset-advanced": { @@ -29052,12 +30197,6 @@ "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", "dev": true }, - "dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "dev": true - }, "debounce": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", @@ -29073,6 +30212,12 @@ "ms": "^2.1.3" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true + }, "decode-named-character-reference": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", @@ -29185,11 +30330,12 @@ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true + "detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "optional": true }, "detect-node": { "version": "2.1.0", @@ -29398,16 +30544,6 @@ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true }, - "errno": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", - "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, - "optional": true, - "requires": { - "prr": "~1.0.1" - } - }, "error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", @@ -29486,12 +30622,6 @@ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, "eslint": { "version": "9.39.4", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", @@ -29806,21 +30936,6 @@ } } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "express": { "version": "4.22.2", "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", @@ -30003,15 +31118,6 @@ "xml-js": "^1.6.11" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -30044,12 +31150,6 @@ } } }, - "file-sync-cmp": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/file-sync-cmp/-/file-sync-cmp-0.1.1.tgz", - "integrity": "sha1-peeo/7+kk7Q7kju9TKiaU7Y7YSs=", - "dev": true - }, "fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -30110,37 +31210,6 @@ "locate-path": "^3.0.0" } }, - "findup-sync": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", - "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.3", - "micromatch": "^4.0.4", - "resolve-dir": "^1.0.1" - } - }, - "fined": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", - "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "is-plain-object": "^2.0.3", - "object.defaults": "^1.1.0", - "object.pick": "^1.2.0", - "parse-filepath": "^1.0.1" - } - }, - "flagged-respawn": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", - "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", - "dev": true - }, "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -30169,21 +31238,6 @@ "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", "dev": true }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "form-data-encoder": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", @@ -30225,12 +31279,6 @@ "universalify": "^2.0.0" } }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, "fsevents": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", @@ -30250,6 +31298,12 @@ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -30290,32 +31344,12 @@ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "getobject": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", - "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", - "dev": true - }, "github-slugger": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", "dev": true }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -30347,47 +31381,6 @@ "ini": "2.0.0" } }, - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - }, - "dependencies": { - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "globals": { "version": "17.6.0", "resolved": "https://registry.npmjs.org/globals/-/globals-17.6.0.tgz", @@ -30459,379 +31452,12 @@ "strip-bom-string": "^1.0.0" } }, - "grunt": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.6.2.tgz", - "integrity": "sha512-bUzh5nA/P5L66ihXTDP6J5BGnMB/8lXJXejYWSbH4Y4TvWM9t2S39sggQDYYQlx06cYcCsmu63HMYHGCIzUVfg==", - "dev": true, - "requires": { - "dateformat": "~4.6.2", - "eventemitter2": "~0.4.13", - "exit": "~0.1.2", - "findup-sync": "~5.0.0", - "glob": "~7.1.6", - "grunt-cli": "^1.4.3", - "grunt-known-options": "~2.0.0", - "grunt-legacy-log": "~3.0.0", - "grunt-legacy-util": "~2.0.1", - "iconv-lite": "~0.6.3", - "js-yaml": "~3.14.0", - "minimatch": "^3.1.5", - "nopt": "^5.0.0" - }, - "dependencies": { - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - } - } - }, - "grunt-banner": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/grunt-banner/-/grunt-banner-0.6.0.tgz", - "integrity": "sha512-50H/Wxydlf+ifve5Jzcz9oB4jr6oCGEPyfhEDUsl2NEMX80cWUJqVMXSHBr2n9Rb3nd+rRSKeQzqNxWrqoyQ1A==", - "dev": true, - "requires": { - "chalk": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "grunt-cli": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", - "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", - "dev": true, - "requires": { - "grunt-known-options": "~2.0.0", - "interpret": "~1.1.0", - "liftup": "~3.0.1", - "nopt": "~4.0.1", - "v8flags": "~3.2.0" - }, - "dependencies": { - "nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - } - } - }, - "grunt-contrib-clean": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-contrib-clean/-/grunt-contrib-clean-2.0.1.tgz", - "integrity": "sha512-uRvnXfhiZt8akb/ZRDHJpQQtkkVkqc/opWO4Po/9ehC2hPxgptB9S6JHDC/Nxswo4CJSM0iFPT/Iym3cEMWzKA==", - "dev": true, - "requires": { - "async": "^3.2.3", - "rimraf": "^2.6.2" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "grunt-contrib-concat": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-concat/-/grunt-contrib-concat-2.1.0.tgz", - "integrity": "sha512-Vnl95JIOxfhEN7bnYIlCgQz41kkbi7tsZ/9a4usZmxNxi1S2YAIOy8ysFmO8u4MN26Apal1O106BwARdaNxXQw==", - "dev": true, - "requires": { - "chalk": "^4.1.2", - "source-map": "^0.5.3" - } - }, - "grunt-contrib-copy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-copy/-/grunt-contrib-copy-1.0.0.tgz", - "integrity": "sha512-gFRFUB0ZbLcjKb67Magz1yOHGBkyU6uL29hiEW1tdQ9gQt72NuMKIy/kS6dsCbV0cZ0maNCb0s6y+uT1FKU7jA==", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "file-sync-cmp": "^0.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "grunt-contrib-csslint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-csslint/-/grunt-contrib-csslint-2.0.0.tgz", - "integrity": "sha512-op9Adig+K90UyWGE4rQ6AWR5HOnOdtLDVizTueitvtSoIBcGm5OpQmKI9RcLfAn6x8IM4aKMkU15ITtXD6Aemg==", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "csslint": "^1.0.0", - "lodash": "^4.18.1", - "strip-json-comments": "^2.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "grunt-contrib-cssmin": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-cssmin/-/grunt-contrib-cssmin-5.0.0.tgz", - "integrity": "sha512-SNp4H4+85mm2xaHYi83FBHuOXylpi5vcwgtNoYCZBbkgeXQXoeTAKa59VODRb0woTDBvxouP91Ff5PzCkikg6g==", - "dev": true, - "requires": { - "chalk": "^4.1.2", - "clean-css": "^5.3.2", - "maxmin": "^3.0.0" - } - }, - "grunt-contrib-less": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/grunt-contrib-less/-/grunt-contrib-less-3.0.0.tgz", - "integrity": "sha512-fBB8MUDCo5EgT7WdOVQnZq4GF+XCeFdnkhaxI7uepp8P973sH1jdodjF87c6d9WSHKgArJAGP5JEtthhdKVovg==", - "dev": true, - "requires": { - "async": "^3.2.0", - "chalk": "^4.1.0", - "less": "^4.1.1", - "lodash": "^4.18.1" - } - }, - "grunt-contrib-uglify": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-5.2.2.tgz", - "integrity": "sha512-ITxiWxrjjP+RZu/aJ5GLvdele+sxlznh+6fK9Qckio5ma8f7Iv8woZjRkGfafvpuygxNefOJNc+hfjjBayRn2Q==", - "dev": true, - "requires": { - "chalk": "^4.1.2", - "maxmin": "^3.0.0", - "uglify-js": "^3.16.1", - "uri-path": "^1.0.0" - } - }, - "grunt-eslint": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-26.0.0.tgz", - "integrity": "sha512-HP/Mu00nBtdLDk0i1V1gLplYBgce4nBjxwmtpo3Eit/h5OUzGxEsgBxprkT4I5bN1x79w6wDnrN+7CX29OZatg==", - "dev": true, - "requires": { - "chalk": "^4.1.2", - "eslint": "^9.22.0" - } - }, - "grunt-known-options": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", - "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", - "dev": true - }, - "grunt-legacy-log": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", - "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", - "dev": true, - "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.1.0", - "hooker": "~0.2.3", - "lodash": "^4.18.1" - } - }, - "grunt-legacy-log-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", - "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", - "dev": true, - "requires": { - "chalk": "~4.1.0", - "lodash": "^4.18.1" - } - }, - "grunt-legacy-util": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", - "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", - "dev": true, - "requires": { - "async": "~3.2.0", - "exit": "~0.1.2", - "getobject": "~1.0.0", - "hooker": "~0.2.3", - "lodash": "^4.18.1", - "underscore.string": "~3.3.5", - "which": "~2.0.2" - } - }, - "grunt-version": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/grunt-version/-/grunt-version-3.0.2.tgz", - "integrity": "sha512-tD/RCuwRaHnKa7Mdh9Hh0lA+Ia1ossIw0R5kVQ2g64KHKB8zT7huBsdkoJ5WHgkUHC7DPGbR6v2K/N0CGVsHZg==", - "dev": true, - "requires": { - "grunt": "^1.6.1", - "semver": "^7.6.3" - } - }, - "gzip-size": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", - "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", - "dev": true, - "requires": { - "duplexer": "^0.1.1", - "pify": "^4.0.1" - } - }, "handle-thing": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "dev": true }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -31027,21 +31653,6 @@ "react-is": "^16.7.0" } }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, "hpack.js": { "version": "2.1.6", "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", @@ -31288,19 +31899,18 @@ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", - "dev": true, - "optional": true - }, "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", "dev": true }, + "immutable": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.6.tgz", + "integrity": "sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==", + "dev": true + }, "import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -31335,16 +31945,6 @@ "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", "dev": true }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -31363,12 +31963,6 @@ "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", "dev": true }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true - }, "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", @@ -31384,16 +31978,6 @@ "integrity": "sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==", "dev": true }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, "is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", @@ -31566,15 +32150,6 @@ "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "dev": true }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, "is-stream": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", @@ -31587,27 +32162,6 @@ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "dev": true }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-what": { - "version": "4.1.16", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.16.tgz", - "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, "is-wsl": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", @@ -31840,32 +32394,6 @@ } } }, - "less": { - "version": "4.6.4", - "resolved": "https://registry.npmjs.org/less/-/less-4.6.4.tgz", - "integrity": "sha512-OJmO5+HxZLLw0RLzkqaNHzcgEAQG7C0y3aMbwtCzIUFZsLMNNq/1IdAdHEycQ58CwUO3jPTHmoN+tE5I7FQxNg==", - "dev": true, - "requires": { - "copy-anything": "^3.0.5", - "errno": "^0.1.1", - "graceful-fs": "^4.1.2", - "image-size": "~0.5.0", - "make-dir": "^2.1.0", - "mime": "^1.4.1", - "needle": "^3.1.0", - "parse-node-version": "^1.0.1", - "source-map": "~0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -31882,36 +32410,6 @@ "type-check": "~0.4.0" } }, - "liftup": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", - "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", - "dev": true, - "requires": { - "extend": "^3.0.2", - "findup-sync": "^4.0.0", - "fined": "^1.2.0", - "flagged-respawn": "^1.0.1", - "is-plain-object": "^2.0.4", - "object.map": "^1.0.1", - "rechoir": "^0.7.0", - "resolve": "^1.19.0" - }, - "dependencies": { - "findup-sync": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", - "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^4.0.2", - "resolve-dir": "^1.0.1" - } - } - } - }, "lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -31924,18 +32422,6 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, - "load-grunt-tasks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/load-grunt-tasks/-/load-grunt-tasks-5.1.0.tgz", - "integrity": "sha512-oNj0Jlka1TsfDe+9He0kcA1cRln+TMoTsEByW7ij6kyktNLxBKJtslCFEvFrLC2Dj0S19IWJh3fOCIjLby2Xrg==", - "dev": true, - "requires": { - "arrify": "^2.0.1", - "multimatch": "^4.0.0", - "pkg-up": "^3.1.0", - "resolve-pkg": "^2.0.0" - } - }, "loader-runner": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz", @@ -31987,6 +32473,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==", + "dev": true + }, "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -32044,41 +32536,6 @@ "integrity": "sha512-3LVgE7ekWXt04NBci/hjm+NXJxXZeRXuyClL0kA0HONyBOjxhP3ZQkuWIM4Ok3pbeptUW/rj3XcJcJuJVPwPYA==", "dev": true }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "optional": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "optional": true - } - } - }, - "make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, "mark.js": { "version": "8.11.1", "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", @@ -32103,18 +32560,6 @@ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true }, - "maxmin": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-3.0.0.tgz", - "integrity": "sha512-wcahMInmGtg/7c6a75fr21Ch/Ks1Tb+Jtoan5Ft4bAI0ZvJqyOw8kkM7e7p8hDSzY805vmxwHT50KcjGwKyJ0g==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "figures": "^3.2.0", - "gzip-size": "^5.1.1", - "pretty-bytes": "^5.3.0" - } - }, "mdast-util-directive": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", @@ -33541,19 +33986,6 @@ "thunky": "^1.0.2" } }, - "multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, "nanoid": { "version": "3.3.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", @@ -33566,17 +33998,6 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, - "needle": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-3.5.0.tgz", - "integrity": "sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==", - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.3", - "sax": "^1.2.4" - } - }, "negotiator": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", @@ -33599,6 +34020,13 @@ "tslib": "^2.0.3" } }, + "node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "optional": true + }, "node-emoji": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", @@ -33617,15 +34045,6 @@ "integrity": "sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==", "dev": true }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -33717,37 +34136,6 @@ "object-keys": "^1.1.1" } }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "object.map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", - "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", @@ -33769,15 +34157,6 @@ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "dev": true }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, "onetime": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", @@ -33818,28 +34197,6 @@ "word-wrap": "^1.2.5" } }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-cancelable": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", @@ -33969,17 +34326,6 @@ } } }, - "parse-filepath": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", - "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "map-cache": "^0.2.0", - "path-root": "^0.1.1" - } - }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -33992,24 +34338,12 @@ "lines-and-columns": "^1.1.6" } }, - "parse-node-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true - }, "parse-numeric-range": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", "dev": true }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, "parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -34046,12 +34380,6 @@ "parse5": "^7.0.0" } }, - "parserlib": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/parserlib/-/parserlib-1.1.1.tgz", - "integrity": "sha1-pkz6ckBiQ0/fw1HJpOwtkrlMBvQ=", - "dev": true - }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -34074,12 +34402,6 @@ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", @@ -34098,21 +34420,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "^0.1.0" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, "path-to-regexp": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", @@ -34148,12 +34455,6 @@ "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "dev": true }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, "pkg-dir": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", @@ -34214,15 +34515,6 @@ } } }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, "pkijs": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.4.0.tgz", @@ -35080,12 +35372,6 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "pretty-bytes": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", - "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", - "dev": true - }, "pretty-error": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", @@ -35181,13 +35467,6 @@ } } }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", - "dev": true, - "optional": true - }, "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -35454,15 +35733,6 @@ "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", "dev": true }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, "recma-build-jsx": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", @@ -35781,6 +36051,12 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, "require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -35793,6 +36069,12 @@ "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "dev": true }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -35817,16 +36099,6 @@ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - } - }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -35839,23 +36111,6 @@ "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", "dev": true }, - "resolve-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg/-/resolve-pkg-2.0.0.tgz", - "integrity": "sha512-+1lzwXehGCXSeryaISr6WujZzowloigEofRB+dj75y9RRa/obVcYgbHJd53tdYw8pvZj8GojXaaENws8Ktw/hQ==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, "responselike": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", @@ -35877,6 +36132,41 @@ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true }, + "rollup": { + "version": "4.62.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.0.tgz", + "integrity": "sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.62.0", + "@rollup/rollup-android-arm64": "4.62.0", + "@rollup/rollup-darwin-arm64": "4.62.0", + "@rollup/rollup-darwin-x64": "4.62.0", + "@rollup/rollup-freebsd-arm64": "4.62.0", + "@rollup/rollup-freebsd-x64": "4.62.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.62.0", + "@rollup/rollup-linux-arm-musleabihf": "4.62.0", + "@rollup/rollup-linux-arm64-gnu": "4.62.0", + "@rollup/rollup-linux-arm64-musl": "4.62.0", + "@rollup/rollup-linux-loong64-gnu": "4.62.0", + "@rollup/rollup-linux-loong64-musl": "4.62.0", + "@rollup/rollup-linux-ppc64-gnu": "4.62.0", + "@rollup/rollup-linux-ppc64-musl": "4.62.0", + "@rollup/rollup-linux-riscv64-gnu": "4.62.0", + "@rollup/rollup-linux-riscv64-musl": "4.62.0", + "@rollup/rollup-linux-s390x-gnu": "4.62.0", + "@rollup/rollup-linux-x64-gnu": "4.62.0", + "@rollup/rollup-linux-x64-musl": "4.62.0", + "@rollup/rollup-openbsd-x64": "4.62.0", + "@rollup/rollup-openharmony-arm64": "4.62.0", + "@rollup/rollup-win32-arm64-msvc": "4.62.0", + "@rollup/rollup-win32-ia32-msvc": "4.62.0", + "@rollup/rollup-win32-x64-gnu": "4.62.0", + "@rollup/rollup-win32-x64-msvc": "4.62.0", + "@types/estree": "1.0.9", + "fsevents": "~2.3.2" + } + }, "rtlcss": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", @@ -35924,6 +36214,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sass": { + "version": "1.101.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz", + "integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==", + "dev": true, + "requires": { + "@parcel/watcher": "^2.4.1", + "chokidar": "^5.0.0", + "immutable": "^5.1.5", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, "sax": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", @@ -36190,6 +36492,12 @@ "send": "~0.19.1" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, "set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -36352,6 +36660,12 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smob": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/smob/-/smob-1.6.2.tgz", + "integrity": "sha512-RQsvleCbF8cVHEv+xuDGaA4pOizFqJ0GgjtMSRo6oP8pnN7WsigHgVGey6aILRBKv4W2YOMHLqbKdnB6hpB9fw==", + "dev": true + }, "snake-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", @@ -36379,12 +36693,6 @@ "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", "dev": true }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, "source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -36873,36 +37181,6 @@ "is-typedarray": "^1.0.0" } }, - "uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "underscore.string": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", - "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", - "dev": true, - "requires": { - "sprintf-js": "^1.1.1", - "util-deprecate": "^1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - } - } - }, "undici": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/undici/-/undici-7.27.2.tgz", @@ -37113,12 +37391,6 @@ "punycode": "^2.1.0" } }, - "uri-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", - "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", - "dev": true - }, "url-loader": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", @@ -37188,15 +37460,6 @@ "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "dev": true }, - "v8flags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", - "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, "value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", @@ -37565,6 +37828,12 @@ "isexe": "^2.0.0" } }, + "which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true + }, "widest-line": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", @@ -37620,12 +37889,6 @@ } } }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -37680,12 +37943,94 @@ "sax": "^1.2.4" } }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index fa0779a7..d327639e 100644 --- a/package.json +++ b/package.json @@ -22,14 +22,13 @@ "files": [ "dist", "js", - "less", "sass", "LICENSE", "README.md" ], "description": "A dependency-free, vanilla JavaScript plugin that brings select elements into the 21st century with intuitive multiselection, searching, and much more. Supports Bootstrap 5+. Forked from snapappointments/bootstrap-select with jQuery and Bootstrap 3/4 support removed.", "version": "1.2.0", - "homepage": "https://github.com/CrestApps/crestapps-bootstrap-select", + "homepage": "https://github.com/CrestApps/bootstrap-select", "author": { "name": "CrestApps", "url": "https://github.com/CrestApps" @@ -50,10 +49,10 @@ ], "repository": { "type": "git", - "url": "git+https://github.com/CrestApps/crestapps-bootstrap-select.git" + "url": "git+https://github.com/CrestApps/bootstrap-select.git" }, "bugs": { - "url": "https://github.com/CrestApps/crestapps-bootstrap-select/issues" + "url": "https://github.com/CrestApps/bootstrap-select/issues" }, "license": "MIT", "publishConfig": { @@ -72,38 +71,38 @@ "@popperjs/core": "^2.11.8", "archiver": "^8.0.0", "autoprefixer": "^10.5.0", + "@rollup/plugin-terser": "^0.4.4", "bootstrap": "^5.3.8", - "chokidar": "^5.0.0", + "chokidar-cli": "^3.0.0", "clsx": "^2.1.1", + "cssnano": "^7.1.1", + "eslint": "^9.29.0", "globals": "^17.6.0", - "grunt": "^1.6.2", - "grunt-banner": "^0.6.0", - "grunt-contrib-clean": "^2.0.1", - "grunt-contrib-concat": "^2.1.0", - "grunt-contrib-copy": "^1.0.0", - "grunt-contrib-csslint": "^2.0.0", - "grunt-contrib-cssmin": "^5.0.0", - "grunt-contrib-less": "^3.0.0", - "grunt-contrib-uglify": "^5.2.2", - "grunt-eslint": "^26.0.0", - "grunt-version": "^3.0.2", - "load-grunt-tasks": "^5.1.0", "postcss": "^8.5.15", "prism-react-renderer": "^2.4.1", "react": "^19.2.7", "react-dom": "^19.2.7", + "rollup": "^4.44.1", + "sass": "^1.89.2", "webpack": "^5.107.2" }, "scripts": { - "build": "grunt build", + "clean": "npm run clean:css && npm run clean:js", + "clean:css": "node scripts/clean.js dist/css", + "clean:js": "node scripts/clean.js dist/js", + "build": "npm run lint && npm run build:css && npm run build:js", + "build:css": "npm run clean:css && node scripts/build-css.js", + "build:js": "npm run clean:js && rollup -c", "docs:build": "npm run docs:prepare && docusaurus build docs --out-dir .pages-build", "docs:clear": "docusaurus clear docs", "docs:pages": "node scripts/publish-docs-to-pages.js", - "docs:prepare": "npm run build && grunt copy-docs", + "docs:prepare": "npm run build && node scripts/copy-dist-to-docs.js", "docs:serve": "npm run docs:build && docusaurus serve docs --dir .pages-build", "docs:start": "npm run docs:prepare && docusaurus start docs", - "lint": "grunt lint", - "test": "playwright test" + "dist": "npm run build && node scripts/create-dist-archive.js && node scripts/copy-dist-to-docs.js", + "lint": "eslint js/bootstrap-select.helpers.js js/bootstrap-select.search.js js/bootstrap-select.constants.js js/i18n/*.js rollup.config.js scripts/**/*.js", + "test": "playwright test", + "watch": "npm run build && chokidar \"js/**/*.js\" \"sass/**/*.scss\" -c \"npm run build\"" }, "browserslist": [ "Chrome >= 60", diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..fb1b630f --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,155 @@ +const fs = require('fs'); +const path = require('path'); +const terser = require('@rollup/plugin-terser'); + +const repoRoot = __dirname; +const packagePath = path.join(repoRoot, 'package.json'); +const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')); +const currentYear = new Date().getFullYear(); +const banner = [ + '/*!', + ` * Bootstrap-select v${packageJson.version} (${packageJson.homepage})`, + ' *', + ' * CrestApps fork (vanilla JavaScript, Bootstrap 5+) of snapappointments/bootstrap-select', + ' * Copyright 2012-2018 SnapAppointments, LLC (original work)', + ` * Fork modifications Copyright 2024-${currentYear} CrestApps`, + ' * Licensed under MIT (https://github.com/CrestApps/bootstrap-select/blob/main/LICENSE)', + ' */' +].join('\n'); + +const jsSources = [ + 'js/bootstrap-select.helpers.js', + 'js/bootstrap-select.search.js', + 'js/bootstrap-select.constants.js', + 'js/bootstrap-select.class.js', + 'js/bootstrap-select.virtual-scroll.js', + 'js/bootstrap-select.data.js', + 'js/bootstrap-select.render.js', + 'js/bootstrap-select.sizing.js', + 'js/bootstrap-select.interaction.js', + 'js/bootstrap-select.api.js', + 'js/bootstrap-select.runtime.js' +]; + +function readProjectFile (relativePath) { + return fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); +} + +function createVirtualPlugin (sources) { + return { + name: 'virtual-bootstrap-select', + resolveId (source) { + return Object.prototype.hasOwnProperty.call(sources, source) ? source : null; + }, + load (id) { + return sources[id] || null; + } + }; +} + +function readWrappedSource (introPath, sourceCode, outroPath) { + return [banner, readProjectFile(introPath), sourceCode, readProjectFile(outroPath)].join('\n'); +} + +function createMainSourceCode (introPath, outroPath) { + return readWrappedSource( + introPath, + jsSources.map(readProjectFile).join('\n\n'), + outroPath + ); +} + +function createMainConfig (id, sourceCode, outputs, external) { + return { + input: id, + output: outputs, + external: external || [], + treeshake: false, + plugins: [createVirtualPlugin({ [id]: sourceCode })] + }; +} + +function createTerserOutput (file) { + return { + file, + format: 'es', + sourcemap: true, + plugins: [ + terser({ + format: { + ascii_only: true, + comments: /^!/ + } + }) + ] + }; +} + +const i18nFiles = fs.readdirSync(path.join(repoRoot, 'js', 'i18n')) + .filter(function (filename) { + return filename.endsWith('.js'); + }) + .sort(); + +const configs = [ + createMainConfig( + 'virtual:bootstrap-select-umd', + createMainSourceCode('js/umd-intro.js', 'js/umd-outro.js'), + [ + { + file: 'dist/js/bootstrap-select.js', + format: 'es', + sourcemap: true + }, + createTerserOutput('dist/js/bootstrap-select.min.js') + ] + ), + createMainConfig( + 'virtual:bootstrap-select-esm', + createMainSourceCode('js/esm-intro.js', 'js/esm-outro.js'), + [ + { + file: 'dist/js/bootstrap-select.esm.mjs', + format: 'es', + sourcemap: true + } + ], + ['bootstrap'] + ), + createMainConfig( + 'virtual:bootstrap-select-cjs', + createMainSourceCode('js/cjs-intro.js', 'js/cjs-outro.js'), + [ + { + file: 'dist/js/bootstrap-select.cjs', + format: 'es', + sourcemap: true + } + ] + ) +]; + +i18nFiles.forEach(function (filename) { + const relativeSourcePath = path.join('js', 'i18n', filename); + const id = `virtual:${relativeSourcePath.replace(/\\/g, '/')}`; + const sourceCode = readWrappedSource( + 'js/umd-intro.js', + readProjectFile(relativeSourcePath), + 'js/umd-outro.js' + ); + + configs.push(createMainConfig( + id, + sourceCode, + [ + { + file: path.join('dist', 'js', 'i18n', filename).replace(/\\/g, '/'), + format: 'es', + sourcemap: true + }, + createTerserOutput(path.join('dist', 'js', 'i18n', filename.replace(/\.js$/, '.min.js')).replace(/\\/g, '/')) + ] + )); +}); + +module.exports = configs; diff --git a/sass/bootstrap-select.scss b/sass/bootstrap-select.scss index 64415e65..748f6e57 100644 --- a/sass/bootstrap-select.scss +++ b/sass/bootstrap-select.scss @@ -1,4 +1,15 @@ -@import "variables"; +@use "sass:math"; +@use "variables" as *; + +@function fade($color, $amount) { + @if math.is-unitless($amount) and $amount > 1 { + $amount: math.div($amount, 100); + } @else if math.unit($amount) == "%" { + $amount: math.div($amount, 100%); + } + + @return rgba($color, $amount); +} @keyframes bs-notify-fadeOut { 0% {opacity: 0.9;} @@ -10,24 +21,6 @@ cursor: not-allowed; } -@mixin box-sizing($fmt) { - -webkit-box-sizing: $fmt; - -moz-box-sizing: $fmt; - box-sizing: $fmt; -} - -@mixin box-shadow($fmt) { - -webkit-box-shadow: $fmt; - box-shadow: $fmt; -} - -@function fade($color, $amnt) { - @if $amnt > 1 { - $amnt: $amnt * 0.01; // convert to percentage if int - } - @return rgba($color, $amnt); -} - // Rules select.bs-select-hidden, .bootstrap-select > select.bs-select-hidden, @@ -36,7 +29,7 @@ select.selectpicker { } .bootstrap-select { - width: 220px; + width: 100%; vertical-align: middle; // The selectpicker button @@ -113,10 +106,6 @@ select.selectpicker { border-color: $color-green-success; } - &.fit-width { - width: auto !important; - } - &:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { width: $width-default; } @@ -222,7 +211,7 @@ select.selectpicker { left: 0; height: 0 !important; padding: 0 !important; - + .dropdown-menu { z-index: $zindex-select-dropdown; } @@ -291,7 +280,7 @@ select.selectpicker { // The selectpicker dropdown .dropdown-menu { min-width: 100%; - @include box-sizing(border-box); + box-sizing: border-box; > .inner:focus { outline: none !important; @@ -350,10 +339,10 @@ select.selectpicker { padding: 3px 5px; background: rgb(245, 245, 245); border: 1px solid rgb(227, 227, 227); - @include box-shadow(inset 0 1px 1px fade(rgb(0, 0, 0), 5)); + box-shadow: inset 0 1px 1px fade(rgb(0, 0, 0), 5%); pointer-events: none; opacity: 0.9; - @include box-sizing(border-box); + box-sizing: border-box; &.fadeOut { animation: 300ms linear 750ms forwards bs-notify-fadeOut; @@ -561,9 +550,40 @@ select.selectpicker { padding: 4px 8px; } +.popover-header { + display: flex; + align-items: center; + gap: 0.75rem; + padding: 0.625rem 0.875rem; + + .popover-header-text { + flex: 1 1 auto; + min-width: 0; + } + + .btn-close, + .close { + flex: 0 0 auto; + margin: 0; + margin-left: auto; + } + + .btn-close { + width: 0.875rem; + height: 0.875rem; + padding: 0.25rem; + background-size: 0.75rem; + } + + .close { + font-size: 0.875rem; + line-height: 1; + } +} + .bs-actionsbox { width: 100%; - @include box-sizing(border-box); + box-sizing: border-box; & .btn-group { display: block; @@ -577,7 +597,7 @@ select.selectpicker { .bs-donebutton { float: left; width: 100%; - @include box-sizing(border-box); + box-sizing: border-box; & .btn-group { display: block; @@ -615,195 +635,195 @@ select.selectpicker { color: var(--bs-primary, #0d6efd); white-space: normal; text-align: left; - - &:hover, - &:focus { - background: rgba(13, 110, 253, 0.12); - color: var(--bs-primary-text-emphasis, var(--bs-primary, #0d6efd)); - } } - .bs-selected-items { - display: flex; - flex-wrap: wrap; - gap: 0.375rem 0.5rem; - margin-top: 0.5rem; + & .bs-create-option:hover, + & .bs-create-option:focus { + background: rgba(13, 110, 253, 0.12); + color: var(--bs-primary-text-emphasis, var(--bs-primary, #0d6efd)); } +} - .bs-selected-items-external { - padding: 0 0.125rem; - } +.bs-selected-items { + display: flex; + flex-wrap: wrap; + gap: 0.375rem 0.5rem; + margin-top: 0.5rem; +} - .bs-selected-item { - display: inline-flex; - align-items: center; - justify-content: space-between; - gap: 0.375rem; - max-width: 100%; - min-height: calc(1.5em + 0.25rem + 2px); - padding: 0.1875rem 0.25rem 0.1875rem 0.625rem; - border: 1px solid var(--bs-border-color, #ced4da); - border-radius: 0.875rem; - background-color: var(--bs-tertiary-bg, #f8f9fa); - color: var(--bs-body-color, inherit); - font-size: 0.8125rem; - line-height: 1.125rem; - text-align: left; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); - transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; - appearance: none; - -webkit-appearance: none; +.bs-selected-items-external { + padding: 0 0.125rem; +} - &:hover, - &:focus { - border-color: rgba(13, 110, 253, 0.35); - background-color: var(--bs-secondary-bg, #e9ecef); - box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.12); - outline: 0; - } - } +.bs-selected-item { + display: inline-flex; + align-items: center; + justify-content: space-between; + gap: 0.375rem; + max-width: 100%; + min-height: calc(1.5em + 0.25rem + 2px); + padding: 0.1875rem 0.25rem 0.1875rem 0.625rem; + border: 1px solid var(--bs-border-color, #ced4da); + border-radius: 0.875rem; + background-color: var(--bs-tertiary-bg, #f8f9fa); + color: var(--bs-body-color, inherit); + font-size: 0.8125rem; + line-height: 1.125rem; + text-align: left; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04); + transition: background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out; + appearance: none; + -webkit-appearance: none; +} - .bs-selected-item-content { - display: inline-flex; - align-items: center; - gap: 0.5rem; - min-width: 0; - } +.bs-selected-item-content { + display: inline-flex; + align-items: center; + gap: 0.5rem; + min-width: 0; +} - .bs-selected-item-icon { - flex: 0 0 auto; - } +.bs-selected-item-icon { + flex: 0 0 auto; +} - .bs-selected-item-label { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } +.bs-selected-item:hover, +.bs-selected-item:focus { + border-color: rgba(13, 110, 253, 0.35); + background-color: var(--bs-secondary-bg, #e9ecef); + box-shadow: 0 0 0 0.2rem rgba(13, 110, 253, 0.12); + outline: 0; +} - .bs-selected-item-remove { - display: inline-flex; - align-items: center; - justify-content: center; - width: 1.125rem; - height: 1.125rem; - border-radius: 999px; - background: rgba(108, 117, 125, 0.14); - color: var(--bs-secondary-color, #6c757d); - font-size: 0.875rem; - font-weight: 900; - line-height: 1; - flex: 0 0 auto; - padding-bottom: 0; - } +.bs-selected-item-label { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} - .bootstrap-select.selected-items-style-list .bs-selected-items { - display: block; - margin-top: 0.5rem; - } +.bs-selected-item-remove { + display: inline-flex; + align-items: center; + justify-content: center; + width: 1.125rem; + height: 1.125rem; + border-radius: 999px; + background: rgba(108, 117, 125, 0.14); + color: var(--bs-secondary-color, #6c757d); + font-size: 0.875rem; + font-weight: 900; + line-height: 1; + flex: 0 0 auto; + padding-bottom: 0; +} - .bootstrap-select.selected-items-style-list .bs-selected-items-external { - padding: 0; - } +.bootstrap-select.selected-items-style-list .bs-selected-items { + display: block; + margin-top: 0.5rem; +} - .bootstrap-select.selected-items-style-list .bs-selected-item { - width: 100%; - min-height: 0; - padding: 0.75rem 1rem; - border: 1px solid var(--bs-list-group-border-color, rgba(0, 0, 0, 0.125)); - border-radius: 0; - background-color: var(--bs-list-group-bg, #fff); - color: var(--bs-list-group-color, inherit); - font-size: 1rem; - line-height: 1.5; - box-shadow: none; - } +.bootstrap-select.selected-items-style-list .bs-selected-items-external { + padding: 0; +} - .bootstrap-select.selected-items-style-list .bs-selected-item:first-child { - border-top-left-radius: var(--bs-list-group-border-radius, 0.375rem); - border-top-right-radius: var(--bs-list-group-border-radius, 0.375rem); - } +.bootstrap-select.selected-items-style-list .bs-selected-item { + width: 100%; + min-height: 0; + padding: 0.75rem 1rem; + border: 1px solid var(--bs-list-group-border-color, rgba(0, 0, 0, 0.125)); + border-radius: 0; + background-color: var(--bs-list-group-bg, #fff); + color: var(--bs-list-group-color, inherit); + font-size: 1rem; + line-height: 1.5; + box-shadow: none; +} - .bootstrap-select.selected-items-style-list .bs-selected-item:last-child { - border-bottom-left-radius: var(--bs-list-group-border-radius, 0.375rem); - border-bottom-right-radius: var(--bs-list-group-border-radius, 0.375rem); - } +.bootstrap-select.selected-items-style-list .bs-selected-item:first-child { + border-top-left-radius: var(--bs-list-group-border-radius, 0.375rem); + border-top-right-radius: var(--bs-list-group-border-radius, 0.375rem); +} - .bootstrap-select.selected-items-style-list .bs-selected-item + .bs-selected-item { - margin-top: -1px; - } +.bootstrap-select.selected-items-style-list .bs-selected-item:last-child { + border-bottom-left-radius: var(--bs-list-group-border-radius, 0.375rem); + border-bottom-right-radius: var(--bs-list-group-border-radius, 0.375rem); +} - .bootstrap-select.selected-items-style-list .bs-selected-item:hover, - .bootstrap-select.selected-items-style-list .bs-selected-item:focus { - border-color: var(--bs-list-group-border-color, rgba(0, 0, 0, 0.125)); - background-color: var(--bs-list-group-action-hover-bg, #f8f9fa); - color: var(--bs-list-group-action-hover-color, inherit); - box-shadow: none; - } +.bootstrap-select.selected-items-style-list .bs-selected-item + .bs-selected-item { + margin-top: -1px; +} - .bootstrap-select.selected-items-style-list .bs-selected-item-content { - flex: 1 1 auto; - } +.bootstrap-select.selected-items-style-list .bs-selected-item:hover, +.bootstrap-select.selected-items-style-list .bs-selected-item:focus { + border-color: var(--bs-list-group-border-color, rgba(0, 0, 0, 0.125)); + background-color: var(--bs-list-group-action-hover-bg, #f8f9fa); + color: var(--bs-list-group-action-hover-color, inherit); + box-shadow: none; +} - .bootstrap-select.selected-items-style-list .bs-selected-item-label { - white-space: normal; +.bootstrap-select.selected-items-style-list .bs-selected-item-content { + flex: 1 1 auto; +} + +.bootstrap-select.selected-items-style-list .bs-selected-item-label { + white-space: normal; +} + +.bootstrap-select.selected-items-style-list .bs-selected-item-remove { + width: auto; + height: auto; + margin-left: auto; + border-radius: 0; + background: transparent; + font-size: 1rem; + color: var(--bs-secondary-color, #6c757d); +} + +.form-floating > .bootstrap-select.show-selected-tags { + position: relative; + min-height: calc(3.5rem + 2px); + border: var(--bs-border-width, 1px) solid var(--bs-border-color, #ced4da); + border-radius: var(--bs-border-radius, 0.375rem); + background-color: var(--bs-body-bg, #fff); + transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; + + &:focus-within, + &.show { + border-color: #86b7fe; + box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); } - .bootstrap-select.selected-items-style-list .bs-selected-item-remove { - width: auto; + > .dropdown-toggle { + min-height: 0; height: auto; - margin-left: auto; - border-radius: 0; - background: transparent; - font-size: 1rem; - color: var(--bs-secondary-color, #6c757d); + padding-top: 1.375rem; + padding-bottom: 0.25rem; + border: 0; + background-color: transparent; + box-shadow: none; } - .form-floating > .bootstrap-select.show-selected-tags { - position: relative; - min-height: calc(3.5rem + 2px); - border: var(--bs-border-width, 1px) solid var(--bs-border-color, #ced4da); - border-radius: var(--bs-border-radius, 0.375rem); - background-color: var(--bs-body-bg, #fff); - transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out; - - &:focus-within, - &.show { - border-color: #86b7fe; - box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25); - } - - > .dropdown-toggle { - min-height: 0; - height: auto; - padding-top: 1.375rem; - padding-bottom: 0.25rem; - border: 0; - background-color: transparent; - box-shadow: none; - - &:hover, - &:focus, - &:active { - background-color: transparent; - box-shadow: none; - } - - .filter-option-inner-inner { - opacity: 0; - } - } + > .dropdown-toggle:hover, + > .dropdown-toggle:focus, + > .dropdown-toggle:active { + background-color: transparent; + box-shadow: none; + } - > .bs-selected-items-external { - position: relative; - z-index: 3; - margin: 0 2.25rem 0 0.75rem; - margin-top: 0; - margin-bottom: 0; - padding-bottom: 1.375rem; - } + > .dropdown-toggle .filter-option-inner-inner { + opacity: 0; } - .form-floating > .bootstrap-select.show-selected-tags ~ label { - padding-top: 0.75rem; + > .bs-selected-items-external { + position: relative; + z-index: 3; + margin: 0 2.25rem 0 0.75rem; + margin-top: 0; + margin-bottom: 0; + padding-bottom: 1.375rem; } } + +.form-floating > .bootstrap-select.show-selected-tags ~ label { + padding-top: 0.75rem; +} diff --git a/sass/variables.scss b/sass/variables.scss index 40fb62e5..903df2d4 100644 --- a/sass/variables.scss +++ b/sass/variables.scss @@ -1,8 +1,8 @@ $color-red-error: rgb(185, 74, 72) !default; -$color-green-success: #28a745; +$color-green-success: #28a745 !default; $color-grey-arrow: rgba(204, 204, 204, 0.2) !default; -$width-default: 220px !default; // 3 960px-grid columns +$width-default: 100% !default; $zindex-select-dropdown: 1060 !default; // must be higher than a modal background (1050) @@ -14,4 +14,4 @@ $input-padding-y-sm: .25rem !default; $input-padding-x-sm: .5rem !default; $input-padding-y-lg: 0.5rem !default; -$input-padding-x-lg: 1rem !default; \ No newline at end of file +$input-padding-x-lg: 1rem !default; diff --git a/scripts/build-css.js b/scripts/build-css.js new file mode 100644 index 00000000..559f821d --- /dev/null +++ b/scripts/build-css.js @@ -0,0 +1,87 @@ +const fs = require('fs/promises'); +const path = require('path'); +const sass = require('sass'); +const postcss = require('postcss'); +const autoprefixer = require('autoprefixer'); +const cssnano = require('cssnano'); + +const packageJson = require('../package.json'); + +const repoRoot = path.resolve(__dirname, '..'); +const sourcePath = path.join(repoRoot, 'sass', 'bootstrap-select.scss'); +const distDir = path.join(repoRoot, 'dist', 'css'); +const expandedCssPath = path.join(distDir, 'bootstrap-select.css'); +const minifiedCssPath = path.join(distDir, 'bootstrap-select.min.css'); +const currentYear = new Date().getFullYear(); +const banner = [ + '/*!', + ` * Bootstrap-select v${packageJson.version} (${packageJson.homepage})`, + ' *', + ' * CrestApps fork (vanilla JavaScript, Bootstrap 5+) of snapappointments/bootstrap-select', + ' * Copyright 2012-2018 SnapAppointments, LLC (original work)', + ` * Fork modifications Copyright 2024-${currentYear} CrestApps`, + ' * Licensed under MIT (https://github.com/CrestApps/bootstrap-select/blob/main/LICENSE)', + ' */' +].join('\n'); + +function writeCssWithMap (cssPath, cssContent, mapContent) { + const sourceMapComment = `/*# sourceMappingURL=${path.basename(cssPath)}.map */`; + return Promise.all([ + fs.writeFile(cssPath, `${cssContent}\n${sourceMapComment}\n`), + fs.writeFile(`${cssPath}.map`, mapContent) + ]); +} + +function insertBanner (cssContent) { + const charsetMatch = cssContent.match(/^@charset "UTF-8";\r?\n?/); + + if (!charsetMatch) { + return `${banner}\n${cssContent}`; + } + + return `${charsetMatch[0]}${banner}\n${cssContent.slice(charsetMatch[0].length)}`; +} + +async function main () { + await fs.mkdir(distDir, { recursive: true }); + + const sassResult = sass.compile(sourcePath, { + style: 'expanded', + sourceMap: true, + sourceMapIncludeSources: true + }); + + const expandedResult = await postcss([ + autoprefixer() + ]).process(sassResult.css, { + from: sourcePath, + to: expandedCssPath, + map: { + prev: sassResult.sourceMap, + inline: false, + annotation: false, + sourcesContent: true + } + }); + + await writeCssWithMap( + expandedCssPath, + insertBanner(expandedResult.css), + expandedResult.map.toString() + ); + + const minifiedResult = await postcss([ + cssnano() + ]).process(expandedResult.css, { + from: expandedCssPath, + to: minifiedCssPath, + map: false + }); + + await fs.writeFile(minifiedCssPath, `${insertBanner(minifiedResult.css)}\n`); +} + +main().catch(function (error) { + console.error(error.message); + process.exitCode = 1; +}); diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 00000000..73723193 --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,19 @@ +const fs = require('fs/promises'); +const path = require('path'); + +async function main () { + const targets = process.argv.slice(2); + + if (!targets.length) { + throw new Error('Expected at least one path to clean.'); + } + + await Promise.all(targets.map(function (target) { + return fs.rm(path.resolve(__dirname, '..', target), { recursive: true, force: true }); + })); +} + +main().catch(function (error) { + console.error(error.message); + process.exitCode = 1; +}); diff --git a/scripts/copy-dist-to-docs.js b/scripts/copy-dist-to-docs.js new file mode 100644 index 00000000..bd63d589 --- /dev/null +++ b/scripts/copy-dist-to-docs.js @@ -0,0 +1,17 @@ +const fs = require('fs/promises'); +const path = require('path'); + +const repoRoot = path.resolve(__dirname, '..'); +const sourcePath = path.join(repoRoot, 'dist'); +const targetPath = path.join(repoRoot, 'docs', 'static', 'dist'); + +async function main () { + await fs.rm(targetPath, { recursive: true, force: true }); + await fs.mkdir(path.dirname(targetPath), { recursive: true }); + await fs.cp(sourcePath, targetPath, { recursive: true, force: true }); +} + +main().catch(function (error) { + console.error(error.message); + process.exitCode = 1; +}); diff --git a/scripts/create-dist-archive.js b/scripts/create-dist-archive.js new file mode 100644 index 00000000..16858ede --- /dev/null +++ b/scripts/create-dist-archive.js @@ -0,0 +1,42 @@ +const fs = require('fs'); +const path = require('path'); +const { ZipArchive } = require('archiver'); + +const packageJson = require('../package.json'); + +const repoRoot = path.resolve(__dirname, '..'); +const archiveName = `bootstrap-select-${packageJson.version}.zip`; +const archivePath = path.join(repoRoot, archiveName); +const archiveRoot = `bootstrap-select-${packageJson.version}`; + +async function main () { + await fs.promises.rm(archivePath, { force: true }); + + await new Promise(function (resolve, reject) { + const output = fs.createWriteStream(archivePath); + const archive = new ZipArchive({ + zlib: { + level: 9 + } + }); + + output.on('close', resolve); + output.on('error', reject); + archive.on('error', reject); + archive.pipe(output); + + archive.directory(path.join(repoRoot, 'dist'), `${archiveRoot}/`); + ['bower.json', 'composer.json', 'package.json'].forEach(function (filename) { + archive.file(path.join(repoRoot, filename), { + name: `${archiveRoot}/${filename}` + }); + }); + + archive.finalize().catch(reject); + }); +} + +main().catch(function (error) { + console.error(error.message); + process.exitCode = 1; +});