Browse code

Add tom select npm package

Benjamin Roth authored on02/02/2023 12:00:30
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,4941 @@
1
+/**
2
+* Tom Select v2.2.2
3
+* Licensed under the Apache License, Version 2.0 (the "License");
4
+*/
5
+
6
+(function (global, factory) {
7
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
8
+	typeof define === 'function' && define.amd ? define(factory) :
9
+	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.TomSelect = factory());
10
+})(this, (function () { 'use strict';
11
+
12
+	/**
13
+	 * MicroEvent - to make any js object an event emitter
14
+	 *
15
+	 * - pure javascript - server compatible, browser compatible
16
+	 * - dont rely on the browser doms
17
+	 * - super simple - you get it immediatly, no mistery, no magic involved
18
+	 *
19
+	 * @author Jerome Etienne (https://github.com/jeromeetienne)
20
+	 */
21
+
22
+	/**
23
+	 * Execute callback for each event in space separated list of event names
24
+	 *
25
+	 */
26
+	function forEvents(events, callback) {
27
+	  events.split(/\s+/).forEach(event => {
28
+	    callback(event);
29
+	  });
30
+	}
31
+
32
+	class MicroEvent {
33
+	  constructor() {
34
+	    this._events = void 0;
35
+	    this._events = {};
36
+	  }
37
+
38
+	  on(events, fct) {
39
+	    forEvents(events, event => {
40
+	      const event_array = this._events[event] || [];
41
+	      event_array.push(fct);
42
+	      this._events[event] = event_array;
43
+	    });
44
+	  }
45
+
46
+	  off(events, fct) {
47
+	    var n = arguments.length;
48
+
49
+	    if (n === 0) {
50
+	      this._events = {};
51
+	      return;
52
+	    }
53
+
54
+	    forEvents(events, event => {
55
+	      if (n === 1) {
56
+	        delete this._events[event];
57
+	        return;
58
+	      }
59
+
60
+	      const event_array = this._events[event];
61
+	      if (event_array === undefined) return;
62
+	      event_array.splice(event_array.indexOf(fct), 1);
63
+	      this._events[event] = event_array;
64
+	    });
65
+	  }
66
+
67
+	  trigger(events, ...args) {
68
+	    var self = this;
69
+	    forEvents(events, event => {
70
+	      const event_array = self._events[event];
71
+	      if (event_array === undefined) return;
72
+	      event_array.forEach(fct => {
73
+	        fct.apply(self, args);
74
+	      });
75
+	    });
76
+	  }
77
+
78
+	}
79
+
80
+	/**
81
+	 * microplugin.js
82
+	 * Copyright (c) 2013 Brian Reavis & contributors
83
+	 *
84
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
85
+	 * file except in compliance with the License. You may obtain a copy of the License at:
86
+	 * http://www.apache.org/licenses/LICENSE-2.0
87
+	 *
88
+	 * Unless required by applicable law or agreed to in writing, software distributed under
89
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
90
+	 * ANY KIND, either express or implied. See the License for the specific language
91
+	 * governing permissions and limitations under the License.
92
+	 *
93
+	 * @author Brian Reavis <brian@thirdroute.com>
94
+	 */
95
+	function MicroPlugin(Interface) {
96
+	  Interface.plugins = {};
97
+	  return class extends Interface {
98
+	    constructor(...args) {
99
+	      super(...args);
100
+	      this.plugins = {
101
+	        names: [],
102
+	        settings: {},
103
+	        requested: {},
104
+	        loaded: {}
105
+	      };
106
+	    }
107
+
108
+	    /**
109
+	     * Registers a plugin.
110
+	     *
111
+	     * @param {function} fn
112
+	     */
113
+	    static define(name, fn) {
114
+	      Interface.plugins[name] = {
115
+	        'name': name,
116
+	        'fn': fn
117
+	      };
118
+	    }
119
+	    /**
120
+	     * Initializes the listed plugins (with options).
121
+	     * Acceptable formats:
122
+	     *
123
+	     * List (without options):
124
+	     *   ['a', 'b', 'c']
125
+	     *
126
+	     * List (with options):
127
+	     *   [{'name': 'a', options: {}}, {'name': 'b', options: {}}]
128
+	     *
129
+	     * Hash (with options):
130
+	     *   {'a': { ... }, 'b': { ... }, 'c': { ... }}
131
+	     *
132
+	     * @param {array|object} plugins
133
+	     */
134
+
135
+
136
+	    initializePlugins(plugins) {
137
+	      var key, name;
138
+	      const self = this;
139
+	      const queue = [];
140
+
141
+	      if (Array.isArray(plugins)) {
142
+	        plugins.forEach(plugin => {
143
+	          if (typeof plugin === 'string') {
144
+	            queue.push(plugin);
145
+	          } else {
146
+	            self.plugins.settings[plugin.name] = plugin.options;
147
+	            queue.push(plugin.name);
148
+	          }
149
+	        });
150
+	      } else if (plugins) {
151
+	        for (key in plugins) {
152
+	          if (plugins.hasOwnProperty(key)) {
153
+	            self.plugins.settings[key] = plugins[key];
154
+	            queue.push(key);
155
+	          }
156
+	        }
157
+	      }
158
+
159
+	      while (name = queue.shift()) {
160
+	        self.require(name);
161
+	      }
162
+	    }
163
+
164
+	    loadPlugin(name) {
165
+	      var self = this;
166
+	      var plugins = self.plugins;
167
+	      var plugin = Interface.plugins[name];
168
+
169
+	      if (!Interface.plugins.hasOwnProperty(name)) {
170
+	        throw new Error('Unable to find "' + name + '" plugin');
171
+	      }
172
+
173
+	      plugins.requested[name] = true;
174
+	      plugins.loaded[name] = plugin.fn.apply(self, [self.plugins.settings[name] || {}]);
175
+	      plugins.names.push(name);
176
+	    }
177
+	    /**
178
+	     * Initializes a plugin.
179
+	     *
180
+	     */
181
+
182
+
183
+	    require(name) {
184
+	      var self = this;
185
+	      var plugins = self.plugins;
186
+
187
+	      if (!self.plugins.loaded.hasOwnProperty(name)) {
188
+	        if (plugins.requested[name]) {
189
+	          throw new Error('Plugin has circular dependency ("' + name + '")');
190
+	        }
191
+
192
+	        self.loadPlugin(name);
193
+	      }
194
+
195
+	      return plugins.loaded[name];
196
+	    }
197
+
198
+	  };
199
+	}
200
+
201
+	/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */
202
+	/**
203
+	 * Convert array of strings to a regular expression
204
+	 *	ex ['ab','a'] => (?:ab|a)
205
+	 * 	ex ['a','b'] => [ab]
206
+	 * @param {string[]} chars
207
+	 * @return {string}
208
+	 */
209
+	const arrayToPattern = chars => {
210
+	  chars = chars.filter(Boolean);
211
+
212
+	  if (chars.length < 2) {
213
+	    return chars[0] || '';
214
+	  }
215
+
216
+	  return maxValueLength(chars) == 1 ? '[' + chars.join('') + ']' : '(?:' + chars.join('|') + ')';
217
+	};
218
+	/**
219
+	 * @param {string[]} array
220
+	 * @return {string}
221
+	 */
222
+
223
+	const sequencePattern = array => {
224
+	  if (!hasDuplicates(array)) {
225
+	    return array.join('');
226
+	  }
227
+
228
+	  let pattern = '';
229
+	  let prev_char_count = 0;
230
+
231
+	  const prev_pattern = () => {
232
+	    if (prev_char_count > 1) {
233
+	      pattern += '{' + prev_char_count + '}';
234
+	    }
235
+	  };
236
+
237
+	  array.forEach((char, i) => {
238
+	    if (char === array[i - 1]) {
239
+	      prev_char_count++;
240
+	      return;
241
+	    }
242
+
243
+	    prev_pattern();
244
+	    pattern += char;
245
+	    prev_char_count = 1;
246
+	  });
247
+	  prev_pattern();
248
+	  return pattern;
249
+	};
250
+	/**
251
+	 * Convert array of strings to a regular expression
252
+	 *	ex ['ab','a'] => (?:ab|a)
253
+	 * 	ex ['a','b'] => [ab]
254
+	 * @param {Set<string>} chars
255
+	 * @return {string}
256
+	 */
257
+
258
+	const setToPattern = chars => {
259
+	  let array = toArray(chars);
260
+	  return arrayToPattern(array);
261
+	};
262
+	/**
263
+	 *
264
+	 * https://stackoverflow.com/questions/7376598/in-javascript-how-do-i-check-if-an-array-has-duplicate-values
265
+	 * @param {any[]} array
266
+	 */
267
+
268
+	const hasDuplicates = array => {
269
+	  return new Set(array).size !== array.length;
270
+	};
271
+	/**
272
+	 * https://stackoverflow.com/questions/63006601/why-does-u-throw-an-invalid-escape-error
273
+	 * @param {string} str
274
+	 * @return {string}
275
+	 */
276
+
277
+	const escape_regex = str => {
278
+	  return (str + '').replace(/([\$\(\)\*\+\.\?\[\]\^\{\|\}\\])/gu, '\\$1');
279
+	};
280
+	/**
281
+	 * Return the max length of array values
282
+	 * @param {string[]} array
283
+	 *
284
+	 */
285
+
286
+	const maxValueLength = array => {
287
+	  return array.reduce((longest, value) => Math.max(longest, unicodeLength(value)), 0);
288
+	};
289
+	/**
290
+	 * @param {string} str
291
+	 */
292
+
293
+	const unicodeLength = str => {
294
+	  return toArray(str).length;
295
+	};
296
+	/**
297
+	 * @param {any} p
298
+	 * @return {any[]}
299
+	 */
300
+
301
+	const toArray = p => Array.from(p);
302
+
303
+	/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */
304
+	/**
305
+	 * Get all possible combinations of substrings that add up to the given string
306
+	 * https://stackoverflow.com/questions/30169587/find-all-the-combination-of-substrings-that-add-up-to-the-given-string
307
+	 * @param {string} input
308
+	 * @return {string[][]}
309
+	 */
310
+	const allSubstrings = input => {
311
+	  if (input.length === 1) return [[input]];
312
+	  /** @type {string[][]} */
313
+
314
+	  let result = [];
315
+	  const start = input.substring(1);
316
+	  const suba = allSubstrings(start);
317
+	  suba.forEach(function (subresult) {
318
+	    let tmp = subresult.slice(0);
319
+	    tmp[0] = input.charAt(0) + tmp[0];
320
+	    result.push(tmp);
321
+	    tmp = subresult.slice(0);
322
+	    tmp.unshift(input.charAt(0));
323
+	    result.push(tmp);
324
+	  });
325
+	  return result;
326
+	};
327
+
328
+	/*! @orchidjs/unicode-variants | https://github.com/orchidjs/unicode-variants | Apache License (v2) */
329
+
330
+	/**
331
+	 * @typedef {{[key:string]:string}} TUnicodeMap
332
+	 * @typedef {{[key:string]:Set<string>}} TUnicodeSets
333
+	 * @typedef {[[number,number]]} TCodePoints
334
+	 * @typedef {{folded:string,composed:string,code_point:number}} TCodePointObj
335
+	 * @typedef {{start:number,end:number,length:number,substr:string}} TSequencePart
336
+	 */
337
+	/** @type {TCodePoints} */
338
+
339
+	const code_points = [[0, 65535]];
340
+	const accent_pat = '[\u0300-\u036F\u{b7}\u{2be}\u{2bc}]';
341
+	/** @type {TUnicodeMap} */
342
+
343
+	let unicode_map;
344
+	/** @type {RegExp} */
345
+
346
+	let multi_char_reg;
347
+	const max_char_length = 3;
348
+	/** @type {TUnicodeMap} */
349
+
350
+	const latin_convert = {};
351
+	/** @type {TUnicodeMap} */
352
+
353
+	const latin_condensed = {
354
+	  '/': '⁄∕',
355
+	  '0': '߀',
356
+	  "a": "ⱥɐɑ",
357
+	  "aa": "ꜳ",
358
+	  "ae": "æǽǣ",
359
+	  "ao": "ꜵ",
360
+	  "au": "ꜷ",
361
+	  "av": "ꜹꜻ",
362
+	  "ay": "ꜽ",
363
+	  "b": "ƀɓƃ",
364
+	  "c": "ꜿƈȼↄ",
365
+	  "d": "đɗɖᴅƌꮷԁɦ",
366
+	  "e": "ɛǝᴇɇ",
367
+	  "f": "ꝼƒ",
368
+	  "g": "ǥɠꞡᵹꝿɢ",
369
+	  "h": "ħⱨⱶɥ",
370
+	  "i": "ɨı",
371
+	  "j": "ɉȷ",
372
+	  "k": "ƙⱪꝁꝃꝅꞣ",
373
+	  "l": "łƚɫⱡꝉꝇꞁɭ",
374
+	  "m": "ɱɯϻ",
375
+	  "n": "ꞥƞɲꞑᴎлԉ",
376
+	  "o": "øǿɔɵꝋꝍᴑ",
377
+	  "oe": "œ",
378
+	  "oi": "ƣ",
379
+	  "oo": "ꝏ",
380
+	  "ou": "ȣ",
381
+	  "p": "ƥᵽꝑꝓꝕρ",
382
+	  "q": "ꝗꝙɋ",
383
+	  "r": "ɍɽꝛꞧꞃ",
384
+	  "s": "ßȿꞩꞅʂ",
385
+	  "t": "ŧƭʈⱦꞇ",
386
+	  "th": "þ",
387
+	  "tz": "ꜩ",
388
+	  "u": "ʉ",
389
+	  "v": "ʋꝟʌ",
390
+	  "vy": "ꝡ",
391
+	  "w": "ⱳ",
392
+	  "y": "ƴɏỿ",
393
+	  "z": "ƶȥɀⱬꝣ",
394
+	  "hv": "ƕ"
395
+	};
396
+
397
+	for (let latin in latin_condensed) {
398
+	  let unicode = latin_condensed[latin] || '';
399
+
400
+	  for (let i = 0; i < unicode.length; i++) {
401
+	    let char = unicode.substring(i, i + 1);
402
+	    latin_convert[char] = latin;
403
+	  }
404
+	}
405
+
406
+	const convert_pat = new RegExp(Object.keys(latin_convert).join('|') + '|' + accent_pat, 'gu');
407
+	/**
408
+	 * Initialize the unicode_map from the give code point ranges
409
+	 *
410
+	 * @param {TCodePoints=} _code_points
411
+	 */
412
+
413
+	const initialize = _code_points => {
414
+	  if (unicode_map !== undefined) return;
415
+	  unicode_map = generateMap(_code_points || code_points);
416
+	};
417
+	/**
418
+	 * Helper method for normalize a string
419
+	 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
420
+	 * @param {string} str
421
+	 * @param {string} form
422
+	 */
423
+
424
+	const normalize = (str, form = 'NFKD') => str.normalize(form);
425
+	/**
426
+	 * Remove accents without reordering string
427
+	 * calling str.normalize('NFKD') on \u{594}\u{595}\u{596} becomes \u{596}\u{594}\u{595}
428
+	 * via https://github.com/krisk/Fuse/issues/133#issuecomment-318692703
429
+	 * @param {string} str
430
+	 * @return {string}
431
+	 */
432
+
433
+	const asciifold = str => {
434
+	  return toArray(str).reduce(
435
+	  /**
436
+	   * @param {string} result
437
+	   * @param {string} char
438
+	   */
439
+	  (result, char) => {
440
+	    return result + _asciifold(char);
441
+	  }, '');
442
+	};
443
+	/**
444
+	 * @param {string} str
445
+	 * @return {string}
446
+	 */
447
+
448
+	const _asciifold = str => {
449
+	  str = normalize(str).toLowerCase().replace(convert_pat, (
450
+	  /** @type {string} */
451
+	  char) => {
452
+	    return latin_convert[char] || '';
453
+	  }); //return str;
454
+
455
+	  return normalize(str, 'NFC');
456
+	};
457
+	/**
458
+	 * Generate a list of unicode variants from the list of code points
459
+	 * @param {TCodePoints} code_points
460
+	 * @yield {TCodePointObj}
461
+	 */
462
+
463
+	function* generator(code_points) {
464
+	  for (const [code_point_min, code_point_max] of code_points) {
465
+	    for (let i = code_point_min; i <= code_point_max; i++) {
466
+	      let composed = String.fromCharCode(i);
467
+	      let folded = asciifold(composed);
468
+
469
+	      if (folded == composed.toLowerCase()) {
470
+	        continue;
471
+	      } // skip when folded is a string longer than 3 characters long
472
+	      // bc the resulting regex patterns will be long
473
+	      // eg:
474
+	      // folded صلى الله عليه وسلم length 18 code point 65018
475
+	      // folded جل جلاله length 8 code point 65019
476
+
477
+
478
+	      if (folded.length > max_char_length) {
479
+	        continue;
480
+	      }
481
+
482
+	      if (folded.length == 0) {
483
+	        continue;
484
+	      }
485
+
486
+	      yield {
487
+	        folded: folded,
488
+	        composed: composed,
489
+	        code_point: i
490
+	      };
491
+	    }
492
+	  }
493
+	}
494
+	/**
495
+	 * Generate a unicode map from the list of code points
496
+	 * @param {TCodePoints} code_points
497
+	 * @return {TUnicodeSets}
498
+	 */
499
+
500
+	const generateSets = code_points => {
501
+	  /** @type {{[key:string]:Set<string>}} */
502
+	  const unicode_sets = {};
503
+	  /**
504
+	   * @param {string} folded
505
+	   * @param {string} to_add
506
+	   */
507
+
508
+	  const addMatching = (folded, to_add) => {
509
+	    /** @type {Set<string>} */
510
+	    const folded_set = unicode_sets[folded] || new Set();
511
+	    const patt = new RegExp('^' + setToPattern(folded_set) + '$', 'iu');
512
+
513
+	    if (to_add.match(patt)) {
514
+	      return;
515
+	    }
516
+
517
+	    folded_set.add(escape_regex(to_add));
518
+	    unicode_sets[folded] = folded_set;
519
+	  };
520
+
521
+	  for (let value of generator(code_points)) {
522
+	    addMatching(value.folded, value.folded);
523
+	    addMatching(value.folded, value.composed);
524
+	  }
525
+
526
+	  return unicode_sets;
527
+	};
528
+	/**
529
+	 * Generate a unicode map from the list of code points
530
+	 * ae => (?:(?:ae|Æ|Ǽ|Ǣ)|(?:A|Ⓐ|A...)(?:E|ɛ|Ⓔ...))
531
+	 *
532
+	 * @param {TCodePoints} code_points
533
+	 * @return {TUnicodeMap}
534
+	 */
535
+
536
+	const generateMap = code_points => {
537
+	  /** @type {TUnicodeSets} */
538
+	  const unicode_sets = generateSets(code_points);
539
+	  /** @type {TUnicodeMap} */
540
+
541
+	  const unicode_map = {};
542
+	  /** @type {string[]} */
543
+
544
+	  let multi_char = [];
545
+
546
+	  for (let folded in unicode_sets) {
547
+	    let set = unicode_sets[folded];
548
+
549
+	    if (set) {
550
+	      unicode_map[folded] = setToPattern(set);
551
+	    }
552
+
553
+	    if (folded.length > 1) {
554
+	      multi_char.push(escape_regex(folded));
555
+	    }
556
+	  }
557
+
558
+	  multi_char.sort((a, b) => b.length - a.length);
559
+	  const multi_char_patt = arrayToPattern(multi_char);
560
+	  multi_char_reg = new RegExp('^' + multi_char_patt, 'u');
561
+	  return unicode_map;
562
+	};
563
+	/**
564
+	 * Map each element of an array from it's folded value to all possible unicode matches
565
+	 * @param {string[]} strings
566
+	 * @param {number} min_replacement
567
+	 * @return {string}
568
+	 */
569
+
570
+	const mapSequence = (strings, min_replacement = 1) => {
571
+	  let chars_replaced = 0;
572
+	  strings = strings.map(str => {
573
+	    if (unicode_map[str]) {
574
+	      chars_replaced += str.length;
575
+	    }
576
+
577
+	    return unicode_map[str] || str;
578
+	  });
579
+
580
+	  if (chars_replaced >= min_replacement) {
581
+	    return sequencePattern(strings);
582
+	  }
583
+
584
+	  return '';
585
+	};
586
+	/**
587
+	 * Convert a short string and split it into all possible patterns
588
+	 * Keep a pattern only if min_replacement is met
589
+	 *
590
+	 * 'abc'
591
+	 * 		=> [['abc'],['ab','c'],['a','bc'],['a','b','c']]
592
+	 *		=> ['abc-pattern','ab-c-pattern'...]
593
+	 *
594
+	 *
595
+	 * @param {string} str
596
+	 * @param {number} min_replacement
597
+	 * @return {string}
598
+	 */
599
+
600
+	const substringsToPattern = (str, min_replacement = 1) => {
601
+	  min_replacement = Math.max(min_replacement, str.length - 1);
602
+	  return arrayToPattern(allSubstrings(str).map(sub_pat => {
603
+	    return mapSequence(sub_pat, min_replacement);
604
+	  }));
605
+	};
606
+	/**
607
+	 * Convert an array of sequences into a pattern
608
+	 * [{start:0,end:3,length:3,substr:'iii'}...] => (?:iii...)
609
+	 *
610
+	 * @param {Sequence[]} sequences
611
+	 * @param {boolean} all
612
+	 */
613
+
614
+	const sequencesToPattern = (sequences, all = true) => {
615
+	  let min_replacement = sequences.length > 1 ? 1 : 0;
616
+	  return arrayToPattern(sequences.map(sequence => {
617
+	    let seq = [];
618
+	    const len = all ? sequence.length() : sequence.length() - 1;
619
+
620
+	    for (let j = 0; j < len; j++) {
621
+	      seq.push(substringsToPattern(sequence.substrs[j] || '', min_replacement));
622
+	    }
623
+
624
+	    return sequencePattern(seq);
625
+	  }));
626
+	};
627
+	/**
628
+	 * Return true if the sequence is already in the sequences
629
+	 * @param {Sequence} needle_seq
630
+	 * @param {Sequence[]} sequences
631
+	 */
632
+
633
+
634
+	const inSequences = (needle_seq, sequences) => {
635
+	  for (const seq of sequences) {
636
+	    if (seq.start != needle_seq.start || seq.end != needle_seq.end) {
637
+	      continue;
638
+	    }
639
+
640
+	    if (seq.substrs.join('') !== needle_seq.substrs.join('')) {
641
+	      continue;
642
+	    }
643
+
644
+	    let needle_parts = needle_seq.parts;
645
+	    /**
646
+	     * @param {TSequencePart} part
647
+	     */
648
+
649
+	    const filter = part => {
650
+	      for (const needle_part of needle_parts) {
651
+	        if (needle_part.start === part.start && needle_part.substr === part.substr) {
652
+	          return false;
653
+	        }
654
+
655
+	        if (part.length == 1 || needle_part.length == 1) {
656
+	          continue;
657
+	        } // check for overlapping parts
658
+	        // a = ['::=','==']
659
+	        // b = ['::','===']
660
+	        // a = ['r','sm']
661
+	        // b = ['rs','m']
662
+
663
+
664
+	        if (part.start < needle_part.start && part.end > needle_part.start) {
665
+	          return true;
666
+	        }
667
+
668
+	        if (needle_part.start < part.start && needle_part.end > part.start) {
669
+	          return true;
670
+	        }
671
+	      }
672
+
673
+	      return false;
674
+	    };
675
+
676
+	    let filtered = seq.parts.filter(filter);
677
+
678
+	    if (filtered.length > 0) {
679
+	      continue;
680
+	    }
681
+
682
+	    return true;
683
+	  }
684
+
685
+	  return false;
686
+	};
687
+
688
+	class Sequence {
689
+	  constructor() {
690
+	    /** @type {TSequencePart[]} */
691
+	    this.parts = [];
692
+	    /** @type {string[]} */
693
+
694
+	    this.substrs = [];
695
+	    this.start = 0;
696
+	    this.end = 0;
697
+	  }
698
+	  /**
699
+	   * @param {TSequencePart|undefined} part
700
+	   */
701
+
702
+
703
+	  add(part) {
704
+	    if (part) {
705
+	      this.parts.push(part);
706
+	      this.substrs.push(part.substr);
707
+	      this.start = Math.min(part.start, this.start);
708
+	      this.end = Math.max(part.end, this.end);
709
+	    }
710
+	  }
711
+
712
+	  last() {
713
+	    return this.parts[this.parts.length - 1];
714
+	  }
715
+
716
+	  length() {
717
+	    return this.parts.length;
718
+	  }
719
+	  /**
720
+	   * @param {number} position
721
+	   * @param {TSequencePart} last_piece
722
+	   */
723
+
724
+
725
+	  clone(position, last_piece) {
726
+	    let clone = new Sequence();
727
+	    let parts = JSON.parse(JSON.stringify(this.parts));
728
+	    let last_part = parts.pop();
729
+
730
+	    for (const part of parts) {
731
+	      clone.add(part);
732
+	    }
733
+
734
+	    let last_substr = last_piece.substr.substring(0, position - last_part.start);
735
+	    let clone_last_len = last_substr.length;
736
+	    clone.add({
737
+	      start: last_part.start,
738
+	      end: last_part.start + clone_last_len,
739
+	      length: clone_last_len,
740
+	      substr: last_substr
741
+	    });
742
+	    return clone;
743
+	  }
744
+
745
+	}
746
+	/**
747
+	 * Expand a regular expression pattern to include unicode variants
748
+	 * 	eg /a/ becomes /aⓐaẚàáâầấẫẩãāăằắẵẳȧǡäǟảåǻǎȁȃạậặḁąⱥɐɑAⒶAÀÁÂẦẤẪẨÃĀĂẰẮẴẲȦǠÄǞẢÅǺǍȀȂẠẬẶḀĄȺⱯ/
749
+	 *
750
+	 * Issue:
751
+	 *  ﺊﺋ [ 'ﺊ = \\u{fe8a}', 'ﺋ = \\u{fe8b}' ]
752
+	 *	becomes:	ئئ [ 'ي = \\u{64a}', 'ٔ = \\u{654}', 'ي = \\u{64a}', 'ٔ = \\u{654}' ]
753
+	 *
754
+	 *	İIJ = IIJ = ⅡJ
755
+	 *
756
+	 * 	1/2/4
757
+	 *
758
+	 * @param {string} str
759
+	 * @return {string|undefined}
760
+	 */
761
+
762
+
763
+	const getPattern = str => {
764
+	  initialize();
765
+	  str = asciifold(str);
766
+	  let pattern = '';
767
+	  let sequences = [new Sequence()];
768
+
769
+	  for (let i = 0; i < str.length; i++) {
770
+	    let substr = str.substring(i);
771
+	    let match = substr.match(multi_char_reg);
772
+	    const char = str.substring(i, i + 1);
773
+	    const match_str = match ? match[0] : null; // loop through sequences
774
+	    // add either the char or multi_match
775
+
776
+	    let overlapping = [];
777
+	    let added_types = new Set();
778
+
779
+	    for (const sequence of sequences) {
780
+	      const last_piece = sequence.last();
781
+
782
+	      if (!last_piece || last_piece.length == 1 || last_piece.end <= i) {
783
+	        // if we have a multi match
784
+	        if (match_str) {
785
+	          const len = match_str.length;
786
+	          sequence.add({
787
+	            start: i,
788
+	            end: i + len,
789
+	            length: len,
790
+	            substr: match_str
791
+	          });
792
+	          added_types.add('1');
793
+	        } else {
794
+	          sequence.add({
795
+	            start: i,
796
+	            end: i + 1,
797
+	            length: 1,
798
+	            substr: char
799
+	          });
800
+	          added_types.add('2');
801
+	        }
802
+	      } else if (match_str) {
803
+	        let clone = sequence.clone(i, last_piece);
804
+	        const len = match_str.length;
805
+	        clone.add({
806
+	          start: i,
807
+	          end: i + len,
808
+	          length: len,
809
+	          substr: match_str
810
+	        });
811
+	        overlapping.push(clone);
812
+	      } else {
813
+	        // don't add char
814
+	        // adding would create invalid patterns: 234 => [2,34,4]
815
+	        added_types.add('3');
816
+	      }
817
+	    } // if we have overlapping
818
+
819
+
820
+	    if (overlapping.length > 0) {
821
+	      // ['ii','iii'] before ['i','i','iii']
822
+	      overlapping = overlapping.sort((a, b) => {
823
+	        return a.length() - b.length();
824
+	      });
825
+
826
+	      for (let clone of overlapping) {
827
+	        // don't add if we already have an equivalent sequence
828
+	        if (inSequences(clone, sequences)) {
829
+	          continue;
830
+	        }
831
+
832
+	        sequences.push(clone);
833
+	      }
834
+
835
+	      continue;
836
+	    } // if we haven't done anything unique
837
+	    // clean up the patterns
838
+	    // helps keep patterns smaller
839
+	    // if str = 'r₨㎧aarss', pattern will be 446 instead of 655
840
+
841
+
842
+	    if (i > 0 && added_types.size == 1 && !added_types.has('3')) {
843
+	      pattern += sequencesToPattern(sequences, false);
844
+	      let new_seq = new Sequence();
845
+	      const old_seq = sequences[0];
846
+
847
+	      if (old_seq) {
848
+	        new_seq.add(old_seq.last());
849
+	      }
850
+
851
+	      sequences = [new_seq];
852
+	    }
853
+	  }
854
+
855
+	  pattern += sequencesToPattern(sequences, true);
856
+	  return pattern;
857
+	};
858
+
859
+	/*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */
860
+
861
+	/**
862
+	 * A property getter resolving dot-notation
863
+	 * @param  {Object}  obj     The root object to fetch property on
864
+	 * @param  {String}  name    The optionally dotted property name to fetch
865
+	 * @return {Object}          The resolved property value
866
+	 */
867
+	const getAttr = (obj, name) => {
868
+	  if (!obj) return;
869
+	  return obj[name];
870
+	};
871
+	/**
872
+	 * A property getter resolving dot-notation
873
+	 * @param  {Object}  obj     The root object to fetch property on
874
+	 * @param  {String}  name    The optionally dotted property name to fetch
875
+	 * @return {Object}          The resolved property value
876
+	 */
877
+
878
+	const getAttrNesting = (obj, name) => {
879
+	  if (!obj) return;
880
+	  var part,
881
+	      names = name.split(".");
882
+
883
+	  while ((part = names.shift()) && (obj = obj[part]));
884
+
885
+	  return obj;
886
+	};
887
+	/**
888
+	 * Calculates how close of a match the
889
+	 * given value is against a search token.
890
+	 *
891
+	 */
892
+
893
+	const scoreValue = (value, token, weight) => {
894
+	  var score, pos;
895
+	  if (!value) return 0;
896
+	  value = value + '';
897
+	  if (token.regex == null) return 0;
898
+	  pos = value.search(token.regex);
899
+	  if (pos === -1) return 0;
900
+	  score = token.string.length / value.length;
901
+	  if (pos === 0) score += 0.5;
902
+	  return score * weight;
903
+	};
904
+	/**
905
+	 * Cast object property to an array if it exists and has a value
906
+	 *
907
+	 */
908
+
909
+	const propToArray = (obj, key) => {
910
+	  var value = obj[key];
911
+	  if (typeof value == 'function') return value;
912
+
913
+	  if (value && !Array.isArray(value)) {
914
+	    obj[key] = [value];
915
+	  }
916
+	};
917
+	/**
918
+	 * Iterates over arrays and hashes.
919
+	 *
920
+	 * ```
921
+	 * iterate(this.items, function(item, id) {
922
+	 *    // invoked for each item
923
+	 * });
924
+	 * ```
925
+	 *
926
+	 */
927
+
928
+	const iterate$1 = (object, callback) => {
929
+	  if (Array.isArray(object)) {
930
+	    object.forEach(callback);
931
+	  } else {
932
+	    for (var key in object) {
933
+	      if (object.hasOwnProperty(key)) {
934
+	        callback(object[key], key);
935
+	      }
936
+	    }
937
+	  }
938
+	};
939
+	const cmp = (a, b) => {
940
+	  if (typeof a === 'number' && typeof b === 'number') {
941
+	    return a > b ? 1 : a < b ? -1 : 0;
942
+	  }
943
+
944
+	  a = asciifold(a + '').toLowerCase();
945
+	  b = asciifold(b + '').toLowerCase();
946
+	  if (a > b) return 1;
947
+	  if (b > a) return -1;
948
+	  return 0;
949
+	};
950
+
951
+	/*! sifter.js | https://github.com/orchidjs/sifter.js | Apache License (v2) */
952
+
953
+	/**
954
+	 * sifter.js
955
+	 * Copyright (c) 2013–2020 Brian Reavis & contributors
956
+	 *
957
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
958
+	 * file except in compliance with the License. You may obtain a copy of the License at:
959
+	 * http://www.apache.org/licenses/LICENSE-2.0
960
+	 *
961
+	 * Unless required by applicable law or agreed to in writing, software distributed under
962
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
963
+	 * ANY KIND, either express or implied. See the License for the specific language
964
+	 * governing permissions and limitations under the License.
965
+	 *
966
+	 * @author Brian Reavis <brian@thirdroute.com>
967
+	 */
968
+
969
+	class Sifter {
970
+	  // []|{};
971
+
972
+	  /**
973
+	   * Textually searches arrays and hashes of objects
974
+	   * by property (or multiple properties). Designed
975
+	   * specifically for autocomplete.
976
+	   *
977
+	   */
978
+	  constructor(items, settings) {
979
+	    this.items = void 0;
980
+	    this.settings = void 0;
981
+	    this.items = items;
982
+	    this.settings = settings || {
983
+	      diacritics: true
984
+	    };
985
+	  }
986
+
987
+	  /**
988
+	   * Splits a search string into an array of individual
989
+	   * regexps to be used to match results.
990
+	   *
991
+	   */
992
+	  tokenize(query, respect_word_boundaries, weights) {
993
+	    if (!query || !query.length) return [];
994
+	    const tokens = [];
995
+	    const words = query.split(/\s+/);
996
+	    var field_regex;
997
+
998
+	    if (weights) {
999
+	      field_regex = new RegExp('^(' + Object.keys(weights).map(escape_regex).join('|') + ')\:(.*)$');
1000
+	    }
1001
+
1002
+	    words.forEach(word => {
1003
+	      let field_match;
1004
+	      let field = null;
1005
+	      let regex = null; // look for "field:query" tokens
1006
+
1007
+	      if (field_regex && (field_match = word.match(field_regex))) {
1008
+	        field = field_match[1];
1009
+	        word = field_match[2];
1010
+	      }
1011
+
1012
+	      if (word.length > 0) {
1013
+	        if (this.settings.diacritics) {
1014
+	          regex = getPattern(word) || null;
1015
+	        } else {
1016
+	          regex = escape_regex(word);
1017
+	        }
1018
+
1019
+	        if (regex && respect_word_boundaries) regex = "\\b" + regex;
1020
+	      }
1021
+
1022
+	      tokens.push({
1023
+	        string: word,
1024
+	        regex: regex ? new RegExp(regex, 'iu') : null,
1025
+	        field: field
1026
+	      });
1027
+	    });
1028
+	    return tokens;
1029
+	  }
1030
+
1031
+	  /**
1032
+	   * Returns a function to be used to score individual results.
1033
+	   *
1034
+	   * Good matches will have a higher score than poor matches.
1035
+	   * If an item is not a match, 0 will be returned by the function.
1036
+	   *
1037
+	   * @returns {T.ScoreFn}
1038
+	   */
1039
+	  getScoreFunction(query, options) {
1040
+	    var search = this.prepareSearch(query, options);
1041
+	    return this._getScoreFunction(search);
1042
+	  }
1043
+	  /**
1044
+	   * @returns {T.ScoreFn}
1045
+	   *
1046
+	   */
1047
+
1048
+
1049
+	  _getScoreFunction(search) {
1050
+	    const tokens = search.tokens,
1051
+	          token_count = tokens.length;
1052
+
1053
+	    if (!token_count) {
1054
+	      return function () {
1055
+	        return 0;
1056
+	      };
1057
+	    }
1058
+
1059
+	    const fields = search.options.fields,
1060
+	          weights = search.weights,
1061
+	          field_count = fields.length,
1062
+	          getAttrFn = search.getAttrFn;
1063
+
1064
+	    if (!field_count) {
1065
+	      return function () {
1066
+	        return 1;
1067
+	      };
1068
+	    }
1069
+	    /**
1070
+	     * Calculates the score of an object
1071
+	     * against the search query.
1072
+	     *
1073
+	     */
1074
+
1075
+
1076
+	    const scoreObject = function () {
1077
+	      if (field_count === 1) {
1078
+	        return function (token, data) {
1079
+	          const field = fields[0].field;
1080
+	          return scoreValue(getAttrFn(data, field), token, weights[field] || 1);
1081
+	        };
1082
+	      }
1083
+
1084
+	      return function (token, data) {
1085
+	        var sum = 0; // is the token specific to a field?
1086
+
1087
+	        if (token.field) {
1088
+	          const value = getAttrFn(data, token.field);
1089
+
1090
+	          if (!token.regex && value) {
1091
+	            sum += 1 / field_count;
1092
+	          } else {
1093
+	            sum += scoreValue(value, token, 1);
1094
+	          }
1095
+	        } else {
1096
+	          iterate$1(weights, (weight, field) => {
1097
+	            sum += scoreValue(getAttrFn(data, field), token, weight);
1098
+	          });
1099
+	        }
1100
+
1101
+	        return sum / field_count;
1102
+	      };
1103
+	    }();
1104
+
1105
+	    if (token_count === 1) {
1106
+	      return function (data) {
1107
+	        return scoreObject(tokens[0], data);
1108
+	      };
1109
+	    }
1110
+
1111
+	    if (search.options.conjunction === 'and') {
1112
+	      return function (data) {
1113
+	        var score,
1114
+	            sum = 0;
1115
+
1116
+	        for (let token of tokens) {
1117
+	          score = scoreObject(token, data);
1118
+	          if (score <= 0) return 0;
1119
+	          sum += score;
1120
+	        }
1121
+
1122
+	        return sum / token_count;
1123
+	      };
1124
+	    } else {
1125
+	      return function (data) {
1126
+	        var sum = 0;
1127
+	        iterate$1(tokens, token => {
1128
+	          sum += scoreObject(token, data);
1129
+	        });
1130
+	        return sum / token_count;
1131
+	      };
1132
+	    }
1133
+	  }
1134
+
1135
+	  /**
1136
+	   * Returns a function that can be used to compare two
1137
+	   * results, for sorting purposes. If no sorting should
1138
+	   * be performed, `null` will be returned.
1139
+	   *
1140
+	   * @return function(a,b)
1141
+	   */
1142
+	  getSortFunction(query, options) {
1143
+	    var search = this.prepareSearch(query, options);
1144
+	    return this._getSortFunction(search);
1145
+	  }
1146
+
1147
+	  _getSortFunction(search) {
1148
+	    var implicit_score,
1149
+	        sort_flds = [];
1150
+	    const self = this,
1151
+	          options = search.options,
1152
+	          sort = !search.query && options.sort_empty ? options.sort_empty : options.sort;
1153
+
1154
+	    if (typeof sort == 'function') {
1155
+	      return sort.bind(this);
1156
+	    }
1157
+	    /**
1158
+	     * Fetches the specified sort field value
1159
+	     * from a search result item.
1160
+	     *
1161
+	     */
1162
+
1163
+
1164
+	    const get_field = function get_field(name, result) {
1165
+	      if (name === '$score') return result.score;
1166
+	      return search.getAttrFn(self.items[result.id], name);
1167
+	    }; // parse options
1168
+
1169
+
1170
+	    if (sort) {
1171
+	      for (let s of sort) {
1172
+	        if (search.query || s.field !== '$score') {
1173
+	          sort_flds.push(s);
1174
+	        }
1175
+	      }
1176
+	    } // the "$score" field is implied to be the primary
1177
+	    // sort field, unless it's manually specified
1178
+
1179
+
1180
+	    if (search.query) {
1181
+	      implicit_score = true;
1182
+
1183
+	      for (let fld of sort_flds) {
1184
+	        if (fld.field === '$score') {
1185
+	          implicit_score = false;
1186
+	          break;
1187
+	        }
1188
+	      }
1189
+
1190
+	      if (implicit_score) {
1191
+	        sort_flds.unshift({
1192
+	          field: '$score',
1193
+	          direction: 'desc'
1194
+	        });
1195
+	      } // without a search.query, all items will have the same score
1196
+
1197
+	    } else {
1198
+	      sort_flds = sort_flds.filter(fld => fld.field !== '$score');
1199
+	    } // build function
1200
+
1201
+
1202
+	    const sort_flds_count = sort_flds.length;
1203
+
1204
+	    if (!sort_flds_count) {
1205
+	      return null;
1206
+	    }
1207
+
1208
+	    return function (a, b) {
1209
+	      var result, field;
1210
+
1211
+	      for (let sort_fld of sort_flds) {
1212
+	        field = sort_fld.field;
1213
+	        let multiplier = sort_fld.direction === 'desc' ? -1 : 1;
1214
+	        result = multiplier * cmp(get_field(field, a), get_field(field, b));
1215
+	        if (result) return result;
1216
+	      }
1217
+
1218
+	      return 0;
1219
+	    };
1220
+	  }
1221
+
1222
+	  /**
1223
+	   * Parses a search query and returns an object
1224
+	   * with tokens and fields ready to be populated
1225
+	   * with results.
1226
+	   *
1227
+	   */
1228
+	  prepareSearch(query, optsUser) {
1229
+	    const weights = {};
1230
+	    var options = Object.assign({}, optsUser);
1231
+	    propToArray(options, 'sort');
1232
+	    propToArray(options, 'sort_empty'); // convert fields to new format
1233
+
1234
+	    if (options.fields) {
1235
+	      propToArray(options, 'fields');
1236
+	      const fields = [];
1237
+	      options.fields.forEach(field => {
1238
+	        if (typeof field == 'string') {
1239
+	          field = {
1240
+	            field: field,
1241
+	            weight: 1
1242
+	          };
1243
+	        }
1244
+
1245
+	        fields.push(field);
1246
+	        weights[field.field] = 'weight' in field ? field.weight : 1;
1247
+	      });
1248
+	      options.fields = fields;
1249
+	    }
1250
+
1251
+	    return {
1252
+	      options: options,
1253
+	      query: query.toLowerCase().trim(),
1254
+	      tokens: this.tokenize(query, options.respect_word_boundaries, weights),
1255
+	      total: 0,
1256
+	      items: [],
1257
+	      weights: weights,
1258
+	      getAttrFn: options.nesting ? getAttrNesting : getAttr
1259
+	    };
1260
+	  }
1261
+
1262
+	  /**
1263
+	   * Searches through all items and returns a sorted array of matches.
1264
+	   *
1265
+	   */
1266
+	  search(query, options) {
1267
+	    var self = this,
1268
+	        score,
1269
+	        search;
1270
+	    search = this.prepareSearch(query, options);
1271
+	    options = search.options;
1272
+	    query = search.query; // generate result scoring function
1273
+
1274
+	    const fn_score = options.score || self._getScoreFunction(search); // perform search and sort
1275
+
1276
+
1277
+	    if (query.length) {
1278
+	      iterate$1(self.items, (item, id) => {
1279
+	        score = fn_score(item);
1280
+
1281
+	        if (options.filter === false || score > 0) {
1282
+	          search.items.push({
1283
+	            'score': score,
1284
+	            'id': id
1285
+	          });
1286
+	        }
1287
+	      });
1288
+	    } else {
1289
+	      iterate$1(self.items, (_, id) => {
1290
+	        search.items.push({
1291
+	          'score': 1,
1292
+	          'id': id
1293
+	        });
1294
+	      });
1295
+	    }
1296
+
1297
+	    const fn_sort = self._getSortFunction(search);
1298
+
1299
+	    if (fn_sort) search.items.sort(fn_sort); // apply limits
1300
+
1301
+	    search.total = search.items.length;
1302
+
1303
+	    if (typeof options.limit === 'number') {
1304
+	      search.items = search.items.slice(0, options.limit);
1305
+	    }
1306
+
1307
+	    return search;
1308
+	  }
1309
+
1310
+	}
1311
+
1312
+	/**
1313
+	 * Iterates over arrays and hashes.
1314
+	 *
1315
+	 * ```
1316
+	 * iterate(this.items, function(item, id) {
1317
+	 *    // invoked for each item
1318
+	 * });
1319
+	 * ```
1320
+	 *
1321
+	 */
1322
+
1323
+	const iterate = (object, callback) => {
1324
+	  if (Array.isArray(object)) {
1325
+	    object.forEach(callback);
1326
+	  } else {
1327
+	    for (var key in object) {
1328
+	      if (object.hasOwnProperty(key)) {
1329
+	        callback(object[key], key);
1330
+	      }
1331
+	    }
1332
+	  }
1333
+	};
1334
+
1335
+	/**
1336
+	 * Return a dom element from either a dom query string, jQuery object, a dom element or html string
1337
+	 * https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518
1338
+	 *
1339
+	 * param query should be {}
1340
+	 */
1341
+
1342
+	const getDom = query => {
1343
+	  if (query.jquery) {
1344
+	    return query[0];
1345
+	  }
1346
+
1347
+	  if (query instanceof HTMLElement) {
1348
+	    return query;
1349
+	  }
1350
+
1351
+	  if (isHtmlString(query)) {
1352
+	    var tpl = document.createElement('template');
1353
+	    tpl.innerHTML = query.trim(); // Never return a text node of whitespace as the result
1354
+
1355
+	    return tpl.content.firstChild;
1356
+	  }
1357
+
1358
+	  return document.querySelector(query);
1359
+	};
1360
+	const isHtmlString = arg => {
1361
+	  if (typeof arg === 'string' && arg.indexOf('<') > -1) {
1362
+	    return true;
1363
+	  }
1364
+
1365
+	  return false;
1366
+	};
1367
+	const escapeQuery = query => {
1368
+	  return query.replace(/['"\\]/g, '\\$&');
1369
+	};
1370
+	/**
1371
+	 * Dispatch an event
1372
+	 *
1373
+	 */
1374
+
1375
+	const triggerEvent = (dom_el, event_name) => {
1376
+	  var event = document.createEvent('HTMLEvents');
1377
+	  event.initEvent(event_name, true, false);
1378
+	  dom_el.dispatchEvent(event);
1379
+	};
1380
+	/**
1381
+	 * Apply CSS rules to a dom element
1382
+	 *
1383
+	 */
1384
+
1385
+	const applyCSS = (dom_el, css) => {
1386
+	  Object.assign(dom_el.style, css);
1387
+	};
1388
+	/**
1389
+	 * Add css classes
1390
+	 *
1391
+	 */
1392
+
1393
+	const addClasses = (elmts, ...classes) => {
1394
+	  var norm_classes = classesArray(classes);
1395
+	  elmts = castAsArray(elmts);
1396
+	  elmts.map(el => {
1397
+	    norm_classes.map(cls => {
1398
+	      el.classList.add(cls);
1399
+	    });
1400
+	  });
1401
+	};
1402
+	/**
1403
+	 * Remove css classes
1404
+	 *
1405
+	 */
1406
+
1407
+	const removeClasses = (elmts, ...classes) => {
1408
+	  var norm_classes = classesArray(classes);
1409
+	  elmts = castAsArray(elmts);
1410
+	  elmts.map(el => {
1411
+	    norm_classes.map(cls => {
1412
+	      el.classList.remove(cls);
1413
+	    });
1414
+	  });
1415
+	};
1416
+	/**
1417
+	 * Return arguments
1418
+	 *
1419
+	 */
1420
+
1421
+	const classesArray = args => {
1422
+	  var classes = [];
1423
+	  iterate(args, _classes => {
1424
+	    if (typeof _classes === 'string') {
1425
+	      _classes = _classes.trim().split(/[\11\12\14\15\40]/);
1426
+	    }
1427
+
1428
+	    if (Array.isArray(_classes)) {
1429
+	      classes = classes.concat(_classes);
1430
+	    }
1431
+	  });
1432
+	  return classes.filter(Boolean);
1433
+	};
1434
+	/**
1435
+	 * Create an array from arg if it's not already an array
1436
+	 *
1437
+	 */
1438
+
1439
+	const castAsArray = arg => {
1440
+	  if (!Array.isArray(arg)) {
1441
+	    arg = [arg];
1442
+	  }
1443
+
1444
+	  return arg;
1445
+	};
1446
+	/**
1447
+	 * Get the closest node to the evt.target matching the selector
1448
+	 * Stops at wrapper
1449
+	 *
1450
+	 */
1451
+
1452
+	const parentMatch = (target, selector, wrapper) => {
1453
+	  if (wrapper && !wrapper.contains(target)) {
1454
+	    return;
1455
+	  }
1456
+
1457
+	  while (target && target.matches) {
1458
+	    if (target.matches(selector)) {
1459
+	      return target;
1460
+	    }
1461
+
1462
+	    target = target.parentNode;
1463
+	  }
1464
+	};
1465
+	/**
1466
+	 * Get the first or last item from an array
1467
+	 *
1468
+	 * > 0 - right (last)
1469
+	 * <= 0 - left (first)
1470
+	 *
1471
+	 */
1472
+
1473
+	const getTail = (list, direction = 0) => {
1474
+	  if (direction > 0) {
1475
+	    return list[list.length - 1];
1476
+	  }
1477
+
1478
+	  return list[0];
1479
+	};
1480
+	/**
1481
+	 * Return true if an object is empty
1482
+	 *
1483
+	 */
1484
+
1485
+	const isEmptyObject = obj => {
1486
+	  return Object.keys(obj).length === 0;
1487
+	};
1488
+	/**
1489
+	 * Get the index of an element amongst sibling nodes of the same type
1490
+	 *
1491
+	 */
1492
+
1493
+	const nodeIndex = (el, amongst) => {
1494
+	  if (!el) return -1;
1495
+	  amongst = amongst || el.nodeName;
1496
+	  var i = 0;
1497
+
1498
+	  while (el = el.previousElementSibling) {
1499
+	    if (el.matches(amongst)) {
1500
+	      i++;
1501
+	    }
1502
+	  }
1503
+
1504
+	  return i;
1505
+	};
1506
+	/**
1507
+	 * Set attributes of an element
1508
+	 *
1509
+	 */
1510
+
1511
+	const setAttr = (el, attrs) => {
1512
+	  iterate(attrs, (val, attr) => {
1513
+	    if (val == null) {
1514
+	      el.removeAttribute(attr);
1515
+	    } else {
1516
+	      el.setAttribute(attr, '' + val);
1517
+	    }
1518
+	  });
1519
+	};
1520
+	/**
1521
+	 * Replace a node
1522
+	 */
1523
+
1524
+	const replaceNode = (existing, replacement) => {
1525
+	  if (existing.parentNode) existing.parentNode.replaceChild(replacement, existing);
1526
+	};
1527
+
1528
+	/**
1529
+	 * highlight v3 | MIT license | Johann Burkard <jb@eaio.com>
1530
+	 * Highlights arbitrary terms in a node.
1531
+	 *
1532
+	 * - Modified by Marshal <beatgates@gmail.com> 2011-6-24 (added regex)
1533
+	 * - Modified by Brian Reavis <brian@thirdroute.com> 2012-8-27 (cleanup)
1534
+	 */
1535
+	const highlight = (element, regex) => {
1536
+	  if (regex === null) return; // convet string to regex
1537
+
1538
+	  if (typeof regex === 'string') {
1539
+	    if (!regex.length) return;
1540
+	    regex = new RegExp(regex, 'i');
1541
+	  } // Wrap matching part of text node with highlighting <span>, e.g.
1542
+	  // Soccer  ->  <span class="highlight">Soc</span>cer  for regex = /soc/i
1543
+
1544
+
1545
+	  const highlightText = node => {
1546
+	    var match = node.data.match(regex);
1547
+
1548
+	    if (match && node.data.length > 0) {
1549
+	      var spannode = document.createElement('span');
1550
+	      spannode.className = 'highlight';
1551
+	      var middlebit = node.splitText(match.index);
1552
+	      middlebit.splitText(match[0].length);
1553
+	      var middleclone = middlebit.cloneNode(true);
1554
+	      spannode.appendChild(middleclone);
1555
+	      replaceNode(middlebit, spannode);
1556
+	      return 1;
1557
+	    }
1558
+
1559
+	    return 0;
1560
+	  }; // Recurse element node, looking for child text nodes to highlight, unless element
1561
+	  // is childless, <script>, <style>, or already highlighted: <span class="hightlight">
1562
+
1563
+
1564
+	  const highlightChildren = node => {
1565
+	    if (node.nodeType === 1 && node.childNodes && !/(script|style)/i.test(node.tagName) && (node.className !== 'highlight' || node.tagName !== 'SPAN')) {
1566
+	      Array.from(node.childNodes).forEach(element => {
1567
+	        highlightRecursive(element);
1568
+	      });
1569
+	    }
1570
+	  };
1571
+
1572
+	  const highlightRecursive = node => {
1573
+	    if (node.nodeType === 3) {
1574
+	      return highlightText(node);
1575
+	    }
1576
+
1577
+	    highlightChildren(node);
1578
+	    return 0;
1579
+	  };
1580
+
1581
+	  highlightRecursive(element);
1582
+	};
1583
+	/**
1584
+	 * removeHighlight fn copied from highlight v5 and
1585
+	 * edited to remove with(), pass js strict mode, and use without jquery
1586
+	 */
1587
+
1588
+	const removeHighlight = el => {
1589
+	  var elements = el.querySelectorAll("span.highlight");
1590
+	  Array.prototype.forEach.call(elements, function (el) {
1591
+	    var parent = el.parentNode;
1592
+	    parent.replaceChild(el.firstChild, el);
1593
+	    parent.normalize();
1594
+	  });
1595
+	};
1596
+
1597
+	const KEY_A = 65;
1598
+	const KEY_RETURN = 13;
1599
+	const KEY_ESC = 27;
1600
+	const KEY_LEFT = 37;
1601
+	const KEY_UP = 38;
1602
+	const KEY_RIGHT = 39;
1603
+	const KEY_DOWN = 40;
1604
+	const KEY_BACKSPACE = 8;
1605
+	const KEY_DELETE = 46;
1606
+	const KEY_TAB = 9;
1607
+	const IS_MAC = typeof navigator === 'undefined' ? false : /Mac/.test(navigator.userAgent);
1608
+	const KEY_SHORTCUT = IS_MAC ? 'metaKey' : 'ctrlKey'; // ctrl key or apple key for ma
1609
+
1610
+	var defaults = {
1611
+	  options: [],
1612
+	  optgroups: [],
1613
+	  plugins: [],
1614
+	  delimiter: ',',
1615
+	  splitOn: null,
1616
+	  // regexp or string for splitting up values from a paste command
1617
+	  persist: true,
1618
+	  diacritics: true,
1619
+	  create: null,
1620
+	  createOnBlur: false,
1621
+	  createFilter: null,
1622
+	  highlight: true,
1623
+	  openOnFocus: true,
1624
+	  shouldOpen: null,
1625
+	  maxOptions: 50,
1626
+	  maxItems: null,
1627
+	  hideSelected: null,
1628
+	  duplicates: false,
1629
+	  addPrecedence: false,
1630
+	  selectOnTab: false,
1631
+	  preload: null,
1632
+	  allowEmptyOption: false,
1633
+	  //closeAfterSelect: false,
1634
+	  loadThrottle: 300,
1635
+	  loadingClass: 'loading',
1636
+	  dataAttr: null,
1637
+	  //'data-data',
1638
+	  optgroupField: 'optgroup',
1639
+	  valueField: 'value',
1640
+	  labelField: 'text',
1641
+	  disabledField: 'disabled',
1642
+	  optgroupLabelField: 'label',
1643
+	  optgroupValueField: 'value',
1644
+	  lockOptgroupOrder: false,
1645
+	  sortField: '$order',
1646
+	  searchField: ['text'],
1647
+	  searchConjunction: 'and',
1648
+	  mode: null,
1649
+	  wrapperClass: 'ts-wrapper',
1650
+	  controlClass: 'ts-control',
1651
+	  dropdownClass: 'ts-dropdown',
1652
+	  dropdownContentClass: 'ts-dropdown-content',
1653
+	  itemClass: 'item',
1654
+	  optionClass: 'option',
1655
+	  dropdownParent: null,
1656
+	  controlInput: '<input type="text" autocomplete="off" size="1" />',
1657
+	  copyClassesToDropdown: false,
1658
+	  placeholder: null,
1659
+	  hidePlaceholder: null,
1660
+	  shouldLoad: function (query) {
1661
+	    return query.length > 0;
1662
+	  },
1663
+
1664
+	  /*
1665
+	  load                 : null, // function(query, callback) { ... }
1666
+	  score                : null, // function(search) { ... }
1667
+	  onInitialize         : null, // function() { ... }
1668
+	  onChange             : null, // function(value) { ... }
1669
+	  onItemAdd            : null, // function(value, $item) { ... }
1670
+	  onItemRemove         : null, // function(value) { ... }
1671
+	  onClear              : null, // function() { ... }
1672
+	  onOptionAdd          : null, // function(value, data) { ... }
1673
+	  onOptionRemove       : null, // function(value) { ... }
1674
+	  onOptionClear        : null, // function() { ... }
1675
+	  onOptionGroupAdd     : null, // function(id, data) { ... }
1676
+	  onOptionGroupRemove  : null, // function(id) { ... }
1677
+	  onOptionGroupClear   : null, // function() { ... }
1678
+	  onDropdownOpen       : null, // function(dropdown) { ... }
1679
+	  onDropdownClose      : null, // function(dropdown) { ... }
1680
+	  onType               : null, // function(str) { ... }
1681
+	  onDelete             : null, // function(values) { ... }
1682
+	  */
1683
+	  render: {
1684
+	    /*
1685
+	    item: null,
1686
+	    optgroup: null,
1687
+	    optgroup_header: null,
1688
+	    option: null,
1689
+	    option_create: null
1690
+	    */
1691
+	  }
1692
+	};
1693
+
1694
+	/**
1695
+	 * Converts a scalar to its best string representation
1696
+	 * for hash keys and HTML attribute values.
1697
+	 *
1698
+	 * Transformations:
1699
+	 *   'str'     -> 'str'
1700
+	 *   null      -> ''
1701
+	 *   undefined -> ''
1702
+	 *   true      -> '1'
1703
+	 *   false     -> '0'
1704
+	 *   0         -> '0'
1705
+	 *   1         -> '1'
1706
+	 *
1707
+	 */
1708
+	const hash_key = value => {
1709
+	  if (typeof value === 'undefined' || value === null) return null;
1710
+	  return get_hash(value);
1711
+	};
1712
+	const get_hash = value => {
1713
+	  if (typeof value === 'boolean') return value ? '1' : '0';
1714
+	  return value + '';
1715
+	};
1716
+	/**
1717
+	 * Escapes a string for use within HTML.
1718
+	 *
1719
+	 */
1720
+
1721
+	const escape_html = str => {
1722
+	  return (str + '').replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
1723
+	};
1724
+	/**
1725
+	 * Debounce the user provided load function
1726
+	 *
1727
+	 */
1728
+
1729
+	const loadDebounce = (fn, delay) => {
1730
+	  var timeout;
1731
+	  return function (value, callback) {
1732
+	    var self = this;
1733
+
1734
+	    if (timeout) {
1735
+	      self.loading = Math.max(self.loading - 1, 0);
1736
+	      clearTimeout(timeout);
1737
+	    }
1738
+
1739
+	    timeout = setTimeout(function () {
1740
+	      timeout = null;
1741
+	      self.loadedSearches[value] = true;
1742
+	      fn.call(self, value, callback);
1743
+	    }, delay);
1744
+	  };
1745
+	};
1746
+	/**
1747
+	 * Debounce all fired events types listed in `types`
1748
+	 * while executing the provided `fn`.
1749
+	 *
1750
+	 */
1751
+
1752
+	const debounce_events = (self, types, fn) => {
1753
+	  var type;
1754
+	  var trigger = self.trigger;
1755
+	  var event_args = {}; // override trigger method
1756
+
1757
+	  self.trigger = function () {
1758
+	    var type = arguments[0];
1759
+
1760
+	    if (types.indexOf(type) !== -1) {
1761
+	      event_args[type] = arguments;
1762
+	    } else {
1763
+	      return trigger.apply(self, arguments);
1764
+	    }
1765
+	  }; // invoke provided function
1766
+
1767
+
1768
+	  fn.apply(self, []);
1769
+	  self.trigger = trigger; // trigger queued events
1770
+
1771
+	  for (type of types) {
1772
+	    if (type in event_args) {
1773
+	      trigger.apply(self, event_args[type]);
1774
+	    }
1775
+	  }
1776
+	};
1777
+	/**
1778
+	 * Determines the current selection within a text input control.
1779
+	 * Returns an object containing:
1780
+	 *   - start
1781
+	 *   - length
1782
+	 *
1783
+	 */
1784
+
1785
+	const getSelection = input => {
1786
+	  return {
1787
+	    start: input.selectionStart || 0,
1788
+	    length: (input.selectionEnd || 0) - (input.selectionStart || 0)
1789
+	  };
1790
+	};
1791
+	/**
1792
+	 * Prevent default
1793
+	 *
1794
+	 */
1795
+
1796
+	const preventDefault = (evt, stop = false) => {
1797
+	  if (evt) {
1798
+	    evt.preventDefault();
1799
+
1800
+	    if (stop) {
1801
+	      evt.stopPropagation();
1802
+	    }
1803
+	  }
1804
+	};
1805
+	/**
1806
+	 * Add event helper
1807
+	 *
1808
+	 */
1809
+
1810
+	const addEvent = (target, type, callback, options) => {
1811
+	  target.addEventListener(type, callback, options);
1812
+	};
1813
+	/**
1814
+	 * Return true if the requested key is down
1815
+	 * Will return false if more than one control character is pressed ( when [ctrl+shift+a] != [ctrl+a] )
1816
+	 * The current evt may not always set ( eg calling advanceSelection() )
1817
+	 *
1818
+	 */
1819
+
1820
+	const isKeyDown = (key_name, evt) => {
1821
+	  if (!evt) {
1822
+	    return false;
1823
+	  }
1824
+
1825
+	  if (!evt[key_name]) {
1826
+	    return false;
1827
+	  }
1828
+
1829
+	  var count = (evt.altKey ? 1 : 0) + (evt.ctrlKey ? 1 : 0) + (evt.shiftKey ? 1 : 0) + (evt.metaKey ? 1 : 0);
1830
+
1831
+	  if (count === 1) {
1832
+	    return true;
1833
+	  }
1834
+
1835
+	  return false;
1836
+	};
1837
+	/**
1838
+	 * Get the id of an element
1839
+	 * If the id attribute is not set, set the attribute with the given id
1840
+	 *
1841
+	 */
1842
+
1843
+	const getId = (el, id) => {
1844
+	  const existing_id = el.getAttribute('id');
1845
+
1846
+	  if (existing_id) {
1847
+	    return existing_id;
1848
+	  }
1849
+
1850
+	  el.setAttribute('id', id);
1851
+	  return id;
1852
+	};
1853
+	/**
1854
+	 * Returns a string with backslashes added before characters that need to be escaped.
1855
+	 */
1856
+
1857
+	const addSlashes = str => {
1858
+	  return str.replace(/[\\"']/g, '\\$&');
1859
+	};
1860
+	/**
1861
+	 *
1862
+	 */
1863
+
1864
+	const append = (parent, node) => {
1865
+	  if (node) parent.append(node);
1866
+	};
1867
+
1868
+	function getSettings(input, settings_user) {
1869
+	  var settings = Object.assign({}, defaults, settings_user);
1870
+	  var attr_data = settings.dataAttr;
1871
+	  var field_label = settings.labelField;
1872
+	  var field_value = settings.valueField;
1873
+	  var field_disabled = settings.disabledField;
1874
+	  var field_optgroup = settings.optgroupField;
1875
+	  var field_optgroup_label = settings.optgroupLabelField;
1876
+	  var field_optgroup_value = settings.optgroupValueField;
1877
+	  var tag_name = input.tagName.toLowerCase();
1878
+	  var placeholder = input.getAttribute('placeholder') || input.getAttribute('data-placeholder');
1879
+
1880
+	  if (!placeholder && !settings.allowEmptyOption) {
1881
+	    let option = input.querySelector('option[value=""]');
1882
+
1883
+	    if (option) {
1884
+	      placeholder = option.textContent;
1885
+	    }
1886
+	  }
1887
+
1888
+	  var settings_element = {
1889
+	    placeholder: placeholder,
1890
+	    options: [],
1891
+	    optgroups: [],
1892
+	    items: [],
1893
+	    maxItems: null
1894
+	  };
1895
+	  /**
1896
+	   * Initialize from a <select> element.
1897
+	   *
1898
+	   */
1899
+
1900
+	  var init_select = () => {
1901
+	    var tagName;
1902
+	    var options = settings_element.options;
1903
+	    var optionsMap = {};
1904
+	    var group_count = 1;
1905
+
1906
+	    var readData = el => {
1907
+	      var data = Object.assign({}, el.dataset); // get plain object from DOMStringMap
1908
+
1909
+	      var json = attr_data && data[attr_data];
1910
+
1911
+	      if (typeof json === 'string' && json.length) {
1912
+	        data = Object.assign(data, JSON.parse(json));
1913
+	      }
1914
+
1915
+	      return data;
1916
+	    };
1917
+
1918
+	    var addOption = (option, group) => {
1919
+	      var value = hash_key(option.value);
1920
+	      if (value == null) return;
1921
+	      if (!value && !settings.allowEmptyOption) return; // if the option already exists, it's probably been
1922
+	      // duplicated in another optgroup. in this case, push
1923
+	      // the current group to the "optgroup" property on the
1924
+	      // existing option so that it's rendered in both places.
1925
+
1926
+	      if (optionsMap.hasOwnProperty(value)) {
1927
+	        if (group) {
1928
+	          var arr = optionsMap[value][field_optgroup];
1929
+
1930
+	          if (!arr) {
1931
+	            optionsMap[value][field_optgroup] = group;
1932
+	          } else if (!Array.isArray(arr)) {
1933
+	            optionsMap[value][field_optgroup] = [arr, group];
1934
+	          } else {
1935
+	            arr.push(group);
1936
+	          }
1937
+	        }
1938
+	      } else {
1939
+	        var option_data = readData(option);
1940
+	        option_data[field_label] = option_data[field_label] || option.textContent;
1941
+	        option_data[field_value] = option_data[field_value] || value;
1942
+	        option_data[field_disabled] = option_data[field_disabled] || option.disabled;
1943
+	        option_data[field_optgroup] = option_data[field_optgroup] || group;
1944
+	        option_data.$option = option;
1945
+	        optionsMap[value] = option_data;
1946
+	        options.push(option_data);
1947
+	      }
1948
+
1949
+	      if (option.selected) {
1950
+	        settings_element.items.push(value);
1951
+	      }
1952
+	    };
1953
+
1954
+	    var addGroup = optgroup => {
1955
+	      var id, optgroup_data;
1956
+	      optgroup_data = readData(optgroup);
1957
+	      optgroup_data[field_optgroup_label] = optgroup_data[field_optgroup_label] || optgroup.getAttribute('label') || '';
1958
+	      optgroup_data[field_optgroup_value] = optgroup_data[field_optgroup_value] || group_count++;
1959
+	      optgroup_data[field_disabled] = optgroup_data[field_disabled] || optgroup.disabled;
1960
+	      settings_element.optgroups.push(optgroup_data);
1961
+	      id = optgroup_data[field_optgroup_value];
1962
+	      iterate(optgroup.children, option => {
1963
+	        addOption(option, id);
1964
+	      });
1965
+	    };
1966
+
1967
+	    settings_element.maxItems = input.hasAttribute('multiple') ? null : 1;
1968
+	    iterate(input.children, child => {
1969
+	      tagName = child.tagName.toLowerCase();
1970
+
1971
+	      if (tagName === 'optgroup') {
1972
+	        addGroup(child);
1973
+	      } else if (tagName === 'option') {
1974
+	        addOption(child);
1975
+	      }
1976
+	    });
1977
+	  };
1978
+	  /**
1979
+	   * Initialize from a <input type="text"> element.
1980
+	   *
1981
+	   */
1982
+
1983
+
1984
+	  var init_textbox = () => {
1985
+	    const data_raw = input.getAttribute(attr_data);
1986
+
1987
+	    if (!data_raw) {
1988
+	      var value = input.value.trim() || '';
1989
+	      if (!settings.allowEmptyOption && !value.length) return;
1990
+	      const values = value.split(settings.delimiter);
1991
+	      iterate(values, value => {
1992
+	        const option = {};
1993
+	        option[field_label] = value;
1994
+	        option[field_value] = value;
1995
+	        settings_element.options.push(option);
1996
+	      });
1997
+	      settings_element.items = values;
1998
+	    } else {
1999
+	      settings_element.options = JSON.parse(data_raw);
2000
+	      iterate(settings_element.options, opt => {
2001
+	        settings_element.items.push(opt[field_value]);
2002
+	      });
2003
+	    }
2004
+	  };
2005
+
2006
+	  if (tag_name === 'select') {
2007
+	    init_select();
2008
+	  } else {
2009
+	    init_textbox();
2010
+	  }
2011
+
2012
+	  return Object.assign({}, defaults, settings_element, settings_user);
2013
+	}
2014
+
2015
+	var instance_i = 0;
2016
+	class TomSelect extends MicroPlugin(MicroEvent) {
2017
+	  // @deprecated 1.8
2018
+	  constructor(input_arg, user_settings) {
2019
+	    super();
2020
+	    this.control_input = void 0;
2021
+	    this.wrapper = void 0;
2022
+	    this.dropdown = void 0;
2023
+	    this.control = void 0;
2024
+	    this.dropdown_content = void 0;
2025
+	    this.focus_node = void 0;
2026
+	    this.order = 0;
2027
+	    this.settings = void 0;
2028
+	    this.input = void 0;
2029
+	    this.tabIndex = void 0;
2030
+	    this.is_select_tag = void 0;
2031
+	    this.rtl = void 0;
2032
+	    this.inputId = void 0;
2033
+	    this._destroy = void 0;
2034
+	    this.sifter = void 0;
2035
+	    this.isOpen = false;
2036
+	    this.isDisabled = false;
2037
+	    this.isRequired = void 0;
2038
+	    this.isInvalid = false;
2039
+	    this.isValid = true;
2040
+	    this.isLocked = false;
2041
+	    this.isFocused = false;
2042
+	    this.isInputHidden = false;
2043
+	    this.isSetup = false;
2044
+	    this.ignoreFocus = false;
2045
+	    this.ignoreHover = false;
2046
+	    this.hasOptions = false;
2047
+	    this.currentResults = void 0;
2048
+	    this.lastValue = '';
2049
+	    this.caretPos = 0;
2050
+	    this.loading = 0;
2051
+	    this.loadedSearches = {};
2052
+	    this.activeOption = null;
2053
+	    this.activeItems = [];
2054
+	    this.optgroups = {};
2055
+	    this.options = {};
2056
+	    this.userOptions = {};
2057
+	    this.items = [];
2058
+	    instance_i++;
2059
+	    var dir;
2060
+	    var input = getDom(input_arg);
2061
+
2062
+	    if (input.tomselect) {
2063
+	      throw new Error('Tom Select already initialized on this element');
2064
+	    }
2065
+
2066
+	    input.tomselect = this; // detect rtl environment
2067
+
2068
+	    var computedStyle = window.getComputedStyle && window.getComputedStyle(input, null);
2069
+	    dir = computedStyle.getPropertyValue('direction'); // setup default state
2070
+
2071
+	    const settings = getSettings(input, user_settings);
2072
+	    this.settings = settings;
2073
+	    this.input = input;
2074
+	    this.tabIndex = input.tabIndex || 0;
2075
+	    this.is_select_tag = input.tagName.toLowerCase() === 'select';
2076
+	    this.rtl = /rtl/i.test(dir);
2077
+	    this.inputId = getId(input, 'tomselect-' + instance_i);
2078
+	    this.isRequired = input.required; // search system
2079
+
2080
+	    this.sifter = new Sifter(this.options, {
2081
+	      diacritics: settings.diacritics
2082
+	    }); // option-dependent defaults
2083
+
2084
+	    settings.mode = settings.mode || (settings.maxItems === 1 ? 'single' : 'multi');
2085
+
2086
+	    if (typeof settings.hideSelected !== 'boolean') {
2087
+	      settings.hideSelected = settings.mode === 'multi';
2088
+	    }
2089
+
2090
+	    if (typeof settings.hidePlaceholder !== 'boolean') {
2091
+	      settings.hidePlaceholder = settings.mode !== 'multi';
2092
+	    } // set up createFilter callback
2093
+
2094
+
2095
+	    var filter = settings.createFilter;
2096
+
2097
+	    if (typeof filter !== 'function') {
2098
+	      if (typeof filter === 'string') {
2099
+	        filter = new RegExp(filter);
2100
+	      }
2101
+
2102
+	      if (filter instanceof RegExp) {
2103
+	        settings.createFilter = input => filter.test(input);
2104
+	      } else {
2105
+	        settings.createFilter = value => {
2106
+	          return this.settings.duplicates || !this.options[value];
2107
+	        };
2108
+	      }
2109
+	    }
2110
+
2111
+	    this.initializePlugins(settings.plugins);
2112
+	    this.setupCallbacks();
2113
+	    this.setupTemplates(); // Create all elements
2114
+
2115
+	    const wrapper = getDom('<div>');
2116
+	    const control = getDom('<div>');
2117
+
2118
+	    const dropdown = this._render('dropdown');
2119
+
2120
+	    const dropdown_content = getDom(`<div role="listbox" tabindex="-1">`);
2121
+	    const classes = this.input.getAttribute('class') || '';
2122
+	    const inputMode = settings.mode;
2123
+	    var control_input;
2124
+	    addClasses(wrapper, settings.wrapperClass, classes, inputMode);
2125
+	    addClasses(control, settings.controlClass);
2126
+	    append(wrapper, control);
2127
+	    addClasses(dropdown, settings.dropdownClass, inputMode);
2128
+
2129
+	    if (settings.copyClassesToDropdown) {
2130
+	      addClasses(dropdown, classes);
2131
+	    }
2132
+
2133
+	    addClasses(dropdown_content, settings.dropdownContentClass);
2134
+	    append(dropdown, dropdown_content);
2135
+	    getDom(settings.dropdownParent || wrapper).appendChild(dropdown); // default controlInput
2136
+
2137
+	    if (isHtmlString(settings.controlInput)) {
2138
+	      control_input = getDom(settings.controlInput); // set attributes
2139
+
2140
+	      var attrs = ['autocorrect', 'autocapitalize', 'autocomplete'];
2141
+	      iterate$1(attrs, attr => {
2142
+	        if (input.getAttribute(attr)) {
2143
+	          setAttr(control_input, {
2144
+	            [attr]: input.getAttribute(attr)
2145
+	          });
2146
+	        }
2147
+	      });
2148
+	      control_input.tabIndex = -1;
2149
+	      control.appendChild(control_input);
2150
+	      this.focus_node = control_input; // dom element
2151
+	    } else if (settings.controlInput) {
2152
+	      control_input = getDom(settings.controlInput);
2153
+	      this.focus_node = control_input;
2154
+	    } else {
2155
+	      control_input = getDom('<input/>');
2156
+	      this.focus_node = control;
2157
+	    }
2158
+
2159
+	    this.wrapper = wrapper;
2160
+	    this.dropdown = dropdown;
2161
+	    this.dropdown_content = dropdown_content;
2162
+	    this.control = control;
2163
+	    this.control_input = control_input;
2164
+	    this.setup();
2165
+	  }
2166
+	  /**
2167
+	   * set up event bindings.
2168
+	   *
2169
+	   */
2170
+
2171
+
2172
+	  setup() {
2173
+	    const self = this;
2174
+	    const settings = self.settings;
2175
+	    const control_input = self.control_input;
2176
+	    const dropdown = self.dropdown;
2177
+	    const dropdown_content = self.dropdown_content;
2178
+	    const wrapper = self.wrapper;
2179
+	    const control = self.control;
2180
+	    const input = self.input;
2181
+	    const focus_node = self.focus_node;
2182
+	    const passive_event = {
2183
+	      passive: true
2184
+	    };
2185
+	    const listboxId = self.inputId + '-ts-dropdown';
2186
+	    setAttr(dropdown_content, {
2187
+	      id: listboxId
2188
+	    });
2189
+	    setAttr(focus_node, {
2190
+	      role: 'combobox',
2191
+	      'aria-haspopup': 'listbox',
2192
+	      'aria-expanded': 'false',
2193
+	      'aria-controls': listboxId
2194
+	    });
2195
+	    const control_id = getId(focus_node, self.inputId + '-ts-control');
2196
+	    const query = "label[for='" + escapeQuery(self.inputId) + "']";
2197
+	    const label = document.querySelector(query);
2198
+	    const label_click = self.focus.bind(self);
2199
+
2200
+	    if (label) {
2201
+	      addEvent(label, 'click', label_click);
2202
+	      setAttr(label, {
2203
+	        for: control_id
2204
+	      });
2205
+	      const label_id = getId(label, self.inputId + '-ts-label');
2206
+	      setAttr(focus_node, {
2207
+	        'aria-labelledby': label_id
2208
+	      });
2209
+	      setAttr(dropdown_content, {
2210
+	        'aria-labelledby': label_id
2211
+	      });
2212
+	    }
2213
+
2214
+	    wrapper.style.width = input.style.width;
2215
+
2216
+	    if (self.plugins.names.length) {
2217
+	      const classes_plugins = 'plugin-' + self.plugins.names.join(' plugin-');
2218
+	      addClasses([wrapper, dropdown], classes_plugins);
2219
+	    }
2220
+
2221
+	    if ((settings.maxItems === null || settings.maxItems > 1) && self.is_select_tag) {
2222
+	      setAttr(input, {
2223
+	        multiple: 'multiple'
2224
+	      });
2225
+	    }
2226
+
2227
+	    if (settings.placeholder) {
2228
+	      setAttr(control_input, {
2229
+	        placeholder: settings.placeholder
2230
+	      });
2231
+	    } // if splitOn was not passed in, construct it from the delimiter to allow pasting universally
2232
+
2233
+
2234
+	    if (!settings.splitOn && settings.delimiter) {
2235
+	      settings.splitOn = new RegExp('\\s*' + escape_regex(settings.delimiter) + '+\\s*');
2236
+	    } // debounce user defined load() if loadThrottle > 0
2237
+	    // after initializePlugins() so plugins can create/modify user defined loaders
2238
+
2239
+
2240
+	    if (settings.load && settings.loadThrottle) {
2241
+	      settings.load = loadDebounce(settings.load, settings.loadThrottle);
2242
+	    }
2243
+
2244
+	    self.control_input.type = input.type;
2245
+	    addEvent(dropdown, 'mousemove', () => {
2246
+	      self.ignoreHover = false;
2247
+	    });
2248
+	    addEvent(dropdown, 'mouseenter', e => {
2249
+	      var target_match = parentMatch(e.target, '[data-selectable]', dropdown);
2250
+	      if (target_match) self.onOptionHover(e, target_match);
2251
+	    }, {
2252
+	      capture: true
2253
+	    }); // clicking on an option should select it
2254
+
2255
+	    addEvent(dropdown, 'click', evt => {
2256
+	      const option = parentMatch(evt.target, '[data-selectable]');
2257
+
2258
+	      if (option) {
2259
+	        self.onOptionSelect(evt, option);
2260
+	        preventDefault(evt, true);
2261
+	      }
2262
+	    });
2263
+	    addEvent(control, 'click', evt => {
2264
+	      var target_match = parentMatch(evt.target, '[data-ts-item]', control);
2265
+
2266
+	      if (target_match && self.onItemSelect(evt, target_match)) {
2267
+	        preventDefault(evt, true);
2268
+	        return;
2269
+	      } // retain focus (see control_input mousedown)
2270
+
2271
+
2272
+	      if (control_input.value != '') {
2273
+	        return;
2274
+	      }
2275
+
2276
+	      self.onClick();
2277
+	      preventDefault(evt, true);
2278
+	    }); // keydown on focus_node for arrow_down/arrow_up
2279
+
2280
+	    addEvent(focus_node, 'keydown', e => self.onKeyDown(e)); // keypress and input/keyup
2281
+
2282
+	    addEvent(control_input, 'keypress', e => self.onKeyPress(e));
2283
+	    addEvent(control_input, 'input', e => self.onInput(e));
2284
+	    addEvent(focus_node, 'blur', e => self.onBlur(e));
2285
+	    addEvent(focus_node, 'focus', e => self.onFocus(e));
2286
+	    addEvent(control_input, 'paste', e => self.onPaste(e));
2287
+
2288
+	    const doc_mousedown = evt => {
2289
+	      // blur if target is outside of this instance
2290
+	      // dropdown is not always inside wrapper
2291
+	      const target = evt.composedPath()[0];
2292
+
2293
+	      if (!wrapper.contains(target) && !dropdown.contains(target)) {
2294
+	        if (self.isFocused) {
2295
+	          self.blur();
2296
+	        }
2297
+
2298
+	        self.inputState();
2299
+	        return;
2300
+	      } // retain focus by preventing native handling. if the
2301
+	      // event target is the input it should not be modified.
2302
+	      // otherwise, text selection within the input won't work.
2303
+	      // Fixes bug #212 which is no covered by tests
2304
+
2305
+
2306
+	      if (target == control_input && self.isOpen) {
2307
+	        evt.stopPropagation(); // clicking anywhere in the control should not blur the control_input (which would close the dropdown)
2308
+	      } else {
2309
+	        preventDefault(evt, true);
2310
+	      }
2311
+	    };
2312
+
2313
+	    const win_scroll = () => {
2314
+	      if (self.isOpen) {
2315
+	        self.positionDropdown();
2316
+	      }
2317
+	    };
2318
+
2319
+	    addEvent(document, 'mousedown', doc_mousedown);
2320
+	    addEvent(window, 'scroll', win_scroll, passive_event);
2321
+	    addEvent(window, 'resize', win_scroll, passive_event);
2322
+
2323
+	    this._destroy = () => {
2324
+	      document.removeEventListener('mousedown', doc_mousedown);
2325
+	      window.removeEventListener('scroll', win_scroll);
2326
+	      window.removeEventListener('resize', win_scroll);
2327
+	      if (label) label.removeEventListener('click', label_click);
2328
+	    }; // store original html and tab index so that they can be
2329
+	    // restored when the destroy() method is called.
2330
+
2331
+
2332
+	    this.revertSettings = {
2333
+	      innerHTML: input.innerHTML,
2334
+	      tabIndex: input.tabIndex
2335
+	    };
2336
+	    input.tabIndex = -1;
2337
+	    input.insertAdjacentElement('afterend', self.wrapper);
2338
+	    self.sync(false);
2339
+	    settings.items = [];
2340
+	    delete settings.optgroups;
2341
+	    delete settings.options;
2342
+	    addEvent(input, 'invalid', () => {
2343
+	      if (self.isValid) {
2344
+	        self.isValid = false;
2345
+	        self.isInvalid = true;
2346
+	        self.refreshState();
2347
+	      }
2348
+	    });
2349
+	    self.updateOriginalInput();
2350
+	    self.refreshItems();
2351
+	    self.close(false);
2352
+	    self.inputState();
2353
+	    self.isSetup = true;
2354
+
2355
+	    if (input.disabled) {
2356
+	      self.disable();
2357
+	    } else {
2358
+	      self.enable(); //sets tabIndex
2359
+	    }
2360
+
2361
+	    self.on('change', this.onChange);
2362
+	    addClasses(input, 'tomselected', 'ts-hidden-accessible');
2363
+	    self.trigger('initialize'); // preload options
2364
+
2365
+	    if (settings.preload === true) {
2366
+	      self.preload();
2367
+	    }
2368
+	  }
2369
+	  /**
2370
+	   * Register options and optgroups
2371
+	   *
2372
+	   */
2373
+
2374
+
2375
+	  setupOptions(options = [], optgroups = []) {
2376
+	    // build options table
2377
+	    this.addOptions(options); // build optgroup table
2378
+
2379
+	    iterate$1(optgroups, optgroup => {
2380
+	      this.registerOptionGroup(optgroup);
2381
+	    });
2382
+	  }
2383
+	  /**
2384
+	   * Sets up default rendering functions.
2385
+	   */
2386
+
2387
+
2388
+	  setupTemplates() {
2389
+	    var self = this;
2390
+	    var field_label = self.settings.labelField;
2391
+	    var field_optgroup = self.settings.optgroupLabelField;
2392
+	    var templates = {
2393
+	      'optgroup': data => {
2394
+	        let optgroup = document.createElement('div');
2395
+	        optgroup.className = 'optgroup';
2396
+	        optgroup.appendChild(data.options);
2397
+	        return optgroup;
2398
+	      },
2399
+	      'optgroup_header': (data, escape) => {
2400
+	        return '<div class="optgroup-header">' + escape(data[field_optgroup]) + '</div>';
2401
+	      },
2402
+	      'option': (data, escape) => {
2403
+	        return '<div>' + escape(data[field_label]) + '</div>';
2404
+	      },
2405
+	      'item': (data, escape) => {
2406
+	        return '<div>' + escape(data[field_label]) + '</div>';
2407
+	      },
2408
+	      'option_create': (data, escape) => {
2409
+	        return '<div class="create">Add <strong>' + escape(data.input) + '</strong>&hellip;</div>';
2410
+	      },
2411
+	      'no_results': () => {
2412
+	        return '<div class="no-results">No results found</div>';
2413
+	      },
2414
+	      'loading': () => {
2415
+	        return '<div class="spinner"></div>';
2416
+	      },
2417
+	      'not_loading': () => {},
2418
+	      'dropdown': () => {
2419
+	        return '<div></div>';
2420
+	      }
2421
+	    };
2422
+	    self.settings.render = Object.assign({}, templates, self.settings.render);
2423
+	  }
2424
+	  /**
2425
+	   * Maps fired events to callbacks provided
2426
+	   * in the settings used when creating the control.
2427
+	   */
2428
+
2429
+
2430
+	  setupCallbacks() {
2431
+	    var key, fn;
2432
+	    var callbacks = {
2433
+	      'initialize': 'onInitialize',
2434
+	      'change': 'onChange',
2435
+	      'item_add': 'onItemAdd',
2436
+	      'item_remove': 'onItemRemove',
2437
+	      'item_select': 'onItemSelect',
2438
+	      'clear': 'onClear',
2439
+	      'option_add': 'onOptionAdd',
2440
+	      'option_remove': 'onOptionRemove',
2441
+	      'option_clear': 'onOptionClear',
2442
+	      'optgroup_add': 'onOptionGroupAdd',
2443
+	      'optgroup_remove': 'onOptionGroupRemove',
2444
+	      'optgroup_clear': 'onOptionGroupClear',
2445
+	      'dropdown_open': 'onDropdownOpen',
2446
+	      'dropdown_close': 'onDropdownClose',
2447
+	      'type': 'onType',
2448
+	      'load': 'onLoad',
2449
+	      'focus': 'onFocus',
2450
+	      'blur': 'onBlur'
2451
+	    };
2452
+
2453
+	    for (key in callbacks) {
2454
+	      fn = this.settings[callbacks[key]];
2455
+	      if (fn) this.on(key, fn);
2456
+	    }
2457
+	  }
2458
+	  /**
2459
+	   * Sync the Tom Select instance with the original input or select
2460
+	   *
2461
+	   */
2462
+
2463
+
2464
+	  sync(get_settings = true) {
2465
+	    const self = this;
2466
+	    const settings = get_settings ? getSettings(self.input, {
2467
+	      delimiter: self.settings.delimiter
2468
+	    }) : self.settings;
2469
+	    self.setupOptions(settings.options, settings.optgroups);
2470
+	    self.setValue(settings.items || [], true); // silent prevents recursion
2471
+
2472
+	    self.lastQuery = null; // so updated options will be displayed in dropdown
2473
+	  }
2474
+	  /**
2475
+	   * Triggered when the main control element
2476
+	   * has a click event.
2477
+	   *
2478
+	   */
2479
+
2480
+
2481
+	  onClick() {
2482
+	    var self = this;
2483
+
2484
+	    if (self.activeItems.length > 0) {
2485
+	      self.clearActiveItems();
2486
+	      self.focus();
2487
+	      return;
2488
+	    }
2489
+
2490
+	    if (self.isFocused && self.isOpen) {
2491
+	      self.blur();
2492
+	    } else {
2493
+	      self.focus();
2494
+	    }
2495
+	  }
2496
+	  /**
2497
+	   * @deprecated v1.7
2498
+	   *
2499
+	   */
2500
+
2501
+
2502
+	  onMouseDown() {}
2503
+	  /**
2504
+	   * Triggered when the value of the control has been changed.
2505
+	   * This should propagate the event to the original DOM
2506
+	   * input / select element.
2507
+	   */
2508
+
2509
+
2510
+	  onChange() {
2511
+	    triggerEvent(this.input, 'input');
2512
+	    triggerEvent(this.input, 'change');
2513
+	  }
2514
+	  /**
2515
+	   * Triggered on <input> paste.
2516
+	   *
2517
+	   */
2518
+
2519
+
2520
+	  onPaste(e) {
2521
+	    var self = this;
2522
+
2523
+	    if (self.isInputHidden || self.isLocked) {
2524
+	      preventDefault(e);
2525
+	      return;
2526
+	    } // If a regex or string is included, this will split the pasted
2527
+	    // input and create Items for each separate value
2528
+
2529
+
2530
+	    if (!self.settings.splitOn) {
2531
+	      return;
2532
+	    } // Wait for pasted text to be recognized in value
2533
+
2534
+
2535
+	    setTimeout(() => {
2536
+	      var pastedText = self.inputValue();
2537
+
2538
+	      if (!pastedText.match(self.settings.splitOn)) {
2539
+	        return;
2540
+	      }
2541
+
2542
+	      var splitInput = pastedText.trim().split(self.settings.splitOn);
2543
+	      iterate$1(splitInput, piece => {
2544
+	        const hash = hash_key(piece);
2545
+
2546
+	        if (hash) {
2547
+	          if (this.options[piece]) {
2548
+	            self.addItem(piece);
2549
+	          } else {
2550
+	            self.createItem(piece);
2551
+	          }
2552
+	        }
2553
+	      });
2554
+	    }, 0);
2555
+	  }
2556
+	  /**
2557
+	   * Triggered on <input> keypress.
2558
+	   *
2559
+	   */
2560
+
2561
+
2562
+	  onKeyPress(e) {
2563
+	    var self = this;
2564
+
2565
+	    if (self.isLocked) {
2566
+	      preventDefault(e);
2567
+	      return;
2568
+	    }
2569
+
2570
+	    var character = String.fromCharCode(e.keyCode || e.which);
2571
+
2572
+	    if (self.settings.create && self.settings.mode === 'multi' && character === self.settings.delimiter) {
2573
+	      self.createItem();
2574
+	      preventDefault(e);
2575
+	      return;
2576
+	    }
2577
+	  }
2578
+	  /**
2579
+	   * Triggered on <input> keydown.
2580
+	   *
2581
+	   */
2582
+
2583
+
2584
+	  onKeyDown(e) {
2585
+	    var self = this;
2586
+	    self.ignoreHover = true;
2587
+
2588
+	    if (self.isLocked) {
2589
+	      if (e.keyCode !== KEY_TAB) {
2590
+	        preventDefault(e);
2591
+	      }
2592
+
2593
+	      return;
2594
+	    }
2595
+
2596
+	    switch (e.keyCode) {
2597
+	      // ctrl+A: select all
2598
+	      case KEY_A:
2599
+	        if (isKeyDown(KEY_SHORTCUT, e)) {
2600
+	          if (self.control_input.value == '') {
2601
+	            preventDefault(e);
2602
+	            self.selectAll();
2603
+	            return;
2604
+	          }
2605
+	        }
2606
+
2607
+	        break;
2608
+	      // esc: close dropdown
2609
+
2610
+	      case KEY_ESC:
2611
+	        if (self.isOpen) {
2612
+	          preventDefault(e, true);
2613
+	          self.close();
2614
+	        }
2615
+
2616
+	        self.clearActiveItems();
2617
+	        return;
2618
+	      // down: open dropdown or move selection down
2619
+
2620
+	      case KEY_DOWN:
2621
+	        if (!self.isOpen && self.hasOptions) {
2622
+	          self.open();
2623
+	        } else if (self.activeOption) {
2624
+	          let next = self.getAdjacent(self.activeOption, 1);
2625
+	          if (next) self.setActiveOption(next);
2626
+	        }
2627
+
2628
+	        preventDefault(e);
2629
+	        return;
2630
+	      // up: move selection up
2631
+
2632
+	      case KEY_UP:
2633
+	        if (self.activeOption) {
2634
+	          let prev = self.getAdjacent(self.activeOption, -1);
2635
+	          if (prev) self.setActiveOption(prev);
2636
+	        }
2637
+
2638
+	        preventDefault(e);
2639
+	        return;
2640
+	      // return: select active option
2641
+
2642
+	      case KEY_RETURN:
2643
+	        if (self.canSelect(self.activeOption)) {
2644
+	          self.onOptionSelect(e, self.activeOption);
2645
+	          preventDefault(e); // if the option_create=null, the dropdown might be closed
2646
+	        } else if (self.settings.create && self.createItem()) {
2647
+	          preventDefault(e); // don't submit form when searching for a value
2648
+	        } else if (document.activeElement == self.control_input && self.isOpen) {
2649
+	          preventDefault(e);
2650
+	        }
2651
+
2652
+	        return;
2653
+	      // left: modifiy item selection to the left
2654
+
2655
+	      case KEY_LEFT:
2656
+	        self.advanceSelection(-1, e);
2657
+	        return;
2658
+	      // right: modifiy item selection to the right
2659
+
2660
+	      case KEY_RIGHT:
2661
+	        self.advanceSelection(1, e);
2662
+	        return;
2663
+	      // tab: select active option and/or create item
2664
+
2665
+	      case KEY_TAB:
2666
+	        if (self.settings.selectOnTab) {
2667
+	          if (self.canSelect(self.activeOption)) {
2668
+	            self.onOptionSelect(e, self.activeOption); // prevent default [tab] behaviour of jump to the next field
2669
+	            // if select isFull, then the dropdown won't be open and [tab] will work normally
2670
+
2671
+	            preventDefault(e);
2672
+	          }
2673
+
2674
+	          if (self.settings.create && self.createItem()) {
2675
+	            preventDefault(e);
2676
+	          }
2677
+	        }
2678
+
2679
+	        return;
2680
+	      // delete|backspace: delete items
2681
+
2682
+	      case KEY_BACKSPACE:
2683
+	      case KEY_DELETE:
2684
+	        self.deleteSelection(e);
2685
+	        return;
2686
+	    } // don't enter text in the control_input when active items are selected
2687
+
2688
+
2689
+	    if (self.isInputHidden && !isKeyDown(KEY_SHORTCUT, e)) {
2690
+	      preventDefault(e);
2691
+	    }
2692
+	  }
2693
+	  /**
2694
+	   * Triggered on <input> keyup.
2695
+	   *
2696
+	   */
2697
+
2698
+
2699
+	  onInput(e) {
2700
+	    var self = this;
2701
+
2702
+	    if (self.isLocked) {
2703
+	      return;
2704
+	    }
2705
+
2706
+	    var value = self.inputValue();
2707
+
2708
+	    if (self.lastValue !== value) {
2709
+	      self.lastValue = value;
2710
+
2711
+	      if (self.settings.shouldLoad.call(self, value)) {
2712
+	        self.load(value);
2713
+	      }
2714
+
2715
+	      self.refreshOptions();
2716
+	      self.trigger('type', value);
2717
+	    }
2718
+	  }
2719
+	  /**
2720
+	   * Triggered when the user rolls over
2721
+	   * an option in the autocomplete dropdown menu.
2722
+	   *
2723
+	   */
2724
+
2725
+
2726
+	  onOptionHover(evt, option) {
2727
+	    if (this.ignoreHover) return;
2728
+	    this.setActiveOption(option, false);
2729
+	  }
2730
+	  /**
2731
+	   * Triggered on <input> focus.
2732
+	   *
2733
+	   */
2734
+
2735
+
2736
+	  onFocus(e) {
2737
+	    var self = this;
2738
+	    var wasFocused = self.isFocused;
2739
+
2740
+	    if (self.isDisabled) {
2741
+	      self.blur();
2742
+	      preventDefault(e);
2743
+	      return;
2744
+	    }
2745
+
2746
+	    if (self.ignoreFocus) return;
2747
+	    self.isFocused = true;
2748
+	    if (self.settings.preload === 'focus') self.preload();
2749
+	    if (!wasFocused) self.trigger('focus');
2750
+
2751
+	    if (!self.activeItems.length) {
2752
+	      self.showInput();
2753
+	      self.refreshOptions(!!self.settings.openOnFocus);
2754
+	    }
2755
+
2756
+	    self.refreshState();
2757
+	  }
2758
+	  /**
2759
+	   * Triggered on <input> blur.
2760
+	   *
2761
+	   */
2762
+
2763
+
2764
+	  onBlur(e) {
2765
+	    if (document.hasFocus() === false) return;
2766
+	    var self = this;
2767
+	    if (!self.isFocused) return;
2768
+	    self.isFocused = false;
2769
+	    self.ignoreFocus = false;
2770
+
2771
+	    var deactivate = () => {
2772
+	      self.close();
2773
+	      self.setActiveItem();
2774
+	      self.setCaret(self.items.length);
2775
+	      self.trigger('blur');
2776
+	    };
2777
+
2778
+	    if (self.settings.create && self.settings.createOnBlur) {
2779
+	      self.createItem(null, deactivate);
2780
+	    } else {
2781
+	      deactivate();
2782
+	    }
2783
+	  }
2784
+	  /**
2785
+	   * Triggered when the user clicks on an option
2786
+	   * in the autocomplete dropdown menu.
2787
+	   *
2788
+	   */
2789
+
2790
+
2791
+	  onOptionSelect(evt, option) {
2792
+	    var value,
2793
+	        self = this; // should not be possible to trigger a option under a disabled optgroup
2794
+
2795
+	    if (option.parentElement && option.parentElement.matches('[data-disabled]')) {
2796
+	      return;
2797
+	    }
2798
+
2799
+	    if (option.classList.contains('create')) {
2800
+	      self.createItem(null, () => {
2801
+	        if (self.settings.closeAfterSelect) {
2802
+	          self.close();
2803
+	        }
2804
+	      });
2805
+	    } else {
2806
+	      value = option.dataset.value;
2807
+
2808
+	      if (typeof value !== 'undefined') {
2809
+	        self.lastQuery = null;
2810
+	        self.addItem(value);
2811
+
2812
+	        if (self.settings.closeAfterSelect) {
2813
+	          self.close();
2814
+	        }
2815
+
2816
+	        if (!self.settings.hideSelected && evt.type && /click/.test(evt.type)) {
2817
+	          self.setActiveOption(option);
2818
+	        }
2819
+	      }
2820
+	    }
2821
+	  }
2822
+	  /**
2823
+	   * Return true if the given option can be selected
2824
+	   *
2825
+	   */
2826
+
2827
+
2828
+	  canSelect(option) {
2829
+	    if (this.isOpen && option && this.dropdown_content.contains(option)) {
2830
+	      return true;
2831
+	    }
2832
+
2833
+	    return false;
2834
+	  }
2835
+	  /**
2836
+	   * Triggered when the user clicks on an item
2837
+	   * that has been selected.
2838
+	   *
2839
+	   */
2840
+
2841
+
2842
+	  onItemSelect(evt, item) {
2843
+	    var self = this;
2844
+
2845
+	    if (!self.isLocked && self.settings.mode === 'multi') {
2846
+	      preventDefault(evt);
2847
+	      self.setActiveItem(item, evt);
2848
+	      return true;
2849
+	    }
2850
+
2851
+	    return false;
2852
+	  }
2853
+	  /**
2854
+	   * Determines whether or not to invoke
2855
+	   * the user-provided option provider / loader
2856
+	   *
2857
+	   * Note, there is a subtle difference between
2858
+	   * this.canLoad() and this.settings.shouldLoad();
2859
+	   *
2860
+	   *	- settings.shouldLoad() is a user-input validator.
2861
+	   *	When false is returned, the not_loading template
2862
+	   *	will be added to the dropdown
2863
+	   *
2864
+	   *	- canLoad() is lower level validator that checks
2865
+	   * 	the Tom Select instance. There is no inherent user
2866
+	   *	feedback when canLoad returns false
2867
+	   *
2868
+	   */
2869
+
2870
+
2871
+	  canLoad(value) {
2872
+	    if (!this.settings.load) return false;
2873
+	    if (this.loadedSearches.hasOwnProperty(value)) return false;
2874
+	    return true;
2875
+	  }
2876
+	  /**
2877
+	   * Invokes the user-provided option provider / loader.
2878
+	   *
2879
+	   */
2880
+
2881
+
2882
+	  load(value) {
2883
+	    const self = this;
2884
+	    if (!self.canLoad(value)) return;
2885
+	    addClasses(self.wrapper, self.settings.loadingClass);
2886
+	    self.loading++;
2887
+	    const callback = self.loadCallback.bind(self);
2888
+	    self.settings.load.call(self, value, callback);
2889
+	  }
2890
+	  /**
2891
+	   * Invoked by the user-provided option provider
2892
+	   *
2893
+	   */
2894
+
2895
+
2896
+	  loadCallback(options, optgroups) {
2897
+	    const self = this;
2898
+	    self.loading = Math.max(self.loading - 1, 0);
2899
+	    self.lastQuery = null;
2900
+	    self.clearActiveOption(); // when new results load, focus should be on first option
2901
+
2902
+	    self.setupOptions(options, optgroups);
2903
+	    self.refreshOptions(self.isFocused && !self.isInputHidden);
2904
+
2905
+	    if (!self.loading) {
2906
+	      removeClasses(self.wrapper, self.settings.loadingClass);
2907
+	    }
2908
+
2909
+	    self.trigger('load', options, optgroups);
2910
+	  }
2911
+
2912
+	  preload() {
2913
+	    var classList = this.wrapper.classList;
2914
+	    if (classList.contains('preloaded')) return;
2915
+	    classList.add('preloaded');
2916
+	    this.load('');
2917
+	  }
2918
+	  /**
2919
+	   * Sets the input field of the control to the specified value.
2920
+	   *
2921
+	   */
2922
+
2923
+
2924
+	  setTextboxValue(value = '') {
2925
+	    var input = this.control_input;
2926
+	    var changed = input.value !== value;
2927
+
2928
+	    if (changed) {
2929
+	      input.value = value;
2930
+	      triggerEvent(input, 'update');
2931
+	      this.lastValue = value;
2932
+	    }
2933
+	  }
2934
+	  /**
2935
+	   * Returns the value of the control. If multiple items
2936
+	   * can be selected (e.g. <select multiple>), this returns
2937
+	   * an array. If only one item can be selected, this
2938
+	   * returns a string.
2939
+	   *
2940
+	   */
2941
+
2942
+
2943
+	  getValue() {
2944
+	    if (this.is_select_tag && this.input.hasAttribute('multiple')) {
2945
+	      return this.items;
2946
+	    }
2947
+
2948
+	    return this.items.join(this.settings.delimiter);
2949
+	  }
2950
+	  /**
2951
+	   * Resets the selected items to the given value.
2952
+	   *
2953
+	   */
2954
+
2955
+
2956
+	  setValue(value, silent) {
2957
+	    var events = silent ? [] : ['change'];
2958
+	    debounce_events(this, events, () => {
2959
+	      this.clear(silent);
2960
+	      this.addItems(value, silent);
2961
+	    });
2962
+	  }
2963
+	  /**
2964
+	   * Resets the number of max items to the given value
2965
+	   *
2966
+	   */
2967
+
2968
+
2969
+	  setMaxItems(value) {
2970
+	    if (value === 0) value = null; //reset to unlimited items.
2971
+
2972
+	    this.settings.maxItems = value;
2973
+	    this.refreshState();
2974
+	  }
2975
+	  /**
2976
+	   * Sets the selected item.
2977
+	   *
2978
+	   */
2979
+
2980
+
2981
+	  setActiveItem(item, e) {
2982
+	    var self = this;
2983
+	    var eventName;
2984
+	    var i, begin, end, swap;
2985
+	    var last;
2986
+	    if (self.settings.mode === 'single') return; // clear the active selection
2987
+
2988
+	    if (!item) {
2989
+	      self.clearActiveItems();
2990
+
2991
+	      if (self.isFocused) {
2992
+	        self.showInput();
2993
+	      }
2994
+
2995
+	      return;
2996
+	    } // modify selection
2997
+
2998
+
2999
+	    eventName = e && e.type.toLowerCase();
3000
+
3001
+	    if (eventName === 'click' && isKeyDown('shiftKey', e) && self.activeItems.length) {
3002
+	      last = self.getLastActive();
3003
+	      begin = Array.prototype.indexOf.call(self.control.children, last);
3004
+	      end = Array.prototype.indexOf.call(self.control.children, item);
3005
+
3006
+	      if (begin > end) {
3007
+	        swap = begin;
3008
+	        begin = end;
3009
+	        end = swap;
3010
+	      }
3011
+
3012
+	      for (i = begin; i <= end; i++) {
3013
+	        item = self.control.children[i];
3014
+
3015
+	        if (self.activeItems.indexOf(item) === -1) {
3016
+	          self.setActiveItemClass(item);
3017
+	        }
3018
+	      }
3019
+
3020
+	      preventDefault(e);
3021
+	    } else if (eventName === 'click' && isKeyDown(KEY_SHORTCUT, e) || eventName === 'keydown' && isKeyDown('shiftKey', e)) {
3022
+	      if (item.classList.contains('active')) {
3023
+	        self.removeActiveItem(item);
3024
+	      } else {
3025
+	        self.setActiveItemClass(item);
3026
+	      }
3027
+	    } else {
3028
+	      self.clearActiveItems();
3029
+	      self.setActiveItemClass(item);
3030
+	    } // ensure control has focus
3031
+
3032
+
3033
+	    self.hideInput();
3034
+
3035
+	    if (!self.isFocused) {
3036
+	      self.focus();
3037
+	    }
3038
+	  }
3039
+	  /**
3040
+	   * Set the active and last-active classes
3041
+	   *
3042
+	   */
3043
+
3044
+
3045
+	  setActiveItemClass(item) {
3046
+	    const self = this;
3047
+	    const last_active = self.control.querySelector('.last-active');
3048
+	    if (last_active) removeClasses(last_active, 'last-active');
3049
+	    addClasses(item, 'active last-active');
3050
+	    self.trigger('item_select', item);
3051
+
3052
+	    if (self.activeItems.indexOf(item) == -1) {
3053
+	      self.activeItems.push(item);
3054
+	    }
3055
+	  }
3056
+	  /**
3057
+	   * Remove active item
3058
+	   *
3059
+	   */
3060
+
3061
+
3062
+	  removeActiveItem(item) {
3063
+	    var idx = this.activeItems.indexOf(item);
3064
+	    this.activeItems.splice(idx, 1);
3065
+	    removeClasses(item, 'active');
3066
+	  }
3067
+	  /**
3068
+	   * Clears all the active items
3069
+	   *
3070
+	   */
3071
+
3072
+
3073
+	  clearActiveItems() {
3074
+	    removeClasses(this.activeItems, 'active');
3075
+	    this.activeItems = [];
3076
+	  }
3077
+	  /**
3078
+	   * Sets the selected item in the dropdown menu
3079
+	   * of available options.
3080
+	   *
3081
+	   */
3082
+
3083
+
3084
+	  setActiveOption(option, scroll = true) {
3085
+	    if (option === this.activeOption) {
3086
+	      return;
3087
+	    }
3088
+
3089
+	    this.clearActiveOption();
3090
+	    if (!option) return;
3091
+	    this.activeOption = option;
3092
+	    setAttr(this.focus_node, {
3093
+	      'aria-activedescendant': option.getAttribute('id')
3094
+	    });
3095
+	    setAttr(option, {
3096
+	      'aria-selected': 'true'
3097
+	    });
3098
+	    addClasses(option, 'active');
3099
+	    if (scroll) this.scrollToOption(option);
3100
+	  }
3101
+	  /**
3102
+	   * Sets the dropdown_content scrollTop to display the option
3103
+	   *
3104
+	   */
3105
+
3106
+
3107
+	  scrollToOption(option, behavior) {
3108
+	    if (!option) return;
3109
+	    const content = this.dropdown_content;
3110
+	    const height_menu = content.clientHeight;
3111
+	    const scrollTop = content.scrollTop || 0;
3112
+	    const height_item = option.offsetHeight;
3113
+	    const y = option.getBoundingClientRect().top - content.getBoundingClientRect().top + scrollTop;
3114
+
3115
+	    if (y + height_item > height_menu + scrollTop) {
3116
+	      this.scroll(y - height_menu + height_item, behavior);
3117
+	    } else if (y < scrollTop) {
3118
+	      this.scroll(y, behavior);
3119
+	    }
3120
+	  }
3121
+	  /**
3122
+	   * Scroll the dropdown to the given position
3123
+	   *
3124
+	   */
3125
+
3126
+
3127
+	  scroll(scrollTop, behavior) {
3128
+	    const content = this.dropdown_content;
3129
+
3130
+	    if (behavior) {
3131
+	      content.style.scrollBehavior = behavior;
3132
+	    }
3133
+
3134
+	    content.scrollTop = scrollTop;
3135
+	    content.style.scrollBehavior = '';
3136
+	  }
3137
+	  /**
3138
+	   * Clears the active option
3139
+	   *
3140
+	   */
3141
+
3142
+
3143
+	  clearActiveOption() {
3144
+	    if (this.activeOption) {
3145
+	      removeClasses(this.activeOption, 'active');
3146
+	      setAttr(this.activeOption, {
3147
+	        'aria-selected': null
3148
+	      });
3149
+	    }
3150
+
3151
+	    this.activeOption = null;
3152
+	    setAttr(this.focus_node, {
3153
+	      'aria-activedescendant': null
3154
+	    });
3155
+	  }
3156
+	  /**
3157
+	   * Selects all items (CTRL + A).
3158
+	   */
3159
+
3160
+
3161
+	  selectAll() {
3162
+	    const self = this;
3163
+	    if (self.settings.mode === 'single') return;
3164
+	    const activeItems = self.controlChildren();
3165
+	    if (!activeItems.length) return;
3166
+	    self.hideInput();
3167
+	    self.close();
3168
+	    self.activeItems = activeItems;
3169
+	    iterate$1(activeItems, item => {
3170
+	      self.setActiveItemClass(item);
3171
+	    });
3172
+	  }
3173
+	  /**
3174
+	   * Determines if the control_input should be in a hidden or visible state
3175
+	   *
3176
+	   */
3177
+
3178
+
3179
+	  inputState() {
3180
+	    var self = this;
3181
+	    if (!self.control.contains(self.control_input)) return;
3182
+	    setAttr(self.control_input, {
3183
+	      placeholder: self.settings.placeholder
3184
+	    });
3185
+
3186
+	    if (self.activeItems.length > 0 || !self.isFocused && self.settings.hidePlaceholder && self.items.length > 0) {
3187
+	      self.setTextboxValue();
3188
+	      self.isInputHidden = true;
3189
+	    } else {
3190
+	      if (self.settings.hidePlaceholder && self.items.length > 0) {
3191
+	        setAttr(self.control_input, {
3192
+	          placeholder: ''
3193
+	        });
3194
+	      }
3195
+
3196
+	      self.isInputHidden = false;
3197
+	    }
3198
+
3199
+	    self.wrapper.classList.toggle('input-hidden', self.isInputHidden);
3200
+	  }
3201
+	  /**
3202
+	   * Hides the input element out of view, while
3203
+	   * retaining its focus.
3204
+	   * @deprecated 1.3
3205
+	   */
3206
+
3207
+
3208
+	  hideInput() {
3209
+	    this.inputState();
3210
+	  }
3211
+	  /**
3212
+	   * Restores input visibility.
3213
+	   * @deprecated 1.3
3214
+	   */
3215
+
3216
+
3217
+	  showInput() {
3218
+	    this.inputState();
3219
+	  }
3220
+	  /**
3221
+	   * Get the input value
3222
+	   */
3223
+
3224
+
3225
+	  inputValue() {
3226
+	    return this.control_input.value.trim();
3227
+	  }
3228
+	  /**
3229
+	   * Gives the control focus.
3230
+	   */
3231
+
3232
+
3233
+	  focus() {
3234
+	    var self = this;
3235
+	    if (self.isDisabled) return;
3236
+	    self.ignoreFocus = true;
3237
+
3238
+	    if (self.control_input.offsetWidth) {
3239
+	      self.control_input.focus();
3240
+	    } else {
3241
+	      self.focus_node.focus();
3242
+	    }
3243
+
3244
+	    setTimeout(() => {
3245
+	      self.ignoreFocus = false;
3246
+	      self.onFocus();
3247
+	    }, 0);
3248
+	  }
3249
+	  /**
3250
+	   * Forces the control out of focus.
3251
+	   *
3252
+	   */
3253
+
3254
+
3255
+	  blur() {
3256
+	    this.focus_node.blur();
3257
+	    this.onBlur();
3258
+	  }
3259
+	  /**
3260
+	   * Returns a function that scores an object
3261
+	   * to show how good of a match it is to the
3262
+	   * provided query.
3263
+	   *
3264
+	   * @return {function}
3265
+	   */
3266
+
3267
+
3268
+	  getScoreFunction(query) {
3269
+	    return this.sifter.getScoreFunction(query, this.getSearchOptions());
3270
+	  }
3271
+	  /**
3272
+	   * Returns search options for sifter (the system
3273
+	   * for scoring and sorting results).
3274
+	   *
3275
+	   * @see https://github.com/orchidjs/sifter.js
3276
+	   * @return {object}
3277
+	   */
3278
+
3279
+
3280
+	  getSearchOptions() {
3281
+	    var settings = this.settings;
3282
+	    var sort = settings.sortField;
3283
+
3284
+	    if (typeof settings.sortField === 'string') {
3285
+	      sort = [{
3286
+	        field: settings.sortField
3287
+	      }];
3288
+	    }
3289
+
3290
+	    return {
3291
+	      fields: settings.searchField,
3292
+	      conjunction: settings.searchConjunction,
3293
+	      sort: sort,
3294
+	      nesting: settings.nesting
3295
+	    };
3296
+	  }
3297
+	  /**
3298
+	   * Searches through available options and returns
3299
+	   * a sorted array of matches.
3300
+	   *
3301
+	   */
3302
+
3303
+
3304
+	  search(query) {
3305
+	    var result, calculateScore;
3306
+	    var self = this;
3307
+	    var options = this.getSearchOptions(); // validate user-provided result scoring function
3308
+
3309
+	    if (self.settings.score) {
3310
+	      calculateScore = self.settings.score.call(self, query);
3311
+
3312
+	      if (typeof calculateScore !== 'function') {
3313
+	        throw new Error('Tom Select "score" setting must be a function that returns a function');
3314
+	      }
3315
+	    } // perform search
3316
+
3317
+
3318
+	    if (query !== self.lastQuery) {
3319
+	      self.lastQuery = query;
3320
+	      result = self.sifter.search(query, Object.assign(options, {
3321
+	        score: calculateScore
3322
+	      }));
3323
+	      self.currentResults = result;
3324
+	    } else {
3325
+	      result = Object.assign({}, self.currentResults);
3326
+	    } // filter out selected items
3327
+
3328
+
3329
+	    if (self.settings.hideSelected) {
3330
+	      result.items = result.items.filter(item => {
3331
+	        let hashed = hash_key(item.id);
3332
+	        return !(hashed && self.items.indexOf(hashed) !== -1);
3333
+	      });
3334
+	    }
3335
+
3336
+	    return result;
3337
+	  }
3338
+	  /**
3339
+	   * Refreshes the list of available options shown
3340
+	   * in the autocomplete dropdown menu.
3341
+	   *
3342
+	   */
3343
+
3344
+
3345
+	  refreshOptions(triggerDropdown = true) {
3346
+	    var i, j, k, n, optgroup, optgroups, html, has_create_option, active_group;
3347
+	    var create;
3348
+	    const groups = {};
3349
+	    const groups_order = [];
3350
+	    var self = this;
3351
+	    var query = self.inputValue();
3352
+	    const same_query = query === self.lastQuery || query == '' && self.lastQuery == null;
3353
+	    var results = self.search(query);
3354
+	    var active_option = null;
3355
+	    var show_dropdown = self.settings.shouldOpen || false;
3356
+	    var dropdown_content = self.dropdown_content;
3357
+
3358
+	    if (same_query) {
3359
+	      active_option = self.activeOption;
3360
+
3361
+	      if (active_option) {
3362
+	        active_group = active_option.closest('[data-group]');
3363
+	      }
3364
+	    } // build markup
3365
+
3366
+
3367
+	    n = results.items.length;
3368
+
3369
+	    if (typeof self.settings.maxOptions === 'number') {
3370
+	      n = Math.min(n, self.settings.maxOptions);
3371
+	    }
3372
+
3373
+	    if (n > 0) {
3374
+	      show_dropdown = true;
3375
+	    } // render and group available options individually
3376
+
3377
+
3378
+	    for (i = 0; i < n; i++) {
3379
+	      // get option dom element
3380
+	      let item = results.items[i];
3381
+	      if (!item) continue;
3382
+	      let opt_value = item.id;
3383
+	      let option = self.options[opt_value];
3384
+	      if (option === undefined) continue;
3385
+	      let opt_hash = get_hash(opt_value);
3386
+	      let option_el = self.getOption(opt_hash, true); // toggle 'selected' class
3387
+
3388
+	      if (!self.settings.hideSelected) {
3389
+	        option_el.classList.toggle('selected', self.items.includes(opt_hash));
3390
+	      }
3391
+
3392
+	      optgroup = option[self.settings.optgroupField] || '';
3393
+	      optgroups = Array.isArray(optgroup) ? optgroup : [optgroup];
3394
+
3395
+	      for (j = 0, k = optgroups && optgroups.length; j < k; j++) {
3396
+	        optgroup = optgroups[j];
3397
+
3398
+	        if (!self.optgroups.hasOwnProperty(optgroup)) {
3399
+	          optgroup = '';
3400
+	        }
3401
+
3402
+	        let group_fragment = groups[optgroup];
3403
+
3404
+	        if (group_fragment === undefined) {
3405
+	          group_fragment = document.createDocumentFragment();
3406
+	          groups_order.push(optgroup);
3407
+	        } // nodes can only have one parent, so if the option is in mutple groups, we need a clone
3408
+
3409
+
3410
+	        if (j > 0) {
3411
+	          option_el = option_el.cloneNode(true);
3412
+	          setAttr(option_el, {
3413
+	            id: option.$id + '-clone-' + j,
3414
+	            'aria-selected': null
3415
+	          });
3416
+	          option_el.classList.add('ts-cloned');
3417
+	          removeClasses(option_el, 'active'); // make sure we keep the activeOption in the same group
3418
+
3419
+	          if (self.activeOption && self.activeOption.dataset.value == opt_value) {
3420
+	            if (active_group && active_group.dataset.group === optgroup.toString()) {
3421
+	              active_option = option_el;
3422
+	            }
3423
+	          }
3424
+	        }
3425
+
3426
+	        group_fragment.appendChild(option_el);
3427
+	        groups[optgroup] = group_fragment;
3428
+	      }
3429
+	    } // sort optgroups
3430
+
3431
+
3432
+	    if (self.settings.lockOptgroupOrder) {
3433
+	      groups_order.sort((a, b) => {
3434
+	        const grp_a = self.optgroups[a];
3435
+	        const grp_b = self.optgroups[b];
3436
+	        const a_order = grp_a && grp_a.$order || 0;
3437
+	        const b_order = grp_b && grp_b.$order || 0;
3438
+	        return a_order - b_order;
3439
+	      });
3440
+	    } // render optgroup headers & join groups
3441
+
3442
+
3443
+	    html = document.createDocumentFragment();
3444
+	    iterate$1(groups_order, optgroup => {
3445
+	      let group_fragment = groups[optgroup];
3446
+	      if (!group_fragment || !group_fragment.children.length) return;
3447
+	      let group_heading = self.optgroups[optgroup];
3448
+
3449
+	      if (group_heading !== undefined) {
3450
+	        let group_options = document.createDocumentFragment();
3451
+	        let header = self.render('optgroup_header', group_heading);
3452
+	        append(group_options, header);
3453
+	        append(group_options, group_fragment);
3454
+	        let group_html = self.render('optgroup', {
3455
+	          group: group_heading,
3456
+	          options: group_options
3457
+	        });
3458
+	        append(html, group_html);
3459
+	      } else {
3460
+	        append(html, group_fragment);
3461
+	      }
3462
+	    });
3463
+	    dropdown_content.innerHTML = '';
3464
+	    append(dropdown_content, html); // highlight matching terms inline
3465
+
3466
+	    if (self.settings.highlight) {
3467
+	      removeHighlight(dropdown_content);
3468
+
3469
+	      if (results.query.length && results.tokens.length) {
3470
+	        iterate$1(results.tokens, tok => {
3471
+	          highlight(dropdown_content, tok.regex);
3472
+	        });
3473
+	      }
3474
+	    } // helper method for adding templates to dropdown
3475
+
3476
+
3477
+	    var add_template = template => {
3478
+	      let content = self.render(template, {
3479
+	        input: query
3480
+	      });
3481
+
3482
+	      if (content) {
3483
+	        show_dropdown = true;
3484
+	        dropdown_content.insertBefore(content, dropdown_content.firstChild);
3485
+	      }
3486
+
3487
+	      return content;
3488
+	    }; // add loading message
3489
+
3490
+
3491
+	    if (self.loading) {
3492
+	      add_template('loading'); // invalid query
3493
+	    } else if (!self.settings.shouldLoad.call(self, query)) {
3494
+	      add_template('not_loading'); // add no_results message
3495
+	    } else if (results.items.length === 0) {
3496
+	      add_template('no_results');
3497
+	    } // add create option
3498
+
3499
+
3500
+	    has_create_option = self.canCreate(query);
3501
+
3502
+	    if (has_create_option) {
3503
+	      create = add_template('option_create');
3504
+	    } // activate
3505
+
3506
+
3507
+	    self.hasOptions = results.items.length > 0 || has_create_option;
3508
+
3509
+	    if (show_dropdown) {
3510
+	      if (results.items.length > 0) {
3511
+	        if (!active_option && self.settings.mode === 'single' && self.items[0] != undefined) {
3512
+	          active_option = self.getOption(self.items[0]);
3513
+	        }
3514
+
3515
+	        if (!dropdown_content.contains(active_option)) {
3516
+	          let active_index = 0;
3517
+
3518
+	          if (create && !self.settings.addPrecedence) {
3519
+	            active_index = 1;
3520
+	          }
3521
+
3522
+	          active_option = self.selectable()[active_index];
3523
+	        }
3524
+	      } else if (create) {
3525
+	        active_option = create;
3526
+	      }
3527
+
3528
+	      if (triggerDropdown && !self.isOpen) {
3529
+	        self.open();
3530
+	        self.scrollToOption(active_option, 'auto');
3531
+	      }
3532
+
3533
+	      self.setActiveOption(active_option);
3534
+	    } else {
3535
+	      self.clearActiveOption();
3536
+
3537
+	      if (triggerDropdown && self.isOpen) {
3538
+	        self.close(false); // if create_option=null, we want the dropdown to close but not reset the textbox value
3539
+	      }
3540
+	    }
3541
+	  }
3542
+	  /**
3543
+	   * Return list of selectable options
3544
+	   *
3545
+	   */
3546
+
3547
+
3548
+	  selectable() {
3549
+	    return this.dropdown_content.querySelectorAll('[data-selectable]');
3550
+	  }
3551
+	  /**
3552
+	   * Adds an available option. If it already exists,
3553
+	   * nothing will happen. Note: this does not refresh
3554
+	   * the options list dropdown (use `refreshOptions`
3555
+	   * for that).
3556
+	   *
3557
+	   * Usage:
3558
+	   *
3559
+	   *   this.addOption(data)
3560
+	   *
3561
+	   */
3562
+
3563
+
3564
+	  addOption(data, user_created = false) {
3565
+	    const self = this; // @deprecated 1.7.7
3566
+	    // use addOptions( array, user_created ) for adding multiple options
3567
+
3568
+	    if (Array.isArray(data)) {
3569
+	      self.addOptions(data, user_created);
3570
+	      return false;
3571
+	    }
3572
+
3573
+	    const key = hash_key(data[self.settings.valueField]);
3574
+
3575
+	    if (key === null || self.options.hasOwnProperty(key)) {
3576
+	      return false;
3577
+	    }
3578
+
3579
+	    data.$order = data.$order || ++self.order;
3580
+	    data.$id = self.inputId + '-opt-' + data.$order;
3581
+	    self.options[key] = data;
3582
+	    self.lastQuery = null;
3583
+
3584
+	    if (user_created) {
3585
+	      self.userOptions[key] = user_created;
3586
+	      self.trigger('option_add', key, data);
3587
+	    }
3588
+
3589
+	    return key;
3590
+	  }
3591
+	  /**
3592
+	   * Add multiple options
3593
+	   *
3594
+	   */
3595
+
3596
+
3597
+	  addOptions(data, user_created = false) {
3598
+	    iterate$1(data, dat => {
3599
+	      this.addOption(dat, user_created);
3600
+	    });
3601
+	  }
3602
+	  /**
3603
+	   * @deprecated 1.7.7
3604
+	   */
3605
+
3606
+
3607
+	  registerOption(data) {
3608
+	    return this.addOption(data);
3609
+	  }
3610
+	  /**
3611
+	   * Registers an option group to the pool of option groups.
3612
+	   *
3613
+	   * @return {boolean|string}
3614
+	   */
3615
+
3616
+
3617
+	  registerOptionGroup(data) {
3618
+	    var key = hash_key(data[this.settings.optgroupValueField]);
3619
+	    if (key === null) return false;
3620
+	    data.$order = data.$order || ++this.order;
3621
+	    this.optgroups[key] = data;
3622
+	    return key;
3623
+	  }
3624
+	  /**
3625
+	   * Registers a new optgroup for options
3626
+	   * to be bucketed into.
3627
+	   *
3628
+	   */
3629
+
3630
+
3631
+	  addOptionGroup(id, data) {
3632
+	    var hashed_id;
3633
+	    data[this.settings.optgroupValueField] = id;
3634
+
3635
+	    if (hashed_id = this.registerOptionGroup(data)) {
3636
+	      this.trigger('optgroup_add', hashed_id, data);
3637
+	    }
3638
+	  }
3639
+	  /**
3640
+	   * Removes an existing option group.
3641
+	   *
3642
+	   */
3643
+
3644
+
3645
+	  removeOptionGroup(id) {
3646
+	    if (this.optgroups.hasOwnProperty(id)) {
3647
+	      delete this.optgroups[id];
3648
+	      this.clearCache();
3649
+	      this.trigger('optgroup_remove', id);
3650
+	    }
3651
+	  }
3652
+	  /**
3653
+	   * Clears all existing option groups.
3654
+	   */
3655
+
3656
+
3657
+	  clearOptionGroups() {
3658
+	    this.optgroups = {};
3659
+	    this.clearCache();
3660
+	    this.trigger('optgroup_clear');
3661
+	  }
3662
+	  /**
3663
+	   * Updates an option available for selection. If
3664
+	   * it is visible in the selected items or options
3665
+	   * dropdown, it will be re-rendered automatically.
3666
+	   *
3667
+	   */
3668
+
3669
+
3670
+	  updateOption(value, data) {
3671
+	    const self = this;
3672
+	    var item_new;
3673
+	    var index_item;
3674
+	    const value_old = hash_key(value);
3675
+	    const value_new = hash_key(data[self.settings.valueField]); // sanity checks
3676
+
3677
+	    if (value_old === null) return;
3678
+	    const data_old = self.options[value_old];
3679
+	    if (data_old == undefined) return;
3680
+	    if (typeof value_new !== 'string') throw new Error('Value must be set in option data');
3681
+	    const option = self.getOption(value_old);
3682
+	    const item = self.getItem(value_old);
3683
+	    data.$order = data.$order || data_old.$order;
3684
+	    delete self.options[value_old]; // invalidate render cache
3685
+	    // don't remove existing node yet, we'll remove it after replacing it
3686
+
3687
+	    self.uncacheValue(value_new);
3688
+	    self.options[value_new] = data; // update the option if it's in the dropdown
3689
+
3690
+	    if (option) {
3691
+	      if (self.dropdown_content.contains(option)) {
3692
+	        const option_new = self._render('option', data);
3693
+
3694
+	        replaceNode(option, option_new);
3695
+
3696
+	        if (self.activeOption === option) {
3697
+	          self.setActiveOption(option_new);
3698
+	        }
3699
+	      }
3700
+
3701
+	      option.remove();
3702
+	    } // update the item if we have one
3703
+
3704
+
3705
+	    if (item) {
3706
+	      index_item = self.items.indexOf(value_old);
3707
+
3708
+	      if (index_item !== -1) {
3709
+	        self.items.splice(index_item, 1, value_new);
3710
+	      }
3711
+
3712
+	      item_new = self._render('item', data);
3713
+	      if (item.classList.contains('active')) addClasses(item_new, 'active');
3714
+	      replaceNode(item, item_new);
3715
+	    } // invalidate last query because we might have updated the sortField
3716
+
3717
+
3718
+	    self.lastQuery = null;
3719
+	  }
3720
+	  /**
3721
+	   * Removes a single option.
3722
+	   *
3723
+	   */
3724
+
3725
+
3726
+	  removeOption(value, silent) {
3727
+	    const self = this;
3728
+	    value = get_hash(value);
3729
+	    self.uncacheValue(value);
3730
+	    delete self.userOptions[value];
3731
+	    delete self.options[value];
3732
+	    self.lastQuery = null;
3733
+	    self.trigger('option_remove', value);
3734
+	    self.removeItem(value, silent);
3735
+	  }
3736
+	  /**
3737
+	   * Clears all options.
3738
+	   */
3739
+
3740
+
3741
+	  clearOptions(filter) {
3742
+	    const boundFilter = (filter || this.clearFilter).bind(this);
3743
+	    this.loadedSearches = {};
3744
+	    this.userOptions = {};
3745
+	    this.clearCache();
3746
+	    const selected = {};
3747
+	    iterate$1(this.options, (option, key) => {
3748
+	      if (boundFilter(option, key)) {
3749
+	        selected[key] = option;
3750
+	      }
3751
+	    });
3752
+	    this.options = this.sifter.items = selected;
3753
+	    this.lastQuery = null;
3754
+	    this.trigger('option_clear');
3755
+	  }
3756
+	  /**
3757
+	   * Used by clearOptions() to decide whether or not an option should be removed
3758
+	   * Return true to keep an option, false to remove
3759
+	   *
3760
+	   */
3761
+
3762
+
3763
+	  clearFilter(option, value) {
3764
+	    if (this.items.indexOf(value) >= 0) {
3765
+	      return true;
3766
+	    }
3767
+
3768
+	    return false;
3769
+	  }
3770
+	  /**
3771
+	   * Returns the dom element of the option
3772
+	   * matching the given value.
3773
+	   *
3774
+	   */
3775
+
3776
+
3777
+	  getOption(value, create = false) {
3778
+	    const hashed = hash_key(value);
3779
+	    if (hashed === null) return null;
3780
+	    const option = this.options[hashed];
3781
+
3782
+	    if (option != undefined) {
3783
+	      if (option.$div) {
3784
+	        return option.$div;
3785
+	      }
3786
+
3787
+	      if (create) {
3788
+	        return this._render('option', option);
3789
+	      }
3790
+	    }
3791
+
3792
+	    return null;
3793
+	  }
3794
+	  /**
3795
+	   * Returns the dom element of the next or previous dom element of the same type
3796
+	   * Note: adjacent options may not be adjacent DOM elements (optgroups)
3797
+	   *
3798
+	   */
3799
+
3800
+
3801
+	  getAdjacent(option, direction, type = 'option') {
3802
+	    var self = this,
3803
+	        all;
3804
+
3805
+	    if (!option) {
3806
+	      return null;
3807
+	    }
3808
+
3809
+	    if (type == 'item') {
3810
+	      all = self.controlChildren();
3811
+	    } else {
3812
+	      all = self.dropdown_content.querySelectorAll('[data-selectable]');
3813
+	    }
3814
+
3815
+	    for (let i = 0; i < all.length; i++) {
3816
+	      if (all[i] != option) {
3817
+	        continue;
3818
+	      }
3819
+
3820
+	      if (direction > 0) {
3821
+	        return all[i + 1];
3822
+	      }
3823
+
3824
+	      return all[i - 1];
3825
+	    }
3826
+
3827
+	    return null;
3828
+	  }
3829
+	  /**
3830
+	   * Returns the dom element of the item
3831
+	   * matching the given value.
3832
+	   *
3833
+	   */
3834
+
3835
+
3836
+	  getItem(item) {
3837
+	    if (typeof item == 'object') {
3838
+	      return item;
3839
+	    }
3840
+
3841
+	    var value = hash_key(item);
3842
+	    return value !== null ? this.control.querySelector(`[data-value="${addSlashes(value)}"]`) : null;
3843
+	  }
3844
+	  /**
3845
+	   * "Selects" multiple items at once. Adds them to the list
3846
+	   * at the current caret position.
3847
+	   *
3848
+	   */
3849
+
3850
+
3851
+	  addItems(values, silent) {
3852
+	    var self = this;
3853
+	    var items = Array.isArray(values) ? values : [values];
3854
+	    items = items.filter(x => self.items.indexOf(x) === -1);
3855
+	    const last_item = items[items.length - 1];
3856
+	    items.forEach(item => {
3857
+	      self.isPending = item !== last_item;
3858
+	      self.addItem(item, silent);
3859
+	    });
3860
+	  }
3861
+	  /**
3862
+	   * "Selects" an item. Adds it to the list
3863
+	   * at the current caret position.
3864
+	   *
3865
+	   */
3866
+
3867
+
3868
+	  addItem(value, silent) {
3869
+	    var events = silent ? [] : ['change', 'dropdown_close'];
3870
+	    debounce_events(this, events, () => {
3871
+	      var item, wasFull;
3872
+	      const self = this;
3873
+	      const inputMode = self.settings.mode;
3874
+	      const hashed = hash_key(value);
3875
+
3876
+	      if (hashed && self.items.indexOf(hashed) !== -1) {
3877
+	        if (inputMode === 'single') {
3878
+	          self.close();
3879
+	        }
3880
+
3881
+	        if (inputMode === 'single' || !self.settings.duplicates) {
3882
+	          return;
3883
+	        }
3884
+	      }
3885
+
3886
+	      if (hashed === null || !self.options.hasOwnProperty(hashed)) return;
3887
+	      if (inputMode === 'single') self.clear(silent);
3888
+	      if (inputMode === 'multi' && self.isFull()) return;
3889
+	      item = self._render('item', self.options[hashed]);
3890
+
3891
+	      if (self.control.contains(item)) {
3892
+	        // duplicates
3893
+	        item = item.cloneNode(true);
3894
+	      }
3895
+
3896
+	      wasFull = self.isFull();
3897
+	      self.items.splice(self.caretPos, 0, hashed);
3898
+	      self.insertAtCaret(item);
3899
+
3900
+	      if (self.isSetup) {
3901
+	        // update menu / remove the option (if this is not one item being added as part of series)
3902
+	        if (!self.isPending && self.settings.hideSelected) {
3903
+	          let option = self.getOption(hashed);
3904
+	          let next = self.getAdjacent(option, 1);
3905
+
3906
+	          if (next) {
3907
+	            self.setActiveOption(next);
3908
+	          }
3909
+	        } // refreshOptions after setActiveOption(),
3910
+	        // otherwise setActiveOption() will be called by refreshOptions() with the wrong value
3911
+
3912
+
3913
+	        if (!self.isPending && !self.settings.closeAfterSelect) {
3914
+	          self.refreshOptions(self.isFocused && inputMode !== 'single');
3915
+	        } // hide the menu if the maximum number of items have been selected or no options are left
3916
+
3917
+
3918
+	        if (self.settings.closeAfterSelect != false && self.isFull()) {
3919
+	          self.close();
3920
+	        } else if (!self.isPending) {
3921
+	          self.positionDropdown();
3922
+	        }
3923
+
3924
+	        self.trigger('item_add', hashed, item);
3925
+
3926
+	        if (!self.isPending) {
3927
+	          self.updateOriginalInput({
3928
+	            silent: silent
3929
+	          });
3930
+	        }
3931
+	      }
3932
+
3933
+	      if (!self.isPending || !wasFull && self.isFull()) {
3934
+	        self.inputState();
3935
+	        self.refreshState();
3936
+	      }
3937
+	    });
3938
+	  }
3939
+	  /**
3940
+	   * Removes the selected item matching
3941
+	   * the provided value.
3942
+	   *
3943
+	   */
3944
+
3945
+
3946
+	  removeItem(item = null, silent) {
3947
+	    const self = this;
3948
+	    item = self.getItem(item);
3949
+	    if (!item) return;
3950
+	    var i, idx;
3951
+	    const value = item.dataset.value;
3952
+	    i = nodeIndex(item);
3953
+	    item.remove();
3954
+
3955
+	    if (item.classList.contains('active')) {
3956
+	      idx = self.activeItems.indexOf(item);
3957
+	      self.activeItems.splice(idx, 1);
3958
+	      removeClasses(item, 'active');
3959
+	    }
3960
+
3961
+	    self.items.splice(i, 1);
3962
+	    self.lastQuery = null;
3963
+
3964
+	    if (!self.settings.persist && self.userOptions.hasOwnProperty(value)) {
3965
+	      self.removeOption(value, silent);
3966
+	    }
3967
+
3968
+	    if (i < self.caretPos) {
3969
+	      self.setCaret(self.caretPos - 1);
3970
+	    }
3971
+
3972
+	    self.updateOriginalInput({
3973
+	      silent: silent
3974
+	    });
3975
+	    self.refreshState();
3976
+	    self.positionDropdown();
3977
+	    self.trigger('item_remove', value, item);
3978
+	  }
3979
+	  /**
3980
+	   * Invokes the `create` method provided in the
3981
+	   * TomSelect options that should provide the data
3982
+	   * for the new item, given the user input.
3983
+	   *
3984
+	   * Once this completes, it will be added
3985
+	   * to the item list.
3986
+	   *
3987
+	   */
3988
+
3989
+
3990
+	  createItem(input = null, callback = () => {}) {
3991
+	    // triggerDropdown parameter @deprecated 2.1.1
3992
+	    if (arguments.length === 3) {
3993
+	      callback = arguments[2];
3994
+	    }
3995
+
3996
+	    if (typeof callback != 'function') {
3997
+	      callback = () => {};
3998
+	    }
3999
+
4000
+	    var self = this;
4001
+	    var caret = self.caretPos;
4002
+	    var output;
4003
+	    input = input || self.inputValue();
4004
+
4005
+	    if (!self.canCreate(input)) {
4006
+	      callback();
4007
+	      return false;
4008
+	    }
4009
+
4010
+	    self.lock();
4011
+	    var created = false;
4012
+
4013
+	    var create = data => {
4014
+	      self.unlock();
4015
+	      if (!data || typeof data !== 'object') return callback();
4016
+	      var value = hash_key(data[self.settings.valueField]);
4017
+
4018
+	      if (typeof value !== 'string') {
4019
+	        return callback();
4020
+	      }
4021
+
4022
+	      self.setTextboxValue();
4023
+	      self.addOption(data, true);
4024
+	      self.setCaret(caret);
4025
+	      self.addItem(value);
4026
+	      callback(data);
4027
+	      created = true;
4028
+	    };
4029
+
4030
+	    if (typeof self.settings.create === 'function') {
4031
+	      output = self.settings.create.call(this, input, create);
4032
+	    } else {
4033
+	      output = {
4034
+	        [self.settings.labelField]: input,
4035
+	        [self.settings.valueField]: input
4036
+	      };
4037
+	    }
4038
+
4039
+	    if (!created) {
4040
+	      create(output);
4041
+	    }
4042
+
4043
+	    return true;
4044
+	  }
4045
+	  /**
4046
+	   * Re-renders the selected item lists.
4047
+	   */
4048
+
4049
+
4050
+	  refreshItems() {
4051
+	    var self = this;
4052
+	    self.lastQuery = null;
4053
+
4054
+	    if (self.isSetup) {
4055
+	      self.addItems(self.items);
4056
+	    }
4057
+
4058
+	    self.updateOriginalInput();
4059
+	    self.refreshState();
4060
+	  }
4061
+	  /**
4062
+	   * Updates all state-dependent attributes
4063
+	   * and CSS classes.
4064
+	   */
4065
+
4066
+
4067
+	  refreshState() {
4068
+	    const self = this;
4069
+	    self.refreshValidityState();
4070
+	    const isFull = self.isFull();
4071
+	    const isLocked = self.isLocked;
4072
+	    self.wrapper.classList.toggle('rtl', self.rtl);
4073
+	    const wrap_classList = self.wrapper.classList;
4074
+	    wrap_classList.toggle('focus', self.isFocused);
4075
+	    wrap_classList.toggle('disabled', self.isDisabled);
4076
+	    wrap_classList.toggle('required', self.isRequired);
4077
+	    wrap_classList.toggle('invalid', !self.isValid);
4078
+	    wrap_classList.toggle('locked', isLocked);
4079
+	    wrap_classList.toggle('full', isFull);
4080
+	    wrap_classList.toggle('input-active', self.isFocused && !self.isInputHidden);
4081
+	    wrap_classList.toggle('dropdown-active', self.isOpen);
4082
+	    wrap_classList.toggle('has-options', isEmptyObject(self.options));
4083
+	    wrap_classList.toggle('has-items', self.items.length > 0);
4084
+	  }
4085
+	  /**
4086
+	   * Update the `required` attribute of both input and control input.
4087
+	   *
4088
+	   * The `required` property needs to be activated on the control input
4089
+	   * for the error to be displayed at the right place. `required` also
4090
+	   * needs to be temporarily deactivated on the input since the input is
4091
+	   * hidden and can't show errors.
4092
+	   */
4093
+
4094
+
4095
+	  refreshValidityState() {
4096
+	    var self = this;
4097
+
4098
+	    if (!self.input.validity) {
4099
+	      return;
4100
+	    }
4101
+
4102
+	    self.isValid = self.input.validity.valid;
4103
+	    self.isInvalid = !self.isValid;
4104
+	  }
4105
+	  /**
4106
+	   * Determines whether or not more items can be added
4107
+	   * to the control without exceeding the user-defined maximum.
4108
+	   *
4109
+	   * @returns {boolean}
4110
+	   */
4111
+
4112
+
4113
+	  isFull() {
4114
+	    return this.settings.maxItems !== null && this.items.length >= this.settings.maxItems;
4115
+	  }
4116
+	  /**
4117
+	   * Refreshes the original <select> or <input>
4118
+	   * element to reflect the current state.
4119
+	   *
4120
+	   */
4121
+
4122
+
4123
+	  updateOriginalInput(opts = {}) {
4124
+	    const self = this;
4125
+	    var option, label;
4126
+	    const empty_option = self.input.querySelector('option[value=""]');
4127
+
4128
+	    if (self.is_select_tag) {
4129
+	      const selected = [];
4130
+	      const has_selected = self.input.querySelectorAll('option:checked').length;
4131
+
4132
+	      function AddSelected(option_el, value, label) {
4133
+	        if (!option_el) {
4134
+	          option_el = getDom('<option value="' + escape_html(value) + '">' + escape_html(label) + '</option>');
4135
+	        } // don't move empty option from top of list
4136
+	        // fixes bug in firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1725293
4137
+
4138
+
4139
+	        if (option_el != empty_option) {
4140
+	          self.input.append(option_el);
4141
+	        }
4142
+
4143
+	        selected.push(option_el); // marking empty option as selected can break validation
4144
+	        // fixes https://github.com/orchidjs/tom-select/issues/303
4145
+
4146
+	        if (option_el != empty_option || has_selected > 0) {
4147
+	          option_el.selected = true;
4148
+	        }
4149
+
4150
+	        return option_el;
4151
+	      } // unselect all selected options
4152
+
4153
+
4154
+	      self.input.querySelectorAll('option:checked').forEach(option_el => {
4155
+	        option_el.selected = false;
4156
+	      }); // nothing selected?
4157
+
4158
+	      if (self.items.length == 0 && self.settings.mode == 'single') {
4159
+	        AddSelected(empty_option, "", ""); // order selected <option> tags for values in self.items
4160
+	      } else {
4161
+	        self.items.forEach(value => {
4162
+	          option = self.options[value];
4163
+	          label = option[self.settings.labelField] || '';
4164
+
4165
+	          if (selected.includes(option.$option)) {
4166
+	            const reuse_opt = self.input.querySelector(`option[value="${addSlashes(value)}"]:not(:checked)`);
4167
+	            AddSelected(reuse_opt, value, label);
4168
+	          } else {
4169
+	            option.$option = AddSelected(option.$option, value, label);
4170
+	          }
4171
+	        });
4172
+	      }
4173
+	    } else {
4174
+	      self.input.value = self.getValue();
4175
+	    }
4176
+
4177
+	    if (self.isSetup) {
4178
+	      if (!opts.silent) {
4179
+	        self.trigger('change', self.getValue());
4180
+	      }
4181
+	    }
4182
+	  }
4183
+	  /**
4184
+	   * Shows the autocomplete dropdown containing
4185
+	   * the available options.
4186
+	   */
4187
+
4188
+
4189
+	  open() {
4190
+	    var self = this;
4191
+	    if (self.isLocked || self.isOpen || self.settings.mode === 'multi' && self.isFull()) return;
4192
+	    self.isOpen = true;
4193
+	    setAttr(self.focus_node, {
4194
+	      'aria-expanded': 'true'
4195
+	    });
4196
+	    self.refreshState();
4197
+	    applyCSS(self.dropdown, {
4198
+	      visibility: 'hidden',
4199
+	      display: 'block'
4200
+	    });
4201
+	    self.positionDropdown();
4202
+	    applyCSS(self.dropdown, {
4203
+	      visibility: 'visible',
4204
+	      display: 'block'
4205
+	    });
4206
+	    self.focus();
4207
+	    self.trigger('dropdown_open', self.dropdown);
4208
+	  }
4209
+	  /**
4210
+	   * Closes the autocomplete dropdown menu.
4211
+	   */
4212
+
4213
+
4214
+	  close(setTextboxValue = true) {
4215
+	    var self = this;
4216
+	    var trigger = self.isOpen;
4217
+
4218
+	    if (setTextboxValue) {
4219
+	      // before blur() to prevent form onchange event
4220
+	      self.setTextboxValue();
4221
+
4222
+	      if (self.settings.mode === 'single' && self.items.length) {
4223
+	        self.hideInput();
4224
+	      }
4225
+	    }
4226
+
4227
+	    self.isOpen = false;
4228
+	    setAttr(self.focus_node, {
4229
+	      'aria-expanded': 'false'
4230
+	    });
4231
+	    applyCSS(self.dropdown, {
4232
+	      display: 'none'
4233
+	    });
4234
+
4235
+	    if (self.settings.hideSelected) {
4236
+	      self.clearActiveOption();
4237
+	    }
4238
+
4239
+	    self.refreshState();
4240
+	    if (trigger) self.trigger('dropdown_close', self.dropdown);
4241
+	  }
4242
+	  /**
4243
+	   * Calculates and applies the appropriate
4244
+	   * position of the dropdown if dropdownParent = 'body'.
4245
+	   * Otherwise, position is determined by css
4246
+	   */
4247
+
4248
+
4249
+	  positionDropdown() {
4250
+	    if (this.settings.dropdownParent !== 'body') {
4251
+	      return;
4252
+	    }
4253
+
4254
+	    var context = this.control;
4255
+	    var rect = context.getBoundingClientRect();
4256
+	    var top = context.offsetHeight + rect.top + window.scrollY;
4257
+	    var left = rect.left + window.scrollX;
4258
+	    applyCSS(this.dropdown, {
4259
+	      width: rect.width + 'px',
4260
+	      top: top + 'px',
4261
+	      left: left + 'px'
4262
+	    });
4263
+	  }
4264
+	  /**
4265
+	   * Resets / clears all selected items
4266
+	   * from the control.
4267
+	   *
4268
+	   */
4269
+
4270
+
4271
+	  clear(silent) {
4272
+	    var self = this;
4273
+	    if (!self.items.length) return;
4274
+	    var items = self.controlChildren();
4275
+	    iterate$1(items, item => {
4276
+	      self.removeItem(item, true);
4277
+	    });
4278
+	    self.showInput();
4279
+	    if (!silent) self.updateOriginalInput();
4280
+	    self.trigger('clear');
4281
+	  }
4282
+	  /**
4283
+	   * A helper method for inserting an element
4284
+	   * at the current caret position.
4285
+	   *
4286
+	   */
4287
+
4288
+
4289
+	  insertAtCaret(el) {
4290
+	    const self = this;
4291
+	    const caret = self.caretPos;
4292
+	    const target = self.control;
4293
+	    target.insertBefore(el, target.children[caret] || null);
4294
+	    self.setCaret(caret + 1);
4295
+	  }
4296
+	  /**
4297
+	   * Removes the current selected item(s).
4298
+	   *
4299
+	   */
4300
+
4301
+
4302
+	  deleteSelection(e) {
4303
+	    var direction, selection, caret, tail;
4304
+	    var self = this;
4305
+	    direction = e && e.keyCode === KEY_BACKSPACE ? -1 : 1;
4306
+	    selection = getSelection(self.control_input); // determine items that will be removed
4307
+
4308
+	    const rm_items = [];
4309
+
4310
+	    if (self.activeItems.length) {
4311
+	      tail = getTail(self.activeItems, direction);
4312
+	      caret = nodeIndex(tail);
4313
+
4314
+	      if (direction > 0) {
4315
+	        caret++;
4316
+	      }
4317
+
4318
+	      iterate$1(self.activeItems, item => rm_items.push(item));
4319
+	    } else if ((self.isFocused || self.settings.mode === 'single') && self.items.length) {
4320
+	      const items = self.controlChildren();
4321
+	      let rm_item;
4322
+
4323
+	      if (direction < 0 && selection.start === 0 && selection.length === 0) {
4324
+	        rm_item = items[self.caretPos - 1];
4325
+	      } else if (direction > 0 && selection.start === self.inputValue().length) {
4326
+	        rm_item = items[self.caretPos];
4327
+	      }
4328
+
4329
+	      if (rm_item !== undefined) {
4330
+	        rm_items.push(rm_item);
4331
+	      }
4332
+	    }
4333
+
4334
+	    if (!self.shouldDelete(rm_items, e)) {
4335
+	      return false;
4336
+	    }
4337
+
4338
+	    preventDefault(e, true); // perform removal
4339
+
4340
+	    if (typeof caret !== 'undefined') {
4341
+	      self.setCaret(caret);
4342
+	    }
4343
+
4344
+	    while (rm_items.length) {
4345
+	      self.removeItem(rm_items.pop());
4346
+	    }
4347
+
4348
+	    self.showInput();
4349
+	    self.positionDropdown();
4350
+	    self.refreshOptions(false);
4351
+	    return true;
4352
+	  }
4353
+	  /**
4354
+	   * Return true if the items should be deleted
4355
+	   */
4356
+
4357
+
4358
+	  shouldDelete(items, evt) {
4359
+	    const values = items.map(item => item.dataset.value); // allow the callback to abort
4360
+
4361
+	    if (!values.length || typeof this.settings.onDelete === 'function' && this.settings.onDelete(values, evt) === false) {
4362
+	      return false;
4363
+	    }
4364
+
4365
+	    return true;
4366
+	  }
4367
+	  /**
4368
+	   * Selects the previous / next item (depending on the `direction` argument).
4369
+	   *
4370
+	   * > 0 - right
4371
+	   * < 0 - left
4372
+	   *
4373
+	   */
4374
+
4375
+
4376
+	  advanceSelection(direction, e) {
4377
+	    var last_active,
4378
+	        adjacent,
4379
+	        self = this;
4380
+	    if (self.rtl) direction *= -1;
4381
+	    if (self.inputValue().length) return; // add or remove to active items
4382
+
4383
+	    if (isKeyDown(KEY_SHORTCUT, e) || isKeyDown('shiftKey', e)) {
4384
+	      last_active = self.getLastActive(direction);
4385
+
4386
+	      if (last_active) {
4387
+	        if (!last_active.classList.contains('active')) {
4388
+	          adjacent = last_active;
4389
+	        } else {
4390
+	          adjacent = self.getAdjacent(last_active, direction, 'item');
4391
+	        } // if no active item, get items adjacent to the control input
4392
+
4393
+	      } else if (direction > 0) {
4394
+	        adjacent = self.control_input.nextElementSibling;
4395
+	      } else {
4396
+	        adjacent = self.control_input.previousElementSibling;
4397
+	      }
4398
+
4399
+	      if (adjacent) {
4400
+	        if (adjacent.classList.contains('active')) {
4401
+	          self.removeActiveItem(last_active);
4402
+	        }
4403
+
4404
+	        self.setActiveItemClass(adjacent); // mark as last_active !! after removeActiveItem() on last_active
4405
+	      } // move caret to the left or right
4406
+
4407
+	    } else {
4408
+	      self.moveCaret(direction);
4409
+	    }
4410
+	  }
4411
+
4412
+	  moveCaret(direction) {}
4413
+	  /**
4414
+	   * Get the last active item
4415
+	   *
4416
+	   */
4417
+
4418
+
4419
+	  getLastActive(direction) {
4420
+	    let last_active = this.control.querySelector('.last-active');
4421
+
4422
+	    if (last_active) {
4423
+	      return last_active;
4424
+	    }
4425
+
4426
+	    var result = this.control.querySelectorAll('.active');
4427
+
4428
+	    if (result) {
4429
+	      return getTail(result, direction);
4430
+	    }
4431
+	  }
4432
+	  /**
4433
+	   * Moves the caret to the specified index.
4434
+	   *
4435
+	   * The input must be moved by leaving it in place and moving the
4436
+	   * siblings, due to the fact that focus cannot be restored once lost
4437
+	   * on mobile webkit devices
4438
+	   *
4439
+	   */
4440
+
4441
+
4442
+	  setCaret(new_pos) {
4443
+	    this.caretPos = this.items.length;
4444
+	  }
4445
+	  /**
4446
+	   * Return list of item dom elements
4447
+	   *
4448
+	   */
4449
+
4450
+
4451
+	  controlChildren() {
4452
+	    return Array.from(this.control.querySelectorAll('[data-ts-item]'));
4453
+	  }
4454
+	  /**
4455
+	   * Disables user input on the control. Used while
4456
+	   * items are being asynchronously created.
4457
+	   */
4458
+
4459
+
4460
+	  lock() {
4461
+	    this.isLocked = true;
4462
+	    this.refreshState();
4463
+	  }
4464
+	  /**
4465
+	   * Re-enables user input on the control.
4466
+	   */
4467
+
4468
+
4469
+	  unlock() {
4470
+	    this.isLocked = false;
4471
+	    this.refreshState();
4472
+	  }
4473
+	  /**
4474
+	   * Disables user input on the control completely.
4475
+	   * While disabled, it cannot receive focus.
4476
+	   */
4477
+
4478
+
4479
+	  disable() {
4480
+	    var self = this;
4481
+	    self.input.disabled = true;
4482
+	    self.control_input.disabled = true;
4483
+	    self.focus_node.tabIndex = -1;
4484
+	    self.isDisabled = true;
4485
+	    this.close();
4486
+	    self.lock();
4487
+	  }
4488
+	  /**
4489
+	   * Enables the control so that it can respond
4490
+	   * to focus and user input.
4491
+	   */
4492
+
4493
+
4494
+	  enable() {
4495
+	    var self = this;
4496
+	    self.input.disabled = false;
4497
+	    self.control_input.disabled = false;
4498
+	    self.focus_node.tabIndex = self.tabIndex;
4499
+	    self.isDisabled = false;
4500
+	    self.unlock();
4501
+	  }
4502
+	  /**
4503
+	   * Completely destroys the control and
4504
+	   * unbinds all event listeners so that it can
4505
+	   * be garbage collected.
4506
+	   */
4507
+
4508
+
4509
+	  destroy() {
4510
+	    var self = this;
4511
+	    var revertSettings = self.revertSettings;
4512
+	    self.trigger('destroy');
4513
+	    self.off();
4514
+	    self.wrapper.remove();
4515
+	    self.dropdown.remove();
4516
+	    self.input.innerHTML = revertSettings.innerHTML;
4517
+	    self.input.tabIndex = revertSettings.tabIndex;
4518
+	    removeClasses(self.input, 'tomselected', 'ts-hidden-accessible');
4519
+
4520
+	    self._destroy();
4521
+
4522
+	    delete self.input.tomselect;
4523
+	  }
4524
+	  /**
4525
+	   * A helper method for rendering "item" and
4526
+	   * "option" templates, given the data.
4527
+	   *
4528
+	   */
4529
+
4530
+
4531
+	  render(templateName, data) {
4532
+	    var id, html;
4533
+	    const self = this;
4534
+
4535
+	    if (typeof this.settings.render[templateName] !== 'function') {
4536
+	      return null;
4537
+	    } // render markup
4538
+
4539
+
4540
+	    html = self.settings.render[templateName].call(this, data, escape_html);
4541
+
4542
+	    if (!html) {
4543
+	      return null;
4544
+	    }
4545
+
4546
+	    html = getDom(html); // add mandatory attributes
4547
+
4548
+	    if (templateName === 'option' || templateName === 'option_create') {
4549
+	      if (data[self.settings.disabledField]) {
4550
+	        setAttr(html, {
4551
+	          'aria-disabled': 'true'
4552
+	        });
4553
+	      } else {
4554
+	        setAttr(html, {
4555
+	          'data-selectable': ''
4556
+	        });
4557
+	      }
4558
+	    } else if (templateName === 'optgroup') {
4559
+	      id = data.group[self.settings.optgroupValueField];
4560
+	      setAttr(html, {
4561
+	        'data-group': id
4562
+	      });
4563
+
4564
+	      if (data.group[self.settings.disabledField]) {
4565
+	        setAttr(html, {
4566
+	          'data-disabled': ''
4567
+	        });
4568
+	      }
4569
+	    }
4570
+
4571
+	    if (templateName === 'option' || templateName === 'item') {
4572
+	      const value = get_hash(data[self.settings.valueField]);
4573
+	      setAttr(html, {
4574
+	        'data-value': value
4575
+	      }); // make sure we have some classes if a template is overwritten
4576
+
4577
+	      if (templateName === 'item') {
4578
+	        addClasses(html, self.settings.itemClass);
4579
+	        setAttr(html, {
4580
+	          'data-ts-item': ''
4581
+	        });
4582
+	      } else {
4583
+	        addClasses(html, self.settings.optionClass);
4584
+	        setAttr(html, {
4585
+	          role: 'option',
4586
+	          id: data.$id
4587
+	        }); // update cache
4588
+
4589
+	        data.$div = html;
4590
+	        self.options[value] = data;
4591
+	      }
4592
+	    }
4593
+
4594
+	    return html;
4595
+	  }
4596
+	  /**
4597
+	   * Type guarded rendering
4598
+	   *
4599
+	   */
4600
+
4601
+
4602
+	  _render(templateName, data) {
4603
+	    const html = this.render(templateName, data);
4604
+
4605
+	    if (html == null) {
4606
+	      throw 'HTMLElement expected';
4607
+	    }
4608
+
4609
+	    return html;
4610
+	  }
4611
+	  /**
4612
+	   * Clears the render cache for a template. If
4613
+	   * no template is given, clears all render
4614
+	   * caches.
4615
+	   *
4616
+	   */
4617
+
4618
+
4619
+	  clearCache() {
4620
+	    iterate$1(this.options, option => {
4621
+	      if (option.$div) {
4622
+	        option.$div.remove();
4623
+	        delete option.$div;
4624
+	      }
4625
+	    });
4626
+	  }
4627
+	  /**
4628
+	   * Removes a value from item and option caches
4629
+	   *
4630
+	   */
4631
+
4632
+
4633
+	  uncacheValue(value) {
4634
+	    const option_el = this.getOption(value);
4635
+	    if (option_el) option_el.remove();
4636
+	  }
4637
+	  /**
4638
+	   * Determines whether or not to display the
4639
+	   * create item prompt, given a user input.
4640
+	   *
4641
+	   */
4642
+
4643
+
4644
+	  canCreate(input) {
4645
+	    return this.settings.create && input.length > 0 && this.settings.createFilter.call(this, input);
4646
+	  }
4647
+	  /**
4648
+	   * Wraps this.`method` so that `new_fn` can be invoked 'before', 'after', or 'instead' of the original method
4649
+	   *
4650
+	   * this.hook('instead','onKeyDown',function( arg1, arg2 ...){
4651
+	   *
4652
+	   * });
4653
+	   */
4654
+
4655
+
4656
+	  hook(when, method, new_fn) {
4657
+	    var self = this;
4658
+	    var orig_method = self[method];
4659
+
4660
+	    self[method] = function () {
4661
+	      var result, result_new;
4662
+
4663
+	      if (when === 'after') {
4664
+	        result = orig_method.apply(self, arguments);
4665
+	      }
4666
+
4667
+	      result_new = new_fn.apply(self, arguments);
4668
+
4669
+	      if (when === 'instead') {
4670
+	        return result_new;
4671
+	      }
4672
+
4673
+	      if (when === 'before') {
4674
+	        result = orig_method.apply(self, arguments);
4675
+	      }
4676
+
4677
+	      return result;
4678
+	    };
4679
+	  }
4680
+
4681
+	}
4682
+
4683
+	/**
4684
+	 * Plugin: "dropdown_input" (Tom Select)
4685
+	 * Copyright (c) contributors
4686
+	 *
4687
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4688
+	 * file except in compliance with the License. You may obtain a copy of the License at:
4689
+	 * http://www.apache.org/licenses/LICENSE-2.0
4690
+	 *
4691
+	 * Unless required by applicable law or agreed to in writing, software distributed under
4692
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4693
+	 * ANY KIND, either express or implied. See the License for the specific language
4694
+	 * governing permissions and limitations under the License.
4695
+	 *
4696
+	 */
4697
+	function caret_position () {
4698
+	  var self = this;
4699
+	  /**
4700
+	   * Moves the caret to the specified index.
4701
+	   *
4702
+	   * The input must be moved by leaving it in place and moving the
4703
+	   * siblings, due to the fact that focus cannot be restored once lost
4704
+	   * on mobile webkit devices
4705
+	   *
4706
+	   */
4707
+
4708
+	  self.hook('instead', 'setCaret', new_pos => {
4709
+	    if (self.settings.mode === 'single' || !self.control.contains(self.control_input)) {
4710
+	      new_pos = self.items.length;
4711
+	    } else {
4712
+	      new_pos = Math.max(0, Math.min(self.items.length, new_pos));
4713
+
4714
+	      if (new_pos != self.caretPos && !self.isPending) {
4715
+	        self.controlChildren().forEach((child, j) => {
4716
+	          if (j < new_pos) {
4717
+	            self.control_input.insertAdjacentElement('beforebegin', child);
4718
+	          } else {
4719
+	            self.control.appendChild(child);
4720
+	          }
4721
+	        });
4722
+	      }
4723
+	    }
4724
+
4725
+	    self.caretPos = new_pos;
4726
+	  });
4727
+	  self.hook('instead', 'moveCaret', direction => {
4728
+	    if (!self.isFocused) return; // move caret before or after selected items
4729
+
4730
+	    const last_active = self.getLastActive(direction);
4731
+
4732
+	    if (last_active) {
4733
+	      const idx = nodeIndex(last_active);
4734
+	      self.setCaret(direction > 0 ? idx + 1 : idx);
4735
+	      self.setActiveItem();
4736
+	      removeClasses(last_active, 'last-active'); // move caret left or right of current position
4737
+	    } else {
4738
+	      self.setCaret(self.caretPos + direction);
4739
+	    }
4740
+	  });
4741
+	}
4742
+
4743
+	/**
4744
+	 * Plugin: "dropdown_input" (Tom Select)
4745
+	 * Copyright (c) contributors
4746
+	 *
4747
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4748
+	 * file except in compliance with the License. You may obtain a copy of the License at:
4749
+	 * http://www.apache.org/licenses/LICENSE-2.0
4750
+	 *
4751
+	 * Unless required by applicable law or agreed to in writing, software distributed under
4752
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4753
+	 * ANY KIND, either express or implied. See the License for the specific language
4754
+	 * governing permissions and limitations under the License.
4755
+	 *
4756
+	 */
4757
+	function dropdown_input () {
4758
+	  const self = this;
4759
+	  self.settings.shouldOpen = true; // make sure the input is shown even if there are no options to display in the dropdown
4760
+
4761
+	  self.hook('before', 'setup', () => {
4762
+	    self.focus_node = self.control;
4763
+	    addClasses(self.control_input, 'dropdown-input');
4764
+	    const div = getDom('<div class="dropdown-input-wrap">');
4765
+	    div.append(self.control_input);
4766
+	    self.dropdown.insertBefore(div, self.dropdown.firstChild); // set a placeholder in the select control
4767
+
4768
+	    const placeholder = getDom('<input class="items-placeholder" tabindex="-1" />');
4769
+	    placeholder.placeholder = self.settings.placeholder || '';
4770
+	    self.control.append(placeholder);
4771
+	  });
4772
+	  self.on('initialize', () => {
4773
+	    // set tabIndex on control to -1, otherwise [shift+tab] will put focus right back on control_input
4774
+	    self.control_input.addEventListener('keydown', evt => {
4775
+	      //addEvent(self.control_input,'keydown' as const,(evt:KeyboardEvent) =>{
4776
+	      switch (evt.keyCode) {
4777
+	        case KEY_ESC:
4778
+	          if (self.isOpen) {
4779
+	            preventDefault(evt, true);
4780
+	            self.close();
4781
+	          }
4782
+
4783
+	          self.clearActiveItems();
4784
+	          return;
4785
+
4786
+	        case KEY_TAB:
4787
+	          self.focus_node.tabIndex = -1;
4788
+	          break;
4789
+	      }
4790
+
4791
+	      return self.onKeyDown.call(self, evt);
4792
+	    });
4793
+	    self.on('blur', () => {
4794
+	      self.focus_node.tabIndex = self.isDisabled ? -1 : self.tabIndex;
4795
+	    }); // give the control_input focus when the dropdown is open
4796
+
4797
+	    self.on('dropdown_open', () => {
4798
+	      self.control_input.focus();
4799
+	    }); // prevent onBlur from closing when focus is on the control_input
4800
+
4801
+	    const orig_onBlur = self.onBlur;
4802
+	    self.hook('instead', 'onBlur', evt => {
4803
+	      if (evt && evt.relatedTarget == self.control_input) return;
4804
+	      return orig_onBlur.call(self);
4805
+	    });
4806
+	    addEvent(self.control_input, 'blur', () => self.onBlur()); // return focus to control to allow further keyboard input
4807
+
4808
+	    self.hook('before', 'close', () => {
4809
+	      if (!self.isOpen) return;
4810
+	      self.focus_node.focus({
4811
+	        preventScroll: true
4812
+	      });
4813
+	    });
4814
+	  });
4815
+	}
4816
+
4817
+	/**
4818
+	 * Plugin: "input_autogrow" (Tom Select)
4819
+	 *
4820
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4821
+	 * file except in compliance with the License. You may obtain a copy of the License at:
4822
+	 * http://www.apache.org/licenses/LICENSE-2.0
4823
+	 *
4824
+	 * Unless required by applicable law or agreed to in writing, software distributed under
4825
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4826
+	 * ANY KIND, either express or implied. See the License for the specific language
4827
+	 * governing permissions and limitations under the License.
4828
+	 *
4829
+	 */
4830
+	function no_backspace_delete () {
4831
+	  var self = this;
4832
+	  var orig_deleteSelection = self.deleteSelection;
4833
+	  this.hook('instead', 'deleteSelection', evt => {
4834
+	    if (self.activeItems.length) {
4835
+	      return orig_deleteSelection.call(self, evt);
4836
+	    }
4837
+
4838
+	    return false;
4839
+	  });
4840
+	}
4841
+
4842
+	/**
4843
+	 * Plugin: "remove_button" (Tom Select)
4844
+	 * Copyright (c) contributors
4845
+	 *
4846
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4847
+	 * file except in compliance with the License. You may obtain a copy of the License at:
4848
+	 * http://www.apache.org/licenses/LICENSE-2.0
4849
+	 *
4850
+	 * Unless required by applicable law or agreed to in writing, software distributed under
4851
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4852
+	 * ANY KIND, either express or implied. See the License for the specific language
4853
+	 * governing permissions and limitations under the License.
4854
+	 *
4855
+	 */
4856
+	function remove_button (userOptions) {
4857
+	  const options = Object.assign({
4858
+	    label: '&times;',
4859
+	    title: 'Remove',
4860
+	    className: 'remove',
4861
+	    append: true
4862
+	  }, userOptions); //options.className = 'remove-single';
4863
+
4864
+	  var self = this; // override the render method to add remove button to each item
4865
+
4866
+	  if (!options.append) {
4867
+	    return;
4868
+	  }
4869
+
4870
+	  var html = '<a href="javascript:void(0)" class="' + options.className + '" tabindex="-1" title="' + escape_html(options.title) + '">' + options.label + '</a>';
4871
+	  self.hook('after', 'setupTemplates', () => {
4872
+	    var orig_render_item = self.settings.render.item;
4873
+
4874
+	    self.settings.render.item = (data, escape) => {
4875
+	      var item = getDom(orig_render_item.call(self, data, escape));
4876
+	      var close_button = getDom(html);
4877
+	      item.appendChild(close_button);
4878
+	      addEvent(close_button, 'mousedown', evt => {
4879
+	        preventDefault(evt, true);
4880
+	      });
4881
+	      addEvent(close_button, 'click', evt => {
4882
+	        // propagating will trigger the dropdown to show for single mode
4883
+	        preventDefault(evt, true);
4884
+	        if (self.isLocked) return;
4885
+	        if (!self.shouldDelete([item], evt)) return;
4886
+	        self.removeItem(item);
4887
+	        self.refreshOptions(false);
4888
+	        self.inputState();
4889
+	      });
4890
+	      return item;
4891
+	    };
4892
+	  });
4893
+	}
4894
+
4895
+	/**
4896
+	 * Plugin: "restore_on_backspace" (Tom Select)
4897
+	 * Copyright (c) contributors
4898
+	 *
4899
+	 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
4900
+	 * file except in compliance with the License. You may obtain a copy of the License at:
4901
+	 * http://www.apache.org/licenses/LICENSE-2.0
4902
+	 *
4903
+	 * Unless required by applicable law or agreed to in writing, software distributed under
4904
+	 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
4905
+	 * ANY KIND, either express or implied. See the License for the specific language
4906
+	 * governing permissions and limitations under the License.
4907
+	 *
4908
+	 */
4909
+	function restore_on_backspace (userOptions) {
4910
+	  const self = this;
4911
+	  const options = Object.assign({
4912
+	    text: option => {
4913
+	      return option[self.settings.labelField];
4914
+	    }
4915
+	  }, userOptions);
4916
+	  self.on('item_remove', function (value) {
4917
+	    if (!self.isFocused) {
4918
+	      return;
4919
+	    }
4920
+
4921
+	    if (self.control_input.value.trim() === '') {
4922
+	      var option = self.options[value];
4923
+
4924
+	      if (option) {
4925
+	        self.setTextboxValue(options.text.call(self, option));
4926
+	      }
4927
+	    }
4928
+	  });
4929
+	}
4930
+
4931
+	TomSelect.define('caret_position', caret_position);
4932
+	TomSelect.define('dropdown_input', dropdown_input);
4933
+	TomSelect.define('no_backspace_delete', no_backspace_delete);
4934
+	TomSelect.define('remove_button', remove_button);
4935
+	TomSelect.define('restore_on_backspace', restore_on_backspace);
4936
+
4937
+	return TomSelect;
4938
+
4939
+}));
4940
+var tomSelect=function(el,opts){return new TomSelect(el,opts);} 
4941
+//# sourceMappingURL=tom-select.popular.js.map