1"use strict";(self.webpackChunkkunstmaan_edition=self.webpackChunkkunstmaan_edition||[]).push([[2354],{2354:(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__)=>{eval("{\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n A: () => (/* binding */ tom_select_complete)\n});\n\n;// ./node_modules/tom-select/dist/esm/contrib/microevent.js\n/**\n * MicroEvent - to make any js object an event emitter\n *\n * - pure javascript - server compatible, browser compatible\n * - dont rely on the browser doms\n * - super simple - you get it immediatly, no mistery, no magic involved\n *\n * @author Jerome Etienne (https://github.com/jeromeetienne)\n */\n/**\n * Execute callback for each event in space separated list of event names\n *\n */\nfunction forEvents(events, callback) {\n events.split(/\\s+/).forEach((event) => {\n callback(event);\n });\n}\nclass MicroEvent {\n constructor() {\n this._events = {};\n }\n on(events, fct) {\n forEvents(events, (event) => {\n const event_array = this._events[event] || [];\n event_array.push(fct);\n this._events[event] = event_array;\n });\n }\n off(events, fct) {\n var n = arguments.length;\n if (n === 0) {\n this._events = {};\n return;\n }\n forEvents(events, (event) => {\n if (n === 1) {\n delete this._events[event];\n return;\n }\n const event_array = this._events[event];\n if (event_array === undefined)\n return;\n event_array.splice(event_array.indexOf(fct), 1);\n this._events[event] = event_array;\n });\n }\n trigger(events, ...args) {\n var self = this;\n forEvents(events, (event) => {\n const event_array = self._events[event];\n if (event_array === undefined)\n return;\n event_array.forEach(fct => {\n fct.apply(self, args);\n });\n });\n }\n}\n;\n//# sourceMappingURL=microevent.js.map\n;// ./node_modules/tom-select/dist/esm/contrib/microplugin.js\n/**\n * microplugin.js\n * Copyright (c) 2013 Brian Reavis & contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n * @author Brian Reavis <[email protected]>\n */\nfunction MicroPlugin(Interface) {\n Interface.plugins = {};\n return class extends Interface {\n constructor() {\n super(...arguments);\n this.plugins = {\n names: [],\n settings: {},\n requested: {},\n loaded: {}\n };\n }\n /**\n * Registers a plugin.\n *\n * @param {function} fn\n */\n static define(name, fn) {\n Interface.plugins[name] = {\n 'name': name,\n 'fn': fn\n };\n }\n /**\n * Initializes the listed plugins (with options).\n * Acceptable formats:\n *\n * List (without options):\n * ['a', 'b', 'c']\n *\n * List (with options):\n * [{'name': 'a', options: {}}, {'name': 'b', options: {}}]\n *\n * Hash (with options):\n * {'a': { ... }, 'b': { ... }, 'c': { ... }}\n *\n * @param {array|object} plugins\n */\n initializePlugins(plugins) {\n var key, name;\n const self = this;\n const queue = [];\n if (Array.isArray(plugins)) {\n plugins.forEach((plugin) =>
1 {\n if (typeof plugin === 'string') {\n queue.push(plugin);\n }\n else {\n self.plugins.settings[plugin.name] = plugin.options;\n queue.push(plugin.name);\n }\n });\n }\n else if (plugins) {\n for (key in plugins) {\n if (plugins.hasOwnProperty(key)) {\n self.plugins.settings[key] = plugins[key];\n queue.push(key);\n }\n }\n }\n while (name = queue.shift()) {\n self.require(name);\n }\n }\n loadPlugin(name) {\n var self = this;\n var plugins = self.plugins;\n var plugin = Interface.plugins[name];\n if (!Interface.plugins.hasOwnProperty(name)) {\n throw new Error('Unable to find \"' + name + '\" plugin');\n }\n plugins.requested[name] = true;\n plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);\n plugins.names.push(name);\n }\n /**\n * Initializes a plugin.\n *\n */\n require(name) {\n var self = this;\n var plugins = self.plugins;\n if (!self.plugins.loaded.hasOwnProperty(name)) {\n if (plugins.requested[name]) {\n throw new Error('Plugin has circular dependency (\"' + name + '\")');\n }\n self.loadPlugin(name);\n }\n return plugins.loaded[name];\n }\n };\n}\n//# sourceMappingURL=microplugin.js.map\n;// ./node_modules/@orchidjs/unicode-variants/dist/esm/regex.js\n/**\n * Convert array of strings to a regular expression\n *\tex ['ab','a'] => (?:ab|a)\n * \tex ['a','b'] => [ab]\n */\nconst arrayToPattern = (chars) => {\n chars = chars.filter(Boolean);\n if (chars.length < 2) {\n return chars[0] || '';\n }\n return (maxValueLength(chars) == 1) ? '[' + chars.join('') + ']' : '(?:' + chars.join('|') + ')';\n};\nconst sequencePattern = (array) => {\n if (!hasDuplicates(array)) {\n return array.join('');\n }\n let pattern = '';\n let prev_char_count = 0;\n const prev_pattern = () => {\n if (prev_char_count > 1) {\n pattern += '{' + prev_char_count + '}';\n }\n };\n array.forEach((char, i) => {\n if (char === array[i - 1]) {\n prev_char_count++;\n return;\n }\n prev_pattern();\n pattern += char;\n prev_char_count = 1;\n });\n prev_pattern();\n return pattern;\n};\n/**\n * Convert array of strings to a regular expression\n *\tex ['ab','a'] => (?:ab|a)\n * \tex ['a','b'] => [ab]\n */\nconst setToPattern = (chars) => {\n let array = Array.from(chars);\n return arrayToPattern(array);\n};\n/**\n * https://stackoverflow.com/questions/7376598/in-javascript-how-do-i-check-if-an-array-has-duplicate-values\n */\nconst hasDuplicates = (array) => {\n return (new Set(array)).size !== array.length;\n};\n/**\n * https://stackoverflow.com/questions/63006601/why-does-u-throw-an-invalid-escape-error\n */\nconst escape_regex = (str) => {\n return (str + '').replace(/([\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\|\\}\\\\])/gu, '\\\\$1');\n};\n/**\n * Return the max length of array values\n */\nconst maxValueLength = (array) => {\n return array.reduce((longest, value) => Math.max(longest, unicodeLength(value)), 0);\n};\nconst unicodeLength = (str) => {\n return Array.from(str).length;\n};\n//# sourceMappingURL=regex.js.map\n;// ./node_modules/@orchidjs/unicode-variants/dist/esm/strings.js\n/**\n * Get all possible combinations of substrings that add up to the given string\n * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string\n */\nconst allSubstrings = (input) => {\n if (input.length === 1)\n return [[input]];\n let result = [];\n const start = input.substring(1);\n const suba = allSubstrings(start);\n suba.forEach(function (subresult) {\n let tmp = subresult.slice(0);\n tmp[0] = input.charAt(0) + tmp[0];\n result.push(tmp);\n tmp = subresult.slice(0);\n tmp.unshift(input.charAt(0));\n result.push(tmp);\n });\n return result;\n};\n//# sourceMappingURL=strings.js.map\n;// ./node_modules/@orchidjs/unicode-variants/dist/esm/index.js\n\n\nconst code_points = [[0, 65535]];\nconst accent_pat = '[\\u0300-\\u036F\\u{b7}\\u{2be}\\u{2bc}]';\nlet unicode_map;\nlet multi_char_reg;\nconst max_char_length = 3;\nconst latin_convert = {};
1\nconst latin_condensed = {\n '/': 'ââ',\n '0': 'ß',\n \"a\": \"â±¥ÉÉ\",\n \"aa\": \"ê³\",\n \"ae\": \"æǽǣ\",\n \"ao\": \"êµ\",\n \"au\": \"ê·\",\n \"av\": \"ê¹ê»\",\n \"ay\": \"ê½\",\n \"b\": \"ÆÉÆ\",\n \"c\": \"ê¿ÆÈ¼â\",\n \"d\": \"ÄÉÉá´
Æê®·Ôɦ\",\n \"e\": \"ÉÇá´É\",\n \"f\": \"ê¼Æ\",\n \"g\": \"Ç¥É ê¡áµ¹ê¿É¢\",\n \"h\": \"ħⱨⱶɥ\",\n \"i\": \"ɨı\",\n \"j\": \"ÉÈ·\",\n \"k\": \"Æâ±ªêêê
ê£\",\n \"l\": \"ÅÆÉ«â±¡êêêÉ\",\n \"m\": \"ɱɯϻ\",\n \"n\": \"ê¥ÆÉ²êá´Ð»Ô\",\n \"o\": \"øǿÉɵêêá´\",\n \"oe\": \"Å\",\n \"oi\": \"Æ£\",\n \"oo\": \"ê\",\n \"ou\": \"È£\",\n \"p\": \"ƥᵽêêêÏ\",\n \"q\": \"êêÉ\",\n \"r\": \"Éɽêê§ê\",\n \"s\": \"ÃÈ¿ê©ê
Ê\",\n \"t\": \"ŧÆÊⱦê\",\n \"th\": \"þ\",\n \"tz\": \"ê©\",\n \"u\": \"Ê\",\n \"v\": \"ÊêÊ\",\n \"vy\": \"ê¡\",\n \"w\": \"â±³\",\n \"y\": \"Æ´Éỿ\",\n \"z\": \"ƶȥÉⱬê£\",\n \"hv\": \"Æ\"\n};\nfor (let latin in latin_condensed) {\n let unicode = latin_condensed[latin] || '';\n for (let i = 0; i < unicode.length; i++) {\n let char = unicode.substring(i, i + 1);\n latin_convert[char] = latin;\n }\n}\nconst convert_pat = new RegExp(Object.keys(latin_convert).join('|') + '|' + accent_pat, 'gu');\n/**\n * Initialize the unicode_map from the give code point ranges\n */\nconst initialize = (_code_points) => {\n if (unicode_map !== undefined)\n return;\n unicode_map = generateMap(_code_points || code_points);\n};\n/**\n * Helper method for normalize a string\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n */\nconst normalize = (str, form = 'NFKD') => str.normalize(form);\n/**\n * Remove accents without reordering string\n * calling str.normalize('NFKD') on \\u{594}\\u{595}\\u{596} becomes \\u{596}\\u{594}\\u{595}\n * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703\n */\nconst asciifold = (str) => {\n return Array.from(str).reduce(\n /**\n * @param {string} result\n * @param {string} char\n */\n (result, char) => {\n return result + _asciifold(char);\n }, '');\n};\nconst _asciifold = (str) => {\n str = normalize(str)\n .toLowerCase()\n .replace(convert_pat, (/** @type {string} */ char) => {\n return latin_convert[char] || '';\n });\n //return str;\n return normalize(str, 'NFC');\n};\n/**\n * Generate a list of unicode variants from the list of code points\n */\nfunction* generator(code_points) {\n for (const [code_point_min, code_point_max] of code_points) {\n for (let i = code_point_min; i <= code_point_max; i++) {\n let composed = String.fromCharCode(i);\n let folded = asciifold(composed);\n if (folded == composed.toLowerCase()) {\n continue;\n }\n // skip when folded is a string longer than 3 characters long\n // bc the resulting regex patterns will be long\n // eg:\n // folded صÙ٠اÙÙ٠عÙÙÙ ÙØ³ÙÙ
length 18 code point 65018\n // folded Ø¬Ù Ø¬ÙØ§ÙÙ length 8 code point 65019\n if (folded.length > max_char_length) {\n continue;\n }\n if (folded.length == 0) {\n continue;\n }\n yield { folded: folded, composed: composed, code_point: i };\n }\n }\n}\n/**\n * Generate a unicode map from the list of code points\n */\nconst generateSets = (code_points) => {\n const unicode_sets = {};\n const addMatching = (folded, to_add) => {\n /** @type {Set<string>} */\n const folded_set = unicode_sets[folded] || new Set();\n const patt = new RegExp('^' + setToPattern(folded_set) + '$', 'iu');\n if (to_add.match(patt)) {\n return;\n }\n folded_set.add(escape_regex(to_add));\n unicode_sets[folded] = folded_set;\n };\n for (let value of generator(code_points)) {\n addMatching(value.folded, value.folded);\n addMatching(value.folded, value.composed);\n }\n return unicode_sets;\n};\n/**\n * Generate a unicode map from the list of code points\n * ae => (?:(?:ae|Ã|Ǽ|Ç¢)|(?:A|â¶|A...)(?:E|É|âº...))\n */\nconst generateMap = (code_points) => {\n const unicode_sets = generateSets(code_points);\n const unicode_map = {};\n let multi_char = [];\n for (let folded in unicode_sets) {\n let set = unicode_sets[folded];\n if (set) {\n unicode_map[folded] = setToPattern(set);\n }\n if (folded.length > 1) {\n multi_char.push(escape_regex(folded));\n }\n }\n multi_char.sort((a, b) => b.length - a.length);\n const multi_char_patt = arrayToPattern(multi_char);\n multi_char_reg = new RegExp('^' + multi_char_patt, 'u');\n return unicode_map;\n};\n/**\n * Map each element of an array from its folded value to all possible unicode matches\n */\nconst mapSequence = (strings, min_replacement = 1) =>
1 {\n let chars_replaced = 0;\n strings = strings.map((str) => {\n if (unicode_map[str]) {\n chars_replaced += str.length;\n }\n return unicode_map[str] || str;\n });\n if (chars_replaced >= min_replacement) {\n return sequencePattern(strings);\n }\n return '';\n};\n/**\n * Convert a short string and split it into all possible patterns\n * Keep a pattern only if min_replacement is met\n *\n * 'abc'\n * \t\t=> [['abc'],['ab','c'],['a','bc'],['a','b','c']]\n *\t\t=> ['abc-pattern','ab-c-pattern'...]\n */\nconst substringsToPattern = (str, min_replacement = 1) => {\n min_replacement = Math.max(min_replacement, str.length - 1);\n return arrayToPattern(allSubstrings(str).map((sub_pat) => {\n return mapSequence(sub_pat, min_replacement);\n }));\n};\n/**\n * Convert an array of sequences into a pattern\n * [{start:0,end:3,length:3,substr:'iii'}...] => (?:iii...)\n */\nconst sequencesToPattern = (sequences, all = true) => {\n let min_replacement = sequences.length > 1 ? 1 : 0;\n return arrayToPattern(sequences.map((sequence) => {\n let seq = [];\n const len = all ? sequence.length() : sequence.length() - 1;\n for (let j = 0; j < len; j++) {\n seq.push(substringsToPattern(sequence.substrs[j] || '', min_replacement));\n }\n return sequencePattern(seq);\n }));\n};\n/**\n * Return true if the sequence is already in the sequences\n */\nconst inSequences = (needle_seq, sequences) => {\n for (const seq of sequences) {\n if (seq.start != needle_seq.start || seq.end != needle_seq.end) {\n continue;\n }\n if (seq.substrs.join('') !== needle_seq.substrs.join('')) {\n continue;\n }\n let needle_parts = needle_seq.parts;\n const filter = (part) => {\n for (const needle_part of needle_parts) {\n if (needle_part.start === part.start && needle_part.substr === part.substr) {\n return false;\n }\n if (part.length == 1 || needle_part.length == 1) {\n continue;\n }\n // check for overlapping parts\n // a = ['::=','==']\n // b = ['::','===']\n // a = ['r','sm']\n // b = ['rs','m']\n if (part.start < needle_part.start && part.end > needle_part.start) {\n return true;\n }\n if (needle_part.start < part.start && needle_part.end > part.start) {\n return true;\n }\n }\n return false;\n };\n let filtered = seq.parts.filter(filter);\n if (filtered.length > 0) {\n continue;\n }\n return true;\n }\n return false;\n};\nclass Sequence {\n parts;\n substrs;\n start;\n end;\n constructor() {\n this.parts = [];\n this.substrs = [];\n this.start = 0;\n this.end = 0;\n }\n add(part) {\n if (part) {\n this.parts.push(part);\n this.substrs.push(part.substr);\n this.start = Math.min(part.start, this.start);\n this.end = Math.max(part.end, this.end);\n }\n }\n last() {\n return this.parts[this.parts.length - 1];\n }\n length() {\n return this.parts.length;\n }\n clone(position, last_piece) {\n let clone = new Sequence();\n let parts = JSON.parse(JSON.stringify(this.parts));\n let last_part = parts.pop();\n for (const part of parts) {\n clone.add(part);\n }\n let last_substr = last_piece.substr.substring(0, position - last_part.start);\n let clone_last_len = last_substr.length;\n clone.add({ start: last_part.start, end: last_part.start + clone_last_len, length: clone_last_len, substr: last_substr });\n return clone;\n }\n}\n/**\n * Expand a regular expression pattern to include unicode variants\n * \teg /a/ becomes /aâï½áºÃ áâầấẫẩãÄÄằắẵẳȧǡäÇảåǻÇÈÈạáºáº·á¸Ä
â±¥ÉÉAâ¶ï¼¡ÃÃÃẦẤẪẨÃÄÄáº°áº®áº´áº²È¦Ç ÃÇẢÃ
ǺÇÈÈẠẬẶá¸ÄȺⱯ/\n *\n * Issue:\n * ïºïº [ 'ïº = \\\\u{fe8a}', 'ïº = \\\\u{fe8b}' ]\n *\tbecomes:\tÙÙÙÙ [ 'Ù = \\\\u{64a}', 'Ù = \\\\u{654}', 'Ù = \\\\u{64a}', 'Ù = \\\\u{654}' ]\n *\n *\tİIJ = IIJ = â
¡J\n *\n * \t1/2/4\n */\nconst getPattern = (str) => {\n initialize();\n str = asciifold(str);\n let pattern = '';\n let sequences = [new Sequence()];\n for (let i = 0; i < str.length;
1 i++) {\n let substr = str.substring(i);\n let match = substr.match(multi_char_reg);\n const char = str.substring(i, i + 1);\n const match_str = match ? match[0] : null;\n // loop through sequences\n // add either the char or multi_match\n let overlapping = [];\n let added_types = new Set();\n for (const sequence of sequences) {\n const last_piece = sequence.last();\n if (!last_piece || last_piece.length == 1 || last_piece.end <= i) {\n // if we have a multi match\n if (match_str) {\n const len = match_str.length;\n sequence.add({ start: i, end: i + len, length: len, substr: match_str });\n added_types.add('1');\n }\n else {\n sequence.add({ start: i, end: i + 1, length: 1, substr: char });\n added_types.add('2');\n }\n }\n else if (match_str) {\n let clone = sequence.clone(i, last_piece);\n const len = match_str.length;\n clone.add({ start: i, end: i + len, length: len, substr: match_str });\n overlapping.push(clone);\n }\n else {\n // don't add char\n // adding would create invalid patterns: 234 => [2,34,4]\n added_types.add('3');\n }\n }\n // if we have overlapping\n if (overlapping.length > 0) {\n // ['ii','iii'] before ['i','i','iii']\n overlapping = overlapping.sort((a, b) => {\n return a.length() - b.length();\n });\n for (let clone of overlapping) {\n // don't add if we already have an equivalent sequence\n if (inSequences(clone, sequences)) {\n continue;\n }\n sequences.push(clone);\n }\n continue;\n }\n // if we haven't done anything unique\n // clean up the patterns\n // helps keep patterns smaller\n // if str = 'râ¨ã§aarss', pattern will be 446 instead of 655\n if (i > 0 && added_types.size == 1 && !added_types.has('3')) {\n pattern += sequencesToPattern(sequences, false);\n let new_seq = new Sequence();\n const old_seq = sequences[0];\n if (old_seq) {\n new_seq.add(old_seq.last());\n }\n sequences = [new_seq];\n }\n }\n pattern += sequencesToPattern(sequences, true);\n return pattern;\n};\n\n//# sourceMappingURL=index.js.map\n;// ./node_modules/@orchidjs/sifter/dist/esm/utils.js\n\n/**\n * A property getter resolving dot-notation\n * @param {Object} obj The root object to fetch property on\n * @param {String} name The optionally dotted property name to fetch\n * @return {Object} The resolved property value\n */\nconst getAttr = (obj, name) => {\n if (!obj)\n return;\n return obj[name];\n};\n/**\n * A property getter resolving dot-notation\n * @param {Object} obj The root object to fetch property on\n * @param {String} name The optionally dotted property name to fetch\n * @return {Object} The resolved property value\n */\nconst getAttrNesting = (obj, name) => {\n if (!obj)\n return;\n var part, names = name.split(\".\");\n while ((part = names.shift()) && (obj = obj[part]))\n ;\n return obj;\n};\n/**\n * Calculates how close of a match the\n * given value is against a search token.\n *\n */\nconst scoreValue = (value, token, weight) => {\n var score, pos;\n if (!value)\n return 0;\n value = value + '';\n if (token.regex == null)\n return 0;\n pos = value.search(token.regex);\n if (pos === -1)\n return 0;\n score = token.string.length / value.length;\n if (pos === 0)\n score += 0.5;\n return score * weight;\n};\n/**\n * Cast object property to an array if it exists and has a value\
1n *\n */\nconst propToArray = (obj, key) => {\n var value = obj[key];\n if (typeof value == 'function')\n return value;\n if (value && !Array.isArray(value)) {\n obj[key] = [value];\n }\n};\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst iterate = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n }\n else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\nconst cmp = (a, b) => {\n if (typeof a === 'number' && typeof b === 'number') {\n return a > b ? 1 : (a < b ? -1 : 0);\n }\n a = asciifold(a + '').toLowerCase();\n b = asciifold(b + '').toLowerCase();\n if (a > b)\n return 1;\n if (b > a)\n return -1;\n return 0;\n};\n//# sourceMappingURL=utils.js.map\n;// ./node_modules/@orchidjs/sifter/dist/esm/sifter.js\n/**\n * sifter.js\n * Copyright (c) 2013â2020 Brian Reavis & contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n * @author Brian Reavis <[email protected]>\n */\n\n\nclass Sifter {\n items; // []|{};\n settings;\n /**\n * Textually searches arrays and hashes of objects\n * by property (or multiple properties). Designed\n * specifically for autocomplete.\n *\n */\n constructor(items, settings) {\n this.items = items;\n this.settings = settings || { diacritics: true };\n }\n ;\n /**\n * Splits a search string into an array of individual\n * regexps to be used to match results.\n *\n */\n tokenize(query, respect_word_boundaries, weights) {\n if (!query || !query.length)\n return [];\n const tokens = [];\n const words = query.split(/\\s+/);\n var field_regex;\n if (weights) {\n field_regex = new RegExp('^(' + Object.keys(weights).map(escape_regex).join('|') + ')\\:(.*)$');\n }\n words.forEach((word) => {\n let field_match;\n let field = null;\n let regex = null;\n // look for \"field:query\" tokens\n if (field_regex && (field_match = word.match(field_regex))) {\n field = field_match[1];\n word = field_match[2];\n }\n if (word.length > 0) {\n if (this.settings.diacritics) {\n regex = getPattern(word) || null;\n }\n else {\n regex = escape_regex(word);\n }\n if (regex && respect_word_boundaries)\n regex = \"\\\\b\" + regex;\n }\n tokens.push({\n string: word,\n regex: regex ? new RegExp(regex, 'iu') : null,\n field: field,\n });\n });\n return tokens;\n }\n ;\n /**\n * Returns a function to be used to score individual results.\n *\n * Good matches will have a higher score than poor matches.\n * If an item is not a match, 0 will be returned by the function.\n *\n * @returns {T.ScoreFn}\n */\n getScoreFunction(query, options) {\n var search = this.prepareSearch(query, options);\n return this._getScoreFunction(search);\n }\n /**\n * @returns {T.ScoreFn}\n *\n */\n _getScoreFunction(search) {\n const tokens = search.tokens, token_count = tokens.length;\n if (!token_count) {\n return function () { return 0; };\n }\n const fields = search.options.fields, weights = search.weights, field_count = fields.length, getAttrFn = search.getAttrFn;\n if (!field_count) {\n return function () { return 1; };\n }\n /**\n * Calculates the score of an object\n * against the search query.\n *\n */\n const scoreObject = (function () {\n if (field_count === 1) {\n return function (token, data) {\n const field = fields[0].field;\n return scoreValue(getAttrFn(data, field), token, weights[field] || 1);\n };\n }\n return function (token, data) {\n var sum = 0;\n // is the token specific to a field?\n if (token.field) {\n const value = getAttrFn(data, token.field);\n if (!token.regex && value) {\n sum += (1 / field_count);\n }\n else {\n sum += scoreValue(value, token, 1);\n }\n }\n else {\n iterate(weights, (weight, field) =>
1 {\n sum += scoreValue(getAttrFn(data, field), token, weight);\n });\n }\n return sum / field_count;\n };\n })();\n if (token_count === 1) {\n return function (data) {\n return scoreObject(tokens[0], data);\n };\n }\n if (search.options.conjunction === 'and') {\n return function (data) {\n var score, sum = 0;\n for (let token of tokens) {\n score = scoreObject(token, data);\n if (score <= 0)\n return 0;\n sum += score;\n }\n return sum / token_count;\n };\n }\n else {\n return function (data) {\n var sum = 0;\n iterate(tokens, (token) => {\n sum += scoreObject(token, data);\n });\n return sum / token_count;\n };\n }\n }\n ;\n /**\n * Returns a function that can be used to compare two\n * results, for sorting purposes. If no sorting should\n * be performed, `null` will be returned.\n *\n * @return function(a,b)\n */\n getSortFunction(query, options) {\n var search = this.prepareSearch(query, options);\n return this._getSortFunction(search);\n }\n _getSortFunction(search) {\n var implicit_score, sort_flds = [];\n const self = this, options = search.options, sort = (!search.query && options.sort_empty) ? options.sort_empty : options.sort;\n if (typeof sort == 'function') {\n return sort.bind(this);\n }\n /**\n * Fetches the specified sort field value\n * from a search result item.\n *\n */\n const get_field = function (name, result) {\n if (name === '$score')\n return result.score;\n return search.getAttrFn(self.items[result.id], name);\n };\n // parse options\n if (sort) {\n for (let s of sort) {\n if (search.query || s.field !== '$score') {\n sort_flds.push(s);\n }\n }\n }\n // the \"$score\" field is implied to be the primary\n // sort field, unless it's manually specified\n if (search.query) {\n implicit_score = true;\n for (let fld of sort_flds) {\n if (fld.field === '$score') {\n implicit_score = false;\n break;\n }\n }\n if (implicit_score) {\n sort_flds.unshift({ field: '$score', direction: 'desc' });\n }\n // without a search.query, all items will have the same score\n }\n else {\n sort_flds = sort_flds.filter((fld) => fld.field !== '$score');\n }\n // build function\n const sort_flds_count = sort_flds.length;\n if (!sort_flds_count) {\n return null;\n }\n return function (a, b) {\n var result, field;\n for (let sort_fld of sort_flds) {\n field = sort_fld.field;\n let multiplier = sort_fld.direction === 'desc' ? -1 : 1;\n result = multiplier * cmp(get_field(field, a), get_field(field, b));\n if (result)\n return result;\n }\n return 0;\n };\n }\n ;\n /**\n * Parses a search query and returns an object\n * with tokens and fields ready to be populated\n * with results.\n *\n */\n prepareSearch(query, optsUser) {\n const weights = {};\n var options = Object.assign({}, optsUser);\n propToArray(options, 'sort');\n propToArray(options, 'sort_empty');\n // convert fields to new format\n if (options.fields) {\n propToArray(options, 'fields');\n const fields = [];\n options.fields.forEach((field) =>
1 {\n if (typeof field == 'string') {\n field = { field: field, weight: 1 };\n }\n fields.push(field);\n weights[field.field] = ('weight' in field) ? field.weight : 1;\n });\n options.fields = fields;\n }\n return {\n options: options,\n query: query.toLowerCase().trim(),\n tokens: this.tokenize(query, options.respect_word_boundaries, weights),\n total: 0,\n items: [],\n weights: weights,\n getAttrFn: (options.nesting) ? getAttrNesting : getAttr,\n };\n }\n ;\n /**\n * Searches through all items and returns a sorted array of matches.\n *\n */\n search(query, options) {\n var self = this, score, search;\n search = this.prepareSearch(query, options);\n options = search.options;\n query = search.query;\n // generate result scoring function\n const fn_score = options.score || self._getScoreFunction(search);
1\n // perform search and sort\n if (query.length) {\n iterate(self.items, (item, id) => {\n score = fn_score(item);\n if (options.filter === false || score > 0) {\n search.items.push({ 'score': score, 'id': id });\n }\n });\n }\n else {\n iterate(self.items, (_, id) => {\n search.items.push({ 'score': 1, 'id': id });\n });\n }\n const fn_sort = self._getSortFunction(search);\n if (fn_sort)\n search.items.sort(fn_sort);\n // apply limits\n search.total = search.items.length;\n if (typeof options.limit === 'number') {\n search.items = search.items.slice(0, options.limit);\n }\n return search;\n }\n ;\n}\n\n\n//# sourceMappingURL=sifter.js.map\n;// ./node_modules/tom-select/dist/esm/utils.js\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\nconst hash_key = (value) => {\n if (typeof value === 'undefined' || value === null)\n return null;\n return get_hash(value);\n};\nconst get_hash = (value) => {\n if (typeof value === 'boolean')\n return value ? '1' : '0';\n return value + '';\n};\n/**\n * Escapes a string for use within HTML.\n *\n */\nconst escape_html = (str) => {\n return (str + '')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"');\n};\n/**\n * use setTimeout if timeout > 0\n */\nconst timeout = (fn, timeout) => {\n if (timeout > 0) {\n return window.setTimeout(fn, timeout);\n }\n fn.call(null);\n return null;\n};\n/**\n * Debounce the user provided load function\n *\n */\nconst loadDebounce = (fn, delay) =>
1 {\n var timeout;\n return function (value, callback) {\n var self = this;\n if (timeout) {\n self.loading = Math.max(self.loading - 1, 0);\n clearTimeout(timeout);\n }\n timeout = setTimeout(function () {\n timeout = null;\n self.loadedSearches[value] = true;\n fn.call(self, value, callback);\n }, delay);\n };\n};\n/**\n * Debounce all fired events types listed in `types`\n * while executing the provided `fn`.\n *\n */\nconst debounce_events = (self, types, fn) => {\n var type;\n var trigger = self.trigger;\n var event_args = {};\n // override trigger method\n self.trigger = function () {\n var type = arguments[0];\n if (types.indexOf(type) !== -1) {\n event_args[type] = arguments;\n }\n else {\n return trigger.apply(self, arguments);\n }\n };\n // invoke provided function\n fn.apply(self, []);\n self.trigger = trigger;\n // trigger queued events\n for (type of types) {\n if (type in event_args) {\n trigger.apply(self, event_args[type]);\n }\n }\n};\n/**\n * Determines the current selection within a text input control.\n * Returns an object c
1ontaining:\n * - start\n * - length\n *\n * Note: \"selectionStart, selectionEnd ... apply only to inputs of types text, search, URL, tel and password\"\n * \t- https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n */\nconst getSelection = (input) => {\n return {\n start: input.selectionStart || 0,\n length: (input.selectionEnd || 0) - (input.selectionStart || 0),\n };\n};\n/**\n * Prevent default\n *\n */\nconst preventDefault = (evt, stop = false) => {\n if (evt) {\n evt.preventDefault();\n if (stop) {\n evt.stopPropagation();\n }\n }\n};\n/**\n * Add event helper\n *\n */\nconst addEvent = (target, type, callback, options) => {\n target.addEventListener(type, callback, options);\n};\n/**\n * Return true if the requested key is down\n * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )\n * The current evt may not always set ( eg calling advanceSelection() )\n *\n */\nconst isKeyDown = (key_name, evt) => {\n if (!evt) {\n return false;\n }\n if (!evt[key_name]) {\n return false;\n }\n var count = (evt.altKey ? 1 : 0) + (evt.ctrlKey ? 1 : 0) + (evt.shiftKey ? 1 : 0) + (evt.metaKey ? 1 : 0);\n if (count === 1) {\n return true;\n }\n return false;\n};\n/**\n * Get the id of an element\n * If the id attribute is not set, set the attribute with the given id\n *\n */\nconst getId = (el, id) => {\n const existing_id = el.getAttribute('id');\n if (existing_id) {\n return existing_id;\n }\n el.setAttribute('id', id);\n return id;\n};\n/**\n * Returns a string with backslashes added before characters that need to be escaped.\n */\nconst addSlashes = (str) => {\n return str.replace(/[\\\\\"']/g, '\\\\$&');\n};\n/**\n *\n */\nconst append = (parent, node) => {\n if (node)\n parent.append(node);\n};\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst utils_iterate = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n }\n else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\n//# sourceMappingURL=utils.js.map\n;// ./node_modules/tom-select/dist/esm/vanilla.js\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst getDom = (query) => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst isHtmlString = (arg) => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\nconst escapeQuery = (query) => {\n return query.replace(/['\"\\\\]/g, '\\\\$&');\n};\n/**\n * Dispatch an event\n *\n */\nconst triggerEvent = (dom_el, event_name) => {\n var event = document.createEvent('HTMLEvents');\n event.initEvent(event_name, true, false);\n dom_el.dispatchEvent(event);\n};\n/**\n * Apply CSS rules to a dom element\n *\n */\nconst applyCSS = (dom_el, css) => {\n Object.assign(dom_el.style, css);\n};\n/**\n * Add css classes\n *\n */\nconst addClasses = (elmts, ...classes) => {\n var norm_classes = classesArray(classes);\n elmts = castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.add(cls);\n });\n });\n};\n/**\n * Remove css classes\n *\n */\nconst removeClasses = (elmts, ...classes) =>
1 {\n var norm_classes = classesArray(classes);\n elmts = castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.remove(cls);\n });\n });\n};\n/**\n * Return arguments\n *\n */\nconst classesArray = (args) => {\n var classes = [];\n utils_iterate(args, (_classes) => {\n if (typeof _classes === 'string') {\n _classes = _classes.trim().split(/[\\t\\n\\f\\r\\s]/);\n }\n if (Array.isArray(_classes)) {\n classes = classes.concat(_classes);\n }\n });\n return classes.filter(Boolean);\n};\n/**\n * Create an array from arg if it's not already an array\n *\n */\nconst castAsArray = (arg) => {\n if (!Array.isArray(arg)) {\n arg = [arg];\n }\n return arg;\n};\n/**\n * Get the closest node to the evt.target matching the selector\n * Stops at wrapper\n *\n */\nconst parentMatch = (target, selector, wrapper) => {\n if (wrapper && !wrapper.contains(target)) {\n return;\n }\n while (target && target.matches) {\n if (target.matches(selector)) {\n return target;\n }\n target = target.parentNode;\n }\n};\n/**\n * Get the first or last item from an array\n *\n * > 0 - right (last)\n * <= 0 - left (first)\n *\n */\nconst getTail = (list, direction = 0) => {\n if (direction > 0) {\n return list[list.length - 1];\n }\n return list[0];\n};\n/**\n * Return true if an object is empty\n *\n */\nconst isEmptyObject = (obj) => {\n return (Object.keys(obj).length === 0);\n};\n/**\n * Get the index of an element amongst sibling nodes of the same type\n *\n */\nconst nodeIndex = (el, amongst) => {\n if (!el)\n return -1;\n amongst = amongst || el.nodeName;\n var i = 0;\n while (el = el.previousElementSibling) {\n if (el.matches(amongst)) {\n i++;\n }\n }\n return i;\n};\n/**\n * Set attributes of an element\n *\n */\nconst setAttr = (el, attrs) => {\n utils_iterate(attrs, (val, attr) => {\n if (val == null) {\n el.removeAttribute(attr);\n }\n else {\n el.setAttribute(attr, '' + val);\n }\n });\n};\n/**\n * Replace a node\n */\nconst replaceNode = (existing, replacement) => {\n if (existing.parentNode)\n existing.parentNode.replaceChild(replacement, existing);\n};\n//# sourceMappingURL=vanilla.js.map\n;// ./node_modules/tom-select/dist/esm/contrib/highlight.js\n/**\n * highlight v3 | MIT license | Johann Burkard <[email protected]>\n * Highlights arbitrary terms in a node.\n *\n * - Modified by Marshal <[email protected]> 2011-6-24 (added regex)\n * - Modified by Brian Reavis <[email protected]> 2012-8-27 (cleanup)\n */\n\nconst highlight = (element, regex) => {\n if (regex === null)\n return;\n // convet string to regex\n if (typeof regex === 'string') {\n if (!regex.length)\n return;\n regex = new RegExp(regex, 'i');\n }\n // Wrap matching part of text node with highlighting <span>, e.g.\n // Soccer -> <span class=\"highlight\">Soc</span>cer for regex = /soc/i\n const highlightText = (node) => {\n var match = node.data.match(regex);\n if (match && node.data.length > 0) {\n var spannode = document.createElement('span');\n spannode.className = 'highlight';\n var middlebit = node.splitText(match.index);\n middlebit.splitText(match[0].length);\n var middleclone = middlebit.cloneNode(true);\n spannode.appendChild(middleclone);\n replaceNode(middlebit, spannode);\n return 1;\n }\n return 0;\n };\n // Recurse element node, looking for child text nodes to highlight, unless element\n // is childless, <script>, <style>, or already highlighted: <span class=\"hightlight\">\n const highlightChildren = (node) => {\n if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && (node.className !== 'highlight' || node.tagName !== 'SPAN')) {\n Array.from(node.childNodes).forEac
1h(element => {\n highlightRecursive(element);\n });\n }\n };\n const highlightRecursive = (node) => {\n if (node.nodeType === 3) {\n return highlightText(node);\n }\n highlightChildren(node);\n return 0;\n };\n highlightRecursive(element);\n};\n/**\n * removeHighlight fn copied from highlight v5 and\n * edited to remove with(), pass js strict mode, and use without jquery\n */\nconst removeHighlight = (el) => {\n var elements = el.querySelectorAll(\"span.highlight\");\n Array.prototype.forEach.call(elements, function (el) {\n var parent = el.parentNode;\n parent.replaceChild(el.firstChild, el);\n parent.normalize();\n });\n};\n//# sourceMappingURL=highlight.js.map\n;// ./node_modules/tom-select/dist/esm/constants.js\nconst KEY_A = 65;\nconst KEY_RETURN = 13;\nconst KEY_ESC = 27;\nconst KEY_LEFT = 37;\nconst KEY_UP = 38;\nconst KEY_RIGHT = 39;\nconst KEY_DOWN = 40;\nconst KEY_BACKSPACE = 8;\nconst KEY_DELETE = 46;\nconst KEY_TAB = 9;\nconst IS_MAC = typeof navigator === 'undefined' ? false : /Mac/.test(navigator.userAgent);\nconst KEY_SHORTCUT = IS_MAC ? 'metaKey' : 'ctrlKey'; // ctrl key or apple key for ma\n//# sourceMappingURL=constants.js.map\n;// ./node_modules/tom-select/dist/esm/defaults.js\n/* harmony default export */ const defaults = ({\n options: [],\n optgroups: [],\n plugins: [],\n delimiter: ',',\n splitOn: null, // regexp or string for splitting up values from a paste command\n persist: true,\n diacritics: true,\n create: null,\n createOnBlur: false,\n createFilter: null,\n highlight: true,\n openOnFocus: true,\n shouldOpen: null,\n maxOptions: 50,\n maxItems: null,\n hideSelected: null,\n duplicates: false,\n addPrecedence: false,\n selectOnTab: false,\n preload: null,\n allowEmptyOption: false,\n //closeAfterSelect: false,\n refreshThrottle: 300,\n loadThrottle: 300,\n loadingClass: 'loading',\n dataAttr: null, //'data-data',\n optgroupField: 'optgroup',\n valueField: 'value',\n labelField: 'text',\n disabledField: 'disabled',\n optgroupLabelField: 'label',\n optgroupValueField: 'value',\n lockOptgroupOrder: false,\n sortField: '$order',\n searchField: ['text'],\n searchConjunction: 'and',\n mode: null,\n wrapperClass: 'ts-wrapper',\n controlClass: 'ts-control',\n dropdownClass: 'ts-dropdown',\n dropdownContentClass: 'ts-dropdown-content',\n itemClass: 'item',\n optionClass: 'option',\n dropdownParent: null,\n controlInput: '<input type=\"text\" autocomplete=\"off\" size=\"1\" />',\n copyClassesToDropdown: false,\n placeholder: null,\n hidePlaceholder: null,\n shouldLoad: function (query) {\n return query.length > 0;\n },\n /*\n load : null, // function(query, callback) { ... }\n score : null, // function(search) { ... }\n onInitialize : null, // function() { ... }\n onChange : null, // function(value) { ... }\n onItemAdd : null, // function(value, $item) { ... }\n onItemRemove : null, // function(value) { ... }\n onClear : null, // function() { ... }\n onOptionAdd : null, // function(value, data) { ... }\n onOptionRemove : null, // function(value) { ... }\n onOptionClear : null, // function() { ... }\n onOptionGroupAdd : null, // function(id, data) { ... }\n onOptionGroupRemove : null, // function(id) { ... }\n onOptionGroupClear : null, // function() { ... }\n onDropdownOpen : null, // function(dropdown) { ... }\n onDropdownClose : null, // function(dropdown) { ... }\n onType : null, // function(str) { ... }\n onDelete : null, // function(values) { ... }\n */\n render: {\n /*\n item: null,\n optgroup: null,\n optgroup_header: null,\n option: null,\n option_create: null\n */\n }\n});\n//# sourceMappingURL=defaults.js.map\n;// ./node_modules/tom-select/dist/esm/getSettings.js\n\n\nfunction getSettings(input, settings_user) {\n var settings = Object.assign({}, defaults, settings_user);\n var attr_data = settings.dataAttr;\n var field_label = settings.labelField;\n var field_value = settings.valueField;\n var field_disabled = settings.disabledField;\n var field_optgroup = settings.optgroupField;\n var field_optgroup_label = settings.optgroupLabelField;\n var field_optgroup_value = settings.optgroupValueField;\n var tag_name = input.tagName.toLowerCase();\n var placeholder = input.getAttribute('placeholder') || input.getAttribute('data-placeholder');
1\n if (!placeholder && !settings.allowEmptyOption) {\n let option = input.querySelector('option[value=\"\"]');\n if (option) {\n placeholder = option.textContent;\n }\n }\n var settings_element = {\n placeholder: placeholder,\n options: [],\n optgroups: [],\n items: [],\n maxItems: null,\n };\n /**\n * Initialize from a <select> element.\n *\n */\n var init_select = () => {\n var tagName;\n var options = settings_element.options;\n var optionsMap = {};\n var group_count = 1;\n let $order = 0;\n var readData = (el) => {\n var data = Object.assign({}, el.dataset); // get plain object from DOMStringMap\n var json = attr_data && data[attr_data];\n if (typeof json === 'string' && json.length) {\n data = Object.assign(data, JSON.parse(json));\n }\n return data;\n };\n var addOption = (option, group) => {\n var value = hash_key(option.value);\n if (value == null)\n return;\n if (!value && !settings.allowEmptyOption)\n return;\n // if the option already exists, it's probably been\n // duplicated in another optgroup. in this case, push\n // the current group to the \"optgroup\" property on the\n // existing option so that it's rendered in both places.\n if (optionsMap.hasOwnProperty(value)) {\n if (group) {\n var arr = optionsMap[value][field_optgroup];\n if (!arr) {\n optionsMap[value][field_optgroup] = group;\n }\n else if (!Array.isArray(arr)) {\n optionsMap[value][field_optgroup] = [arr, group];\n }\n else {\n arr.push(group);\n }\n }\n }\n else {\n var option_data = readData(option);\n option_data[field_label] = option_data[field_label] || option.textContent;\n option_data[field_value] = option_data[field_value] || value;\n option_data[field_disabled] = option_data[field_disabled] || option.disabled;\n option_data[field_optgroup] = option_data[field_optgroup] || group;\n option_data.$option = option;\n option_data.$order = option_data.$order || ++$order;\n optionsMap[value] = option_data;\n options.push(option_data);\n }\n if (option.selected) {\n settings_element.items.push(value);\n }\n };\n var addGroup = (optgroup) => {\n var id, optgroup_data;\n optgroup_data = readData(optgroup);\n optgroup_data[field_optgroup_label] = optgroup_data[field_optgroup_label] || optgroup.getAttribute('label') || '';\n optgroup_data[field_optgroup_value] = optgroup_data[field_optgroup_value] || group_count++;\n optgroup_data[field_disabled] = optgroup_data[field_disabled] || optgroup.disabled;\n optgroup_data.$order = optgroup_data.$order || ++$order;\n settings_element.optgroups.push(optgroup_data);\n id = optgroup_data[field_optgroup_value];\n utils_iterate(optgroup.children, (option) => {\n addOption(option, id);\n });\n };\n settings_element.maxItems = input.hasAttribute('multiple') ? null : 1;\n utils_iterate(input.children, (child) =>
1 {\n tagName = child.tagName.toLowerCase();\n if (tagName === 'optgroup') {\n addGroup(child);\n }\n else if (tagName === 'option') {\n addOption(child);\n }\n });\n };\n /**\n * Initialize from a <input type=\"text\"> element.\n *\n */\n var init_textbox = () => {\n const data_raw = input.getAttribute(attr_data);\n if (!data_raw) {\n var value = input.value.trim() || '';\n if (!settings.allowEmptyOption && !value.length)\n return;\n const values = value.split(settings.delimiter);\n utils_iterate(values, (value) => {\n const option = {};\n option[field_label] = value;\n option[field_value] = value;\n settings_element.options.push(option);\n });\n settings_element.items = values;\n }\n else {\n settings_element.options = JSON.parse(data_raw);\n utils_iterate(settings_element.options, (opt) => {\n settings_element.items.push(opt[field_value]);\n });\n }\n };\n if (tag_name === 'select') {\n init_select();\n }\n else {\n init_textbox();\n }\n return Object.assign({}, defaults, settings_element, settings_user);\n}\n;\n//# sourceMappingURL=getSettings.js.map\n;// ./node_modules/tom-select/dist/esm/tom-select.js\n\n\n\n\n\n\n\n\n\nvar instance_i = 0;\nclass TomSelect extends MicroPlugin(MicroEvent) {\n constructor(input_arg, user_settings) {\n super();\n this.order = 0;\n this.isOpen = false;\n this.isDisabled = false;\n this.isReadOnly = false;\n this.isInvalid = false; // @deprecated 1.8\n this.isValid = true;\n this.isLocked = false;\n this.isFocused = false;\n this.isInputHidden = false;\n this.isSetup = false;\n this.ignoreFocus = false;\n this.ignoreHover = false;\n this.hasOptions = false;\n this.lastValue = '';\n this.caretPos = 0;\n this.loading = 0;\n this.loadedSearches = {};\n this.activeOption = null;\n this.activeItems = [];\n this.optgroups = {};\n this.options = {};\n this.userOptions = {};\n this.items = [];\n this.refreshTimeout = null;\n instance_i++;\n var dir;\n var input = getDom(input_arg);\n if (input.tomselect) {\n throw new Error('Tom Select already initialized on this element');\n }\n input.tomselect = this;\n // detect rtl environment\n var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);\n dir = computedStyle.getPropertyValue('direction');\n // setup default state\n const settings = getSettings(input, user_settings);\n this.settings = settings;\n this.input = input;\n this.tabIndex = input.tabIndex || 0;\n this.is_select_tag = input.tagName.toLowerCase() === 'select';\n this.rtl = /rtl/i.test(dir);\n this.inputId = getId(input, 'tomselect-' + instance_i);\n this.isRequired = input.required;\n // search system\n this.sifter = new Sifter(this.options, { diacritics: settings.diacritics });\n // option-dependent defaults\n settings.mode = settings.mode || (settings.maxItems === 1 ? 'single' : 'multi');\n if (typeof settings.hideSelected !== 'boolean') {\n settings.hideSelected = settings.mode === 'multi';\n }\n if (typeof settings.hidePlaceholder !== 'boolean') {\n settings.hidePlaceholder = settings.mode !== 'multi';\n }\n // set up createFilter callback\n var filter = settings.createFilter;\n if (typeof filter !== 'function') {\n if (typeof filter === 'string') {\n filter = new RegExp(filter);\n }\n if (filter instanceof RegExp) {\n settings.createFilter = (input) => filter.test(input);\n }\n else {\n settings.createFilter = (value) => {\n return this.settings.duplicates || !this.options[value];\n };\n }\n }\n this.initializePlugins(settings.plugins);\n this.setupCallbacks();\n this.setupTemplates();\n // Create all elements\n const wrapper = getDom('<div>');\n const control = getDom('<div>');\n const dropdown = this._render('dropdown');\n const dropdown_content = getDom(`<div role=\"listbox\" tabindex=\"-1\">`);\n const classes = this.input.getAttribute('class') || '';\n const inputMode = settings.mode;\n var control_input;\n addClasses(wrapper, settings.wrapperClass, classes, inputMode);\n addClasses(control, settings.controlClass);\n append(wrapper, control);\n addClasses(dropdown, settings.dropdownClass, inputMode);\n if (settings.copyClassesToDropdown) {\n addClasses(dropdown, classes);\n }\n addClasses(dropdown_content, settings.dropdownContentClass);\n append(dropdown, dropdown_content);\n getDom(settings.dropdownParent || wrapper).appendChild(dropdown);\n // default controlInput\n if (isHtmlString(settings.controlInput)) {\n control_input = getDom(settings.controlInput);\n // set attributes\n var attrs = ['autocorrect', 'autocapitalize', 'autocomplete', 'spellcheck'];\n utils_iterate(attrs, (attr) => {\n if (input.getAttribute(attr)) {\n setAttr(control_input, { [attr]: input.getAttribute(attr) });\n }\n });\n control_input.tabIndex = -1;\n control.appendChild(control_input);\n this.focus_node = control_input;\n // dom element\n }\n else if (settings.controlInput) {\n control_input = getDom(settings.controlInput);\n this.focus_node = control_input;\n }\n else {\n control_input = getDom('<input/>');\n this.focus_node = control;\n }\n this.wrapper = wrapper;\n this.dropdown = dropdown;\n this.dropdown_content = dropdown_content;\n this.control = control;\n this.control_input = control_input;\n this.setup();\n }\n /**\n * set up event bindings.\n *\n */\n setup() {\n const self = this;\n const settings = self.settings;\n const control_input = self.control_input;\n const dropdown = self.dropdown;\n const dropdown_content = self.dropdown_content;\n const wrapper = self.wrapper;\n const control = self.control;\n const input = self.input;\n const focus_node = self.focus_node;\n const passive_event = { passive: true };\n const listboxId = self.inputId + '-ts-dropdown';\n setAttr(dropdown_content, {\n id: listboxId\n });\n setAttr(focus_node, {\n role: 'combobox',\n 'aria-haspopup': 'listbox',\n 'aria-expanded': 'false',\n 'aria-controls': listboxId\n });\n const control_id = getId(focus_node, self.inputId + '-ts-control');\n const query = \"label[for='\" + escapeQuery(self.inputId) + \"']\";\n const label = document.querySelector(query);\n const label_click = self.focus.bind(self);\n if (label) {\n addEvent(label, 'click', label_click);\n setAttr(label, { for: control_id });\n const label_id = getId(label, self.inputId + '-ts-label');\n setAttr(focus_node, { 'aria-labelledby': label_id });\n setAttr(dropdown_content, { 'aria-labelledby': label_id });\n }\n wrapper.style.width = input.style.width;\n if (self.plugins.names.length) {\n const classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');\n addClasses([wrapper, dropdown], classes_plugins);\n }\n if ((settings.maxItems === null || settings.maxItems > 1) && self.is_select_tag) {\n setAttr(input, { multiple: 'multiple' });\n }\n if (settings.placeholder) {\n setAttr(control_input, { placeholder: settings.placeholder });\n }\n // if splitOn was not passed in, construct it from the delimiter to allow pasting universally\n if (!settings.splitOn && settings.delimiter) {\n settings.splitOn = new RegExp('\\\\s*' + escape_regex(settings.delimiter) + '+\\\\s*');\n }\n // debounce user defined load() if loadThrottle > 0\n // after initializePlugins() so plugins can create/modify user defined loaders\n if (settings.load && settings.loadThrottle) {\n settings.load = loadDebounce(settings.load, settings.loadThrottle);\n }\n addEvent(dropdown, 'mousemove', () => {\n self.ignoreHover = false;\n });\n addEvent(dropdown, 'mouseenter', (e) => {\n var target_match = parentMatch(e.target, '[data-selectable]', dropdown);\n if (target_match)\n self.onOptionHover(e, target_match);\n }, { capture: true });\n // clicking on an option should select it\n addEvent(dropdown, 'click', (evt) => {\n const option = parentMatch(evt.target, '[data-selectable]');\n if (option) {\n self.onOptionSelect(evt, option);\n preventDefault(evt, true);\n }\n });\n addEvent(control, 'click', (evt) => {\n var target_match = parentMatch(evt.target, '[data-ts-item]', control);\n if (target_match && self.onItemSelect(evt, target_match)) {\n preventDefault(evt, true);\n return;\n }\n // retain focus (see control_input mousedown)\n if (control_input.value != '') {\n return;\n }\n self.onClick();\n preventDefault(evt, true);\n });\n // keydown on focus_node for arrow_down/arrow_up\n addEvent(focus_node, 'keydown', (e) => self.onKeyDown(e));\n // keypress and input/keyup\n addEvent(control_input, 'keypress', (e) => self.onKeyPress(e));\n addEvent(control_input, 'input', (e) => self.onInput(e));\n addEvent(focus_node, 'blur', (e) => self.onBlur(e));\n addEvent(focus_node, 'focus', (e) => self.onFocus(e));\n addEvent(control_input, 'paste', (e) => self.onPaste(e));\n const doc_mousedown = (evt) => {\n // blur if target is outside of this instance\n // dropdown is not always inside wrapper\n const target = evt.composedPath()[0];\n if (!wrapper.contains(target) && !dropdown.contains(target)) {\n if (self.isFocused) {\n self.blur();\n }\n self.inputState();\n return;\n }\n // retain focus by preventing native handling. if the\n // event target is the input it should not be modified.\n // otherwise, text selection within the input won't work.\n // Fixes bug #212 which is no covered by tests\n if (target == control_input && self.isOpen) {\n evt.stopPropagation();\n // clicking anywhere in the control should not blur the control_input (which would close the dropdown)\n }\n else {\n preventDefault(evt, true);\n }\n };\n const win_scroll = () => {\n if (self.isOpen) {\n self.positionDropdown();\n }\n };\n addEvent(document, 'mousedown', doc_mousedown);\n addEvent(window, 'scroll', win_scroll, passive_event);\n addEvent(window, 'resize', win_scroll, passive_event);\n this._destroy = () => {\n document.removeEventListener('mousedown', doc_mousedown);\n window.removeEventListener('scroll', win_scroll);\n window.removeEventListener('resize', win_scroll);\n if (label)\n label.removeEventListener('click', label_click);\n };\n // store original html and tab index so that they can be\n // restored when the destroy() method is called.\n this.revertSettings = {\n innerHTML: input.innerHTML,\n tabIndex: input.tabIndex\n };\n input.tabIndex = -1;\n input.insertAdjacentElement('afterend', self.wrapper);\n self.sync(false);\n settings.items = [];\n delete settings.optgroups;\n delete settings.options;\n addEvent(input, 'invalid', () => {\n if (self.isValid) {\n self.isValid = false;\n self.isInvalid = true;\n self.refreshState();\n }\n });\n self.updateOriginalInput();\n self.refreshItems();\n self.close(false);\n self.inputState();\n self.isSetup = true;\n if (input.disabled) {\n self.disable();\n }\n else if (input.readOnly) {\n self.setReadOnly(true);\n }\n else {\n self.enable(); //sets tabIndex\n }\n self.on('change', this.onChange);\n addClasses(input, 'tomselected', 'ts-hidden-accessible');\n self.trigger('initialize');\n // preload options\n if (settings.preload === true) {\n self.preload();\n }\n }\n /**\n * Register options and optgroups\n *\n */\n setupOptions(options = [], optgroups = []) {\n // build options table\n this.addOptions(options);\n // build optgroup table\n utils_iterate(optgroups, (optgroup) =>
1 {\n this.registerOptionGroup(optgroup);\n });\n }\n /**\n * Sets up default rendering functions.\n */\n setupTemplates() {\n var self = this;\n var field_label = self.settings.labelField;\n var field_optgroup = self.settings.optgroupLabelField;\n var templates = {\n 'optgroup': (data) => {\n let optgroup = document.createElement('div');\n optgroup.className = 'optgroup';\n optgroup.appendChild(data.options);\n return optgroup;\n },\n 'optgroup_header': (data, escape) => {\n return '<div class=\"optgroup-header\">' + escape(data[field_optgroup]) + '</div>';\n },\n 'option': (data, escape) => {\n return '<div>' + escape(data[field_label]) + '</div>';\n },\n 'item': (data, escape) => {\n return '<div>' + escape(data[field_label]) + '</div>';\n },\n 'option_create': (data, escape) => {\n return '<div class=\"create\">Add <strong>' + escape(data.input) + '</strong>…</div>';\n },\n 'no_results': () => {\n return '<div class=\"no-results\">No results found</div>';\n },\n 'loading': () => {\n return '<div class=\"spinner\"></div>';\n },\n 'not_loading': () => { },\n 'dropdown': () => {\n return '<div></div>';\n }\n };\n self.settings.render = Object.assign({}, templates, self.settings.render);\n }\n /**\n * Maps fired events to callbacks provided\n * in the settings used when creating the control.\n */\n setupCallbacks() {\n var key, fn;\n var callbacks = {\n 'initialize': 'onInitialize',\n 'change': 'onChange',\n 'item_add': 'onItemAdd',\n 'item_remove': 'onItemRemove',\n 'item_select': 'onItemSelect',\n 'clear': 'onClear',\n 'option_add': 'onOptionAdd',\n 'option_remove': 'onOptionRemove',\n 'option_clear': 'onOptionClear',\n 'optgroup_add': 'onOptionGroupAdd',\n 'optgroup_remove': 'onOptionGroupRemove',\n 'optgroup_clear': 'onOptionGroupClear',\n 'dropdown_open': 'onDropdownOpen',\n 'dropdown_close': 'onDropdownClose',\n 'type': 'onType',\n 'load': 'onLoad',\n 'focus': 'onFocus',\n 'blur': 'onBlur'\n };\n for (key in callbacks) {\n fn = this.settings[callbacks[key]];\n if (fn)\n this.on(key, fn);\n }\n }\n /**\n * Sync the Tom Select instance with the original input or select\n *\n */\n sync(get_settings = true) {\n const self = this;\n const settings = get_settings ? getSettings(self.input, { delimiter: self.settings.delimiter }) : self.settings;\n self.setupOptions(settings.options, settings.optgroups);\n self.setValue(settings.items || [], true); // silent prevents recursion\n self.lastQuery = null; // so updated options will be displayed in dropdown\n }\n /**\n * Triggered when the main control element\n * has a click event.\n *\n */\n onClick() {\n var self = this;\n if (self.activeItems.length > 0) {\n self.clearActiveItems();\n self.focus();\n return;\n }\n if (self.isFocused && self.isOpen) {\n self.blur();\n }\n else {\n self.focus();\n }\n }\n /**\n * @deprecated v1.7\n *\n */\n onMouseDown() { }\n /**\n * Triggered when the value of the control has been changed.\n * This should propagate the event to the original DOM\n * input / select element.\n */\n onChange() {\n triggerEvent(this.input, 'input');\n triggerEvent(this.input, 'change');\n }\n /**\n * Triggered on <input> paste.\n *\n */\n onPaste(e) {\n var self = this;\n if (self.isInputHidden || self.isLocked) {\n preventDefault(e);\n return;\n }\n // If a regex or string is included, this will split the pasted\n // input and create Items for each separate value\n if (!self.settings.splitOn) {\n return;\n }
1\n // Wait for pasted text to be recognized in value\n setTimeout(() => {\n var pastedText = self.inputValue();\n if (!pastedText.match(self.settings.splitOn)) {\n return;\n }\n var splitInput = pastedText.trim().split(self.settings.splitOn);\n utils_iterate(splitInput, (piece) => {\n const hash = hash_key(piece);\n if (hash) {\n if (this.options[piece]) {\n self.addItem(piece);\n }\n else {\n self.createItem(piece);\n }\n }\n });\n }, 0);\n }\n /**\n * Triggered on <input> keypress.\n *\n */\n onKeyPress(e) {\n var self = this;\n if (self.isLocked) {\n preventDefault(e);\n return;\n }\n var character = String.fromCharCode(e.keyCode || e.which);\n if (self.settings.create && self.settings.mode === 'multi' && character === self.settings.delimiter) {\n self.createItem();\n preventDefault(e);\n return;\n }\n }\n /**\n * Triggered on <input> keydown.\n *\n */\n onKeyDown(e) {\n var self = this;\n self.ignoreHover = true;\n if (self.isLocked) {\n if (e.keyCode !== KEY_TAB) {\n preventDefault(e);\n }\n return;\n }\n switch (e.keyCode) {\n // ctrl+A: select all\n case KEY_A:\n if (isKeyDown(KEY_SHORTCUT, e)) {\n if (self.control_input.value == '') {\n preventDefault(e);\n self.selectAll();\n return;\n }\n }\n break;\n // esc: close dropdown\n case KEY_ESC:\n if (self.isOpen) {\n preventDefault(e, true);\n self.close();\n }\n self.clearActiveItems();\n return;\n // down: open dropdown or move selection down\n case KEY_DOWN:\n if (!self.isOpen && self.hasOptions) {\n self.open();\n }\n else if (self.activeOption) {\n let next = self.getAdjacent(self.activeOption, 1);\n if (next)\n self.setActiveOption(next);\n }\n preventDefault(e);\n return;\n // up: move selection up\n case KEY_UP:\n if (self.activeOption) {\n let prev = self.getAdjacent(self.activeOption, -1);\n if (prev)\n self.setActiveOption(prev);\n }\n preventDefault(e);\n return;\n // return: select active option\n case KEY_RETURN:\n if (self.canSelect(self.activeOption)) {\n self.onOptionSelect(e, self.activeOption);\n preventDefault(e);\n // if the option_create=null, the dropdown might be closed\n }\n else if (self.settings.create && self.createItem()) {\n preventDefault(e);\n // don't submit form when searching for a value\n }\n else if (document.activeElement == self.control_input && self.isOpen) {\n preventDefault(e);\n }\n return;\n // left: modifiy item selection to the left\n case KEY_LEFT:\n self.advanceSelection(-1, e);\n return;\n // right: modifiy item selection to the right\n case KEY_RIGHT:\n self.advanceSelection(1, e);\n return;\n // tab: select active option and/or create item\n case KEY_TAB:\n if (self.settings.selectOnTab) {\n if (self.canSelect(self.activeOption)) {\n self.onOptionSelect(e, self.activeOption);\n // prevent default [tab] behaviour of jump to the next field\n // if select isFull, then the dropdown won't be open and [tab] will work normally\n preventDefault(e);\n }\n if (self.settings.create && self.createItem()) {\n preventDefault(e);\n }\n }\n return;\n // delete|backspace: delete items\n case KEY_BACKSPACE:\n case KEY_DELETE:\n self.deleteSelection(e);\n return;\n }\n // don't enter text in the control_input when active items are selected\n if (self.isInputHidden && !isKeyDown(KEY_SHORTCUT, e)) {\n preventDefault(e);\n }\n }\n /**\n * Triggered on <input> keyup.\n *\n */\n onInput(e) {\n if (this.isLocked) {\n return;\n }\n const value = this.inputValue();\n if (this.lastValue === value)\n return;\n this.lastValue = value;\n if (value == '') {\n this._onInput();\n return;\n }\n if (this.refreshTimeout) {\n window.clearTimeout(this.refreshTimeout);\n }\n this.refreshTimeout = timeout(() =>
1 {\n this.refreshTimeout = null;\n this._onInput();\n }, this.settings.refreshThrottle);\n }\n _onInput() {\n const value = this.lastValue;\n if (this.settings.shouldLoad.call(this, value)) {\n this.load(value);\n }\n this.refreshOptions();\n this.trigger('type', value);\n }\n /**\n * Triggered when the user rolls over\n * an option in the autocomplete dropdown menu.\n *\n */\n onOptionHover(evt, option) {\n if (this.ignoreHover)\n return;\n this.setActiveOption(option, false);\n }\n /**\n * Triggered on <input> focus.\n *\n */\n onFocus(e) {\n var self = this;\n var wasFocused = self.isFocused;\n if (self.isDisabled || self.isReadOnly) {\n self.blur();\n preventDefault(e);\n return;\n }\n if (self.ignoreFocus)\n return;\n self.isFocused = true;\n if (self.settings.preload === 'focus')\n self.preload();\n if (!wasFocused)\n self.trigger('focus');\n if (!self.activeItems.length) {\n self.inputState();\n self.refreshOptions(!!self.settings.openOnFocus);\n }\n self.refreshState();\n }\n /**\n * Triggered on <input> blur.\n *\n */\n onBlur(e) {\n if (document.hasFocus() === false)\n return;\n var self = this;\n if (!self.isFocused)\n return;\n self.isFocused = false;\n self.ignoreFocus = false;\n var deactivate = () => {\n self.close();\n self.setActiveItem();\n self.setCaret(self.items.length);\n self.trigger('blur');\n };\n if (self.settings.create && self.settings.createOnBlur) {\n self.createItem(null, deactivate);\n }\n else {\n deactivate();\n }\n }\n /**\n * Triggered when the user clicks on an option\n * in the autocomplete dropdown menu.\n *\n */\n onOptionSelect(evt, option) {\n var value, self = this;\n // should not be possible to trigger a option under a disabled optgroup\n if (option.parentElement && option.parentElement.matches('[data-disabled]')) {\n return;\n }\n if (option.classList.contains('create')) {\n self.createItem(null, () => {\n if (self.settings.closeAfterSelect) {\n self.close();\n }\n });\n }\n else {\n value = option.dataset.value;\n if (typeof value !== 'undefined') {\n self.lastQuery = null;\n self.addItem(value);\n if (self.settings.closeAfterSelect) {\n self.close();\n }\n if (!self.settings.hideSelected && evt.type && /click/.test(evt.type)) {\n self.setActiveOption(option);\n }\n }\n }\n }\n /**\n * Return true if the given option can be selected\n *\n */\n canSelect(option) {\n if (this.isOpen && option && this.dropdown_content.contains(option)) {\n return true;\n }\n return false;\n }\n /**\n * Triggered when the user clicks on an item\n * that has been selected.\n *\n */\n onItemSelect(evt, item) {\n var self = this;\n if (!self.isLocked && self.settings.mode === 'multi') {\n preventDefault(evt);\n self.setActiveItem(item, evt);\n return true;\n }\n return false;\n }\n /**\n * Determines whether or not to invoke\n * the user-provided option provider / loader\n *\n * Note, there is a subtle difference between\n * this.canLoad() and this.settings.shouldLoad();\n *\n *\t- settings.shouldLoad() is a user-input validator.\n *\tWhen false is returned, the not_loading template\n *\twill be added to the dropdown\n *\n *\t- canLoad() is lower level validator that checks\n * \tthe Tom Select instance. There is no inherent user\n *\tfeedback when canLoad returns false\n *\n */\n canLoad(value) {\n if (!this.settings.load)\n return false;\n if (this.loadedSearches.hasOwnProperty(value))\n return false;\n return true;\n }
1\n /**\n * Invokes the user-provided option provider / loader.\n *\n */\n load(value) {\n const self = this;\n if (!self.canLoad(value))\n return;\n addClasses(self.wrapper, self.settings.loadingClass);\n self.loading++;\n const callback = self.loadCallback.bind(self);\n self.settings.load.call(self, value, callback);\n }\n /**\n * Invoked by the user-provided option provider\n *\n */\n loadCallback(options, optgroups) {\n const self = this;\n self.loading = Math.max(self.loading - 1, 0);\n self.lastQuery = null;\n self.clearActiveOption(); // when new results load, focus should be on first option\n self.setupOptions(options, optgroups);\n self.refreshOptions(self.isFocused && !self.isInputHidden);\n if (!self.loading) {\n removeClasses(self.wrapper, self.settings.loadingClass);\n }\n self.trigger('load', options, optgroups);\n }\n preload() {\n var classList = this.wrapper.classList;\n if (classList.contains('preloaded'))\n return;\n classList.add('preloaded');\n this.load('');\n }\n /**\n * Sets the input field of the control to the specified value.\n *\n */\n setTextboxValue(value = '') {\n var input = this.control_input;\n var changed = input.value !== value;\n if (changed) {\n input.value = value;\n triggerEvent(input, 'update');\n this.lastValue = value;\n }\n }\n /**\n * Returns the value of the control. If multiple items\n * can be selected (e.g. <select multiple>), this returns\n * an array. If only one item can be selected, this\n * returns a string.\n *\n */\n getValue() {\n if (this.is_select_tag && this.input.hasAttribute('multiple')) {\n return this.items;\n }\n return this.items.join(this.settings.delimiter);\n }\n /**\n * Resets the selected items to the given value.\n *\n */\n setValue(value, silent) {\n var events = silent ? [] : ['change'];\n debounce_events(this, events, () => {\n this.clear(silent);\n this.addItems(value, silent);\n });\n }\n /**\n * Resets the number of max items to the given value\n *\n */\n setMaxItems(value) {\n if (value === 0)\n value = null; //reset to unlimited items.\n this.settings.maxItems = value;\n this.refreshState();\n }\n /**\n * Sets the selected item.\n *\n */\n setActiveItem(item, e) {\n var self = this;\n var eventName;\n var i, begin, end, swap;\n var last;\n if (self.settings.mode === 'single')\n return;\n // clear the active selection\n if (!item) {\n self.clearActiveItems();\n if (self.isFocused) {\n self.inputState();\n }\n return;\n }\n // modify selection\n eventName = e && e.type.toLowerCase();\n if (eventName === 'click' && isKeyDown('shiftKey', e) && self.activeItems.length) {\n last = self.getLastActive();\n begin = Array.prototype.indexOf.call(self.control.children, last);\n end = Array.prototype.indexOf.call(self.control.children, item);\n if (begin > end) {\n swap = begin;\n begin = end;\n end = swap;\n }\n for (i = begin; i <= end; i++) {\n item = self.control.children[i];\n if (self.activeItems.indexOf(item) === -1) {\n self.setActiveItemClass(item);\n }\n }\n preventDefault(e);\n }\n else if ((eventName === 'click' && isKeyDown(KEY_SHORTCUT, e)) || (eventName === 'keydown' && isKeyDown('shiftKey', e))) {\n if (item.classList.contains('active')) {\n self.removeActiveItem(item);\n }
1\n else {\n self.setActiveItemClass(item);\n }\n }\n else {\n self.clearActiveItems();\n self.setActiveItemClass(item);\n }\n // ensure control has focus\n self.inputState();\n if (!self.isFocused) {\n self.focus();\n }\n }\n /**\n * Set the active and last-active classes\n *\n */\n setActiveItemClass(item) {\n const self = this;\n const last_active = self.control.querySelector('.last-active');\n if (last_active)\n removeClasses(last_active, 'last-active');\n addClasses(item, 'active last-active');\n self.trigger('item_select', item);\n if (self.activeItems.indexOf(item) == -1) {\n self.activeItems.push(item);\n }\n }\n /**\n * Remove active item\n *\n */\n removeActiveItem(item) {\n var idx = this.activeItems.indexOf(item);\n this.activeItems.splice(idx, 1);\n removeClasses(item, 'active');\n }\n /**\n * Clears all the active items\n *\n */\n clearActiveItems() {\n removeClasses(this.activeItems, 'active');\n this.activeItems = [];\n }\n /**\n * Sets the selected item in the dropdown menu\n * of available options.\n *\n */\n setActiveOption(option, scroll = true) {\n if (option === this.activeOption) {\n return;\n }\n this.clearActiveOption();\n if (!option)\n return;\n this.activeOption = option;\n setAttr(this.focus_node, { 'aria-activedescendant': option.getAttribute('id') });\n setAttr(option, { 'aria-selected': 'true' });\n addClasses(option, 'active');\n if (scroll)\n this.scrollToOption(option);\n }\n /**\n * Sets the dropdown_content scrollTop to display the option\n *\n */\n scrollToOption(option, behavior) {\n if (!option)\n return;\n const content = this.dropdown_content;\n const height_menu = content.clientHeight;\n const scrollTop = content.scrollTop || 0;\n const height_item = option.offsetHeight;\n const y = option.getBoundingClientRect().top - content.getBoundingClientRect().top + scrollTop;\n if (y + height_item > height_menu + scrollTop) {\n this.scroll(y - height_menu + height_item, behavior);\n }\n else if (y < scrollTop) {\n this.scroll(y, behavior);\n }\n }\n /**\n * Scroll the dropdown to the given position\n *\n */\n scroll(scrollTop, behavior) {\n const content = this.dropdown_content;\n if (behavior) {\n content.style.scrollBehavior = behavior;\n }\n content.scrollTop = scrollTop;\n content.style.scrollBehavior = '';\n }\n /**\n * Clears the active option\n *\n */\n clearActiveOption() {\n if (this.activeOption) {\n removeClasses(this.activeOption, 'active');\n setAttr(this.activeOption, { 'aria-selected': null });\n }\n this.activeOption = null;\n setAttr(this.focus_node, { 'aria-activedescendant': null });\n }\n /**\n * Selects all items (CTRL + A).\n */\n selectAll() {\n const self = this;\n if (self.settings.mode === 'single')\n return;\n const activeItems = self.controlChildren();\n if (!activeItems.length)\n return;\n self.inputState();\n self.close();\n self.activeItems = activeItems;\n utils_iterate(activeItems, (item) => {\n self.setActiveItemClass(item);\n });\n }\n /**\n * Determines if the control_input should be in a hidden or visible state\n *\n */\n inputState() {\n var self = this;\n if (!self.control.contains(self.control_input))\n return;\n setAttr(self.control_input, { placeholder: self.settings.placeholder });\n if (self.activeItems.length > 0 || (!self.isFocused && self.settings.hidePlaceholder && self.items.length > 0)) {\n self.setTextboxValue();\n self.isInputHidden = true;\n }\n else {\n if (self.settings.hidePlaceholder && self.items.length > 0) {\n setAttr(self.control_input, { placeholder: '' });\n }\n self.isInputHidden = false;\n }\n self.wrapper.classList.toggle('input-hidden', self.isInputHidden);\n }\n /**\n * Get the input value\n */\n inputValue() {\n return this.control_input.value.trim();\n }\n /**\n * Gives the control focus.\n */\n focus() {\n var self = this;\n if (self.isDisabled || self.isReadOnly)\n return;\n self.ignoreFocus = true;\n if (self.control_input.offsetWidth) {\n self.control_input.focus();\n }\n else {\n self.focus_node.focus();\n }\n setTimeout(() =>
1 {\n self.ignoreFocus = false;\n self.onFocus();\n }, 0);\n }\n /**\n * Forces the control out of focus.\n *\n */\n blur() {\n this.focus_node.blur();\n this.onBlur();\n }\n /**\n * Returns a function that scores an object\n * to show how good of a match it is to the\n * provided query.\n *\n * @return {function}\n */\n getScoreFunction(query) {\n return this.sifter.getScoreFunction(query, this.getSearchOptions());\n }\n /**\n * Returns search options for sifter (the system\n * for scoring and sorting results).\n *\n * @see https://github.com/orchidjs/sifter.js\n * @return {object}\n */\n getSearchOptions() {\n var settings = this.settings;\n var sort = settings.sortField;\n if (typeof settings.sortField === 'string') {\n sort = [{ field: settings.sortField }];\n }\n return {\n fields: settings.searchField,\n conjunction: settings.searchConjunction,\n sort: sort,\n nesting: settings.nesting\n };\n }\n /**\n * Searches through available options and returns\n * a sorted array of matches.\n *\n */\n search(query) {\n var result, calculateScore;\n var self = this;\n var options = this.getSearchOptions();\n // validate user-provided result scoring function\n if (self.settings.score) {\n calculateScore = self.settings.score.call(self, query);\n if (typeof calculateScore !== 'function') {\n throw new Error('Tom Select \"score\" setting must be a function that returns a function');\n }\n }\n // perform search\n if (query !== self.lastQuery) {\n self.lastQuery = query;\n result = self.sifter.search(query, Object.assign(options, { score: calculateScore }));\n self.currentResults = result;\n }\n else {\n result = Object.assign({}, self.currentResults);\n }\n // filter out selected items\n if (self.settings.hideSelected) {\n result.items = result.items.filter((item) => {\n let hashed = hash_key(item.id);\n return !(hashed && self.items.indexOf(hashed) !== -1);\n });\n }\n return result;\n }\n /**\n * Refreshes the list of available options shown\n * in the autocomplete dropdown menu.\n *\n */\n refreshOptions(triggerDropdown = true) {\n var i, j, k, n, optgroup, optgroups, html, has_create_option, active_group;\n var create;\n const groups = {};\n const groups_order = [];\n var self = this;\n var query = self.inputValue();\n const same_query = query === self.lastQuery || (query == '' && self.lastQuery == null);\n var results = self.search(query);\n var active_option = null;\n var show_dropdown = self.settings.shouldOpen || false;\n var dropdown_content = self.dropdown_content;\n if (same_query) {\n active_option = self.activeOption;\n if (active_option) {\n active_group = active_option.closest('[data-group]');\n }\n }\n // build markup\n n = results.items.length;\n if (typeof self.settings.maxOptions === 'number') {\n n = Math.min(n, self.settings.maxOptions);\n }\n if (n > 0) {\n show_dropdown = true;\n }\n // get fragment for group and the position of the group in group_order\n const getGroupFragment = (optgroup, order) => {\n let group_order_i = groups[optgroup];\n if (group_order_i !== undefined) {\n let order_group = groups_order[group_order_i];\n if (order_group !== undefined) {\n return [group_order_i, order_group.fragment];\n }\n }\n let group_fragment = document.createDocumentFragment();\n group_order_i = groups_order.length;\n groups_order.push({ fragment: group_fragment, order, optgroup });\n return [group_order_i, group_fragment];\n };\n // render and group available options individually\n for (i = 0; i < n;
1 i++) {\n // get option dom element\n let item = results.items[i];\n if (!item)\n continue;\n let opt_value = item.id;\n let option = self.options[opt_value];\n if (option === undefined)\n continue;\n let opt_hash = get_hash(opt_value);\n let option_el = self.getOption(opt_hash, true);\n // toggle 'selected' class\n if (!self.settings.hideSelected) {\n option_el.classList.toggle('selected', self.items.includes(opt_hash));\n }\n optgroup = option[self.settings.optgroupField] || '';\n optgroups = Array.isArray(optgroup) ? optgroup : [optgroup];\n for (j = 0, k = optgroups && optgroups.length; j < k; j++) {\n optgroup = optgroups[j];\n let order = option.$order;\n let self_optgroup = self.optgroups[optgroup];\n if (self_optgroup === undefined) {\n optgroup = '';\n }\n else {\n order = self_optgroup.$order;\n }\n const [group_order_i, group_fragment] = getGroupFragment(optgroup, order);\n // nodes can only have one parent, so if the option is in mutple groups, we need a clone\n if (j > 0) {\n option_el = option_el.cloneNode(true);\n setAttr(option_el, { id: option.$id + '-clone-' + j, 'aria-selected': null });\n option_el.classList.add('ts-cloned');\n removeClasses(option_el, 'active');\n // make sure we keep the activeOption in the same group\n if (self.activeOption && self.activeOption.dataset.value == opt_value) {\n if (active_group && active_group.dataset.group === optgroup.toString()) {\n active_option = option_el;\n }\n }\n }\n group_fragment.appendChild(option_el);\n if (optgroup != '') {\n groups[optgroup] = group_order_i;\n }\n }\n }\n // sort optgroups\n if (self.settings.lockOptgroupOrder) {\n groups_order.sort((a, b) => {\n return a.order - b.order;\n });\n }\n // render optgroup headers & join groups\n html = document.createDocumentFragment();\n utils_iterate(groups_order, (group_order) => {\n let group_fragment = group_order.fragment;\n let optgroup = group_order.optgroup;\n if (!group_fragment || !group_fragment.children.length)\n return;\n let group_heading = self.optgroups[optgroup];\n if (group_heading !== undefined) {\n let group_options = document.createDocumentFragment();\n let header = self.render('optgroup_header', group_heading);\n append(group_options, header);\n append(group_options, group_fragment);\n let group_html = self.render('optgroup', { group: group_heading, options: group_options });\n append(html, group_html);\n }\n else {\n append(html, group_fragment);\n }\n });\n dropdown_content.innerHTML = '';\n append(dropdown_content, html);\n // highlight matching terms inline\n if (self.settings.highlight) {\n removeHighlight(dropdown_content);\n if (results.query.length && results.tokens.length) {\n utils_iterate(results.tokens, (tok) => {\n highlight(dropdown_content, tok.regex);\n });\n }\n }\n // helper method for adding templates to dropdown\n var add_template = (template) => {\n let content = self.render(template, { input: query });\n if (content) {\n show_dropdown = true;\n dropdown_content.insertBefore(content, dropdown_content.firstChild);\n }\n return content;\n };\n // add loading message\n if (self.loading) {\n add_template('loading');\n // invalid query\n }\n else if (!self.settings.shouldLoad.call(self, query)) {\n add_template('not_loading');\n // add no_results message\n }\n else if (results.items.length === 0) {\n add_template('no_results');\n }\n // add create option\n has_create_option = self.canCreate(query);\n if (has_create_option) {\n create = add_template('option_create');\n }\n // activate\n self.hasOptions = results.items.length > 0 || has_create_option;\n if (show_dropdown) {\n if (results.items.length > 0) {\n if (!active_option && self.settings.mode === 'single' && self.items[0] != undefined) {\n active_option = self.getOption(self.items[0]);\n }\n if (!dropdown_content.contains(active_option)) {\n let active_index = 0;\n if (create && !self.settings.addPrecedence) {\n active_index = 1;\n }\n active_option = self.selectable()[active_index];\n }\n }\n else if (create) {\n active_option = create;\n }\n if (triggerDropdown && !self.isOpen) {\n self.open();\n self.scrollToOption(active_option, 'auto');\n }\n self.setActiveOption(active_option);\n }\n else {\n self.clearActiveOption();\n if (triggerDropdown && self.isOpen) {\n self.close(false); // if create_option=null, we want the dropdown to close but not reset the textbox value\n }\n }\n }\n /**\n * Return list of selectable options\n *\n */\n selectable() {\n return this.dropdown_content.querySelectorAll('[data-selectable]');\n }\n /**\n * Adds an available option. If it already exists,\n * nothing will happen. Note: this does not refresh\n * the options list dropdown (use `refreshOptions`\n * for that).\n *\n * Usage:\n *\n * this.addOption(data)\n *\n */\n addOption(data, user_created = false) {\n const self = this;\n // @deprecated 1.7.7\n // use addOptions( array, user_created ) for adding multiple options\n if (Array.isArray(data)) {\n self.addOptions(data, user_created);\n return false;\n }
1\n const key = hash_key(data[self.settings.valueField]);\n if (key === null || self.options.hasOwnProperty(key)) {\n return false;\n }\n data.$order = data.$order || ++self.order;\n data.$id = self.inputId + '-opt-' + data.$order;\n self.options[key] = data;\n self.lastQuery = null;\n if (user_created) {\n self.userOptions[key] = user_created;\n self.trigger('option_add', key, data);\n }\n return key;\n }\n /**\n * Add multiple options\n *\n */\n addOptions(data, user_created = false) {\n utils_iterate(data, (dat) => {\n this.addOption(dat, user_created);\n });\n }\n /**\n * @deprecated 1.7.7\n */\n registerOption(data) {\n return this.addOption(data);\n }\n /**\n * Registers an option group to the pool of option groups.\n *\n * @return {boolean|string}\n */\n registerOptionGroup(data) {\n var key = hash_key(data[this.settings.optgroupValueField]);\n if (key === null)\n return false;\n data.$order = data.$order || ++this.order;\n this.optgroups[key] = data;\n return key;\n }\n /**\n * Registers a new optgroup for options\n * to be bucketed into.\n *\n */\n addOptionGroup(id, data) {\n var hashed_id;\n data[this.settings.optgroupValueField] = id;\n if (hashed_id = this.registerOptionGroup(data)) {\n this.trigger('optgroup_add', hashed_id, data);\n }\n }\n /**\n * Removes an existing option group.\n *\n */\n removeOptionGroup(id) {\n if (this.optgroups.hasOwnProperty(id)) {\n delete this.optgroups[id];\n this.clearCache();\n this.trigger('optgroup_remove', id);\n }\n }\n /**\n * Clears all existing option groups.\n */\n clearOptionGroups() {\n this.optgroups = {};\n this.clearCache();\n this.trigger('optgroup_clear');\n }\n /**\n * Updates an option available for selection. If\n * it is visible in the selected items or options\n * dropdown, it will be re-rendered automatically.\n *\n */\n updateOption(value, data) {\n const self = this;\n var item_new;\n var index_item;\n const value_old = hash_key(value);\n const value_new = hash_key(data[self.settings.valueField]);\n // sanity checks\n if (value_old === null)\n return;\n const data_old = self.options[value_old];\n if (data_old == undefined)\n return;\n if (typeof value_new !== 'string')\n throw new Error('Value must be set in option data');\n const option = self.getOption(value_old);\n const item = self.getItem(value_old);\n data.$order = data.$order || data_old.$order;\n delete self.options[value_old];\n // invalidate render cache\n // don't remove existing node yet, we'll remove it after replacing it\n self.uncacheValue(value_new);\n self.options[value_new] = data;\n // update the option if it's in the dropdown\n if (option) {\n if (self.dropdown_content.contains(option)) {\n const option_new = self._render('option', data);\n replaceNode(option, option_new);\n if (self.activeOption === option) {\n self.setActiveOption(option_new);\n }\n }\n option.remove();\n }\n // update the item if we have one\n if (item) {\n index_item = self.items.indexOf(value_old);\n if (index_item !== -1) {\n self.items.splice(index_item, 1, value_new);\n }\n item_new = self._render('item', data);\n if (item.classList.contains('active'))\n addClasses(item_new, 'active');\n replaceNode(item, item_new);\n }\n // invalidate last query because we might have updated the sortField\n self.lastQuery = null;\n }\n /**\n * Removes a single option.\n *\n */\n removeOption(value, silent) {\n const self = this;\n value = get_hash(value);\n self.uncacheValue(value);\n delete self.userOptions[value];\n delete self.options[value];\n self.lastQuery = null;\n self.trigger('option_remove', value);\n self.removeItem(value, silent);\n }\n /**\n * Clears all options.\n */\n clearOptions(filter) {\n const boundFilter = (filter || this.clearFilter).bind(this);\n this.loadedSearches = {};\n this.userOptions = {};\n this.clearCache();\n const selected = {};\n utils_iterate(this.options, (option, key) => {\n if (boundFilter(option, key)) {\n selected[key] = option;\n }\n });\n this.options = this.sifter.items = selected;\n this.lastQuery = null;\n this.trigger('option_clear');\n }\n /**\n * Used by clearOptions() to decide whether or not an option should be removed\n * Return true to keep an option, false to remove\n *\n */\n clearFilter(option, value) {\n if (this.items.indexOf(value) >= 0) {\n return true;\n }\n return false;\n }\n /**\n * Returns the dom element of the option\n * matching the given value.\n *\n */\n getOption(value, create = false) {\n const hashed = hash_key(value);\n if (hashed === null)\n return null;\n const option = this.options[hashed];\n if (option != undefined) {\n if (option.$div) {\n return option.$div;\n }\n if (create) {\n return this._render('option', option);\n }\n }\n return null;\n }\n /**\n * Returns the dom element of the next or previous dom element of the same type\n * Note: adjacent options may not be adjacent DOM elements (optgroups)\n *\n */\n getAdjacent(option, direction, type = 'option') {\n var self = this, all;\n if (!option) {\n return null;\n }\n if (type == 'item') {\n all = self.controlChildren();\n }\n else {\n all = self.dropdown_content.querySelectorAll('[data-selectable]');\n }\n for (let i = 0; i < all.length;
1 i++) {\n if (all[i] != option) {\n continue;\n }\n if (direction > 0) {\n return all[i + 1];\n }\n return all[i - 1];\n }\n return null;\n }\n /**\n * Returns the dom element of the item\n * matching the given value.\n *\n */\n getItem(item) {\n if (typeof item == 'object') {\n return item;\n }\n var value = hash_key(item);\n return value !== null\n ? this.control.querySelector(`[data-value=\"${addSlashes(value)}\"]`)\n : null;\n }\n /**\n * \"Selects\" multiple items at once. Adds them to the list\n * at the current caret position.\n *\n */\n addItems(values, silent) {\n var self = this;\n var items = Array.isArray(values) ? values : [values];\n items = items.filter(x => self.items.indexOf(x) === -1);\n const last_item = items[items.length - 1];\n items.forEach(item => {\n self.isPending = (item !== last_item);\n self.addItem(item, silent);\n });\n }\n /**\n * \"Selects\" an item. Adds it to the list\n * at the current caret position.\n *\n */\n addItem(value, silent) {\n var events = silent ? [] : ['change', 'dropdown_close'];\n debounce_events(this, events, () => {\n var item, wasFull;\n const self = this;\n const inputMode = self.settings.mode;\n const hashed = hash_key(value);\n if (hashed && self.items.indexOf(hashed) !== -1) {\n if (inputMode === 'single') {\n self.close();\n }\n if (inputMode === 'single' || !self.settings.duplicates) {\n return;\n }\n }\n if (hashed === null || !self.options.hasOwnProperty(hashed))\n return;\n if (inputMode === 'single')\n self.clear(silent);\n if (inputMode === 'multi' && self.isFull())\n return;\n item = self._render('item', self.options[hashed]);\n if (self.control.contains(item)) { // duplicates\n item = item.cloneNode(true);\n }\n wasFull = self.isFull();\n self.items.splice(self.caretPos, 0, hashed);\n self.insertAtCaret(item);\n if (self.isSetup) {\n // update menu / remove the option (if this is not one item being added as part of series)\n if (!self.isPending && self.settings.hideSelected) {\n let option = self.getOption(hashed);\n let next = self.getAdjacent(option, 1);\n if (next) {\n self.setActiveOption(next);\n }\n }\n // refreshOptions after setActiveOption(),\n // otherwise setActiveOption() will be called by refreshOptions() with the wrong value\n if (!self.isPending && !self.settings.closeAfterSelect) {\n self.refreshOptions(self.isFocused && inputMode !== 'single');\n }\n // hide the menu if the maximum number of items have been selected or no options are left\n if (self.settings.closeAfterSelect != false && self.isFull()) {\n self.close();\n }\n else if (!self.isPending) {\n self.positionDropdown();\n }\n self.trigger('item_add', hashed, item);\n if (!self.isPending) {\n self.updateOriginalInput({ silent: silent });\n }\n }\n if (!self.isPending || (!wasFull && self.isFull())) {\n self.inputState();\n self.refreshState();\n }\n });\n }\n /**\n * Removes the selected item matching\n * the provided value.\n *\n */\n removeItem(item = null, silent) {\n const self = this;\n item = self.getItem(item);\n if (!item)\n return;\n var i, idx;\n const value = item.dataset.value;\n i = nodeIndex(item);\n item.remove();\n if (item.classList.contains('active')) {\n idx = self.activeItems.indexOf(item);\n self.activeItems.splice(idx, 1);\n removeClasses(item, 'active');\n }\n self.items.splice(i, 1);\n self.lastQuery = null;\n if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {\n self.removeOption(value, silent);\n }\n if (i < self.caretPos) {\n self.setCaret(self.caretPos - 1);\n }\n self.updateOriginalInput({ silent: silent });\n self.refreshState();\n self.positionDropdown();\n self.trigger('item_remove', value, item);\n }\n /**\n * Invokes the `create` method provided in the\n * TomSelect options that should provide the data\n * for the new item, given the user input.\n *\n * Once this completes, it will be added\n * to the item list.\n *\n */\n createItem(input = null, callback = () => { }) {\n // triggerDropdown parameter @deprecated 2.1.1\n if (arguments.length === 3) {\n callback = arguments[2];\n }\n if (typeof callback != 'function') {\n callback = () => { };\n }\n var self = this;\n var caret = self.caretPos;\n var output;\n input = input || self.inputValue();\n if (!self.canCreate(input)) {\n callback();\n return false;\n }\n self.lock();\n var created = false;\n var create = (data) =>
1 {\n self.unlock();\n if (!data || typeof data !== 'object')\n return callback();\n var value = hash_key(data[self.settings.valueField]);\n if (typeof value !== 'string') {\n return callback();\n }\n self.setTextboxValue();\n self.addOption(data, true);\n self.setCaret(caret);\n self.addItem(value);\n callback(data);\n created = true;\n };\n if (typeof self.settings.create === 'function') {\n output = self.settings.create.call(this, input, create);\n }\n else {\n output = {\n [self.settings.labelField]: input,\n [self.settings.valueField]: input,\n };\n }\n if (!created) {\n create(output);\n }\n return true;\n }\n /**\n * Re-renders the selected item lists.\n */\n refreshItems() {\n var self = this;\n self.lastQuery = null;\n if (self.isSetup) {\n self.addItems(self.items);\n }\n self.updateOriginalInput();\n self.refreshState();\n }\n /**\n * Updates all state-dependent attributes\n * and CSS classes.\n */\n refreshState() {\n const self = this;\n self.refreshValidityState();\n const isFull = self.isFull();\n const isLocked = self.isLocked;\n self.wrapper.classList.toggle('rtl', self.rtl);\n const wrap_classList = self.wrapper.classList;\n wrap_classList.toggle('focus', self.isFocused);\n wrap_classList.toggle('disabled', self.isDisabled);\n wrap_classList.toggle('readonly', self.isReadOnly);\n wrap_classList.toggle('required', self.isRequired);\n wrap_classList.toggle('invalid', !self.isValid);\n wrap_classList.toggle('locked', isLocked);\n wrap_classList.toggle('full', isFull);\n wrap_classList.toggle('input-active', self.isFocused && !self.isInputHidden);\n wrap_classList.toggle('dropdown-active', self.isOpen);\n wrap_classList.toggle('has-options', isEmptyObject(self.options));\n wrap_classList.toggle('has-items', self.items.length > 0);\n }\n /**\n * Update the `required` attribute of both input and control input.\n *\n * The `required` property needs to be activated on the control input\n * for the error to be displayed at the right place. `required` also\n * needs to be temporarily deactivated on the input since the input is\n * hidden and can't show errors.\n */\n refreshValidityState() {\n var self = this;\n if (!self.input.validity) {\n return;\n }\n self.isValid = self.input.validity.valid;\n self.isInvalid = !self.isValid;\n }\n /**\n * Determines whether or not more items can be added\n * to the control without exceeding the user-defined maximum.\n *\n * @returns {boolean}\n */\n isFull() {\n return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;\n }\n /**\n * Refreshes the original <select> or <input>\n * element to reflect the current state.\n *\n */\n updateOriginalInput(opts = {}) {\n const self = this;\n var option, label;\n const empty_option = self.input.querySelector('option[value=\"\"]');\n if (self.is_select_tag) {\n const selected = [];\n const has_selected = self.input.querySelectorAll('option:checked').length;\n function AddSelected(option_el, value, label) {\n if (!option_el) {\n option_el = getDom('<option value=\"' + escape_html(value) + '\">' + escape_html(label) + '</option>');\n }\n // don't move empty option from top of list\n // fixes bug in firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1725293\n if (option_el != empty_option) {\n self.input.append(option_el);\n }\n selected.push(option_el);\n // marking empty option as selected can break validation\n // fixes https://github.com/orchidjs/tom-select/issues/303\n if (option_el != empty_option || has_selected > 0) {\n option_el.selected = true;\n }\n return option_el;\n }\n // unselect all selected options\n self.input.querySelectorAll('option:checked').forEach((option_el) => {\n option_el.selected = false;\n });\n // nothing selected?\n if (self.items.length == 0 && self.settings.mode == 'single') {\n AddSelected(empty_option, \"\", \"\");\n // order selected <option> tags for values in self.items\n }
1\n else {\n self.items.forEach((value) => {\n option = self.options[value];\n label = option[self.settings.labelField] || '';\n if (selected.includes(option.$option)) {\n const reuse_opt = self.input.querySelector(`option[value=\"${addSlashes(value)}\"]:not(:checked)`);\n AddSelected(reuse_opt, value, label);\n }\n else {\n option.$option = AddSelected(option.$option, value, label);\n }\n });\n }\n }\n else {\n self.input.value = self.getValue();\n }\n if (self.isSetup) {\n if (!opts.silent) {\n self.trigger('change', self.getValue());\n }\n }\n }\n /**\n * Shows the autocomplete dropdown containing\n * the available options.\n */\n open() {\n var self = this;\n if (self.isLocked || self.isOpen || (self.settings.mode === 'multi' && self.isFull()))\n return;\n self.isOpen = true;\n setAttr(self.focus_node, { 'aria-expanded': 'true' });\n self.refreshState();\n applyCSS(self.dropdown, { visibility: 'hidden', display: 'block' });\n self.positionDropdown();\n applyCSS(self.dropdown, { visibility: 'visible', display: 'block' });\n self.focus();\n self.trigger('dropdown_open', self.dropdown);\n }\n /**\n * Closes the autocomplete dropdown menu.\n */\n close(setTextboxValue = true) {\n var self = this;\n var trigger = self.isOpen;\n if (setTextboxValue) {\n // before blur() to prevent form onchange event\n self.setTextboxValue();\n if (self.settings.mode === 'single' && self.items.length) {\n self.inputState();\n }\n }\n self.isOpen = false;\n setAttr(self.focus_node, { 'aria-expanded': 'false' });\n applyCSS(self.dropdown, { display: 'none' });\n if (self.settings.hideSelected) {\n self.clearActiveOption();\n }\n self.refreshState();\n if (trigger)\n self.trigger('dropdown_close', self.dropdown);\n }\n /**\n * Calculates and applies the appropriate\n * position of the dropdown if dropdownParent = 'body'.\n * Otherwise, position is determined by css\n */\n positionDropdown() {\n if (this.settings.dropdownParent !== 'body') {\n return;\n }\n var context = this.control;\n var rect = context.getBoundingClientRect();\n var top = context.offsetHeight + rect.top + window.scrollY;\n var left = rect.left + window.scrollX;\n applyCSS(this.dropdown, {\n width: rect.width + 'px',\n top: top + 'px',\n left: left + 'px'\n });\n }\n /**\n * Resets / clears all selected items\n * from the control.\n *\n */\n clear(silent) {\n var self = this;\n if (!self.items.length)\n return;\n var items = self.controlChildren();\n utils_iterate(items, (item) => {\n self.removeItem(item, true);\n });\n self.inputState();\n if (!silent)\n self.updateOriginalInput();\n self.trigger('clear');\n }\n /**\n * A helper method for inserting an element\n * at the current caret position.\n *\n */\n insertAtCaret(el) {\n const self = this;\n const caret = self.caretPos;\n const target = self.control;\n target.insertBefore(el, target.children[caret] || null);\n self.setCaret(caret + 1);\n }\n /**\n * Removes the current selected item(s).\n *\n */\n deleteSelection(e) {\n var direction, selection, caret, tail;\n var self = this;\n direction = (e && e.keyCode === KEY_BACKSPACE) ? -1 : 1;\n selection = getSelection(self.control_input);\n // determine items that will be removed\n const rm_items = [];\n if (self.activeItems.length) {\n tail = getTail(self.activeItems, direction);\n caret = nodeIndex(tail);\n if (direction > 0) {\n caret++;\n }\n utils_iterate(self.activeItems, (item) => rm_items.push(item));\n }\n else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {\n const items = self.controlChildren();\n let rm_item;\n if (direction < 0 && selection.start === 0 && selection.length === 0) {\n rm_item = items[self.caretPos - 1];\n }\n else if (direction > 0 && selection.start === self.inputValue().length) {\n rm_item = items[self.caretPos];\n }\n if (rm_item !== undefined) {\n rm_items.push(rm_item);\n }\n }\n if (!self.shouldDelete(rm_items, e)) {\n return false;\n }\n preventDefault(e, true);\n // perform removal\n if (typeof caret !== 'undefined') {\n self.setCaret(caret);\n }\n while (rm_items.length) {\n self.removeItem(rm_items.pop());\n }\n self.inputState();\n self.positionDropdown();\n self.refreshOptions(false);\n return true;\n }\n /**\n * Return true if the items should be deleted\n */\n shouldDelete(items, evt) {\n const values = items.map(item => item.dataset.value);\n // allow the callback to abort\n if (!values.length || (typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false)) {\n return false;\n }\n return true;\n }\n /**\n * Selects the previous / next item (depending on the `direction` argument).\n *\n * > 0 - right\n * < 0 - left\n *\n */\n advanceSelection(direction, e) {\n var last_active, adjacent, self = this;\n if (self.rtl)\n direction *= -1;\n if (self.inputValue().length)\n return;\n // add or remove to active items\n if (isKeyDown(KEY_SHORTCUT, e) || isKeyDown('shift
1Key', e)) {\n last_active = self.getLastActive(direction);\n if (last_active) {\n if (!last_active.classList.contains('active')) {\n adjacent = last_active;\n }\n else {\n adjacent = self.getAdjacent(last_active, direction, 'item');\n }\n // if no active item, get items adjacent to the control input\n }\n else if (direction > 0) {\n adjacent = self.control_input.nextElementSibling;\n }\n else {\n adjacent = self.control_input.previousElementSibling;\n }\n if (adjacent) {\n if (adjacent.classList.contains('active')) {\n self.removeActiveItem(last_active);\n }\n self.setActiveItemClass(adjacent); // mark as last_active !! after removeActiveItem() on last_active\n }\n // move caret to the left or right\n }\n else {\n self.moveCaret(direction);\n }\n }\n moveCaret(direction) { }\n /**\n * Get the last active item\n *\n */\n getLastActive(direction) {\n let last_active = this.control.querySelector('.last-active');\n if (last_active) {\n return last_active;\n }\n var result = this.control.querySelectorAll('.active');\n if (result) {\n return getTail(result, direction);\n }\n }\n /**\n * Moves the caret to the specified index.\n *\n * The input must be moved by leaving it in place and moving the\n * siblings, due to the fact that focus cannot be restored once lost\n * on mobile webkit devices\n *\n */\n setCaret(new_pos) {\n this.caretPos = this.items.length;\n }\n /**\n * Return list of item dom elements\n *\n */\n controlChildren() {\n return Array.from(this.control.querySelectorAll('[data-ts-item]'));\n }\n /**\n * Disables user input on the control. Used while\n * items are being asynchronously created.\n */\n lock() {\n this.setLocked(true);\n }\n /**\n * Re-enables user input on the control.\n */\n unlock() {\n this.setLocked(false);\n }\n /**\n * Disable or enable user input on the control\n */\n set
1Locked(lock = this.isReadOnly || this.isDisabled) {\n this.isLocked = lock;\n this.refreshState();\n }\n /**\n * Disables user input on the control completely.\n * While disabled, it cannot receive focus.\n */\n disable() {\n this.setDisabled(true);\n this.close();\n }\n /**\n * Enables the control so that it can respond\n * to focus and user input.\n */\n enable() {\n this.setDisabled(false);\n }\n setDisabled(disabled) {\n this.focus_node.tabIndex = disabled ? -1 : this.tabIndex;\n this.isDisabled = disabled;\n this.input.disabled = disabled;\n this.control_input.disabled = disabled;\n this.setLocked();\n }\n setReadOnly(isReadOnly) {\n this.isReadOnly = isReadOnly;\n this.input.readOnly = isReadOnly;\n this.control_input.readOnly = isReadOnly;\n this.setLocked();\n }\n /**\n * Completely destroys the control and\n * unbinds all event listeners so that it can\n * be garbage collected.\n */\n destroy() {\n var self = this;\n var revertSettings = self.revertSettings;\n self.trigger('destroy');\n self.off();\n self.wrapper.remove();\n self.dropdown.remove();\n self.input.innerHTML = revertSettings.innerHTML;\n self.input.tabIndex = revertSettings.tabIndex;\n removeClasses(self.input, 'tomselected', 'ts-hidden-accessible');\n self._destroy();\n delete self.input.tomselect;\n }\n /**\n * A helper method for rendering \"item\" and\n * \"option\" templates, given the data.\n *\n */\n render(templateName, data) {\n var id, html;\n const self = this;\n if (typeof this.settings.render[templateName] !== 'function') {\n return null;\n }\n // render markup\n html = self.settings.render[templateName].call(this, data, escape_html);\n if (!html) {\n return null;\n }\n html = getDom(html);\n // add mandatory attributes\n if (templateName === 'option' || templateName === 'option_create') {\n if (data[self.settings.disabledField]) {\n setAttr(html, { 'aria-disabled': 'true' });\n }\n else {\n setAttr(html, { 'data-selectable': '' });\n }\n }\n else if (templateName === 'optgroup') {\n id = data.group[self.settings.optgroupValueField];\n setAttr(html, { 'data-group': id });\n if (data.group[self.settings.disabledField]) {\n setAttr(html, { 'data-disabled': '' });\n }\n }\n if (templateName === 'option' || templateName === 'item') {\n const value = get_hash(data[self.settings.valueField]);\n setAttr(html, { 'data-value': value });\n // make sure we have some classes if a template is overwritten\n if (templateName === 'item') {\n addClasses(html, self.settings.itemClass);\n setAttr(html, { 'data-ts-item': '' });\n }\n else {\n addClasses(html, self.settings.optionClass);\n setAttr(html, {\n role: 'option',\n id: data.$id\n });\n // update cache\n data.$div = html;\n self.options[value] = data;\n }\n }\n return html;\n }\n /**\n * Type guarded rendering\n *\n */\n _render(templateName, data) {\n const html = this.render(templateName, data);\n if (html == null) {\n throw 'HTMLElement expected';\n }\n return html;\n }\n /**\n * Clears the render cache for a template. If\n * no template is given, clears all render\n * caches.\n *\n */\n clearCache() {\n utils_iterate(this.options, (option) => {\n if (option.$div) {\n option.$div.remove();\n delete option.$div;\n }\n });\n }\n /**\n * Removes a value from item and option caches\n *\n */\n uncacheValue(value) {\n const option_el = this.getOption(value);\n if (option_el)\n option_el.remove();\n }\n /**\n * Determines whether or not to display the\n * create item prompt, given a user input.\n *\n */\n canCreate(input) {\n return this.settings.create && (input.length > 0) && this.settings.createFilter.call(this, input);\n }\n /**\n * Wraps this.`method` so that `new_fn` can be invoked 'before', 'after', or 'instead' of the original method\n *\n * this.hook('instead','onKeyDown',function( arg1, arg2 ...){\n *\n * });\n */\n hook(when, method, new_fn) {\n var self = this;\n var orig_method = self[method];\n self[method] = function () {\n var result, result_new;\n if (when === 'after') {\n result = orig_method.apply(self, arguments);\n }\n result_new = new_fn.apply(self, arguments);\n if (when === 'instead') {\n return result_new;\n }\n if (when === 'before') {\n result = orig_method.apply(self, arguments);\n }\n return result;\n };\n }\n}\n;\n//# sourceMappingURL=tom-select.js.map\n;// ./node_modules/tom-select/dist/esm/plugins/change_listener/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\
1n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Add event helper\n *\n */\nconst plugin_addEvent = (target, type, callback, options) => {\n target.addEventListener(type, callback, options);\n};\n\n/**\n * Plugin: \"change_listener\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction plugin_plugin () {\n plugin_addEvent(this.input, 'change', () => {\n this.sync();\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/checkbox_options/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\nconst plugin_hash_key = value => {\n if (typeof value === 'undefined' || value === null) return null;\n return plugin_get_hash(value);\n};\nconst plugin_get_hash = value => {\n if (typeof value === 'boolean') return value ? '1' : '0';\n return value + '';\n};\n\n/**\n * Prevent default\n *\n */\nconst plugin_preventDefault = (evt, stop = false) => {\n if (evt) {\n evt.preventDefault();\n if (stop) {\n evt.stopPropagation();\n }\n }\n};\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst plugin_getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (plugin_isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst plugin_isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\n\n/**\n * Plugin: \"checkbox_options\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction checkbox_options_plugin_plugin (userOptions) {\n var self = this;\n var orig_onOptionSelect = self.onOptionSelect;\n self.settings.hideSelected = false;\n const cbOptions = Object.assign({\n // so that the user may add different ones as well\n className: \"tomselect-checkbox\",\n // the following default to the historic plugin's values\n checkedClassNames: undefined,\n uncheckedClassNames: undefined\n }, userOptions);\n var UpdateChecked = function UpdateChecked(checkbox, toCheck) {\n if (toCheck) {\n checkbox.checked = true;\n if (cbOptions.uncheckedClassNames) {\n checkbox.classList.remove(...cbOptions.uncheckedClassNames);\n }\n if (cbOptions.checkedClassNames) {\n checkbox.classList.add(...cbOptions.checkedClassNames);\n }\n } else {\n checkbox.checked = false;\n if (cbOptions.checkedClassNames) {\n checkbox.classList.remove(...cbOptions.checkedClassNames);\n }\n if (cbOptions.uncheckedClassNames) {\n checkbox.classList.add(...cbOptions.uncheckedClassNames);\n }\n }\n };\n\n // update the checkbox for an option\n var UpdateCheckbox = function UpdateCheckbox(option) {\n setTimeout(() =>
1 {\n var checkbox = option.querySelector('input.' + cbOptions.className);\n if (checkbox instanceof HTMLInputElement) {\n UpdateChecked(checkbox, option.classList.contains('selected'));\n }\n }, 1);\n };\n\n // add checkbox to option template\n self.hook('after', 'setupTemplates', () => {\n var orig_render_option = self.settings.render.option;\n self.settings.render.option = (data, escape_html) => {\n var rendered = plugin_getDom(orig_render_option.call(self, data, escape_html));\n var checkbox = document.createElement('input');\n if (cbOptions.className) {\n checkbox.classList.add(cbOptions.className);\n }\n checkbox.addEventListener('click', function (evt) {\n plugin_preventDefault(evt);\n });\n checkbox.type = 'checkbox';\n const hashed = plugin_hash_key(data[self.settings.valueField]);\n UpdateChecked(checkbox, !!(hashed && self.items.indexOf(hashed) > -1));\n rendered.prepend(checkbox);\n return rendered;\n };\n });\n\n // uncheck when item removed\n self.on('item_remove', value => {\n var option = self.getOption(value);\n if (option) {\n // if dropdown hasn't been opened yet, the option won't exist\n option.classList.remove('selected'); // selected class won't be removed yet\n UpdateCheckbox(option);\n }\n });\n\n // check when item added\n self.on('item_add', value => {\n var option = self.getOption(value);\n if (option) {\n // if dropdown hasn't been opened yet, the option won't exist\n UpdateCheckbox(option);\n }\n });\n\n // remove items when selected option is clicked\n self.hook('instead', 'onOptionSelect', (evt, option) => {\n if (option.classList.contains('selected')) {\n option.classList.remove('selected');\n self.removeItem(option.dataset.value);\n self.refreshOptions();\n plugin_preventDefault(evt, true);\n return;\n }\n orig_onOptionSelect.call(self, evt, option);\n UpdateCheckbox(option);\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/clear_button/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst clear_button_plugin_getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (clear_button_plugin_isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst clear_button_plugin_isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\n\n/**\n * Plugin: \"dropdown_header\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction clear_button_plugin_plugin (userOptions) {\n const self = this;\n const options = Object.assign({\n className: 'clear-button',\n title: 'Clear All',\n html: data => {\n return `<div class=\"${data.className}\" title=\"${data.title}\">⨯</div>`;\n }\n }, userOptions);\n self.on('initialize', () => {\n var button = clear_button_plugin_getDom(options.html(options));\n button.addEventListener('click', evt => {\n if (self.isLocked) return;\n self.clear();\n if (self.settings.mode === 'single' && self.settings.allowEmptyOption) {\n self.addItem('');\n }\n evt.preventDefault();\n evt.stopPropagation();\n });\n self.control.appendChild(button);\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/drag_drop/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\
1n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Prevent default\n *\n */\nconst drag_drop_plugin_preventDefault = (evt, stop = false) => {\n if (evt) {\n evt.preventDefault();\n if (stop) {\n evt.stopPropagation();\n }\n }\n};\n\n/**\n * Add event helper\n *\n */\nconst drag_drop_plugin_addEvent = (target, type, callback, options) => {\n target.addEventListener(type, callback, options);\n};\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst plugin_iterate = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n } else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst drag_drop_plugin_getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (drag_drop_plugin_isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst drag_drop_plugin_isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\n\n/**\n * Set attributes of an element\n *\n */\nconst plugin_setAttr = (el, attrs) => {\n plugin_iterate(attrs, (val, attr) => {\n if (val == null) {\n el.removeAttribute(attr);\n } else {\n el.setAttribute(attr, '' + val);\n }\n });\n};\n\n/**\n * Plugin: \"drag_drop\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nconst insertAfter = (referenceNode, newNode) => {\n var _referenceNode$parent;\n (_referenceNode$parent = referenceNode.parentNode) == null || _referenceNode$parent.insertBefore(newNode, referenceNode.nextSibling);\n};\nconst insertBefore = (referenceNode, newNode) => {\n var _referenceNode$parent2;\n (_referenceNode$parent2 = referenceNode.parentNode) == null || _referenceNode$parent2.insertBefore(newNode, referenceNode);\n};\nconst isBefore = (referenceNode, newNode) => {\n do {\n var _newNode;\n newNode = (_newNode = newNode) == null ? void 0 : _newNode.previousElementSibling;\n if (referenceNode == newNode) {\n return true;\n }\n } while (newNode && newNode.previousElementSibling);\n return false;\n};\nfunction drag_drop_plugin_plugin () {\n var self = this;\n if (self.settings.mode !== 'multi') return;\n var orig_lock = self.lock;\n var orig_unlock = self.unlock;\n let sortable = true;\n let drag_item;\n\n /**\n * Add draggable attribute to item\n */\n self.hook('after', 'setupTemplates', () => {\n var orig_render_item = self.settings.render.item;\n self.settings.render.item = (data, escape) => {\n const item = drag_drop_plugin_getDom(orig_render_item.call(self, data, escape));\n plugin_setAttr(item, {\n 'draggable': 'true'\n });\n\n // prevent doc_mousedown (see tom-select.ts)\n const mousedown = evt => {\n if (!sortable) drag_drop_plugin_preventDefault(evt);\n evt.stopPropagation();\n };\n const dragStart = evt => {\n drag_item = item;\n setTimeout(() =>
1 {\n item.classList.add('ts-dragging');\n }, 0);\n };\n const dragOver = evt => {\n evt.preventDefault();\n item.classList.add('ts-drag-over');\n moveitem(item, drag_item);\n };\n const dragLeave = () => {\n item.classList.remove('ts-drag-over');\n };\n const moveitem = (targetitem, dragitem) => {\n if (dragitem === undefined) return;\n if (isBefore(dragitem, item)) {\n insertAfter(targetitem, dragitem);\n } else {\n insertBefore(targetitem, dragitem);\n }\n };\n const dragend = () => {\n var _drag_item;\n document.querySelectorAll('.ts-drag-over').forEach(el => el.classList.remove('ts-drag-over'));\n (_drag_item = drag_item) == null || _drag_item.classList.remove('ts-dragging');\n drag_item = undefined;\n var values = [];\n self.control.querySelectorAll(`[data-value]`).forEach(el => {\n if (el.dataset.value) {\n let value = el.dataset.value;\n if (value) {\n values.push(value);\n }\n }\n });\n self.setValue(values);\n };\n drag_drop_plugin_addEvent(item, 'mousedown', mousedown);\n drag_drop_plugin_addEvent(item, 'dragstart', dragStart);\n drag_drop_plugin_addEvent(item, 'dragenter', dragOver);\n drag_drop_plugin_addEvent(item, 'dragover', dragOver);\n drag_drop_plugin_addEvent(item, 'dragleave', dragLeave);\n drag_drop_plugin_addEvent(item, 'dragend', dragend);\n return item;\n };\n });
1\n self.hook('instead', 'lock', () => {\n sortable = false;\n return orig_lock.call(self);\n });\n self.hook('instead', 'unlock', () => {\n sortable = true;\n return orig_unlock.call(self);\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/dropdown_header/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Prevent default\n *\n */\nconst dropdown_header_plugin_preventDefault = (evt, stop = false) => {\n if (evt) {\n evt.preventDefault();\n if (stop) {\n evt.stopPropagation();\n }\n }\n};\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst dropdown_header_plugin_getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (dropdown_header_plugin_isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst dropdown_header_plugin_isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\n\n/**\n * Plugin: \"dropdown_header\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction dropdown_header_plugin_plugin (userOptions) {\n const self = this;\n const options = Object.assign({\n title: 'Untitled',\n headerClass: 'dropdown-header',\n titleRowClass: 'dropdown-header-title',\n labelClass: 'dropdown-header-label',\n closeClass: 'dropdown-header-close',\n html: data => {\n return '<div class=\"' + data.headerClass + '\">' + '<div class=\"' + data.titleRowClass + '\">' + '<span class=\"' + data.labelClass + '\">' + data.title + '</span>' + '<a class=\"' + data.closeClass + '\">×</a>' + '</div>' + '</div>';\n }\n }, userOptions);\n self.on('initialize', () => {\n var header = dropdown_header_plugin_getDom(options.html(options));\n var close_link = header.querySelector('.' + options.closeClass);\n if (close_link) {\n close_link.addEventListener('click', evt => {\n dropdown_header_plugin_preventDefault(evt, true);\n self.close();\n });\n }\n self.dropdown.insertBefore(header, self.dropdown.firstChild);\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/caret_position/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst caret_position_plugin_iterate = (object, callback) =>
1 {\n if (Array.isArray(object)) {\n object.forEach(callback);\n } else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\n\n/**\n * Remove css classes\n *\n */\nconst plugin_removeClasses = (elmts, ...classes) => {\n var norm_classes = plugin_classesArray(classes);\n elmts = plugin_castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.remove(cls);\n });\n });\n};\n\n/**\n * Return arguments\n *\n */\nconst plugin_classesArray = args => {\n var classes = [];\n caret_position_plugin_iterate(args, _classes => {\n if (typeof _classes === 'string') {\n _classes = _classes.trim().split(/[\\t\\n\\f\\r\\s]/);\n }\n if (Array.isArray(_classes)) {\n classes = classes.concat(_classes);\n }\n });\n return classes.filter(Boolean);\n};\n\n/**\n * Create an array from arg if it's not already an array\n *\n */\nconst plugin_castAsArray = arg => {\n if (!Array.isArray(arg)) {\n arg = [arg];\n }\n return arg;\n};\n\n/**\n * Get the index of an element amongst sibling nodes of the same type\n *\n */\nconst plugin_nodeIndex = (el, amongst) => {\n if (!el) return -1;\n amongst = amongst || el.nodeName;\n var i = 0;\n while (el = el.previousElementSibling) {\n if (el.matches(amongst)) {\n i++;\n }\n }\n return i;\n};\n\n/**\n * Plugin: \"dropdown_input\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction caret_position_plugin_plugin () {\n var self = this;\n\n /**\n * Moves the caret to the specified index.\n *\n * The input must be moved by leaving it in place and moving the\n * siblings, due to the fact that focus cannot be restored once lost\n * on mobile webkit devices\n *\n */\n self.hook('instead', 'setCaret', new_pos => {\n if (self.settings.mode === 'single' || !self.control.contains(self.control_input)) {\n new_pos = self.items.length;\n } else {\n new_pos = Math.max(0, Math.min(self.items.length, new_pos));\n if (new_pos != self.caretPos && !self.isPending) {\n self.controlChildren().forEac
1h((child, j) => {\n if (j < new_pos) {\n self.control_input.insertAdjacentElement('beforebegin', child);\n } else {\n self.control.appendChild(child);\n }\n });\n }\n }\n self.caretPos = new_pos;\n });\n self.hook('instead', 'moveCaret', direction => {\n if (!self.isFocused) return;\n\n // move caret before or after selected items\n const last_active = self.getLastActive(direction);\n if (last_active) {\n const idx = plugin_nodeIndex(last_active);\n self.setCaret(direction > 0 ? idx + 1 : idx);\n self.setActiveItem();\n plugin_removeClasses(last_active, 'last-active');\n\n // move caret left or right of current position\n } else {\n self.setCaret(self.caretPos + direction);\n }\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/dropdown_input/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\nconst plugin_KEY_ESC = 27;\nconst plugin_KEY_TAB = 9;\n // ctrl key or apple key for ma\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Prevent default\n *\n */\nconst dropdown_input_plugin_preventDefault = (evt, stop = false) => {\n if (evt) {\n evt.preventDefault();\n if (stop) {\n evt.stopPropagation();\n }\n }\n};\n\n/**\n * Add event helper\n *\n */\nconst dropdown_input_plugin_addEvent = (target, type, callback, options) => {\n target.addEventListener(type, callback, options);\n};\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst dropdown_input_plugin_iterate = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n } else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst dropdown_input_plugin_getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (dropdown_input_plugin_isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst dropdown_input_plugin_isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\n\n/**\n * Add css classes\n *\n */\nconst plugin_addClasses = (elmts, ...classes) => {\n var norm_classes = dropdown_input_plugin_classesArray(classes);\n elmts = dropdown_input_plugin_castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.add(cls);\n });\n });\n};\n\n/**\n * Return arguments\n *\n */\nconst dropdown_input_plugin_classesArray = args => {\n var classes = [];\n dropdown_input_plugin_iterate(args, _classes => {\n if (typeof _classes === 'string') {\n _classes = _classes.trim().split(/[\\t\\n\\f\\r\\s]/);\n }\n if (Array.isArray(_classes)) {\n classes = classes.concat(_classes);\n }\n });\n return classes.filter(Boolean);\n};\n\n/**\n * Create an array from arg if it's not already an array\n *\n */\nconst dropdown_input_plugin_castAsArray = arg => {\n if (!Array.isArray(arg)) {\n arg = [arg];\n }\n return arg;\n};\n\n/**\n * Plugin: \"dropdown_input\" (Tom Select)\n * Copyright (c) contributors\n *\n *
1Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction dropdown_input_plugin_plugin () {\n const self = this;\n self.settings.shouldOpen = true; // make sure the input is shown even if there are no options to display in the dropdown\n\n self.hook('before', 'setup', () => {\n self.focus_node = self.control;\n plugin_addClasses(self.control_input, 'dropdown-input');\n const div = dropdown_input_plugin_getDom('<div class=\"dropdown-input-wrap\">');\n div.append(self.control_input);\n self.dropdown.insertBefore(div, self.dropdown.firstChild);\n\n // set a placeholder in the select control\n const placeholder = dropdown_input_plugin_getDom('<input class=\"items-placeholder\" tabindex=\"-1\" />');\n placeholder.placeholder = self.settings.placeholder || '';\n self.control.append(placeholder);\n });\n self.on('initialize', () => {\n // set tabIndex on control to -1, otherwise [shift+tab] will put focus right back on control_input\n self.control_input.addEventListener('keydown', evt => {\n //addEvent(self.control_input,'keydown' as const,(evt:KeyboardEvent) =>{\n switch (evt.keyCode) {\n case plugin_KEY_ESC:\n if (self.isOpen) {\n dropdown_input_plugin_preventDefault(evt, true);\n self.close();\n }\n self.clearActiveItems();\n return;\n case plugin_KEY_TAB:\n self.focus_node.tabIndex = -1;\n break;\n }\n return self.onKeyDown.call(self, evt);\n });\n self.on('blur', () => {\n self.focus_node.tabIndex = self.isDisabled ? -1 : self.tabIndex;\n });\n\n // give the control_input focus when the dropdown is open\n self.on('dropdown_open', () => {\n self.control_input.focus();\n });\n\n // prevent onBlur from closing when focus is on the control_input\n const orig_onBlur = self.onBlur;\n self.hook('instead', 'onBlur', evt => {\n if (evt && evt.relatedTarget == self.control_input) return;\n return orig_onBlur.call(self);\n });\n dropdown_input_plugin_addEvent(self.control_input, 'blur', () => self.onBlur());\n\n // return focus to control to allow further keyboard input\n self.hook('before', 'close', () => {\n if (!self.isOpen) return;\n self.focus_node.focus({\n preventScroll: true\n });\n });\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/input_autogrow/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Add event helper\n *\n */\nconst input_autogrow_plugin_addEvent = (target, type, callback, options) => {\n target.addEventListener(type, callback, options);\n};\n\n/**\n * Plugin: \"input_autogrow\" (Tom Select)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction input_autogrow_plugin_plugin () {\n var self = this;\n self.on('initialize', () => {\n var test_input = document.createElement('span');\n var control = self.control_input;\n test_input.style.cssText = 'position:absolute; top:-99999px; left:-99999px; width:auto; padding:0; white-space:pre; ';\n self.wrapper.appendChild(test_input);\n var transfer_styles = ['letterSpacing', 'fontSize', 'fontFamily', 'fontWeight', 'textTransform'];\n for (const style_name of transfer_styles) {\n // @ts-ignore TS7015 https://stackoverflow.com/a/50506154/697576\n test_input.style[style_name] = control.style[style_name];\n }\n\n /**\n * Set the control width\n *\n */\n var resize = () => {\n test_input.textContent = control.value;\n control.style.width = test_input.clientWidth + 'px';\n };\n resize();\n self.on('update item_add item_remove', resize);\n input_autogrow_plugin_addEvent(control, 'input', resize);\n input_autogrow_plugin_addEvent(control, 'keyup', resize);\n input_autogrow_plugin_addEvent(control, 'blur', resize);\n input_autogrow_plugin_addEvent(control, 'update', resize);\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/no_backspace_delete/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Plugin: \"input_autogrow\" (Tom Select)\n *\n *
1Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction no_backspace_delete_plugin_plugin () {\n var self = this;\n var orig_deleteSelection = self.deleteSelection;\n this.hook('instead', 'deleteSelection', evt => {\n if (self.activeItems.length) {\n return orig_deleteSelection.call(self, evt);\n }\n return false;\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/no_active_items/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Plugin: \"no_active_items\" (Tom Select)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction no_active_items_plugin_plugin () {\n this.hook('instead', 'setActiveItem', () => {});\n this.hook('instead', 'selectAll', () => {});\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/optgroup_columns/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\nconst plugin_KEY_LEFT = 37;\nconst plugin_KEY_RIGHT = 39;\n // ctrl key or apple key for ma\n\n/**\n * Get the closest node to the evt.target matching the selector\n * Stops at wrapper\n *\n */\nconst plugin_parentMatch = (target, selector, wrapper) => {\n while (target && target.matches) {\n if (target.matches(selector)) {\n return target;\n }\n target = target.parentNode;\n }\n};\n\n/**\n * Get the index of an element amongst sibling nodes of the same type\n *\n */\nconst optgroup_columns_plugin_nodeIndex = (el, amongst) => {\n if (!el) return -1;\n amongst = amongst || el.nodeName;\n var i = 0;\n while (el = el.previousElementSibling) {\n if (el.matches(amongst)) {\n i++;\n }\n }\n return i;\n};\n\n/**\n * Plugin: \"optgroup_columns\" (Tom Select.js)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction optgroup_columns_plugin_plugin () {\n var self = this;\n var orig_keydown = self.onKeyDown;\n self.hook('instead', 'onKeyDown', evt => {\n var index, option, options, optgroup;\n if (!self.isOpen || !(evt.keyCode === plugin_KEY_LEFT || evt.keyCode === plugin_KEY_RIGHT)) {\n return orig_keydown.call(self, evt);\n }\n self.ignoreHover = true;\n optgroup = plugin_parentMatch(self.activeOption, '[data-group]');\n index = optgroup_columns_plugin_nodeIndex(self.activeOption, '[data-selectable]');\n if (!optgroup) {\n return;\n }\n if (evt.keyCode === plugin_KEY_LEFT) {\n optgroup = optgroup.previousSibling;\n } else {\n optgroup = optgroup.nextSibling;\n }\n if (!optgroup) {\n return;\n }\n options = optgroup.querySelectorAll('[data-selectable]');\n option = options[Math.min(options.length - 1, index)];\n if (option) {\n self.setActiveOption(option);\n }\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/remove_button/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\
1n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Escapes a string for use within HTML.\n *\n */\nconst plugin_escape_html = str => {\n return (str + '').replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n};\n\n/**\n * Prevent default\n *\n */\nconst remove_button_plugin_preventDefault = (evt, stop = false) => {\n if (evt) {\n evt.preventDefault();\n if (stop) {\n evt.stopPropagation();\n }\n }\n};\n\n/**\n * Add event helper\n *\n */\nconst remove_button_plugin_addEvent = (target, type, callback, options) => {\n target.addEventListener(type, callback, options);\n};\n\n/**\n * Return a dom element from either a dom query string, jQuery object, a dom element or html string\n * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518\n *\n * param query should be {}\n */\nconst remove_button_plugin_getDom = query => {\n if (query.jquery) {\n return query[0];\n }\n if (query instanceof HTMLElement) {\n return query;\n }\n if (remove_button_plugin_isHtmlString(query)) {\n var tpl = document.createElement('template');\n tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result\n return tpl.content.firstChild;\n }\n return document.querySelector(query);\n};\nconst remove_button_plugin_isHtmlString = arg => {\n if (typeof arg === 'string' && arg.indexOf('<') > -1) {\n return true;\n }\n return false;\n};\n\n/**\n * Plugin: \"remove_button\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction remove_button_plugin_plugin (userOptions) {\n const options = Object.assign({\n label: '×',\n title: 'Remove',\n className: 'remove',\n append: true\n }, userOptions);\n\n //options.className = 'remove-single';\n var self = this;\n\n // override the render method to add remove button to each item\n if (!options.append) {\n return;\n }\n var html = '<a href=\"javascript:void(0)\" class=\"' + options.className + '\" tabindex=\"-1\" title=\"' + plugin_escape_html(options.title) + '\">' + options.label + '</a>';\n self.hook('after', 'setupTemplates', () => {\n var orig_render_item = self.settings.render.item;\n self.settings.render.item = (data, escape) => {\n var item = remove_button_plugin_getDom(orig_render_item.call(self, data, escape));\n var close_button = remove_button_plugin_getDom(html);\n item.appendChild(close_button);\n remove_button_plugin_addEvent(close_button, 'mousedown', evt => {\n remove_button_plugin_preventDefault(evt, true);\n });\n remove_button_plugin_addEvent(close_button, 'click', evt => {\n if (self.isLocked) return;\n\n // propagating will trigger the dropdown to show for single mode\n remove_button_plugin_preventDefault(evt, true);\n if (self.isLocked) return;\n if (!self.shouldDelete([item], evt)) return;\n self.removeItem(item);\n self.refreshOptions(false);\n self.inputState();\n });\n return item;\n };\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/restore_on_backspace/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Plugin: \"restore_on_backspace\" (Tom Select)\n * Copyright (c) contributors\n *\n *
1Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction restore_on_backspace_plugin_plugin (userOptions) {\n const self = this;\n const options = Object.assign({\n text: option => {\n return option[self.settings.labelField];\n }\n }, userOptions);\n self.on('item_remove', function (value) {\n if (!self.isFocused) {\n return;\n }\n if (self.control_input.value.trim() === '') {\n var option = self.options[value];\n if (option) {\n self.setTextboxValue(options.text.call(self, option));\n }\n }\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/plugins/virtual_scroll/plugin.js\n/**\n* Tom Select v2.4.3\n* Licensed under the Apache License, Version 2.0 (the \"License\");\n*/\n\n/**\n * Converts a scalar to its best string representation\n * for hash keys and HTML attribute values.\n *\n * Transformations:\n * 'str' -> 'str'\n * null -> ''\n * undefined -> ''\n * true -> '1'\n * false -> '0'\n * 0 -> '0'\n * 1 -> '1'\n *\n */\n\n/**\n * Iterates over arrays and hashes.\n *\n * ```\n * iterate(this.items, function(item, id) {\n * // invoked for each item\n * });\n * ```\n *\n */\nconst virtual_scroll_plugin_iterate = (object, callback) => {\n if (Array.isArray(object)) {\n object.forEach(callback);\n } else {\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n callback(object[key], key);\n }\n }\n }\n};\n\n/**\n * Add css classes\n *\n */\nconst virtual_scroll_plugin_addClasses = (elmts, ...classes) => {\n var norm_classes = virtual_scroll_plugin_classesArray(classes);\n elmts = virtual_scroll_plugin_castAsArray(elmts);\n elmts.map(el => {\n norm_classes.map(cls => {\n el.classList.add(cls);\n });\n });\n};\n\n/**\n * Return arguments\n *\n */\nconst virtual_scroll_plugin_classesArray = args => {\n var classes = [];\n virtual_scroll_plugin_iterate(args, _classes => {\n if (typeof _classes === 'string') {\n _classes = _classes.trim().split(/[\\t\\n\\f\\r\\s]/);\n }\n if (Array.isArray(_classes)) {\n classes = classes.concat(_classes);\n }\n });\n return classes.filter(Boolean);\n};\n\n/**\n * Create an array from arg if it's not already an array\n *\n */\nconst virtual_scroll_plugin_castAsArray = arg => {\n if (!Array.isArray(arg)) {\n arg = [arg];\n }\n return arg;\n};\n\n/**\n * Plugin: \"restore_on_backspace\" (Tom Select)\n * Copyright (c) contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this\n * file except in compliance with the License. You may obtain a copy of the License at:\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n * ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n *\n */\n\nfunction virtual_scroll_plugin_plugin () {\n const self = this;\n const orig_canLoad = self.canLoad;\n const orig_clearActiveOption = self.clearActiveOption;\n const orig_loadCallback = self.loadCallback;\n var pagination = {};\n var dropdown_content;\n var loading_more = false;\n var load_more_opt;\n var default_values = [];\n if (!self.settings.shouldLoadMore) {\n // return true if additional results should be loaded\n self.settings.shouldLoadMore = () => {\n const scroll_percent = dropdown_content.clientHeight / (dropdown_content.scrollHeight - dropdown_content.scrollTop);\n if (scroll_percent > 0.9) {\n return true;\n }\n if (self.activeOption) {\n var selectable = self.selectable();\n var index = Array.from(selectable).indexOf(self.activeOption);\n if (index >= selectable.length - 2) {\n return true;\n }\n }\n return false;\n };\n }\n if (!self.settings.firstUrl) {\n throw 'virtual_scroll plugin requires a firstUrl() method';
1\n }\n\n // in order for virtual scrolling to work,\n // options need to be ordered the same way they're returned from the remote data source\n self.settings.sortField = [{\n field: '$order'\n }, {\n field: '$score'\n }];\n\n // can we load more results for given query?\n const canLoadMore = query => {\n if (typeof self.settings.maxOptions === 'number' && dropdown_content.children.length >= self.settings.maxOptions) {\n return false;\n }\n if (query in pagination && pagination[query]) {\n return true;\n }\n return false;\n };\n const clearFilter = (option, value) => {\n if (self.items.indexOf(value) >= 0 || default_values.indexOf(value) >= 0) {\n return true;\n }\n return false;\n };\n\n // set the next url that will be\n self.setNextUrl = (value, next_url) => {\n pagination[value] = next_url;\n };\n\n // getUrl() to be used in settings.load()\n self.getUrl = query => {\n if (query in pagination) {\n const next_url = pagination[query];\n pagination[query] = false;\n return next_url;\n }\n\n // if the user goes back to a previous query\n // we need to load the first page again\n self.clearPagination();\n return self.settings.firstUrl.call(self, query);\n };\n\n // clear pagination\n self.clearPagination = () => {\n pagination = {};\n };\n\n // don't clear the active option (and cause unwanted dropdown scroll)\n // while loading more results\n self.hook('instead', 'clearActiveOption', () => {\n if (loading_more) {\n return;\n }\n return orig_clearActiveOption.call(self);\n });\n\n // override the canLoad method\n self.hook('instead', 'canLoad', query => {\n // first time the query has been seen\n if (!(query in pagination)) {\n return orig_canLoad.call(self, query);\n }\n return canLoadMore(query);\n });\n\n // wrap the load\n self.hook('instead', 'loadCallback', (options, optgroups) => {\n if (!loading_more) {\n self.clearOptions(clearFilter);\n } else if (load_more_opt) {\n const first_option = options[0];\n if (first_option !== undefined) {\n load_more_opt.dataset.value = first_option[self.settings.valueField];\n }\n }\n orig_loadCallback.call(self, options, optgroups);\n loading_more = false;\n });\n\n // add templates to dropdown\n //\tloading_more if we have another url in the queue\n //\tno_more_results if we don't have another url in the queue\n self.hook('after', 'refreshOptions', () => {\n const query = self.lastValue;\n var option;\n if (canLoadMore(query)) {\n option = self.render('loading_more', {\n query: query\n });\n if (option) {\n option.setAttribute('data-selectable', ''); // so that navigating dropdown with [down] keypresses can navigate to this node\n load_more_opt = option;\n }\n } else if (query in pagination && !dropdown_content.querySelector('.no-results')) {\n option = self.render('no_more_results', {\n query: query\n });\n }\n if (option) {\n virtual_scroll_plugin_addClasses(option, self.settings.optionClass);\n dropdown_content.append(option);\n }\n });\n\n // add scroll listener and default templates\n self.on('initialize', () => {\n default_values = Object.keys(self.options);\n dropdown_content = self.dropdown_content;\n\n // default templates\n self.settings.render = Object.assign({}, {\n loading_more: () => {\n return `<div class=\"loading-more-results\">Loading more results ... </div>`;\n },\n no_more_results: () => {\n return `<div class=\"no-more-results\">No more results</div>`;\n }\n }, self.settings.render);\n\n // watch dropdown content scroll position\n dropdown_content.addEventListener('scroll', () => {\n if (!self.settings.shouldLoadMore.call(self)) {\n return;\n }\n\n // !important: this will get checked again in load() but we still need to check here otherwise loading_more will be set to true\n if (!canLoadMore(self.lastValue)) {\n return;\n }\n\n // don't call load() too much\n if (loading_more) return;\n loading_more = true;\n self.load.call(self, self.lastValue);\n });\n });\n}\n\n\n//# sourceMappingURL=plugin.js.map\n\n;// ./node_modules/tom-select/dist/esm/tom-select.complete.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nTomSelect.define('change_listener', plugin_plugin);\nTomSelect.define('checkbox_options', checkbox_options_plugin_plugin);\nTomSelect.define('clear_button', clear_button_plugin_plugin);\nTomSelect.define('drag_drop', drag_drop_plugin_plugin);\nTomSelect.define('dropdown_header', dropdown_header_plugin_plugin);\nTomSelect.define('caret_position', caret_position_plugin_plugin);\nTomSelect.define('dropdown_input', dropdown_input_plugin_plugin);\nTomSelect.define('input_autogrow', input_autogrow_plugin_plugin);\nTomSelect.define('no_backspace_delete', no_backspace_delete_plugin_plugin);\nTomSelect.define('no_active_items', no_active_items_plugin_plugin);\nTomSelect.define('optgroup_columns', optgroup_columns_plugin_plugin);\nTomSelect.define('remove_button', remove_button_plugin_plugin);\nTomSelect.define('restore_on_backspace', restore_on_backspace_plugin_plugin);\nTomSelect.define('virtual_scroll', virtual_scroll_plugin_plugin);\n/* harmony default export */ const tom_select_complete = (TomSelect);\n//# sourceMappingURL=tom-select.complete.js.map\n\n//# sourceURL=webpack://kunstmaan-edition/./node_modules/tom-select/dist/esm/tom-select.complete.js_+_28_modules?\n}")}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.