PluginProbe
Elementor Website Builder – more than just a page builder / 3.31.3
Elementor Website Builder – more than just a page builder v3.31.3
4.3.0-beta3 4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 All 452 releases
elementor / assets / lib / e-select2 / js / e-select2.full.js

e-select2.full.js in Elementor Website Builder – more than just a page builder 3.31.3, at assets/lib/e-select2/js/e-select2.full.js

6,563 lines 162.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*!
2 * Select2 4.0.6-rc.1
3 * https://select2.github.io
4 *
5 * With a fix by Elementor team at lines 4329, 5449.
6 * Also deprecated jQuery features fixed at lines: 1477, 1479, 1617, 2111, 2113, 3244, 3548, 3573, 3632, 3708, 3801,
7 * 4047, 4050, 4058, 4063, 4873, 4936, 5395, 5693, 5772, 5785, 5826, 5852, 5883, 5909, 5956, 6103, 6346, 6350.
8 *
9 * Released under the MIT license
10 * https://github.com/select2/select2/blob/master/LICENSE.md
11 */
12 ;(function (factory) {
13 if (typeof define === 'function' && define.amd) {
14 // AMD. Register as an anonymous module.
15 define(['jquery'], factory);
16 } else if (typeof module === 'object' && module.exports) {
17 // Node/CommonJS
18 module.exports = function (root, jQuery) {
19 if (jQuery === undefined) {
20 // require('jQuery') returns a factory that requires window to
21 // build a jQuery instance, we normalize how we use modules
22 // that require this pattern but the window provided is a noop
23 // if it's defined (how jquery works)
24 if (typeof window !== 'undefined') {
25 jQuery = require('jquery');
26 }
27 else {
28 jQuery = require('jquery')(root);
29 }
30 }
31 factory(jQuery);
32 return jQuery;
33 };
34 } else {
35 // Browser globals
36 factory(jQuery);
37 }
38 } (function (jQuery) {
39 // This is needed so we can catch the AMD loader configuration and use it
40 // The inner file should be wrapped (by `banner.start.js`) in a function that
41 // returns the AMD loader references.
42 var S2 =(function () {
43 // Restore the Select2 AMD loader so it can be used
44 // Needed mostly in the language files, where the loader is not inserted
45 if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {
46 var S2 = jQuery.fn.select2.amd;
47 }
48 var S2;(function () { if (!S2 || !S2.requirejs) {
49 if (!S2) { S2 = {}; } else { require = S2; }
50 /**
51 * @license almond 0.3.3 Copyright jQuery Foundation and other contributors.
52 * Released under MIT license, http://github.com/requirejs/almond/LICENSE
53 */
54 //Going sloppy to avoid 'use strict' string cost, but strict practices should
55 //be followed.
56 /*global setTimeout: false */
57
58 var requirejs, require, define;
59 (function (undef) {
60 var main, req, makeMap, handlers,
61 defined = {},
62 waiting = {},
63 config = {},
64 defining = {},
65 hasOwn = Object.prototype.hasOwnProperty,
66 aps = [].slice,
67 jsSuffixRegExp = /\.js$/;
68
69 function hasProp(obj, prop) {
70 return hasOwn.call(obj, prop);
71 }
72
73 /**
74 * Given a relative module name, like ./something, normalize it to
75 * a real name that can be mapped to a path.
76 * @param {String} name the relative name
77 * @param {String} baseName a real name that the name arg is relative
78 * to.
79 * @returns {String} normalized name
80 */
81 function normalize(name, baseName) {
82 var nameParts, nameSegment, mapValue, foundMap, lastIndex,
83 foundI, foundStarMap, starI, i, j, part, normalizedBaseParts,
84 baseParts = baseName && baseName.split("/"),
85 map = config.map,
86 starMap = (map && map['*']) || {};
87
88 //Adjust any relative paths.
89 if (name) {
90 name = name.split('/');
91 lastIndex = name.length - 1;
92
93 // If wanting node ID compatibility, strip .js from end
94 // of IDs. Have to do this here, and not in nameToUrl
95 // because node allows either .js or non .js to map
96 // to same file.
97 if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
98 name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
99 }
100
101 // Starts with a '.' so need the baseName
102 if (name[0].charAt(0) === '.' && baseParts) {
103 //Convert baseName to array, and lop off the last part,
104 //so that . matches that 'directory' and not name of the baseName's
105 //module. For instance, baseName of 'one/two/three', maps to
106 //'one/two/three.js', but we want the directory, 'one/two' for
107 //this normalization.
108 normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
109 name = normalizedBaseParts.concat(name);
110 }
111
112 //start trimDots
113 for (i = 0; i < name.length; i++) {
114 part = name[i];
115 if (part === '.') {
116 name.splice(i, 1);
117 i -= 1;
118 } else if (part === '..') {
119 // If at the start, or previous value is still ..,
120 // keep them so that when converted to a path it may
121 // still work when converted to a path, even though
122 // as an ID it is less than ideal. In larger point
123 // releases, may be better to just kick out an error.
124 if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') {
125 continue;
126 } else if (i > 0) {
127 name.splice(i - 1, 2);
128 i -= 2;
129 }
130 }
131 }
132 //end trimDots
133
134 name = name.join('/');
135 }
136
137 //Apply map config if available.
138 if ((baseParts || starMap) && map) {
139 nameParts = name.split('/');
140
141 for (i = nameParts.length; i > 0; i -= 1) {
142 nameSegment = nameParts.slice(0, i).join("/");
143
144 if (baseParts) {
145 //Find the longest baseName segment match in the config.
146 //So, do joins on the biggest to smallest lengths of baseParts.
147 for (j = baseParts.length; j > 0; j -= 1) {
148 mapValue = map[baseParts.slice(0, j).join('/')];
149
150 //baseName segment has config, find if it has one for
151 //this name.
152 if (mapValue) {
153 mapValue = mapValue[nameSegment];
154 if (mapValue) {
155 //Match, update name to the new value.
156 foundMap = mapValue;
157 foundI = i;
158 break;
159 }
160 }
161 }
162 }
163
164 if (foundMap) {
165 break;
166 }
167
168 //Check for a star map match, but just hold on to it,
169 //if there is a shorter segment match later in a matching
170 //config, then favor over this star map.
171 if (!foundStarMap && starMap && starMap[nameSegment]) {
172 foundStarMap = starMap[nameSegment];
173 starI = i;
174 }
175 }
176
177 if (!foundMap && foundStarMap) {
178 foundMap = foundStarMap;
179 foundI = starI;
180 }
181
182 if (foundMap) {
183 nameParts.splice(0, foundI, foundMap);
184 name = nameParts.join('/');
185 }
186 }
187
188 return name;
189 }
190
191 function makeRequire(relName, forceSync) {
192 return function () {
193 //A version of a require function that passes a moduleName
194 //value for items that may need to
195 //look up paths relative to the moduleName
196 var args = aps.call(arguments, 0);
197
198 //If first arg is not require('string'), and there is only
199 //one arg, it is the array form without a callback. Insert
200 //a null so that the following concat is correct.
201 if (typeof args[0] !== 'string' && args.length === 1) {
202 args.push(null);
203 }
204 return req.apply(undef, args.concat([relName, forceSync]));
205 };
206 }
207
208 function makeNormalize(relName) {
209 return function (name) {
210 return normalize(name, relName);
211 };
212 }
213
214 function makeLoad(depName) {
215 return function (value) {
216 defined[depName] = value;
217 };
218 }
219
220 function callDep(name) {
221 if (hasProp(waiting, name)) {
222 var args = waiting[name];
223 delete waiting[name];
224 defining[name] = true;
225 main.apply(undef, args);
226 }
227
228 if (!hasProp(defined, name) && !hasProp(defining, name)) {
229 throw new Error('No ' + name);
230 }
231 return defined[name];
232 }
233
234 //Turns a plugin!resource to [plugin, resource]
235 //with the plugin being undefined if the name
236 //did not have a plugin prefix.
237 function splitPrefix(name) {
238 var prefix,
239 index = name ? name.indexOf('!') : -1;
240 if (index > -1) {
241 prefix = name.substring(0, index);
242 name = name.substring(index + 1, name.length);
243 }
244 return [prefix, name];
245 }
246
247 //Creates a parts array for a relName where first part is plugin ID,
248 //second part is resource ID. Assumes relName has already been normalized.
249 function makeRelParts(relName) {
250 return relName ? splitPrefix(relName) : [];
251 }
252
253 /**
254 * Makes a name map, normalizing the name, and using a plugin
255 * for normalization if necessary. Grabs a ref to plugin
256 * too, as an optimization.
257 */
258 makeMap = function (name, relParts) {
259 var plugin,
260 parts = splitPrefix(name),
261 prefix = parts[0],
262 relResourceName = relParts[1];
263
264 name = parts[1];
265
266 if (prefix) {
267 prefix = normalize(prefix, relResourceName);
268 plugin = callDep(prefix);
269 }
270
271 //Normalize according
272 if (prefix) {
273 if (plugin && plugin.normalize) {
274 name = plugin.normalize(name, makeNormalize(relResourceName));
275 } else {
276 name = normalize(name, relResourceName);
277 }
278 } else {
279 name = normalize(name, relResourceName);
280 parts = splitPrefix(name);
281 prefix = parts[0];
282 name = parts[1];
283 if (prefix) {
284 plugin = callDep(prefix);
285 }
286 }
287
288 //Using ridiculous property names for space reasons
289 return {
290 f: prefix ? prefix + '!' + name : name, //fullName
291 n: name,
292 pr: prefix,
293 p: plugin
294 };
295 };
296
297 function makeConfig(name) {
298 return function () {
299 return (config && config.config && config.config[name]) || {};
300 };
301 }
302
303 handlers = {
304 require: function (name) {
305 return makeRequire(name);
306 },
307 exports: function (name) {
308 var e = defined[name];
309 if (typeof e !== 'undefined') {
310 return e;
311 } else {
312 return (defined[name] = {});
313 }
314 },
315 module: function (name) {
316 return {
317 id: name,
318 uri: '',
319 exports: defined[name],
320 config: makeConfig(name)
321 };
322 }
323 };
324
325 main = function (name, deps, callback, relName) {
326 var cjsModule, depName, ret, map, i, relParts,
327 args = [],
328 callbackType = typeof callback,
329 usingExports;
330
331 //Use name if no relName
332 relName = relName || name;
333 relParts = makeRelParts(relName);
334
335 //Call the callback to define the module, if necessary.
336 if (callbackType === 'undefined' || callbackType === 'function') {
337 //Pull out the defined dependencies and pass the ordered
338 //values to the callback.
339 //Default to [require, exports, module] if no deps
340 deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;
341 for (i = 0; i < deps.length; i += 1) {
342 map = makeMap(deps[i], relParts);
343 depName = map.f;
344
345 //Fast path CommonJS standard dependencies.
346 if (depName === "require") {
347 args[i] = handlers.require(name);
348 } else if (depName === "exports") {
349 //CommonJS module spec 1.1
350 args[i] = handlers.exports(name);
351 usingExports = true;
352 } else if (depName === "module") {
353 //CommonJS module spec 1.1
354 cjsModule = args[i] = handlers.module(name);
355 } else if (hasProp(defined, depName) ||
356 hasProp(waiting, depName) ||
357 hasProp(defining, depName)) {
358 args[i] = callDep(depName);
359 } else if (map.p) {
360 map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});
361 args[i] = defined[depName];
362 } else {
363 throw new Error(name + ' missing ' + depName);
364 }
365 }
366
367 ret = callback ? callback.apply(defined[name], args) : undefined;
368
369 if (name) {
370 //If setting exports via "module" is in play,
371 //favor that over return value and exports. After that,
372 //favor a non-undefined return value over exports use.
373 if (cjsModule && cjsModule.exports !== undef &&
374 cjsModule.exports !== defined[name]) {
375 defined[name] = cjsModule.exports;
376 } else if (ret !== undef || !usingExports) {
377 //Use the return value from the function.
378 defined[name] = ret;
379 }
380 }
381 } else if (name) {
382 //May just be an object definition for the module. Only
383 //worry about defining if have a module name.
384 defined[name] = callback;
385 }
386 };
387
388 requirejs = require = req = function (deps, callback, relName, forceSync, alt) {
389 if (typeof deps === "string") {
390 if (handlers[deps]) {
391 //callback in this case is really relName
392 return handlers[deps](callback);
393 }
394 //Just return the module wanted. In this scenario, the
395 //deps arg is the module name, and second arg (if passed)
396 //is just the relName.
397 //Normalize module name, if it contains . or ..
398 return callDep(makeMap(deps, makeRelParts(callback)).f);
399 } else if (!deps.splice) {
400 //deps is a config object, not an array.
401 config = deps;
402 if (config.deps) {
403 req(config.deps, config.callback);
404 }
405 if (!callback) {
406 return;
407 }
408
409 if (callback.splice) {
410 //callback is an array, which means it is a dependency list.
411 //Adjust args if there are dependencies
412 deps = callback;
413 callback = relName;
414 relName = null;
415 } else {
416 deps = undef;
417 }
418 }
419
420 //Support require(['a'])
421 callback = callback || function () {};
422
423 //If relName is a function, it is an errback handler,
424 //so remove it.
425 if (typeof relName === 'function') {
426 relName = forceSync;
427 forceSync = alt;
428 }
429
430 //Simulate async callback;
431 if (forceSync) {
432 main(undef, deps, callback, relName);
433 } else {
434 //Using a non-zero value because of concern for what old browsers
435 //do, and latest browsers "upgrade" to 4 if lower value is used:
436 //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:
437 //If want a value immediately, use require('id') instead -- something
438 //that works in almond on the global level, but not guaranteed and
439 //unlikely to work in other AMD implementations.
440 setTimeout(function () {
441 main(undef, deps, callback, relName);
442 }, 4);
443 }
444
445 return req;
446 };
447
448 /**
449 * Just drops the config on the floor, but returns req in case
450 * the config return value is used.
451 */
452 req.config = function (cfg) {
453 return req(cfg);
454 };
455
456 /**
457 * Expose module registry for debugging and tooling
458 */
459 requirejs._defined = defined;
460
461 define = function (name, deps, callback) {
462 if (typeof name !== 'string') {
463 throw new Error('See almond README: incorrect module build, no module name');
464 }
465
466 //This module may not have dependencies
467 if (!deps.splice) {
468 //deps is not an array, so probably means
469 //an object literal or factory function for
470 //the value. Adjust args.
471 callback = deps;
472 deps = [];
473 }
474
475 if (!hasProp(defined, name) && !hasProp(waiting, name)) {
476 waiting[name] = [name, deps, callback];
477 }
478 };
479
480 define.amd = {
481 jQuery: true
482 };
483 }());
484
485 S2.requirejs = requirejs;S2.require = require;S2.define = define;
486 }
487 }());
488 S2.define("almond", function(){});
489
490 /* global jQuery:false, $:false */
491 S2.define('jquery',[],function () {
492 var _$ = jQuery || $;
493
494 if (_$ == null && console && console.error) {
495 console.error(
496 'Select2: An instance of jQuery or a jQuery-compatible library was not ' +
497 'found. Make sure that you are including jQuery before Select2 on your ' +
498 'web page.'
499 );
500 }
501
502 return _$;
503 });
504
505 S2.define('select2/utils',[
506 'jquery'
507 ], function ($) {
508 var Utils = {};
509
510 Utils.Extend = function (ChildClass, SuperClass) {
511 var __hasProp = {}.hasOwnProperty;
512
513 function BaseConstructor () {
514 this.constructor = ChildClass;
515 }
516
517 for (var key in SuperClass) {
518 if (__hasProp.call(SuperClass, key)) {
519 ChildClass[key] = SuperClass[key];
520 }
521 }
522
523 BaseConstructor.prototype = SuperClass.prototype;
524 ChildClass.prototype = new BaseConstructor();
525 ChildClass.__super__ = SuperClass.prototype;
526
527 return ChildClass;
528 };
529
530 function getMethods (theClass) {
531 var proto = theClass.prototype;
532
533 var methods = [];
534
535 for (var methodName in proto) {
536 var m = proto[methodName];
537
538 if (typeof m !== 'function') {
539 continue;
540 }
541
542 if (methodName === 'constructor') {
543 continue;
544 }
545
546 methods.push(methodName);
547 }
548
549 return methods;
550 }
551
552 Utils.Decorate = function (SuperClass, DecoratorClass) {
553 var decoratedMethods = getMethods(DecoratorClass);
554 var superMethods = getMethods(SuperClass);
555
556 function DecoratedClass () {
557 var unshift = Array.prototype.unshift;
558
559 var argCount = DecoratorClass.prototype.constructor.length;
560
561 var calledConstructor = SuperClass.prototype.constructor;
562
563 if (argCount > 0) {
564 unshift.call(arguments, SuperClass.prototype.constructor);
565
566 calledConstructor = DecoratorClass.prototype.constructor;
567 }
568
569 calledConstructor.apply(this, arguments);
570 }
571
572 DecoratorClass.displayName = SuperClass.displayName;
573
574 function ctr () {
575 this.constructor = DecoratedClass;
576 }
577
578 DecoratedClass.prototype = new ctr();
579
580 for (var m = 0; m < superMethods.length; m++) {
581 var superMethod = superMethods[m];
582
583 DecoratedClass.prototype[superMethod] =
584 SuperClass.prototype[superMethod];
585 }
586
587 var calledMethod = function (methodName) {
588 // Stub out the original method if it's not decorating an actual method
589 var originalMethod = function () {};
590
591 if (methodName in DecoratedClass.prototype) {
592 originalMethod = DecoratedClass.prototype[methodName];
593 }
594
595 var decoratedMethod = DecoratorClass.prototype[methodName];
596
597 return function () {
598 var unshift = Array.prototype.unshift;
599
600 unshift.call(arguments, originalMethod);
601
602 return decoratedMethod.apply(this, arguments);
603 };
604 };
605
606 for (var d = 0; d < decoratedMethods.length; d++) {
607 var decoratedMethod = decoratedMethods[d];
608
609 DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);
610 }
611
612 return DecoratedClass;
613 };
614
615 var Observable = function () {
616 this.listeners = {};
617 };
618
619 Observable.prototype.on = function (event, callback) {
620 this.listeners = this.listeners || {};
621
622 if (event in this.listeners) {
623 this.listeners[event].push(callback);
624 } else {
625 this.listeners[event] = [callback];
626 }
627 };
628
629 Observable.prototype.trigger = function (event) {
630 var slice = Array.prototype.slice;
631 var params = slice.call(arguments, 1);
632
633 this.listeners = this.listeners || {};
634
635 // Params should always come in as an array
636 if (params == null) {
637 params = [];
638 }
639
640 // If there are no arguments to the event, use a temporary object
641 if (params.length === 0) {
642 params.push({});
643 }
644
645 // Set the `_type` of the first object to the event
646 params[0]._type = event;
647
648 if (event in this.listeners) {
649 this.invoke(this.listeners[event], slice.call(arguments, 1));
650 }
651
652 if ('*' in this.listeners) {
653 this.invoke(this.listeners['*'], arguments);
654 }
655 };
656
657 Observable.prototype.invoke = function (listeners, params) {
658 for (var i = 0, len = listeners.length; i < len; i++) {
659 listeners[i].apply(this, params);
660 }
661 };
662
663 Utils.Observable = Observable;
664
665 Utils.generateChars = function (length) {
666 var chars = '';
667
668 for (var i = 0; i < length; i++) {
669 var randomChar = Math.floor(Math.random() * 36);
670 chars += randomChar.toString(36);
671 }
672
673 return chars;
674 };
675
676 Utils.bind = function (func, context) {
677 return function () {
678 func.apply(context, arguments);
679 };
680 };
681
682 Utils._convertData = function (data) {
683 for (var originalKey in data) {
684 var keys = originalKey.split('-');
685
686 var dataLevel = data;
687
688 if (keys.length === 1) {
689 continue;
690 }
691
692 for (var k = 0; k < keys.length; k++) {
693 var key = keys[k];
694
695 // Lowercase the first letter
696 // By default, dash-separated becomes camelCase
697 key = key.substring(0, 1).toLowerCase() + key.substring(1);
698
699 if (!(key in dataLevel)) {
700 dataLevel[key] = {};
701 }
702
703 if (k == keys.length - 1) {
704 dataLevel[key] = data[originalKey];
705 }
706
707 dataLevel = dataLevel[key];
708 }
709
710 delete data[originalKey];
711 }
712
713 return data;
714 };
715
716 Utils.hasScroll = function (index, el) {
717 // Adapted from the function created by @ShadowScripter
718 // and adapted by @BillBarry on the Stack Exchange Code Review website.
719 // The original code can be found at
720 // http://codereview.stackexchange.com/q/13338
721 // and was designed to be used with the Sizzle selector engine.
722
723 var $el = $(el);
724 var overflowX = el.style.overflowX;
725 var overflowY = el.style.overflowY;
726
727 //Check both x and y declarations
728 if (overflowX === overflowY &&
729 (overflowY === 'hidden' || overflowY === 'visible')) {
730 return false;
731 }
732
733 if (overflowX === 'scroll' || overflowY === 'scroll') {
734 return true;
735 }
736
737 return ($el.innerHeight() < el.scrollHeight ||
738 $el.innerWidth() < el.scrollWidth);
739 };
740
741 Utils.escapeMarkup = function (markup) {
742 var replaceMap = {
743 '\\': '&#92;',
744 '&': '&amp;',
745 '<': '&lt;',
746 '>': '&gt;',
747 '"': '&quot;',
748 '\'': '&#39;',
749 '/': '&#47;'
750 };
751
752 // Do not try to escape the markup if it's not a string
753 if (typeof markup !== 'string') {
754 return markup;
755 }
756
757 return String(markup).replace(/[&<>"'\/\\]/g, function (match) {
758 return replaceMap[match];
759 });
760 };
761
762 // Append an array of jQuery nodes to a given element.
763 Utils.appendMany = function ($element, $nodes) {
764 // jQuery 1.7.x does not support $.fn.append() with an array
765 // Fall back to a jQuery object collection using $.fn.add()
766 if ($.fn.jquery.substr(0, 3) === '1.7') {
767 var $jqNodes = $();
768
769 $.map($nodes, function (node) {
770 $jqNodes = $jqNodes.add(node);
771 });
772
773 $nodes = $jqNodes;
774 }
775
776 $element.append($nodes);
777 };
778
779 // Cache objects in Utils.__cache instead of $.data (see #4346)
780 Utils.__cache = {};
781
782 var id = 0;
783 Utils.GetUniqueElementId = function (element) {
784 // Get a unique element Id. If element has no id,
785 // creates a new unique number, stores it in the id
786 // attribute and returns the new id.
787 // If an id already exists, it simply returns it.
788
789 var select2Id = element.getAttribute('data-select2-id');
790 if (select2Id == null) {
791 // If element has id, use it.
792 if (element.id) {
793 select2Id = element.id;
794 element.setAttribute('data-select2-id', select2Id);
795 } else {
796 element.setAttribute('data-select2-id', ++id);
797 select2Id = id.toString();
798 }
799 }
800 return select2Id;
801 };
802
803 Utils.StoreData = function (element, name, value) {
804 // Stores an item in the cache for a specified element.
805 // name is the cache key.
806 var id = Utils.GetUniqueElementId(element);
807 if (!Utils.__cache[id]) {
808 Utils.__cache[id] = {};
809 }
810
811 Utils.__cache[id][name] = value;
812 };
813
814 Utils.GetData = function (element, name) {
815 // Retrieves a value from the cache by its key (name)
816 // name is optional. If no name specified, return
817 // all cache items for the specified element.
818 // and for a specified element.
819 var id = Utils.GetUniqueElementId(element);
820 if (name) {
821 if (Utils.__cache[id]) {
822 return Utils.__cache[id][name] != null ?
823 Utils.__cache[id][name]:
824 $(element).data(name); // Fallback to HTML5 data attribs.
825 }
826 return $(element).data(name); // Fallback to HTML5 data attribs.
827 } else {
828 return Utils.__cache[id];
829 }
830 };
831
832 Utils.RemoveData = function (element) {
833 // Removes all cached items for a specified element.
834 var id = Utils.GetUniqueElementId(element);
835 if (Utils.__cache[id] != null) {
836 delete Utils.__cache[id];
837 }
838 };
839
840 return Utils;
841 });
842
843 S2.define('select2/results',[
844 'jquery',
845 './utils'
846 ], function ($, Utils) {
847 function Results ($element, options, dataAdapter) {
848 this.$element = $element;
849 this.data = dataAdapter;
850 this.options = options;
851
852 Results.__super__.constructor.call(this);
853 }
854
855 Utils.Extend(Results, Utils.Observable);
856
857 Results.prototype.render = function () {
858 var $results = $(
859 '<ul class="select2-results__options" role="tree"></ul>'
860 );
861
862 if (this.options.get('multiple')) {
863 $results.attr('aria-multiselectable', 'true');
864 }
865
866 this.$results = $results;
867
868 return $results;
869 };
870
871 Results.prototype.clear = function () {
872 this.$results.empty();
873 };
874
875 Results.prototype.displayMessage = function (params) {
876 var escapeMarkup = this.options.get('escapeMarkup');
877
878 this.clear();
879 this.hideLoading();
880
881 var $message = $(
882 '<li role="treeitem" aria-live="assertive"' +
883 ' class="select2-results__option"></li>'
884 );
885
886 var message = this.options.get('translations').get(params.message);
887
888 $message.append(
889 escapeMarkup(
890 message(params.args)
891 )
892 );
893
894 $message[0].className += ' select2-results__message';
895
896 this.$results.append($message);
897 };
898
899 Results.prototype.hideMessages = function () {
900 this.$results.find('.select2-results__message').remove();
901 };
902
903 Results.prototype.append = function (data) {
904 this.hideLoading();
905
906 var $options = [];
907
908 if (data.results == null || data.results.length === 0) {
909 if (this.$results.children().length === 0) {
910 this.trigger('results:message', {
911 message: 'noResults'
912 });
913 }
914
915 return;
916 }
917
918 data.results = this.sort(data.results);
919
920 for (var d = 0; d < data.results.length; d++) {
921 var item = data.results[d];
922
923 var $option = this.option(item);
924
925 $options.push($option);
926 }
927
928 this.$results.append($options);
929 };
930
931 Results.prototype.position = function ($results, $dropdown) {
932 var $resultsContainer = $dropdown.find('.select2-results');
933 $resultsContainer.append($results);
934 };
935
936 Results.prototype.sort = function (data) {
937 var sorter = this.options.get('sorter');
938
939 return sorter(data);
940 };
941
942 Results.prototype.highlightFirstItem = function () {
943 var $options = this.$results
944 .find('.select2-results__option[aria-selected]');
945
946 var $selected = $options.filter('[aria-selected=true]');
947
948 // Check if there are any selected options
949 if ($selected.length > 0) {
950 // If there are selected options, highlight the first
951 $selected.first().trigger('mouseenter');
952 } else {
953 // If there are no selected options, highlight the first option
954 // in the dropdown
955 $options.first().trigger('mouseenter');
956 }
957
958 this.ensureHighlightVisible();
959 };
960
961 Results.prototype.setClasses = function () {
962 var self = this;
963
964 this.data.current(function (selected) {
965 var selectedIds = $.map(selected, function (s) {
966 return s.id.toString();
967 });
968
969 var $options = self.$results
970 .find('.select2-results__option[aria-selected]');
971
972 $options.each(function () {
973 var $option = $(this);
974
975 var item = Utils.GetData(this, 'data');
976
977 // id needs to be converted to a string when comparing
978 var id = '' + item.id;
979
980 if ((item.element != null && item.element.selected) ||
981 (item.element == null && $.inArray(id, selectedIds) > -1)) {
982 $option.attr('aria-selected', 'true');
983 } else {
984 $option.attr('aria-selected', 'false');
985 }
986 });
987
988 });
989 };
990
991 Results.prototype.showLoading = function (params) {
992 this.hideLoading();
993
994 var loadingMore = this.options.get('translations').get('searching');
995
996 var loading = {
997 disabled: true,
998 loading: true,
999 text: loadingMore(params)
1000 };
1001 var $loading = this.option(loading);
1002 $loading.className += ' loading-results';
1003
1004 this.$results.prepend($loading);
1005 };
1006
1007 Results.prototype.hideLoading = function () {
1008 this.$results.find('.loading-results').remove();
1009 };
1010
1011 Results.prototype.option = function (data) {
1012 var option = document.createElement('li');
1013 option.className = 'select2-results__option';
1014
1015 var attrs = {
1016 'role': 'treeitem',
1017 'aria-selected': 'false'
1018 };
1019
1020 if (data.disabled) {
1021 delete attrs['aria-selected'];
1022 attrs['aria-disabled'] = 'true';
1023 }
1024
1025 if (data.id == null) {
1026 delete attrs['aria-selected'];
1027 }
1028
1029 if (data._resultId != null) {
1030 option.id = data._resultId;
1031 }
1032
1033 if (data.title) {
1034 option.title = data.title;
1035 }
1036
1037 if (data.children) {
1038 attrs.role = 'group';
1039 attrs['aria-label'] = data.text;
1040 delete attrs['aria-selected'];
1041 }
1042
1043 for (var attr in attrs) {
1044 var val = attrs[attr];
1045
1046 option.setAttribute(attr, val);
1047 }
1048
1049 if (data.children) {
1050 var $option = $(option);
1051
1052 var label = document.createElement('strong');
1053 label.className = 'select2-results__group';
1054
1055 var $label = $(label);
1056 this.template(data, label);
1057
1058 var $children = [];
1059
1060 for (var c = 0; c < data.children.length; c++) {
1061 var child = data.children[c];
1062
1063 var $child = this.option(child);
1064
1065 $children.push($child);
1066 }
1067
1068 var $childrenContainer = $('<ul></ul>', {
1069 'class': 'select2-results__options select2-results__options--nested'
1070 });
1071
1072 $childrenContainer.append($children);
1073
1074 $option.append(label);
1075 $option.append($childrenContainer);
1076 } else {
1077 this.template(data, option);
1078 }
1079
1080 Utils.StoreData(option, 'data', data);
1081
1082 return option;
1083 };
1084
1085 Results.prototype.bind = function (container, $container) {
1086 var self = this;
1087
1088 var id = container.id + '-results';
1089
1090 this.$results.attr('id', id);
1091
1092 container.on('results:all', function (params) {
1093 self.clear();
1094 self.append(params.data);
1095
1096 if (container.isOpen()) {
1097 self.setClasses();
1098 self.highlightFirstItem();
1099 }
1100 });
1101
1102 container.on('results:append', function (params) {
1103 self.append(params.data);
1104
1105 if (container.isOpen()) {
1106 self.setClasses();
1107 }
1108 });
1109
1110 container.on('query', function (params) {
1111 self.hideMessages();
1112 self.showLoading(params);
1113 });
1114
1115 container.on('select', function () {
1116 if (!container.isOpen()) {
1117 return;
1118 }
1119
1120 self.setClasses();
1121 self.highlightFirstItem();
1122 });
1123
1124 container.on('unselect', function () {
1125 if (!container.isOpen()) {
1126 return;
1127 }
1128
1129 self.setClasses();
1130 self.highlightFirstItem();
1131 });
1132
1133 container.on('open', function () {
1134 // When the dropdown is open, aria-expended="true"
1135 self.$results.attr('aria-expanded', 'true');
1136 self.$results.attr('aria-hidden', 'false');
1137
1138 self.setClasses();
1139 self.ensureHighlightVisible();
1140 });
1141
1142 container.on('close', function () {
1143 // When the dropdown is closed, aria-expended="false"
1144 self.$results.attr('aria-expanded', 'false');
1145 self.$results.attr('aria-hidden', 'true');
1146 self.$results.removeAttr('aria-activedescendant');
1147 });
1148
1149 container.on('results:toggle', function () {
1150 var $highlighted = self.getHighlightedResults();
1151
1152 if ($highlighted.length === 0) {
1153 return;
1154 }
1155
1156 $highlighted.trigger('mouseup');
1157 });
1158
1159 container.on('results:select', function () {
1160 var $highlighted = self.getHighlightedResults();
1161
1162 if ($highlighted.length === 0) {
1163 return;
1164 }
1165
1166 var data = Utils.GetData($highlighted[0], 'data');
1167
1168 if ($highlighted.attr('aria-selected') == 'true') {
1169 self.trigger('close', {});
1170 } else {
1171 self.trigger('select', {
1172 data: data
1173 });
1174 }
1175 });
1176
1177 container.on('results:previous', function () {
1178 var $highlighted = self.getHighlightedResults();
1179
1180 var $options = self.$results.find('[aria-selected]');
1181
1182 var currentIndex = $options.index($highlighted);
1183
1184 // If we are already at te top, don't move further
1185 // If no options, currentIndex will be -1
1186 if (currentIndex <= 0) {
1187 return;
1188 }
1189
1190 var nextIndex = currentIndex - 1;
1191
1192 // If none are highlighted, highlight the first
1193 if ($highlighted.length === 0) {
1194 nextIndex = 0;
1195 }
1196
1197 var $next = $options.eq(nextIndex);
1198
1199 $next.trigger('mouseenter');
1200
1201 var currentOffset = self.$results.offset().top;
1202 var nextTop = $next.offset().top;
1203 var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
1204
1205 if (nextIndex === 0) {
1206 self.$results.scrollTop(0);
1207 } else if (nextTop - currentOffset < 0) {
1208 self.$results.scrollTop(nextOffset);
1209 }
1210 });
1211
1212 container.on('results:next', function () {
1213 var $highlighted = self.getHighlightedResults();
1214
1215 var $options = self.$results.find('[aria-selected]');
1216
1217 var currentIndex = $options.index($highlighted);
1218
1219 var nextIndex = currentIndex + 1;
1220
1221 // If we are at the last option, stay there
1222 if (nextIndex >= $options.length) {
1223 return;
1224 }
1225
1226 var $next = $options.eq(nextIndex);
1227
1228 $next.trigger('mouseenter');
1229
1230 var currentOffset = self.$results.offset().top +
1231 self.$results.outerHeight(false);
1232 var nextBottom = $next.offset().top + $next.outerHeight(false);
1233 var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
1234
1235 if (nextIndex === 0) {
1236 self.$results.scrollTop(0);
1237 } else if (nextBottom > currentOffset) {
1238 self.$results.scrollTop(nextOffset);
1239 }
1240 });
1241
1242 container.on('results:focus', function (params) {
1243 params.element.addClass('select2-results__option--highlighted');
1244 });
1245
1246 container.on('results:message', function (params) {
1247 self.displayMessage(params);
1248 });
1249
1250 if ($.fn.mousewheel) {
1251 this.$results.on('mousewheel', function (e) {
1252 var top = self.$results.scrollTop();
1253
1254 var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
1255
1256 var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
1257 var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
1258
1259 if (isAtTop) {
1260 self.$results.scrollTop(0);
1261
1262 e.preventDefault();
1263 e.stopPropagation();
1264 } else if (isAtBottom) {
1265 self.$results.scrollTop(
1266 self.$results.get(0).scrollHeight - self.$results.height()
1267 );
1268
1269 e.preventDefault();
1270 e.stopPropagation();
1271 }
1272 });
1273 }
1274
1275 this.$results.on('mouseup', '.select2-results__option[aria-selected]',
1276 function (evt) {
1277 var $this = $(this);
1278
1279 var data = Utils.GetData(this, 'data');
1280
1281 if ($this.attr('aria-selected') === 'true') {
1282 if (self.options.get('multiple')) {
1283 self.trigger('unselect', {
1284 originalEvent: evt,
1285 data: data
1286 });
1287 } else {
1288 self.trigger('close', {});
1289 }
1290
1291 return;
1292 }
1293
1294 self.trigger('select', {
1295 originalEvent: evt,
1296 data: data
1297 });
1298 });
1299
1300 this.$results.on('mouseenter', '.select2-results__option[aria-selected]',
1301 function (evt) {
1302 var data = Utils.GetData(this, 'data');
1303
1304 self.getHighlightedResults()
1305 .removeClass('select2-results__option--highlighted');
1306
1307 self.trigger('results:focus', {
1308 data: data,
1309 element: $(this)
1310 });
1311 });
1312 };
1313
1314 Results.prototype.getHighlightedResults = function () {
1315 var $highlighted = this.$results
1316 .find('.select2-results__option--highlighted');
1317
1318 return $highlighted;
1319 };
1320
1321 Results.prototype.destroy = function () {
1322 this.$results.remove();
1323 };
1324
1325 Results.prototype.ensureHighlightVisible = function () {
1326 var $highlighted = this.getHighlightedResults();
1327
1328 if ($highlighted.length === 0) {
1329 return;
1330 }
1331
1332 var $options = this.$results.find('[aria-selected]');
1333
1334 var currentIndex = $options.index($highlighted);
1335
1336 var currentOffset = this.$results.offset().top;
1337 var nextTop = $highlighted.offset().top;
1338 var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
1339
1340 var offsetDelta = nextTop - currentOffset;
1341 nextOffset -= $highlighted.outerHeight(false) * 2;
1342
1343 if (currentIndex <= 2) {
1344 this.$results.scrollTop(0);
1345 } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
1346 this.$results.scrollTop(nextOffset);
1347 }
1348 };
1349
1350 Results.prototype.template = function (result, container) {
1351 var template = this.options.get('templateResult');
1352 var escapeMarkup = this.options.get('escapeMarkup');
1353
1354 var content = template(result, container);
1355
1356 if (content == null) {
1357 container.style.display = 'none';
1358 } else if (typeof content === 'string') {
1359 container.innerHTML = escapeMarkup(content);
1360 } else {
1361 $(container).append(content);
1362 }
1363 };
1364
1365 return Results;
1366 });
1367
1368 S2.define('select2/keys',[
1369
1370 ], function () {
1371 var KEYS = {
1372 BACKSPACE: 8,
1373 TAB: 9,
1374 ENTER: 13,
1375 SHIFT: 16,
1376 CTRL: 17,
1377 ALT: 18,
1378 ESC: 27,
1379 SPACE: 32,
1380 PAGE_UP: 33,
1381 PAGE_DOWN: 34,
1382 END: 35,
1383 HOME: 36,
1384 LEFT: 37,
1385 UP: 38,
1386 RIGHT: 39,
1387 DOWN: 40,
1388 DELETE: 46
1389 };
1390
1391 return KEYS;
1392 });
1393
1394 S2.define('select2/selection/base',[
1395 'jquery',
1396 '../utils',
1397 '../keys'
1398 ], function ($, Utils, KEYS) {
1399 function BaseSelection ($element, options) {
1400 this.$element = $element;
1401 this.options = options;
1402
1403 BaseSelection.__super__.constructor.call(this);
1404 }
1405
1406 Utils.Extend(BaseSelection, Utils.Observable);
1407
1408 BaseSelection.prototype.render = function () {
1409 var $selection = $(
1410 '<span class="select2-selection" role="combobox" ' +
1411 ' aria-haspopup="true" aria-expanded="false">' +
1412 '</span>'
1413 );
1414
1415 this._tabindex = 0;
1416
1417 if (Utils.GetData(this.$element[0], 'old-tabindex') != null) {
1418 this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex');
1419 } else if (this.$element.attr('tabindex') != null) {
1420 this._tabindex = this.$element.attr('tabindex');
1421 }
1422
1423 $selection.attr('title', this.$element.attr('title'));
1424 $selection.attr('tabindex', this._tabindex);
1425
1426 this.$selection = $selection;
1427
1428 return $selection;
1429 };
1430
1431 BaseSelection.prototype.bind = function (container, $container) {
1432 var self = this;
1433
1434 var id = container.id + '-container';
1435 var resultsId = container.id + '-results';
1436
1437 this.container = container;
1438
1439 this.$selection.on('focus', function (evt) {
1440 self.trigger('focus', evt);
1441 });
1442
1443 this.$selection.on('blur', function (evt) {
1444 self._handleBlur(evt);
1445 });
1446
1447 this.$selection.on('keydown', function (evt) {
1448 self.trigger('keypress', evt);
1449
1450 if (evt.which === KEYS.SPACE) {
1451 evt.preventDefault();
1452 }
1453 });
1454
1455 container.on('results:focus', function (params) {
1456 self.$selection.attr('aria-activedescendant', params.data._resultId);
1457 });
1458
1459 container.on('selection:update', function (params) {
1460 self.update(params.data);
1461 });
1462
1463 container.on('open', function () {
1464 // When the dropdown is open, aria-expanded="true"
1465 self.$selection.attr('aria-expanded', 'true');
1466 self.$selection.attr('aria-owns', resultsId);
1467
1468 self._attachCloseHandler(container);
1469 });
1470
1471 container.on('close', function () {
1472 // When the dropdown is closed, aria-expanded="false"
1473 self.$selection.attr('aria-expanded', 'false');
1474 self.$selection.removeAttr('aria-activedescendant');
1475 self.$selection.removeAttr('aria-owns');
1476
1477 self.$selection.trigger('focus');
1478 window.setTimeout(function () {
1479 self.$selection.trigger('focus');
1480 }, 0);
1481
1482 self._detachCloseHandler(container);
1483 });
1484
1485 container.on('enable', function () {
1486 self.$selection.attr('tabindex', self._tabindex);
1487 });
1488
1489 container.on('disable', function () {
1490 self.$selection.attr('tabindex', '-1');
1491 });
1492 };
1493
1494 BaseSelection.prototype._handleBlur = function (evt) {
1495 var self = this;
1496
1497 // This needs to be delayed as the active element is the body when the tab
1498 // key is pressed, possibly along with others.
1499 window.setTimeout(function () {
1500 // Don't trigger `blur` if the focus is still in the selection
1501 if (
1502 (document.activeElement == self.$selection[0]) ||
1503 ($.contains(self.$selection[0], document.activeElement))
1504 ) {
1505 return;
1506 }
1507
1508 self.trigger('blur', evt);
1509 }, 1);
1510 };
1511
1512 BaseSelection.prototype._attachCloseHandler = function (container) {
1513 var self = this;
1514
1515 $(document.body).on('mousedown.select2.' + container.id, function (e) {
1516 var $target = $(e.target);
1517
1518 var $select = $target.closest('.select2');
1519
1520 var $all = $('.select2.select2-container--open');
1521
1522 $all.each(function () {
1523 var $this = $(this);
1524
1525 if (this == $select[0]) {
1526 return;
1527 }
1528
1529 var $element = Utils.GetData(this, 'element');
1530
1531 $element.select2('close');
1532 });
1533 });
1534 };
1535
1536 BaseSelection.prototype._detachCloseHandler = function (container) {
1537 $(document.body).off('mousedown.select2.' + container.id);
1538 };
1539
1540 BaseSelection.prototype.position = function ($selection, $container) {
1541 var $selectionContainer = $container.find('.selection');
1542 $selectionContainer.append($selection);
1543 };
1544
1545 BaseSelection.prototype.destroy = function () {
1546 this._detachCloseHandler(this.container);
1547 };
1548
1549 BaseSelection.prototype.update = function (data) {
1550 throw new Error('The `update` method must be defined in child classes.');
1551 };
1552
1553 return BaseSelection;
1554 });
1555
1556 S2.define('select2/selection/single',[
1557 'jquery',
1558 './base',
1559 '../utils',
1560 '../keys'
1561 ], function ($, BaseSelection, Utils, KEYS) {
1562 function SingleSelection () {
1563 SingleSelection.__super__.constructor.apply(this, arguments);
1564 }
1565
1566 Utils.Extend(SingleSelection, BaseSelection);
1567
1568 SingleSelection.prototype.render = function () {
1569 var $selection = SingleSelection.__super__.render.call(this);
1570
1571 $selection.addClass('select2-selection--single');
1572
1573 $selection.html(
1574 '<span class="select2-selection__rendered"></span>' +
1575 '<span class="select2-selection__arrow" role="presentation">' +
1576 '<b role="presentation"></b>' +
1577 '</span>'
1578 );
1579
1580 return $selection;
1581 };
1582
1583 SingleSelection.prototype.bind = function (container, $container) {
1584 var self = this;
1585
1586 SingleSelection.__super__.bind.apply(this, arguments);
1587
1588 var id = container.id + '-container';
1589
1590 this.$selection.find('.select2-selection__rendered')
1591 .attr('id', id)
1592 .attr('role', 'textbox')
1593 .attr('aria-readonly', 'true');
1594 this.$selection.attr('aria-labelledby', id);
1595
1596 this.$selection.on('mousedown', function (evt) {
1597 // Only respond to left clicks
1598 if (evt.which !== 1) {
1599 return;
1600 }
1601
1602 self.trigger('toggle', {
1603 originalEvent: evt
1604 });
1605 });
1606
1607 this.$selection.on('focus', function (evt) {
1608 // User focuses on the container
1609 });
1610
1611 this.$selection.on('blur', function (evt) {
1612 // User exits the container
1613 });
1614
1615 container.on('focus', function (evt) {
1616 if (!container.isOpen()) {
1617 self.$selection.trigger('focus');
1618 }
1619 });
1620 };
1621
1622 SingleSelection.prototype.clear = function () {
1623 var $rendered = this.$selection.find('.select2-selection__rendered');
1624 $rendered.empty();
1625 $rendered.removeAttr('title'); // clear tooltip on empty
1626 };
1627
1628 SingleSelection.prototype.display = function (data, container) {
1629 var template = this.options.get('templateSelection');
1630 var escapeMarkup = this.options.get('escapeMarkup');
1631
1632 return escapeMarkup(template(data, container));
1633 };
1634
1635 SingleSelection.prototype.selectionContainer = function () {
1636 return $('<span></span>');
1637 };
1638
1639 SingleSelection.prototype.update = function (data) {
1640 if (data.length === 0) {
1641 this.clear();
1642 return;
1643 }
1644
1645 var selection = data[0];
1646
1647 var $rendered = this.$selection.find('.select2-selection__rendered');
1648 var formatted = this.display(selection, $rendered);
1649
1650 $rendered.empty().append(formatted);
1651 $rendered.attr('title', selection.title || selection.text);
1652 };
1653
1654 return SingleSelection;
1655 });
1656
1657 S2.define('select2/selection/multiple',[
1658 'jquery',
1659 './base',
1660 '../utils'
1661 ], function ($, BaseSelection, Utils) {
1662 function MultipleSelection ($element, options) {
1663 MultipleSelection.__super__.constructor.apply(this, arguments);
1664 }
1665
1666 Utils.Extend(MultipleSelection, BaseSelection);
1667
1668 MultipleSelection.prototype.render = function () {
1669 var $selection = MultipleSelection.__super__.render.call(this);
1670
1671 $selection.addClass('select2-selection--multiple');
1672
1673 $selection.html(
1674 '<ul class="select2-selection__rendered"></ul>'
1675 );
1676
1677 return $selection;
1678 };
1679
1680 MultipleSelection.prototype.bind = function (container, $container) {
1681 var self = this;
1682
1683 MultipleSelection.__super__.bind.apply(this, arguments);
1684
1685 this.$selection.on('click', function (evt) {
1686 self.trigger('toggle', {
1687 originalEvent: evt
1688 });
1689 });
1690
1691 this.$selection.on(
1692 'click',
1693 '.select2-selection__choice__remove',
1694 function (evt) {
1695 // Ignore the event if it is disabled
1696 if (self.options.get('disabled')) {
1697 return;
1698 }
1699
1700 var $remove = $(this);
1701 var $selection = $remove.parent();
1702
1703 var data = Utils.GetData($selection[0], 'data');
1704
1705 self.trigger('unselect', {
1706 originalEvent: evt,
1707 data: data
1708 });
1709 }
1710 );
1711 };
1712
1713 MultipleSelection.prototype.clear = function () {
1714 var $rendered = this.$selection.find('.select2-selection__rendered');
1715 $rendered.empty();
1716 $rendered.removeAttr('title');
1717 };
1718
1719 MultipleSelection.prototype.display = function (data, container) {
1720 var template = this.options.get('templateSelection');
1721 var escapeMarkup = this.options.get('escapeMarkup');
1722
1723 return escapeMarkup(template(data, container));
1724 };
1725
1726 MultipleSelection.prototype.selectionContainer = function () {
1727 var $container = $(
1728 '<li class="select2-selection__choice">' +
1729 '<span class="select2-selection__choice__remove" role="presentation">' +
1730 '&times;' +
1731 '</span>' +
1732 '</li>'
1733 );
1734
1735 return $container;
1736 };
1737
1738 MultipleSelection.prototype.update = function (data) {
1739 this.clear();
1740
1741 if (data.length === 0) {
1742 return;
1743 }
1744
1745 var $selections = [];
1746
1747 for (var d = 0; d < data.length; d++) {
1748 var selection = data[d];
1749
1750 var $selection = this.selectionContainer();
1751 var formatted = this.display(selection, $selection);
1752
1753 $selection.append(formatted);
1754 $selection.attr('title', selection.title || selection.text);
1755
1756 Utils.StoreData($selection[0], 'data', selection);
1757
1758 $selections.push($selection);
1759 }
1760
1761 var $rendered = this.$selection.find('.select2-selection__rendered');
1762
1763 Utils.appendMany($rendered, $selections);
1764 };
1765
1766 return MultipleSelection;
1767 });
1768
1769 S2.define('select2/selection/placeholder',[
1770 '../utils'
1771 ], function (Utils) {
1772 function Placeholder (decorated, $element, options) {
1773 this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
1774
1775 decorated.call(this, $element, options);
1776 }
1777
1778 Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
1779 if (typeof placeholder === 'string') {
1780 placeholder = {
1781 id: '',
1782 text: placeholder
1783 };
1784 }
1785
1786 return placeholder;
1787 };
1788
1789 Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
1790 var $placeholder = this.selectionContainer();
1791
1792 $placeholder.html(this.display(placeholder));
1793 $placeholder.addClass('select2-selection__placeholder')
1794 .removeClass('select2-selection__choice');
1795
1796 return $placeholder;
1797 };
1798
1799 Placeholder.prototype.update = function (decorated, data) {
1800 var singlePlaceholder = (
1801 data.length == 1 && data[0].id != this.placeholder.id
1802 );
1803 var multipleSelections = data.length > 1;
1804
1805 if (multipleSelections || singlePlaceholder) {
1806 return decorated.call(this, data);
1807 }
1808
1809 this.clear();
1810
1811 var $placeholder = this.createPlaceholder(this.placeholder);
1812
1813 this.$selection.find('.select2-selection__rendered').append($placeholder);
1814 };
1815
1816 return Placeholder;
1817 });
1818
1819 S2.define('select2/selection/allowClear',[
1820 'jquery',
1821 '../keys',
1822 '../utils'
1823 ], function ($, KEYS, Utils) {
1824 function AllowClear () { }
1825
1826 AllowClear.prototype.bind = function (decorated, container, $container) {
1827 var self = this;
1828
1829 decorated.call(this, container, $container);
1830
1831 if (this.placeholder == null) {
1832 if (this.options.get('debug') && window.console && console.error) {
1833 console.error(
1834 'Select2: The `allowClear` option should be used in combination ' +
1835 'with the `placeholder` option.'
1836 );
1837 }
1838 }
1839
1840 this.$selection.on('mousedown', '.select2-selection__clear',
1841 function (evt) {
1842 self._handleClear(evt);
1843 });
1844
1845 container.on('keypress', function (evt) {
1846 self._handleKeyboardClear(evt, container);
1847 });
1848 };
1849
1850 AllowClear.prototype._handleClear = function (_, evt) {
1851 // Ignore the event if it is disabled
1852 if (this.options.get('disabled')) {
1853 return;
1854 }
1855
1856 var $clear = this.$selection.find('.select2-selection__clear');
1857
1858 // Ignore the event if nothing has been selected
1859 if ($clear.length === 0) {
1860 return;
1861 }
1862
1863 evt.stopPropagation();
1864
1865 var data = Utils.GetData($clear[0], 'data');
1866
1867 var previousVal = this.$element.val();
1868 this.$element.val(this.placeholder.id);
1869
1870 var unselectData = {
1871 data: data
1872 };
1873 this.trigger('clear', unselectData);
1874 if (unselectData.prevented) {
1875 this.$element.val(previousVal);
1876 return;
1877 }
1878
1879 for (var d = 0; d < data.length; d++) {
1880 unselectData = {
1881 data: data[d]
1882 };
1883
1884 // Trigger the `unselect` event, so people can prevent it from being
1885 // cleared.
1886 this.trigger('unselect', unselectData);
1887
1888 // If the event was prevented, don't clear it out.
1889 if (unselectData.prevented) {
1890 this.$element.val(previousVal);
1891 return;
1892 }
1893 }
1894
1895 this.$element.trigger('change');
1896
1897 this.trigger('toggle', {});
1898 };
1899
1900 AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
1901 if (container.isOpen()) {
1902 return;
1903 }
1904
1905 if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
1906 this._handleClear(evt);
1907 }
1908 };
1909
1910 AllowClear.prototype.update = function (decorated, data) {
1911 decorated.call(this, data);
1912
1913 if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
1914 data.length === 0) {
1915 return;
1916 }
1917
1918 var $remove = $(
1919 '<span class="select2-selection__clear">' +
1920 '&times;' +
1921 '</span>'
1922 );
1923 Utils.StoreData($remove[0], 'data', data);
1924
1925 this.$selection.find('.select2-selection__rendered').prepend($remove);
1926 };
1927
1928 return AllowClear;
1929 });
1930
1931 S2.define('select2/selection/search',[
1932 'jquery',
1933 '../utils',
1934 '../keys'
1935 ], function ($, Utils, KEYS) {
1936 function Search (decorated, $element, options) {
1937 decorated.call(this, $element, options);
1938 }
1939
1940 Search.prototype.render = function (decorated) {
1941 var $search = $(
1942 '<li class="select2-search select2-search--inline">' +
1943 '<input class="select2-search__field" type="search" tabindex="-1"' +
1944 ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
1945 ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
1946 '</li>'
1947 );
1948
1949 this.$searchContainer = $search;
1950 this.$search = $search.find('input');
1951
1952 var $rendered = decorated.call(this);
1953
1954 this._transferTabIndex();
1955
1956 return $rendered;
1957 };
1958
1959 Search.prototype.bind = function (decorated, container, $container) {
1960 var self = this;
1961
1962 decorated.call(this, container, $container);
1963
1964 container.on('open', function () {
1965 self.$search.trigger('focus');
1966 });
1967
1968 container.on('close', function () {
1969 self.$search.val('');
1970 self.$search.removeAttr('aria-activedescendant');
1971 self.$search.trigger('focus');
1972 });
1973
1974 container.on('enable', function () {
1975 self.$search.prop('disabled', false);
1976
1977 self._transferTabIndex();
1978 });
1979
1980 container.on('disable', function () {
1981 self.$search.prop('disabled', true);
1982 });
1983
1984 container.on('focus', function (evt) {
1985 self.$search.trigger('focus');
1986 });
1987
1988 container.on('results:focus', function (params) {
1989 self.$search.attr('aria-activedescendant', params.id);
1990 });
1991
1992 this.$selection.on('focusin', '.select2-search--inline', function (evt) {
1993 self.trigger('focus', evt);
1994 });
1995
1996 this.$selection.on('focusout', '.select2-search--inline', function (evt) {
1997 self._handleBlur(evt);
1998 });
1999
2000 this.$selection.on('keydown', '.select2-search--inline', function (evt) {
2001 evt.stopPropagation();
2002
2003 self.trigger('keypress', evt);
2004
2005 self._keyUpPrevented = evt.isDefaultPrevented();
2006
2007 var key = evt.which;
2008
2009 if (key === KEYS.BACKSPACE && self.$search.val() === '') {
2010 var $previousChoice = self.$searchContainer
2011 .prev('.select2-selection__choice');
2012
2013 if ($previousChoice.length > 0) {
2014 var item = Utils.GetData($previousChoice[0], 'data');
2015
2016 self.searchRemoveChoice(item);
2017
2018 evt.preventDefault();
2019 }
2020 }
2021 });
2022
2023 // Try to detect the IE version should the `documentMode` property that
2024 // is stored on the document. This is only implemented in IE and is
2025 // slightly cleaner than doing a user agent check.
2026 // This property is not available in Edge, but Edge also doesn't have
2027 // this bug.
2028 var msie = document.documentMode;
2029 var disableInputEvents = msie && msie <= 11;
2030
2031 // Workaround for browsers which do not support the `input` event
2032 // This will prevent double-triggering of events for browsers which support
2033 // both the `keyup` and `input` events.
2034 this.$selection.on(
2035 'input.searchcheck',
2036 '.select2-search--inline',
2037 function (evt) {
2038 // IE will trigger the `input` event when a placeholder is used on a
2039 // search box. To get around this issue, we are forced to ignore all
2040 // `input` events in IE and keep using `keyup`.
2041 if (disableInputEvents) {
2042 self.$selection.off('input.search input.searchcheck');
2043 return;
2044 }
2045
2046 // Unbind the duplicated `keyup` event
2047 self.$selection.off('keyup.search');
2048 }
2049 );
2050
2051 this.$selection.on(
2052 'keyup.search input.search',
2053 '.select2-search--inline',
2054 function (evt) {
2055 // IE will trigger the `input` event when a placeholder is used on a
2056 // search box. To get around this issue, we are forced to ignore all
2057 // `input` events in IE and keep using `keyup`.
2058 if (disableInputEvents && evt.type === 'input') {
2059 self.$selection.off('input.search input.searchcheck');
2060 return;
2061 }
2062
2063 var key = evt.which;
2064
2065 // We can freely ignore events from modifier keys
2066 if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
2067 return;
2068 }
2069
2070 // Tabbing will be handled during the `keydown` phase
2071 if (key == KEYS.TAB) {
2072 return;
2073 }
2074
2075 self.handleSearch(evt);
2076 }
2077 );
2078 };
2079
2080 /**
2081 * This method will transfer the tabindex attribute from the rendered
2082 * selection to the search box. This allows for the search box to be used as
2083 * the primary focus instead of the selection container.
2084 *
2085 * @private
2086 */
2087 Search.prototype._transferTabIndex = function (decorated) {
2088 this.$search.attr('tabindex', this.$selection.attr('tabindex'));
2089 this.$selection.attr('tabindex', '-1');
2090 };
2091
2092 Search.prototype.createPlaceholder = function (decorated, placeholder) {
2093 this.$search.attr('placeholder', placeholder.text);
2094 };
2095
2096 Search.prototype.update = function (decorated, data) {
2097 var searchHadFocus = this.$search[0] == document.activeElement;
2098
2099 this.$search.attr('placeholder', '');
2100
2101 decorated.call(this, data);
2102
2103 this.$selection.find('.select2-selection__rendered')
2104 .append(this.$searchContainer);
2105
2106 this.resizeSearch();
2107 if (searchHadFocus) {
2108 var isTagInput = this.$element.find('[data-select2-tag]').length;
2109 if (isTagInput) {
2110 // fix IE11 bug where tag input lost focus
2111 this.$element.trigger('focus');
2112 } else {
2113 this.$search.trigger('focus');
2114 }
2115 }
2116 };
2117
2118 Search.prototype.handleSearch = function () {
2119 this.resizeSearch();
2120
2121 if (!this._keyUpPrevented) {
2122 var input = this.$search.val();
2123
2124 this.trigger('query', {
2125 term: input
2126 });
2127 }
2128
2129 this._keyUpPrevented = false;
2130 };
2131
2132 Search.prototype.searchRemoveChoice = function (decorated, item) {
2133 this.trigger('unselect', {
2134 data: item
2135 });
2136
2137 this.$search.val(item.text);
2138 this.handleSearch();
2139 };
2140
2141 Search.prototype.resizeSearch = function () {
2142 this.$search.css('width', '25px');
2143
2144 var width = '';
2145
2146 if (this.$search.attr('placeholder') !== '') {
2147 width = this.$selection.find('.select2-selection__rendered').innerWidth();
2148 } else {
2149 var minimumWidth = this.$search.val().length + 1;
2150
2151 width = (minimumWidth * 0.75) + 'em';
2152 }
2153
2154 this.$search.css('width', width);
2155 };
2156
2157 return Search;
2158 });
2159
2160 S2.define('select2/selection/eventRelay',[
2161 'jquery'
2162 ], function ($) {
2163 function EventRelay () { }
2164
2165 EventRelay.prototype.bind = function (decorated, container, $container) {
2166 var self = this;
2167 var relayEvents = [
2168 'open', 'opening',
2169 'close', 'closing',
2170 'select', 'selecting',
2171 'unselect', 'unselecting',
2172 'clear', 'clearing'
2173 ];
2174
2175 var preventableEvents = [
2176 'opening', 'closing', 'selecting', 'unselecting', 'clearing'
2177 ];
2178
2179 decorated.call(this, container, $container);
2180
2181 container.on('*', function (name, params) {
2182 // Ignore events that should not be relayed
2183 if ($.inArray(name, relayEvents) === -1) {
2184 return;
2185 }
2186
2187 // The parameters should always be an object
2188 params = params || {};
2189
2190 // Generate the jQuery event for the Select2 event
2191 var evt = $.Event('select2:' + name, {
2192 params: params
2193 });
2194
2195 self.$element.trigger(evt);
2196
2197 // Only handle preventable events if it was one
2198 if ($.inArray(name, preventableEvents) === -1) {
2199 return;
2200 }
2201
2202 params.prevented = evt.isDefaultPrevented();
2203 });
2204 };
2205
2206 return EventRelay;
2207 });
2208
2209 S2.define('select2/translation',[
2210 'jquery',
2211 'require'
2212 ], function ($, require) {
2213 function Translation (dict) {
2214 this.dict = dict || {};
2215 }
2216
2217 Translation.prototype.all = function () {
2218 return this.dict;
2219 };
2220
2221 Translation.prototype.get = function (key) {
2222 return this.dict[key];
2223 };
2224
2225 Translation.prototype.extend = function (translation) {
2226 this.dict = $.extend({}, translation.all(), this.dict);
2227 };
2228
2229 // Static functions
2230
2231 Translation._cache = {};
2232
2233 Translation.loadPath = function (path) {
2234 if (!(path in Translation._cache)) {
2235 var translations = require(path);
2236
2237 Translation._cache[path] = translations;
2238 }
2239
2240 return new Translation(Translation._cache[path]);
2241 };
2242
2243 return Translation;
2244 });
2245
2246 S2.define('select2/diacritics',[
2247
2248 ], function () {
2249 var diacritics = {
2250 '\u24B6': 'A',
2251 '\uFF21': 'A',
2252 '\u00C0': 'A',
2253 '\u00C1': 'A',
2254 '\u00C2': 'A',
2255 '\u1EA6': 'A',
2256 '\u1EA4': 'A',
2257 '\u1EAA': 'A',
2258 '\u1EA8': 'A',
2259 '\u00C3': 'A',
2260 '\u0100': 'A',
2261 '\u0102': 'A',
2262 '\u1EB0': 'A',
2263 '\u1EAE': 'A',
2264 '\u1EB4': 'A',
2265 '\u1EB2': 'A',
2266 '\u0226': 'A',
2267 '\u01E0': 'A',
2268 '\u00C4': 'A',
2269 '\u01DE': 'A',
2270 '\u1EA2': 'A',
2271 '\u00C5': 'A',
2272 '\u01FA': 'A',
2273 '\u01CD': 'A',
2274 '\u0200': 'A',
2275 '\u0202': 'A',
2276 '\u1EA0': 'A',
2277 '\u1EAC': 'A',
2278 '\u1EB6': 'A',
2279 '\u1E00': 'A',
2280 '\u0104': 'A',
2281 '\u023A': 'A',
2282 '\u2C6F': 'A',
2283 '\uA732': 'AA',
2284 '\u00C6': 'AE',
2285 '\u01FC': 'AE',
2286 '\u01E2': 'AE',
2287 '\uA734': 'AO',
2288 '\uA736': 'AU',
2289 '\uA738': 'AV',
2290 '\uA73A': 'AV',
2291 '\uA73C': 'AY',
2292 '\u24B7': 'B',
2293 '\uFF22': 'B',
2294 '\u1E02': 'B',
2295 '\u1E04': 'B',
2296 '\u1E06': 'B',
2297 '\u0243': 'B',
2298 '\u0182': 'B',
2299 '\u0181': 'B',
2300 '\u24B8': 'C',
2301 '\uFF23': 'C',
2302 '\u0106': 'C',
2303 '\u0108': 'C',
2304 '\u010A': 'C',
2305 '\u010C': 'C',
2306 '\u00C7': 'C',
2307 '\u1E08': 'C',
2308 '\u0187': 'C',
2309 '\u023B': 'C',
2310 '\uA73E': 'C',
2311 '\u24B9': 'D',
2312 '\uFF24': 'D',
2313 '\u1E0A': 'D',
2314 '\u010E': 'D',
2315 '\u1E0C': 'D',
2316 '\u1E10': 'D',
2317 '\u1E12': 'D',
2318 '\u1E0E': 'D',
2319 '\u0110': 'D',
2320 '\u018B': 'D',
2321 '\u018A': 'D',
2322 '\u0189': 'D',
2323 '\uA779': 'D',
2324 '\u01F1': 'DZ',
2325 '\u01C4': 'DZ',
2326 '\u01F2': 'Dz',
2327 '\u01C5': 'Dz',
2328 '\u24BA': 'E',
2329 '\uFF25': 'E',
2330 '\u00C8': 'E',
2331 '\u00C9': 'E',
2332 '\u00CA': 'E',
2333 '\u1EC0': 'E',
2334 '\u1EBE': 'E',
2335 '\u1EC4': 'E',
2336 '\u1EC2': 'E',
2337 '\u1EBC': 'E',
2338 '\u0112': 'E',
2339 '\u1E14': 'E',
2340 '\u1E16': 'E',
2341 '\u0114': 'E',
2342 '\u0116': 'E',
2343 '\u00CB': 'E',
2344 '\u1EBA': 'E',
2345 '\u011A': 'E',
2346 '\u0204': 'E',
2347 '\u0206': 'E',
2348 '\u1EB8': 'E',
2349 '\u1EC6': 'E',
2350 '\u0228': 'E',
2351 '\u1E1C': 'E',
2352 '\u0118': 'E',
2353 '\u1E18': 'E',
2354 '\u1E1A': 'E',
2355 '\u0190': 'E',
2356 '\u018E': 'E',
2357 '\u24BB': 'F',
2358 '\uFF26': 'F',
2359 '\u1E1E': 'F',
2360 '\u0191': 'F',
2361 '\uA77B': 'F',
2362 '\u24BC': 'G',
2363 '\uFF27': 'G',
2364 '\u01F4': 'G',
2365 '\u011C': 'G',
2366 '\u1E20': 'G',
2367 '\u011E': 'G',
2368 '\u0120': 'G',
2369 '\u01E6': 'G',
2370 '\u0122': 'G',
2371 '\u01E4': 'G',
2372 '\u0193': 'G',
2373 '\uA7A0': 'G',
2374 '\uA77D': 'G',
2375 '\uA77E': 'G',
2376 '\u24BD': 'H',
2377 '\uFF28': 'H',
2378 '\u0124': 'H',
2379 '\u1E22': 'H',
2380 '\u1E26': 'H',
2381 '\u021E': 'H',
2382 '\u1E24': 'H',
2383 '\u1E28': 'H',
2384 '\u1E2A': 'H',
2385 '\u0126': 'H',
2386 '\u2C67': 'H',
2387 '\u2C75': 'H',
2388 '\uA78D': 'H',
2389 '\u24BE': 'I',
2390 '\uFF29': 'I',
2391 '\u00CC': 'I',
2392 '\u00CD': 'I',
2393 '\u00CE': 'I',
2394 '\u0128': 'I',
2395 '\u012A': 'I',
2396 '\u012C': 'I',
2397 '\u0130': 'I',
2398 '\u00CF': 'I',
2399 '\u1E2E': 'I',
2400 '\u1EC8': 'I',
2401 '\u01CF': 'I',
2402 '\u0208': 'I',
2403 '\u020A': 'I',
2404 '\u1ECA': 'I',
2405 '\u012E': 'I',
2406 '\u1E2C': 'I',
2407 '\u0197': 'I',
2408 '\u24BF': 'J',
2409 '\uFF2A': 'J',
2410 '\u0134': 'J',
2411 '\u0248': 'J',
2412 '\u24C0': 'K',
2413 '\uFF2B': 'K',
2414 '\u1E30': 'K',
2415 '\u01E8': 'K',
2416 '\u1E32': 'K',
2417 '\u0136': 'K',
2418 '\u1E34': 'K',
2419 '\u0198': 'K',
2420 '\u2C69': 'K',
2421 '\uA740': 'K',
2422 '\uA742': 'K',
2423 '\uA744': 'K',
2424 '\uA7A2': 'K',
2425 '\u24C1': 'L',
2426 '\uFF2C': 'L',
2427 '\u013F': 'L',
2428 '\u0139': 'L',
2429 '\u013D': 'L',
2430 '\u1E36': 'L',
2431 '\u1E38': 'L',
2432 '\u013B': 'L',
2433 '\u1E3C': 'L',
2434 '\u1E3A': 'L',
2435 '\u0141': 'L',
2436 '\u023D': 'L',
2437 '\u2C62': 'L',
2438 '\u2C60': 'L',
2439 '\uA748': 'L',
2440 '\uA746': 'L',
2441 '\uA780': 'L',
2442 '\u01C7': 'LJ',
2443 '\u01C8': 'Lj',
2444 '\u24C2': 'M',
2445 '\uFF2D': 'M',
2446 '\u1E3E': 'M',
2447 '\u1E40': 'M',
2448 '\u1E42': 'M',
2449 '\u2C6E': 'M',
2450 '\u019C': 'M',
2451 '\u24C3': 'N',
2452 '\uFF2E': 'N',
2453 '\u01F8': 'N',
2454 '\u0143': 'N',
2455 '\u00D1': 'N',
2456 '\u1E44': 'N',
2457 '\u0147': 'N',
2458 '\u1E46': 'N',
2459 '\u0145': 'N',
2460 '\u1E4A': 'N',
2461 '\u1E48': 'N',
2462 '\u0220': 'N',
2463 '\u019D': 'N',
2464 '\uA790': 'N',
2465 '\uA7A4': 'N',
2466 '\u01CA': 'NJ',
2467 '\u01CB': 'Nj',
2468 '\u24C4': 'O',
2469 '\uFF2F': 'O',
2470 '\u00D2': 'O',
2471 '\u00D3': 'O',
2472 '\u00D4': 'O',
2473 '\u1ED2': 'O',
2474 '\u1ED0': 'O',
2475 '\u1ED6': 'O',
2476 '\u1ED4': 'O',
2477 '\u00D5': 'O',
2478 '\u1E4C': 'O',
2479 '\u022C': 'O',
2480 '\u1E4E': 'O',
2481 '\u014C': 'O',
2482 '\u1E50': 'O',
2483 '\u1E52': 'O',
2484 '\u014E': 'O',
2485 '\u022E': 'O',
2486 '\u0230': 'O',
2487 '\u00D6': 'O',
2488 '\u022A': 'O',
2489 '\u1ECE': 'O',
2490 '\u0150': 'O',
2491 '\u01D1': 'O',
2492 '\u020C': 'O',
2493 '\u020E': 'O',
2494 '\u01A0': 'O',
2495 '\u1EDC': 'O',
2496 '\u1EDA': 'O',
2497 '\u1EE0': 'O',
2498 '\u1EDE': 'O',
2499 '\u1EE2': 'O',
2500 '\u1ECC': 'O',
2501 '\u1ED8': 'O',
2502 '\u01EA': 'O',
2503 '\u01EC': 'O',
2504 '\u00D8': 'O',
2505 '\u01FE': 'O',
2506 '\u0186': 'O',
2507 '\u019F': 'O',
2508 '\uA74A': 'O',
2509 '\uA74C': 'O',
2510 '\u01A2': 'OI',
2511 '\uA74E': 'OO',
2512 '\u0222': 'OU',
2513 '\u24C5': 'P',
2514 '\uFF30': 'P',
2515 '\u1E54': 'P',
2516 '\u1E56': 'P',
2517 '\u01A4': 'P',
2518 '\u2C63': 'P',
2519 '\uA750': 'P',
2520 '\uA752': 'P',
2521 '\uA754': 'P',
2522 '\u24C6': 'Q',
2523 '\uFF31': 'Q',
2524 '\uA756': 'Q',
2525 '\uA758': 'Q',
2526 '\u024A': 'Q',
2527 '\u24C7': 'R',
2528 '\uFF32': 'R',
2529 '\u0154': 'R',
2530 '\u1E58': 'R',
2531 '\u0158': 'R',
2532 '\u0210': 'R',
2533 '\u0212': 'R',
2534 '\u1E5A': 'R',
2535 '\u1E5C': 'R',
2536 '\u0156': 'R',
2537 '\u1E5E': 'R',
2538 '\u024C': 'R',
2539 '\u2C64': 'R',
2540 '\uA75A': 'R',
2541 '\uA7A6': 'R',
2542 '\uA782': 'R',
2543 '\u24C8': 'S',
2544 '\uFF33': 'S',
2545 '\u1E9E': 'S',
2546 '\u015A': 'S',
2547 '\u1E64': 'S',
2548 '\u015C': 'S',
2549 '\u1E60': 'S',
2550 '\u0160': 'S',
2551 '\u1E66': 'S',
2552 '\u1E62': 'S',
2553 '\u1E68': 'S',
2554 '\u0218': 'S',
2555 '\u015E': 'S',
2556 '\u2C7E': 'S',
2557 '\uA7A8': 'S',
2558 '\uA784': 'S',
2559 '\u24C9': 'T',
2560 '\uFF34': 'T',
2561 '\u1E6A': 'T',
2562 '\u0164': 'T',
2563 '\u1E6C': 'T',
2564 '\u021A': 'T',
2565 '\u0162': 'T',
2566 '\u1E70': 'T',
2567 '\u1E6E': 'T',
2568 '\u0166': 'T',
2569 '\u01AC': 'T',
2570 '\u01AE': 'T',
2571 '\u023E': 'T',
2572 '\uA786': 'T',
2573 '\uA728': 'TZ',
2574 '\u24CA': 'U',
2575 '\uFF35': 'U',
2576 '\u00D9': 'U',
2577 '\u00DA': 'U',
2578 '\u00DB': 'U',
2579 '\u0168': 'U',
2580 '\u1E78': 'U',
2581 '\u016A': 'U',
2582 '\u1E7A': 'U',
2583 '\u016C': 'U',
2584 '\u00DC': 'U',
2585 '\u01DB': 'U',
2586 '\u01D7': 'U',
2587 '\u01D5': 'U',
2588 '\u01D9': 'U',
2589 '\u1EE6': 'U',
2590 '\u016E': 'U',
2591 '\u0170': 'U',
2592 '\u01D3': 'U',
2593 '\u0214': 'U',
2594 '\u0216': 'U',
2595 '\u01AF': 'U',
2596 '\u1EEA': 'U',
2597 '\u1EE8': 'U',
2598 '\u1EEE': 'U',
2599 '\u1EEC': 'U',
2600 '\u1EF0': 'U',
2601 '\u1EE4': 'U',
2602 '\u1E72': 'U',
2603 '\u0172': 'U',
2604 '\u1E76': 'U',
2605 '\u1E74': 'U',
2606 '\u0244': 'U',
2607 '\u24CB': 'V',
2608 '\uFF36': 'V',
2609 '\u1E7C': 'V',
2610 '\u1E7E': 'V',
2611 '\u01B2': 'V',
2612 '\uA75E': 'V',
2613 '\u0245': 'V',
2614 '\uA760': 'VY',
2615 '\u24CC': 'W',
2616 '\uFF37': 'W',
2617 '\u1E80': 'W',
2618 '\u1E82': 'W',
2619 '\u0174': 'W',
2620 '\u1E86': 'W',
2621 '\u1E84': 'W',
2622 '\u1E88': 'W',
2623 '\u2C72': 'W',
2624 '\u24CD': 'X',
2625 '\uFF38': 'X',
2626 '\u1E8A': 'X',
2627 '\u1E8C': 'X',
2628 '\u24CE': 'Y',
2629 '\uFF39': 'Y',
2630 '\u1EF2': 'Y',
2631 '\u00DD': 'Y',
2632 '\u0176': 'Y',
2633 '\u1EF8': 'Y',
2634 '\u0232': 'Y',
2635 '\u1E8E': 'Y',
2636 '\u0178': 'Y',
2637 '\u1EF6': 'Y',
2638 '\u1EF4': 'Y',
2639 '\u01B3': 'Y',
2640 '\u024E': 'Y',
2641 '\u1EFE': 'Y',
2642 '\u24CF': 'Z',
2643 '\uFF3A': 'Z',
2644 '\u0179': 'Z',
2645 '\u1E90': 'Z',
2646 '\u017B': 'Z',
2647 '\u017D': 'Z',
2648 '\u1E92': 'Z',
2649 '\u1E94': 'Z',
2650 '\u01B5': 'Z',
2651 '\u0224': 'Z',
2652 '\u2C7F': 'Z',
2653 '\u2C6B': 'Z',
2654 '\uA762': 'Z',
2655 '\u24D0': 'a',
2656 '\uFF41': 'a',
2657 '\u1E9A': 'a',
2658 '\u00E0': 'a',
2659 '\u00E1': 'a',
2660 '\u00E2': 'a',
2661 '\u1EA7': 'a',
2662 '\u1EA5': 'a',
2663 '\u1EAB': 'a',
2664 '\u1EA9': 'a',
2665 '\u00E3': 'a',
2666 '\u0101': 'a',
2667 '\u0103': 'a',
2668 '\u1EB1': 'a',
2669 '\u1EAF': 'a',
2670 '\u1EB5': 'a',
2671 '\u1EB3': 'a',
2672 '\u0227': 'a',
2673 '\u01E1': 'a',
2674 '\u00E4': 'a',
2675 '\u01DF': 'a',
2676 '\u1EA3': 'a',
2677 '\u00E5': 'a',
2678 '\u01FB': 'a',
2679 '\u01CE': 'a',
2680 '\u0201': 'a',
2681 '\u0203': 'a',
2682 '\u1EA1': 'a',
2683 '\u1EAD': 'a',
2684 '\u1EB7': 'a',
2685 '\u1E01': 'a',
2686 '\u0105': 'a',
2687 '\u2C65': 'a',
2688 '\u0250': 'a',
2689 '\uA733': 'aa',
2690 '\u00E6': 'ae',
2691 '\u01FD': 'ae',
2692 '\u01E3': 'ae',
2693 '\uA735': 'ao',
2694 '\uA737': 'au',
2695 '\uA739': 'av',
2696 '\uA73B': 'av',
2697 '\uA73D': 'ay',
2698 '\u24D1': 'b',
2699 '\uFF42': 'b',
2700 '\u1E03': 'b',
2701 '\u1E05': 'b',
2702 '\u1E07': 'b',
2703 '\u0180': 'b',
2704 '\u0183': 'b',
2705 '\u0253': 'b',
2706 '\u24D2': 'c',
2707 '\uFF43': 'c',
2708 '\u0107': 'c',
2709 '\u0109': 'c',
2710 '\u010B': 'c',
2711 '\u010D': 'c',
2712 '\u00E7': 'c',
2713 '\u1E09': 'c',
2714 '\u0188': 'c',
2715 '\u023C': 'c',
2716 '\uA73F': 'c',
2717 '\u2184': 'c',
2718 '\u24D3': 'd',
2719 '\uFF44': 'd',
2720 '\u1E0B': 'd',
2721 '\u010F': 'd',
2722 '\u1E0D': 'd',
2723 '\u1E11': 'd',
2724 '\u1E13': 'd',
2725 '\u1E0F': 'd',
2726 '\u0111': 'd',
2727 '\u018C': 'd',
2728 '\u0256': 'd',
2729 '\u0257': 'd',
2730 '\uA77A': 'd',
2731 '\u01F3': 'dz',
2732 '\u01C6': 'dz',
2733 '\u24D4': 'e',
2734 '\uFF45': 'e',
2735 '\u00E8': 'e',
2736 '\u00E9': 'e',
2737 '\u00EA': 'e',
2738 '\u1EC1': 'e',
2739 '\u1EBF': 'e',
2740 '\u1EC5': 'e',
2741 '\u1EC3': 'e',
2742 '\u1EBD': 'e',
2743 '\u0113': 'e',
2744 '\u1E15': 'e',
2745 '\u1E17': 'e',
2746 '\u0115': 'e',
2747 '\u0117': 'e',
2748 '\u00EB': 'e',
2749 '\u1EBB': 'e',
2750 '\u011B': 'e',
2751 '\u0205': 'e',
2752 '\u0207': 'e',
2753 '\u1EB9': 'e',
2754 '\u1EC7': 'e',
2755 '\u0229': 'e',
2756 '\u1E1D': 'e',
2757 '\u0119': 'e',
2758 '\u1E19': 'e',
2759 '\u1E1B': 'e',
2760 '\u0247': 'e',
2761 '\u025B': 'e',
2762 '\u01DD': 'e',
2763 '\u24D5': 'f',
2764 '\uFF46': 'f',
2765 '\u1E1F': 'f',
2766 '\u0192': 'f',
2767 '\uA77C': 'f',
2768 '\u24D6': 'g',
2769 '\uFF47': 'g',
2770 '\u01F5': 'g',
2771 '\u011D': 'g',
2772 '\u1E21': 'g',
2773 '\u011F': 'g',
2774 '\u0121': 'g',
2775 '\u01E7': 'g',
2776 '\u0123': 'g',
2777 '\u01E5': 'g',
2778 '\u0260': 'g',
2779 '\uA7A1': 'g',
2780 '\u1D79': 'g',
2781 '\uA77F': 'g',
2782 '\u24D7': 'h',
2783 '\uFF48': 'h',
2784 '\u0125': 'h',
2785 '\u1E23': 'h',
2786 '\u1E27': 'h',
2787 '\u021F': 'h',
2788 '\u1E25': 'h',
2789 '\u1E29': 'h',
2790 '\u1E2B': 'h',
2791 '\u1E96': 'h',
2792 '\u0127': 'h',
2793 '\u2C68': 'h',
2794 '\u2C76': 'h',
2795 '\u0265': 'h',
2796 '\u0195': 'hv',
2797 '\u24D8': 'i',
2798 '\uFF49': 'i',
2799 '\u00EC': 'i',
2800 '\u00ED': 'i',
2801 '\u00EE': 'i',
2802 '\u0129': 'i',
2803 '\u012B': 'i',
2804 '\u012D': 'i',
2805 '\u00EF': 'i',
2806 '\u1E2F': 'i',
2807 '\u1EC9': 'i',
2808 '\u01D0': 'i',
2809 '\u0209': 'i',
2810 '\u020B': 'i',
2811 '\u1ECB': 'i',
2812 '\u012F': 'i',
2813 '\u1E2D': 'i',
2814 '\u0268': 'i',
2815 '\u0131': 'i',
2816 '\u24D9': 'j',
2817 '\uFF4A': 'j',
2818 '\u0135': 'j',
2819 '\u01F0': 'j',
2820 '\u0249': 'j',
2821 '\u24DA': 'k',
2822 '\uFF4B': 'k',
2823 '\u1E31': 'k',
2824 '\u01E9': 'k',
2825 '\u1E33': 'k',
2826 '\u0137': 'k',
2827 '\u1E35': 'k',
2828 '\u0199': 'k',
2829 '\u2C6A': 'k',
2830 '\uA741': 'k',
2831 '\uA743': 'k',
2832 '\uA745': 'k',
2833 '\uA7A3': 'k',
2834 '\u24DB': 'l',
2835 '\uFF4C': 'l',
2836 '\u0140': 'l',
2837 '\u013A': 'l',
2838 '\u013E': 'l',
2839 '\u1E37': 'l',
2840 '\u1E39': 'l',
2841 '\u013C': 'l',
2842 '\u1E3D': 'l',
2843 '\u1E3B': 'l',
2844 '\u017F': 'l',
2845 '\u0142': 'l',
2846 '\u019A': 'l',
2847 '\u026B': 'l',
2848 '\u2C61': 'l',
2849 '\uA749': 'l',
2850 '\uA781': 'l',
2851 '\uA747': 'l',
2852 '\u01C9': 'lj',
2853 '\u24DC': 'm',
2854 '\uFF4D': 'm',
2855 '\u1E3F': 'm',
2856 '\u1E41': 'm',
2857 '\u1E43': 'm',
2858 '\u0271': 'm',
2859 '\u026F': 'm',
2860 '\u24DD': 'n',
2861 '\uFF4E': 'n',
2862 '\u01F9': 'n',
2863 '\u0144': 'n',
2864 '\u00F1': 'n',
2865 '\u1E45': 'n',
2866 '\u0148': 'n',
2867 '\u1E47': 'n',
2868 '\u0146': 'n',
2869 '\u1E4B': 'n',
2870 '\u1E49': 'n',
2871 '\u019E': 'n',
2872 '\u0272': 'n',
2873 '\u0149': 'n',
2874 '\uA791': 'n',
2875 '\uA7A5': 'n',
2876 '\u01CC': 'nj',
2877 '\u24DE': 'o',
2878 '\uFF4F': 'o',
2879 '\u00F2': 'o',
2880 '\u00F3': 'o',
2881 '\u00F4': 'o',
2882 '\u1ED3': 'o',
2883 '\u1ED1': 'o',
2884 '\u1ED7': 'o',
2885 '\u1ED5': 'o',
2886 '\u00F5': 'o',
2887 '\u1E4D': 'o',
2888 '\u022D': 'o',
2889 '\u1E4F': 'o',
2890 '\u014D': 'o',
2891 '\u1E51': 'o',
2892 '\u1E53': 'o',
2893 '\u014F': 'o',
2894 '\u022F': 'o',
2895 '\u0231': 'o',
2896 '\u00F6': 'o',
2897 '\u022B': 'o',
2898 '\u1ECF': 'o',
2899 '\u0151': 'o',
2900 '\u01D2': 'o',
2901 '\u020D': 'o',
2902 '\u020F': 'o',
2903 '\u01A1': 'o',
2904 '\u1EDD': 'o',
2905 '\u1EDB': 'o',
2906 '\u1EE1': 'o',
2907 '\u1EDF': 'o',
2908 '\u1EE3': 'o',
2909 '\u1ECD': 'o',
2910 '\u1ED9': 'o',
2911 '\u01EB': 'o',
2912 '\u01ED': 'o',
2913 '\u00F8': 'o',
2914 '\u01FF': 'o',
2915 '\u0254': 'o',
2916 '\uA74B': 'o',
2917 '\uA74D': 'o',
2918 '\u0275': 'o',
2919 '\u01A3': 'oi',
2920 '\u0223': 'ou',
2921 '\uA74F': 'oo',
2922 '\u24DF': 'p',
2923 '\uFF50': 'p',
2924 '\u1E55': 'p',
2925 '\u1E57': 'p',
2926 '\u01A5': 'p',
2927 '\u1D7D': 'p',
2928 '\uA751': 'p',
2929 '\uA753': 'p',
2930 '\uA755': 'p',
2931 '\u24E0': 'q',
2932 '\uFF51': 'q',
2933 '\u024B': 'q',
2934 '\uA757': 'q',
2935 '\uA759': 'q',
2936 '\u24E1': 'r',
2937 '\uFF52': 'r',
2938 '\u0155': 'r',
2939 '\u1E59': 'r',
2940 '\u0159': 'r',
2941 '\u0211': 'r',
2942 '\u0213': 'r',
2943 '\u1E5B': 'r',
2944 '\u1E5D': 'r',
2945 '\u0157': 'r',
2946 '\u1E5F': 'r',
2947 '\u024D': 'r',
2948 '\u027D': 'r',
2949 '\uA75B': 'r',
2950 '\uA7A7': 'r',
2951 '\uA783': 'r',
2952 '\u24E2': 's',
2953 '\uFF53': 's',
2954 '\u00DF': 's',
2955 '\u015B': 's',
2956 '\u1E65': 's',
2957 '\u015D': 's',
2958 '\u1E61': 's',
2959 '\u0161': 's',
2960 '\u1E67': 's',
2961 '\u1E63': 's',
2962 '\u1E69': 's',
2963 '\u0219': 's',
2964 '\u015F': 's',
2965 '\u023F': 's',
2966 '\uA7A9': 's',
2967 '\uA785': 's',
2968 '\u1E9B': 's',
2969 '\u24E3': 't',
2970 '\uFF54': 't',
2971 '\u1E6B': 't',
2972 '\u1E97': 't',
2973 '\u0165': 't',
2974 '\u1E6D': 't',
2975 '\u021B': 't',
2976 '\u0163': 't',
2977 '\u1E71': 't',
2978 '\u1E6F': 't',
2979 '\u0167': 't',
2980 '\u01AD': 't',
2981 '\u0288': 't',
2982 '\u2C66': 't',
2983 '\uA787': 't',
2984 '\uA729': 'tz',
2985 '\u24E4': 'u',
2986 '\uFF55': 'u',
2987 '\u00F9': 'u',
2988 '\u00FA': 'u',
2989 '\u00FB': 'u',
2990 '\u0169': 'u',
2991 '\u1E79': 'u',
2992 '\u016B': 'u',
2993 '\u1E7B': 'u',
2994 '\u016D': 'u',
2995 '\u00FC': 'u',
2996 '\u01DC': 'u',
2997 '\u01D8': 'u',
2998 '\u01D6': 'u',
2999 '\u01DA': 'u',
3000 '\u1EE7': 'u',
3001 '\u016F': 'u',
3002 '\u0171': 'u',
3003 '\u01D4': 'u',
3004 '\u0215': 'u',
3005 '\u0217': 'u',
3006 '\u01B0': 'u',
3007 '\u1EEB': 'u',
3008 '\u1EE9': 'u',
3009 '\u1EEF': 'u',
3010 '\u1EED': 'u',
3011 '\u1EF1': 'u',
3012 '\u1EE5': 'u',
3013 '\u1E73': 'u',
3014 '\u0173': 'u',
3015 '\u1E77': 'u',
3016 '\u1E75': 'u',
3017 '\u0289': 'u',
3018 '\u24E5': 'v',
3019 '\uFF56': 'v',
3020 '\u1E7D': 'v',
3021 '\u1E7F': 'v',
3022 '\u028B': 'v',
3023 '\uA75F': 'v',
3024 '\u028C': 'v',
3025 '\uA761': 'vy',
3026 '\u24E6': 'w',
3027 '\uFF57': 'w',
3028 '\u1E81': 'w',
3029 '\u1E83': 'w',
3030 '\u0175': 'w',
3031 '\u1E87': 'w',
3032 '\u1E85': 'w',
3033 '\u1E98': 'w',
3034 '\u1E89': 'w',
3035 '\u2C73': 'w',
3036 '\u24E7': 'x',
3037 '\uFF58': 'x',
3038 '\u1E8B': 'x',
3039 '\u1E8D': 'x',
3040 '\u24E8': 'y',
3041 '\uFF59': 'y',
3042 '\u1EF3': 'y',
3043 '\u00FD': 'y',
3044 '\u0177': 'y',
3045 '\u1EF9': 'y',
3046 '\u0233': 'y',
3047 '\u1E8F': 'y',
3048 '\u00FF': 'y',
3049 '\u1EF7': 'y',
3050 '\u1E99': 'y',
3051 '\u1EF5': 'y',
3052 '\u01B4': 'y',
3053 '\u024F': 'y',
3054 '\u1EFF': 'y',
3055 '\u24E9': 'z',
3056 '\uFF5A': 'z',
3057 '\u017A': 'z',
3058 '\u1E91': 'z',
3059 '\u017C': 'z',
3060 '\u017E': 'z',
3061 '\u1E93': 'z',
3062 '\u1E95': 'z',
3063 '\u01B6': 'z',
3064 '\u0225': 'z',
3065 '\u0240': 'z',
3066 '\u2C6C': 'z',
3067 '\uA763': 'z',
3068 '\u0386': '\u0391',
3069 '\u0388': '\u0395',
3070 '\u0389': '\u0397',
3071 '\u038A': '\u0399',
3072 '\u03AA': '\u0399',
3073 '\u038C': '\u039F',
3074 '\u038E': '\u03A5',
3075 '\u03AB': '\u03A5',
3076 '\u038F': '\u03A9',
3077 '\u03AC': '\u03B1',
3078 '\u03AD': '\u03B5',
3079 '\u03AE': '\u03B7',
3080 '\u03AF': '\u03B9',
3081 '\u03CA': '\u03B9',
3082 '\u0390': '\u03B9',
3083 '\u03CC': '\u03BF',
3084 '\u03CD': '\u03C5',
3085 '\u03CB': '\u03C5',
3086 '\u03B0': '\u03C5',
3087 '\u03C9': '\u03C9',
3088 '\u03C2': '\u03C3'
3089 };
3090
3091 return diacritics;
3092 });
3093
3094 S2.define('select2/data/base',[
3095 '../utils'
3096 ], function (Utils) {
3097 function BaseAdapter ($element, options) {
3098 BaseAdapter.__super__.constructor.call(this);
3099 }
3100
3101 Utils.Extend(BaseAdapter, Utils.Observable);
3102
3103 BaseAdapter.prototype.current = function (callback) {
3104 throw new Error('The `current` method must be defined in child classes.');
3105 };
3106
3107 BaseAdapter.prototype.query = function (params, callback) {
3108 throw new Error('The `query` method must be defined in child classes.');
3109 };
3110
3111 BaseAdapter.prototype.bind = function (container, $container) {
3112 // Can be implemented in subclasses
3113 };
3114
3115 BaseAdapter.prototype.destroy = function () {
3116 // Can be implemented in subclasses
3117 };
3118
3119 BaseAdapter.prototype.generateResultId = function (container, data) {
3120 var id = container.id + '-result-';
3121
3122 id += Utils.generateChars(4);
3123
3124 if (data.id != null) {
3125 id += '-' + data.id.toString();
3126 } else {
3127 id += '-' + Utils.generateChars(4);
3128 }
3129 return id;
3130 };
3131
3132 return BaseAdapter;
3133 });
3134
3135 S2.define('select2/data/select',[
3136 './base',
3137 '../utils',
3138 'jquery'
3139 ], function (BaseAdapter, Utils, $) {
3140 function SelectAdapter ($element, options) {
3141 this.$element = $element;
3142 this.options = options;
3143
3144 SelectAdapter.__super__.constructor.call(this);
3145 }
3146
3147 Utils.Extend(SelectAdapter, BaseAdapter);
3148
3149 SelectAdapter.prototype.current = function (callback) {
3150 var data = [];
3151 var self = this;
3152
3153 this.$element.find(':selected').each(function () {
3154 var $option = $(this);
3155
3156 var option = self.item($option);
3157
3158 data.push(option);
3159 });
3160
3161 callback(data);
3162 };
3163
3164 SelectAdapter.prototype.select = function (data) {
3165 var self = this;
3166
3167 data.selected = true;
3168
3169 // If data.element is a DOM node, use it instead
3170 if ($(data.element).is('option')) {
3171 data.element.selected = true;
3172
3173 this.$element.trigger('change');
3174
3175 return;
3176 }
3177
3178 if (this.$element.prop('multiple')) {
3179 this.current(function (currentData) {
3180 var val = [];
3181
3182 data = [data];
3183 data.push.apply(data, currentData);
3184
3185 for (var d = 0; d < data.length; d++) {
3186 var id = data[d].id;
3187
3188 if ($.inArray(id, val) === -1) {
3189 val.push(id);
3190 }
3191 }
3192
3193 self.$element.val(val);
3194 self.$element.trigger('change');
3195 });
3196 } else {
3197 var val = data.id;
3198
3199 this.$element.val(val);
3200 this.$element.trigger('change');
3201 }
3202 };
3203
3204 SelectAdapter.prototype.unselect = function (data) {
3205 var self = this;
3206
3207 if (!this.$element.prop('multiple')) {
3208 return;
3209 }
3210
3211 data.selected = false;
3212
3213 if ($(data.element).is('option')) {
3214 data.element.selected = false;
3215
3216 this.$element.trigger('change');
3217
3218 return;
3219 }
3220
3221 this.current(function (currentData) {
3222 var val = [];
3223
3224 for (var d = 0; d < currentData.length; d++) {
3225 var id = currentData[d].id;
3226
3227 if (id !== data.id && $.inArray(id, val) === -1) {
3228 val.push(id);
3229 }
3230 }
3231
3232 self.$element.val(val);
3233
3234 self.$element.trigger('change');
3235 });
3236 };
3237
3238 SelectAdapter.prototype.bind = function (container, $container) {
3239 var self = this;
3240
3241 this.container = container;
3242
3243 container.on('select', function (params) {
3244 self.select(params.data);
3245 });
3246
3247 container.on('unselect', function (params) {
3248 self.unselect(params.data);
3249 });
3250 };
3251
3252 SelectAdapter.prototype.destroy = function () {
3253 // Remove anything added to child elements
3254 this.$element.find('*').each(function () {
3255 // Remove any custom data set by Select2
3256 Utils.RemoveData(this);
3257 });
3258 };
3259
3260 SelectAdapter.prototype.query = function (params, callback) {
3261 var data = [];
3262 var self = this;
3263
3264 var $options = this.$element.children();
3265
3266 $options.each(function () {
3267 var $option = $(this);
3268
3269 if (!$option.is('option') && !$option.is('optgroup')) {
3270 return;
3271 }
3272
3273 var option = self.item($option);
3274
3275 var matches = self.matches(params, option);
3276
3277 if (matches !== null) {
3278 data.push(matches);
3279 }
3280 });
3281
3282 callback({
3283 results: data
3284 });
3285 };
3286
3287 SelectAdapter.prototype.addOptions = function ($options) {
3288 Utils.appendMany(this.$element, $options);
3289 };
3290
3291 SelectAdapter.prototype.option = function (data) {
3292 var option;
3293
3294 if (data.children) {
3295 option = document.createElement('optgroup');
3296 option.label = data.text;
3297 } else {
3298 option = document.createElement('option');
3299
3300 if (option.textContent !== undefined) {
3301 option.textContent = data.text;
3302 } else {
3303 option.innerText = data.text;
3304 }
3305 }
3306
3307 if (data.id !== undefined) {
3308 option.value = data.id;
3309 }
3310
3311 if (data.disabled) {
3312 option.disabled = true;
3313 }
3314
3315 if (data.selected) {
3316 option.selected = true;
3317 }
3318
3319 if (data.title) {
3320 option.title = data.title;
3321 }
3322
3323 var $option = $(option);
3324
3325 var normalizedData = this._normalizeItem(data);
3326 normalizedData.element = option;
3327
3328 // Override the option's data with the combined data
3329 Utils.StoreData(option, 'data', normalizedData);
3330
3331 return $option;
3332 };
3333
3334 SelectAdapter.prototype.item = function ($option) {
3335 var data = {};
3336
3337 data = Utils.GetData($option[0], 'data');
3338
3339 if (data != null) {
3340 return data;
3341 }
3342
3343 if ($option.is('option')) {
3344 data = {
3345 id: $option.val(),
3346 text: $option.text(),
3347 disabled: $option.prop('disabled'),
3348 selected: $option.prop('selected'),
3349 title: $option.prop('title')
3350 };
3351 } else if ($option.is('optgroup')) {
3352 data = {
3353 text: $option.prop('label'),
3354 children: [],
3355 title: $option.prop('title')
3356 };
3357
3358 var $children = $option.children('option');
3359 var children = [];
3360
3361 for (var c = 0; c < $children.length; c++) {
3362 var $child = $($children[c]);
3363
3364 var child = this.item($child);
3365
3366 children.push(child);
3367 }
3368
3369 data.children = children;
3370 }
3371
3372 data = this._normalizeItem(data);
3373 data.element = $option[0];
3374
3375 Utils.StoreData($option[0], 'data', data);
3376
3377 return data;
3378 };
3379
3380 SelectAdapter.prototype._normalizeItem = function (item) {
3381 if (item !== Object(item)) {
3382 item = {
3383 id: item,
3384 text: item
3385 };
3386 }
3387
3388 item = $.extend({}, {
3389 text: ''
3390 }, item);
3391
3392 var defaults = {
3393 selected: false,
3394 disabled: false
3395 };
3396
3397 if (item.id != null) {
3398 item.id = item.id.toString();
3399 }
3400
3401 if (item.text != null) {
3402 item.text = item.text.toString();
3403 }
3404
3405 if (item._resultId == null && item.id && this.container != null) {
3406 item._resultId = this.generateResultId(this.container, item);
3407 }
3408
3409 return $.extend({}, defaults, item);
3410 };
3411
3412 SelectAdapter.prototype.matches = function (params, data) {
3413 var matcher = this.options.get('matcher');
3414
3415 return matcher(params, data);
3416 };
3417
3418 return SelectAdapter;
3419 });
3420
3421 S2.define('select2/data/array',[
3422 './select',
3423 '../utils',
3424 'jquery'
3425 ], function (SelectAdapter, Utils, $) {
3426 function ArrayAdapter ($element, options) {
3427 var data = options.get('data') || [];
3428
3429 ArrayAdapter.__super__.constructor.call(this, $element, options);
3430
3431 this.addOptions(this.convertToOptions(data));
3432 }
3433
3434 Utils.Extend(ArrayAdapter, SelectAdapter);
3435
3436 ArrayAdapter.prototype.select = function (data) {
3437 var $option = this.$element.find('option').filter(function (i, elm) {
3438 return elm.value == data.id.toString();
3439 });
3440
3441 if ($option.length === 0) {
3442 $option = this.option(data);
3443
3444 this.addOptions($option);
3445 }
3446
3447 ArrayAdapter.__super__.select.call(this, data);
3448 };
3449
3450 ArrayAdapter.prototype.convertToOptions = function (data) {
3451 var self = this;
3452
3453 var $existing = this.$element.find('option');
3454 var existingIds = $existing.map(function () {
3455 return self.item($(this)).id;
3456 }).get();
3457
3458 var $options = [];
3459
3460 // Filter out all items except for the one passed in the argument
3461 function onlyItem (item) {
3462 return function () {
3463 return $(this).val() == item.id;
3464 };
3465 }
3466
3467 for (var d = 0; d < data.length; d++) {
3468 var item = this._normalizeItem(data[d]);
3469
3470 // Skip items which were pre-loaded, only merge the data
3471 if ($.inArray(item.id, existingIds) >= 0) {
3472 var $existingOption = $existing.filter(onlyItem(item));
3473
3474 var existingData = this.item($existingOption);
3475 var newData = $.extend(true, {}, item, existingData);
3476
3477 var $newOption = this.option(newData);
3478
3479 $existingOption.replaceWith($newOption);
3480
3481 continue;
3482 }
3483
3484 var $option = this.option(item);
3485
3486 if (item.children) {
3487 var $children = this.convertToOptions(item.children);
3488
3489 Utils.appendMany($option, $children);
3490 }
3491
3492 $options.push($option);
3493 }
3494
3495 return $options;
3496 };
3497
3498 return ArrayAdapter;
3499 });
3500
3501 S2.define('select2/data/ajax',[
3502 './array',
3503 '../utils',
3504 'jquery'
3505 ], function (ArrayAdapter, Utils, $) {
3506 function AjaxAdapter ($element, options) {
3507 this.ajaxOptions = this._applyDefaults(options.get('ajax'));
3508
3509 if (this.ajaxOptions.processResults != null) {
3510 this.processResults = this.ajaxOptions.processResults;
3511 }
3512
3513 AjaxAdapter.__super__.constructor.call(this, $element, options);
3514 }
3515
3516 Utils.Extend(AjaxAdapter, ArrayAdapter);
3517
3518 AjaxAdapter.prototype._applyDefaults = function (options) {
3519 var defaults = {
3520 data: function (params) {
3521 return $.extend({}, params, {
3522 q: params.term
3523 });
3524 },
3525 transport: function (params, success, failure) {
3526 var $request = $.ajax(params);
3527
3528 $request.then(success);
3529 $request.fail(failure);
3530
3531 return $request;
3532 }
3533 };
3534
3535 return $.extend({}, defaults, options, true);
3536 };
3537
3538 AjaxAdapter.prototype.processResults = function (results) {
3539 return results;
3540 };
3541
3542 AjaxAdapter.prototype.query = function (params, callback) {
3543 var matches = [];
3544 var self = this;
3545
3546 if (this._request != null) {
3547 // JSONP requests cannot always be aborted
3548 if (typeof this._request.abort === 'function') {
3549 this._request.abort();
3550 }
3551
3552 this._request = null;
3553 }
3554
3555 var options = $.extend({
3556 type: 'GET'
3557 }, this.ajaxOptions);
3558
3559 if (typeof options.url === 'function') {
3560 options.url = options.url.call(this.$element, params);
3561 }
3562
3563 if (typeof options.data === 'function') {
3564 options.data = options.data.call(this.$element, params);
3565 }
3566
3567 function request () {
3568 var $request = options.transport(options, function (data) {
3569 var results = self.processResults(data, params);
3570
3571 if (self.options.get('debug') && window.console && console.error) {
3572 // Check to make sure that the response included a `results` key.
3573 if (!results || !results.results || !Array.isArray(results.results)) {
3574 console.error(
3575 'Select2: The AJAX results did not return an array in the ' +
3576 '`results` key of the response.'
3577 );
3578 }
3579 }
3580
3581 callback(results);
3582 }, function () {
3583 // Attempt to detect if a request was aborted
3584 // Only works if the transport exposes a status property
3585 if ('status' in $request &&
3586 ($request.status === 0 || $request.status === '0')) {
3587 return;
3588 }
3589
3590 self.trigger('results:message', {
3591 message: 'errorLoading'
3592 });
3593 });
3594
3595 self._request = $request;
3596 }
3597
3598 if (this.ajaxOptions.delay && params.term != null) {
3599 if (this._queryTimeout) {
3600 window.clearTimeout(this._queryTimeout);
3601 }
3602
3603 this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
3604 } else {
3605 request();
3606 }
3607 };
3608
3609 return AjaxAdapter;
3610 });
3611
3612 S2.define('select2/data/tags',[
3613 'jquery'
3614 ], function ($) {
3615 function Tags (decorated, $element, options) {
3616 var tags = options.get('tags');
3617
3618 var createTag = options.get('createTag');
3619
3620 if (createTag !== undefined) {
3621 this.createTag = createTag;
3622 }
3623
3624 var insertTag = options.get('insertTag');
3625
3626 if (insertTag !== undefined) {
3627 this.insertTag = insertTag;
3628 }
3629
3630 decorated.call(this, $element, options);
3631
3632 if (Array.isArray(tags)) {
3633 for (var t = 0; t < tags.length; t++) {
3634 var tag = tags[t];
3635 var item = this._normalizeItem(tag);
3636
3637 var $option = this.option(item);
3638
3639 this.$element.append($option);
3640 }
3641 }
3642 }
3643
3644 Tags.prototype.query = function (decorated, params, callback) {
3645 var self = this;
3646
3647 this._removeOldTags();
3648
3649 if (params.term == null || params.page != null) {
3650 decorated.call(this, params, callback);
3651 return;
3652 }
3653
3654 function wrapper (obj, child) {
3655 var data = obj.results;
3656
3657 for (var i = 0; i < data.length; i++) {
3658 var option = data[i];
3659
3660 var checkChildren = (
3661 option.children != null &&
3662 !wrapper({
3663 results: option.children
3664 }, true)
3665 );
3666
3667 var optionText = (option.text || '').toUpperCase();
3668 var paramsTerm = (params.term || '').toUpperCase();
3669
3670 var checkText = optionText === paramsTerm;
3671
3672 if (checkText || checkChildren) {
3673 if (child) {
3674 return false;
3675 }
3676
3677 obj.data = data;
3678 callback(obj);
3679
3680 return;
3681 }
3682 }
3683
3684 if (child) {
3685 return true;
3686 }
3687
3688 var tag = self.createTag(params);
3689
3690 if (tag != null) {
3691 var $option = self.option(tag);
3692 $option.attr('data-select2-tag', true);
3693
3694 self.addOptions([$option]);
3695
3696 self.insertTag(data, tag);
3697 }
3698
3699 obj.results = data;
3700
3701 callback(obj);
3702 }
3703
3704 decorated.call(this, params, wrapper);
3705 };
3706
3707 Tags.prototype.createTag = function (decorated, params) {
3708 var term = (params?.term ?? '').trim();
3709
3710 if (term === '') {
3711 return null;
3712 }
3713
3714 return {
3715 id: term,
3716 text: term
3717 };
3718 };
3719
3720 Tags.prototype.insertTag = function (_, data, tag) {
3721 data.unshift(tag);
3722 };
3723
3724 Tags.prototype._removeOldTags = function (_) {
3725 var tag = this._lastTag;
3726
3727 var $options = this.$element.find('option[data-select2-tag]');
3728
3729 $options.each(function () {
3730 if (this.selected) {
3731 return;
3732 }
3733
3734 $(this).remove();
3735 });
3736 };
3737
3738 return Tags;
3739 });
3740
3741 S2.define('select2/data/tokenizer',[
3742 'jquery'
3743 ], function ($) {
3744 function Tokenizer (decorated, $element, options) {
3745 var tokenizer = options.get('tokenizer');
3746
3747 if (tokenizer !== undefined) {
3748 this.tokenizer = tokenizer;
3749 }
3750
3751 decorated.call(this, $element, options);
3752 }
3753
3754 Tokenizer.prototype.bind = function (decorated, container, $container) {
3755 decorated.call(this, container, $container);
3756
3757 this.$search = container.dropdown.$search || container.selection.$search ||
3758 $container.find('.select2-search__field');
3759 };
3760
3761 Tokenizer.prototype.query = function (decorated, params, callback) {
3762 var self = this;
3763
3764 function createAndSelect (data) {
3765 // Normalize the data object so we can use it for checks
3766 var item = self._normalizeItem(data);
3767
3768 // Check if the data object already exists as a tag
3769 // Select it if it doesn't
3770 var $existingOptions = self.$element.find('option').filter(function () {
3771 return $(this).val() === item.id;
3772 });
3773
3774 // If an existing option wasn't found for it, create the option
3775 if (!$existingOptions.length) {
3776 var $option = self.option(item);
3777 $option.attr('data-select2-tag', true);
3778
3779 self._removeOldTags();
3780 self.addOptions([$option]);
3781 }
3782
3783 // Select the item, now that we know there is an option for it
3784 select(item);
3785 }
3786
3787 function select (data) {
3788 self.trigger('select', {
3789 data: data
3790 });
3791 }
3792
3793 params.term = params.term || '';
3794
3795 var tokenData = this.tokenizer(params, this.options, createAndSelect);
3796
3797 if (tokenData.term !== params.term) {
3798 // Replace the search term if we have the search box
3799 if (this.$search.length) {
3800 this.$search.val(tokenData.term);
3801 this.$search.trigger('focus');
3802 }
3803
3804 params.term = tokenData.term;
3805 }
3806
3807 decorated.call(this, params, callback);
3808 };
3809
3810 Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
3811 var separators = options.get('tokenSeparators') || [];
3812 var term = params.term;
3813 var i = 0;
3814
3815 var createTag = this.createTag || function (params) {
3816 return {
3817 id: params.term,
3818 text: params.term
3819 };
3820 };
3821
3822 while (i < term.length) {
3823 var termChar = term[i];
3824
3825 if ($.inArray(termChar, separators) === -1) {
3826 i++;
3827
3828 continue;
3829 }
3830
3831 var part = term.substr(0, i);
3832 var partParams = $.extend({}, params, {
3833 term: part
3834 });
3835
3836 var data = createTag(partParams);
3837
3838 if (data == null) {
3839 i++;
3840 continue;
3841 }
3842
3843 callback(data);
3844
3845 // Reset the term to not include the tokenized portion
3846 term = term.substr(i + 1) || '';
3847 i = 0;
3848 }
3849
3850 return {
3851 term: term
3852 };
3853 };
3854
3855 return Tokenizer;
3856 });
3857
3858 S2.define('select2/data/minimumInputLength',[
3859
3860 ], function () {
3861 function MinimumInputLength (decorated, $e, options) {
3862 this.minimumInputLength = options.get('minimumInputLength');
3863
3864 decorated.call(this, $e, options);
3865 }
3866
3867 MinimumInputLength.prototype.query = function (decorated, params, callback) {
3868 params.term = params.term || '';
3869
3870 if (params.term.length < this.minimumInputLength) {
3871 this.trigger('results:message', {
3872 message: 'inputTooShort',
3873 args: {
3874 minimum: this.minimumInputLength,
3875 input: params.term,
3876 params: params
3877 }
3878 });
3879
3880 return;
3881 }
3882
3883 decorated.call(this, params, callback);
3884 };
3885
3886 return MinimumInputLength;
3887 });
3888
3889 S2.define('select2/data/maximumInputLength',[
3890
3891 ], function () {
3892 function MaximumInputLength (decorated, $e, options) {
3893 this.maximumInputLength = options.get('maximumInputLength');
3894
3895 decorated.call(this, $e, options);
3896 }
3897
3898 MaximumInputLength.prototype.query = function (decorated, params, callback) {
3899 params.term = params.term || '';
3900
3901 if (this.maximumInputLength > 0 &&
3902 params.term.length > this.maximumInputLength) {
3903 this.trigger('results:message', {
3904 message: 'inputTooLong',
3905 args: {
3906 maximum: this.maximumInputLength,
3907 input: params.term,
3908 params: params
3909 }
3910 });
3911
3912 return;
3913 }
3914
3915 decorated.call(this, params, callback);
3916 };
3917
3918 return MaximumInputLength;
3919 });
3920
3921 S2.define('select2/data/maximumSelectionLength',[
3922
3923 ], function (){
3924 function MaximumSelectionLength (decorated, $e, options) {
3925 this.maximumSelectionLength = options.get('maximumSelectionLength');
3926
3927 decorated.call(this, $e, options);
3928 }
3929
3930 MaximumSelectionLength.prototype.query =
3931 function (decorated, params, callback) {
3932 var self = this;
3933
3934 this.current(function (currentData) {
3935 var count = currentData != null ? currentData.length : 0;
3936 if (self.maximumSelectionLength > 0 &&
3937 count >= self.maximumSelectionLength) {
3938 self.trigger('results:message', {
3939 message: 'maximumSelected',
3940 args: {
3941 maximum: self.maximumSelectionLength
3942 }
3943 });
3944 return;
3945 }
3946 decorated.call(self, params, callback);
3947 });
3948 };
3949
3950 return MaximumSelectionLength;
3951 });
3952
3953 S2.define('select2/dropdown',[
3954 'jquery',
3955 './utils'
3956 ], function ($, Utils) {
3957 function Dropdown ($element, options) {
3958 this.$element = $element;
3959 this.options = options;
3960
3961 Dropdown.__super__.constructor.call(this);
3962 }
3963
3964 Utils.Extend(Dropdown, Utils.Observable);
3965
3966 Dropdown.prototype.render = function () {
3967 var $dropdown = $(
3968 '<span class="select2-dropdown">' +
3969 '<span class="select2-results"></span>' +
3970 '</span>'
3971 );
3972
3973 $dropdown.attr('dir', this.options.get('dir'));
3974
3975 this.$dropdown = $dropdown;
3976
3977 return $dropdown;
3978 };
3979
3980 Dropdown.prototype.bind = function () {
3981 // Should be implemented in subclasses
3982 };
3983
3984 Dropdown.prototype.position = function ($dropdown, $container) {
3985 // Should be implmented in subclasses
3986 };
3987
3988 Dropdown.prototype.destroy = function () {
3989 // Remove the dropdown from the DOM
3990 this.$dropdown.remove();
3991 };
3992
3993 return Dropdown;
3994 });
3995
3996 S2.define('select2/dropdown/search',[
3997 'jquery',
3998 '../utils'
3999 ], function ($, Utils) {
4000 function Search () { }
4001
4002 Search.prototype.render = function (decorated) {
4003 var $rendered = decorated.call(this);
4004
4005 var $search = $(
4006 '<span class="select2-search select2-search--dropdown">' +
4007 '<input class="select2-search__field" type="search" tabindex="-1"' +
4008 ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
4009 ' spellcheck="false" role="textbox" />' +
4010 '</span>'
4011 );
4012
4013 this.$searchContainer = $search;
4014 this.$search = $search.find('input');
4015
4016 $rendered.prepend($search);
4017
4018 return $rendered;
4019 };
4020
4021 Search.prototype.bind = function (decorated, container, $container) {
4022 var self = this;
4023
4024 decorated.call(this, container, $container);
4025
4026 this.$search.on('keydown', function (evt) {
4027 self.trigger('keypress', evt);
4028
4029 self._keyUpPrevented = evt.isDefaultPrevented();
4030 });
4031
4032 // Workaround for browsers which do not support the `input` event
4033 // This will prevent double-triggering of events for browsers which support
4034 // both the `keyup` and `input` events.
4035 this.$search.on('input', function (evt) {
4036 // Unbind the duplicated `keyup` event
4037 $(this).off('keyup');
4038 });
4039
4040 this.$search.on('keyup input', function (evt) {
4041 self.handleSearch(evt);
4042 });
4043
4044 container.on('open', function () {
4045 self.$search.attr('tabindex', 0);
4046
4047 self.$search.trigger('focus');
4048
4049 window.setTimeout(function () {
4050 self.$search.trigger('focus');
4051 }, 0);
4052 });
4053
4054 container.on('close', function () {
4055 self.$search.attr('tabindex', -1);
4056
4057 self.$search.val('');
4058 self.$search.trigger('blur');
4059 });
4060
4061 container.on('focus', function () {
4062 if (!container.isOpen()) {
4063 self.$search.trigger('focus');
4064 }
4065 });
4066
4067 container.on('results:all', function (params) {
4068 if (params.query.term == null || params.query.term === '') {
4069 var showSearch = self.showSearch(params);
4070
4071 if (showSearch) {
4072 self.$searchContainer.removeClass('select2-search--hide');
4073 } else {
4074 self.$searchContainer.addClass('select2-search--hide');
4075 }
4076 }
4077 });
4078 };
4079
4080 Search.prototype.handleSearch = function (evt) {
4081 if (!this._keyUpPrevented) {
4082 var input = this.$search.val();
4083
4084 this.trigger('query', {
4085 term: input
4086 });
4087 }
4088
4089 this._keyUpPrevented = false;
4090 };
4091
4092 Search.prototype.showSearch = function (_, params) {
4093 return true;
4094 };
4095
4096 return Search;
4097 });
4098
4099 S2.define('select2/dropdown/hidePlaceholder',[
4100
4101 ], function () {
4102 function HidePlaceholder (decorated, $element, options, dataAdapter) {
4103 this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
4104
4105 decorated.call(this, $element, options, dataAdapter);
4106 }
4107
4108 HidePlaceholder.prototype.append = function (decorated, data) {
4109 data.results = this.removePlaceholder(data.results);
4110
4111 decorated.call(this, data);
4112 };
4113
4114 HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
4115 if (typeof placeholder === 'string') {
4116 placeholder = {
4117 id: '',
4118 text: placeholder
4119 };
4120 }
4121
4122 return placeholder;
4123 };
4124
4125 HidePlaceholder.prototype.removePlaceholder = function (_, data) {
4126 var modifiedData = data.slice(0);
4127
4128 for (var d = data.length - 1; d >= 0; d--) {
4129 var item = data[d];
4130
4131 if (this.placeholder.id === item.id) {
4132 modifiedData.splice(d, 1);
4133 }
4134 }
4135
4136 return modifiedData;
4137 };
4138
4139 return HidePlaceholder;
4140 });
4141
4142 S2.define('select2/dropdown/infiniteScroll',[
4143 'jquery'
4144 ], function ($) {
4145 function InfiniteScroll (decorated, $element, options, dataAdapter) {
4146 this.lastParams = {};
4147
4148 decorated.call(this, $element, options, dataAdapter);
4149
4150 this.$loadingMore = this.createLoadingMore();
4151 this.loading = false;
4152 }
4153
4154 InfiniteScroll.prototype.append = function (decorated, data) {
4155 this.$loadingMore.remove();
4156 this.loading = false;
4157
4158 decorated.call(this, data);
4159
4160 if (this.showLoadingMore(data)) {
4161 this.$results.append(this.$loadingMore);
4162 }
4163 };
4164
4165 InfiniteScroll.prototype.bind = function (decorated, container, $container) {
4166 var self = this;
4167
4168 decorated.call(this, container, $container);
4169
4170 container.on('query', function (params) {
4171 self.lastParams = params;
4172 self.loading = true;
4173 });
4174
4175 container.on('query:append', function (params) {
4176 self.lastParams = params;
4177 self.loading = true;
4178 });
4179
4180 this.$results.on('scroll', function () {
4181 var isLoadMoreVisible = $.contains(
4182 document.documentElement,
4183 self.$loadingMore[0]
4184 );
4185
4186 if (self.loading || !isLoadMoreVisible) {
4187 return;
4188 }
4189
4190 var currentOffset = self.$results.offset().top +
4191 self.$results.outerHeight(false);
4192 var loadingMoreOffset = self.$loadingMore.offset().top +
4193 self.$loadingMore.outerHeight(false);
4194
4195 if (currentOffset + 50 >= loadingMoreOffset) {
4196 self.loadMore();
4197 }
4198 });
4199 };
4200
4201 InfiniteScroll.prototype.loadMore = function () {
4202 this.loading = true;
4203
4204 var params = $.extend({}, {page: 1}, this.lastParams);
4205
4206 params.page++;
4207
4208 this.trigger('query:append', params);
4209 };
4210
4211 InfiniteScroll.prototype.showLoadingMore = function (_, data) {
4212 return data.pagination && data.pagination.more;
4213 };
4214
4215 InfiniteScroll.prototype.createLoadingMore = function () {
4216 var $option = $(
4217 '<li ' +
4218 'class="select2-results__option select2-results__option--load-more"' +
4219 'role="treeitem" aria-disabled="true"></li>'
4220 );
4221
4222 var message = this.options.get('translations').get('loadingMore');
4223
4224 $option.html(message(this.lastParams));
4225
4226 return $option;
4227 };
4228
4229 return InfiniteScroll;
4230 });
4231
4232 S2.define('select2/dropdown/attachBody',[
4233 'jquery',
4234 '../utils'
4235 ], function ($, Utils) {
4236 function AttachBody (decorated, $element, options) {
4237 this.$dropdownParent = options.get('dropdownParent') || $(document.body);
4238
4239 decorated.call(this, $element, options);
4240 }
4241
4242 AttachBody.prototype.bind = function (decorated, container, $container) {
4243 var self = this;
4244
4245 var setupResultsEvents = false;
4246
4247 decorated.call(this, container, $container);
4248
4249 container.on('open', function () {
4250 self._showDropdown();
4251 self._attachPositioningHandler(container);
4252
4253 if (!setupResultsEvents) {
4254 setupResultsEvents = true;
4255
4256 container.on('results:all', function () {
4257 self._positionDropdown();
4258 self._resizeDropdown();
4259 });
4260
4261 container.on('results:append', function () {
4262 self._positionDropdown();
4263 self._resizeDropdown();
4264 });
4265 }
4266 });
4267
4268 container.on('close', function () {
4269 self._hideDropdown();
4270 self._detachPositioningHandler(container);
4271 });
4272
4273 this.$dropdownContainer.on('mousedown', function (evt) {
4274 evt.stopPropagation();
4275 });
4276 };
4277
4278 AttachBody.prototype.destroy = function (decorated) {
4279 decorated.call(this);
4280
4281 this.$dropdownContainer.remove();
4282 };
4283
4284 AttachBody.prototype.position = function (decorated, $dropdown, $container) {
4285 // Clone all of the container classes
4286 $dropdown.attr('class', $container.attr('class'));
4287
4288 $dropdown.removeClass('select2');
4289 $dropdown.addClass('select2-container--open');
4290
4291 $dropdown.css({
4292 position: 'absolute',
4293 top: -999999
4294 });
4295
4296 this.$container = $container;
4297 };
4298
4299 AttachBody.prototype.render = function (decorated) {
4300 var $container = $('<span></span>');
4301
4302 var $dropdown = decorated.call(this);
4303 $container.append($dropdown);
4304
4305 this.$dropdownContainer = $container;
4306
4307 return $container;
4308 };
4309
4310 AttachBody.prototype._hideDropdown = function (decorated) {
4311 this.$dropdownContainer.detach();
4312 };
4313
4314 AttachBody.prototype._attachPositioningHandler =
4315 function (decorated, container) {
4316 var self = this;
4317
4318 var scrollEvent = 'scroll.select2.' + container.id;
4319 var resizeEvent = 'resize.select2.' + container.id;
4320 var orientationEvent = 'orientationchange.select2.' + container.id;
4321
4322 var $watchers = this.$container.parents().filter(Utils.hasScroll);
4323 $watchers.each(function () {
4324 Utils.StoreData(this, 'select2-scroll-position', {
4325 x: $(this).scrollLeft(),
4326 y: $(this).scrollTop()
4327 });
4328 });
4329
4330 $watchers.on(scrollEvent, function (ev) {
4331 self._positionDropdown();
4332 });
4333
4334 $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
4335 function (e) {
4336 self._positionDropdown();
4337 self._resizeDropdown();
4338 });
4339 };
4340
4341 AttachBody.prototype._detachPositioningHandler =
4342 function (decorated, container) {
4343 var scrollEvent = 'scroll.select2.' + container.id;
4344 var resizeEvent = 'resize.select2.' + container.id;
4345 var orientationEvent = 'orientationchange.select2.' + container.id;
4346
4347 var $watchers = this.$container.parents().filter(Utils.hasScroll);
4348 $watchers.off(scrollEvent);
4349
4350 $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
4351 };
4352
4353 AttachBody.prototype._positionDropdown = function () {
4354 var $window = $(window);
4355
4356 var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
4357 var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
4358
4359 var newDirection = null;
4360
4361 var offset = this.$container.offset();
4362
4363 offset.bottom = offset.top + this.$container.outerHeight(false);
4364
4365 var container = {
4366 height: this.$container.outerHeight(false)
4367 };
4368
4369 container.top = offset.top;
4370 container.bottom = offset.top + container.height;
4371
4372 var dropdown = {
4373 height: this.$dropdown.outerHeight(false)
4374 };
4375
4376 var viewport = {
4377 top: $window.scrollTop(),
4378 bottom: $window.scrollTop() + $window.height()
4379 };
4380
4381 var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
4382 var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
4383
4384 var css = {
4385 left: offset.left,
4386 top: container.bottom
4387 };
4388
4389 // Determine what the parent element is to use for calciulating the offset
4390 var $offsetParent = this.$dropdownParent;
4391
4392 // For statically positoned elements, we need to get the element
4393 // that is determining the offset
4394 if ($offsetParent.css('position') === 'static') {
4395 $offsetParent = $offsetParent.offsetParent();
4396 }
4397
4398 var parentOffset = $offsetParent.offset();
4399
4400 css.top -= parentOffset.top;
4401 css.left -= parentOffset.left;
4402
4403 if (!isCurrentlyAbove && !isCurrentlyBelow) {
4404 newDirection = 'below';
4405 }
4406
4407 if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
4408 newDirection = 'above';
4409 } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
4410 newDirection = 'below';
4411 }
4412
4413 if (newDirection == 'above' ||
4414 (isCurrentlyAbove && newDirection !== 'below')) {
4415 css.top = container.top - parentOffset.top - dropdown.height;
4416 }
4417
4418 if (newDirection != null) {
4419 this.$dropdown
4420 .removeClass('select2-dropdown--below select2-dropdown--above')
4421 .addClass('select2-dropdown--' + newDirection);
4422 this.$container
4423 .removeClass('select2-container--below select2-container--above')
4424 .addClass('select2-container--' + newDirection);
4425 }
4426
4427 this.$dropdownContainer.css(css);
4428 };
4429
4430 AttachBody.prototype._resizeDropdown = function () {
4431 var css = {
4432 width: this.$container.outerWidth(false) + 'px'
4433 };
4434
4435 if (this.options.get('dropdownAutoWidth')) {
4436 css.minWidth = css.width;
4437 css.position = 'relative';
4438 css.width = 'auto';
4439 }
4440
4441 this.$dropdown.css(css);
4442 };
4443
4444 AttachBody.prototype._showDropdown = function (decorated) {
4445 this.$dropdownContainer.appendTo(this.$dropdownParent);
4446
4447 this._positionDropdown();
4448 this._resizeDropdown();
4449 };
4450
4451 return AttachBody;
4452 });
4453
4454 S2.define('select2/dropdown/minimumResultsForSearch',[
4455
4456 ], function () {
4457 function countResults (data) {
4458 var count = 0;
4459
4460 for (var d = 0; d < data.length; d++) {
4461 var item = data[d];
4462
4463 if (item.children) {
4464 count += countResults(item.children);
4465 } else {
4466 count++;
4467 }
4468 }
4469
4470 return count;
4471 }
4472
4473 function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
4474 this.minimumResultsForSearch = options.get('minimumResultsForSearch');
4475
4476 if (this.minimumResultsForSearch < 0) {
4477 this.minimumResultsForSearch = Infinity;
4478 }
4479
4480 decorated.call(this, $element, options, dataAdapter);
4481 }
4482
4483 MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
4484 if (countResults(params.data.results) < this.minimumResultsForSearch) {
4485 return false;
4486 }
4487
4488 return decorated.call(this, params);
4489 };
4490
4491 return MinimumResultsForSearch;
4492 });
4493
4494 S2.define('select2/dropdown/selectOnClose',[
4495 '../utils'
4496 ], function (Utils) {
4497 function SelectOnClose () { }
4498
4499 SelectOnClose.prototype.bind = function (decorated, container, $container) {
4500 var self = this;
4501
4502 decorated.call(this, container, $container);
4503
4504 container.on('close', function (params) {
4505 self._handleSelectOnClose(params);
4506 });
4507 };
4508
4509 SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
4510 if (params && params.originalSelect2Event != null) {
4511 var event = params.originalSelect2Event;
4512
4513 // Don't select an item if the close event was triggered from a select or
4514 // unselect event
4515 if (event._type === 'select' || event._type === 'unselect') {
4516 return;
4517 }
4518 }
4519
4520 var $highlightedResults = this.getHighlightedResults();
4521
4522 // Only select highlighted results
4523 if ($highlightedResults.length < 1) {
4524 return;
4525 }
4526
4527 var data = Utils.GetData($highlightedResults[0], 'data');
4528
4529 // Don't re-select already selected resulte
4530 if (
4531 (data.element != null && data.element.selected) ||
4532 (data.element == null && data.selected)
4533 ) {
4534 return;
4535 }
4536
4537 this.trigger('select', {
4538 data: data
4539 });
4540 };
4541
4542 return SelectOnClose;
4543 });
4544
4545 S2.define('select2/dropdown/closeOnSelect',[
4546
4547 ], function () {
4548 function CloseOnSelect () { }
4549
4550 CloseOnSelect.prototype.bind = function (decorated, container, $container) {
4551 var self = this;
4552
4553 decorated.call(this, container, $container);
4554
4555 container.on('select', function (evt) {
4556 self._selectTriggered(evt);
4557 });
4558
4559 container.on('unselect', function (evt) {
4560 self._selectTriggered(evt);
4561 });
4562 };
4563
4564 CloseOnSelect.prototype._selectTriggered = function (_, evt) {
4565 var originalEvent = evt.originalEvent;
4566
4567 // Don't close if the control key is being held
4568 if (originalEvent && originalEvent.ctrlKey) {
4569 return;
4570 }
4571
4572 this.trigger('close', {
4573 originalEvent: originalEvent,
4574 originalSelect2Event: evt
4575 });
4576 };
4577
4578 return CloseOnSelect;
4579 });
4580
4581 S2.define('select2/i18n/en',[],function () {
4582 // English
4583 return {
4584 errorLoading: function () {
4585 return 'The results could not be loaded.';
4586 },
4587 inputTooLong: function (args) {
4588 var overChars = args.input.length - args.maximum;
4589
4590 var message = 'Please delete ' + overChars + ' character';
4591
4592 if (overChars != 1) {
4593 message += 's';
4594 }
4595
4596 return message;
4597 },
4598 inputTooShort: function (args) {
4599 var remainingChars = args.minimum - args.input.length;
4600
4601 var message = 'Please enter ' + remainingChars + ' or more characters';
4602
4603 return message;
4604 },
4605 loadingMore: function () {
4606 return 'Loading more results…';
4607 },
4608 maximumSelected: function (args) {
4609 var message = 'You can only select ' + args.maximum + ' item';
4610
4611 if (args.maximum != 1) {
4612 message += 's';
4613 }
4614
4615 return message;
4616 },
4617 noResults: function () {
4618 return 'No results found';
4619 },
4620 searching: function () {
4621 return 'Searching…';
4622 }
4623 };
4624 });
4625
4626 S2.define('select2/defaults',[
4627 'jquery',
4628 'require',
4629
4630 './results',
4631
4632 './selection/single',
4633 './selection/multiple',
4634 './selection/placeholder',
4635 './selection/allowClear',
4636 './selection/search',
4637 './selection/eventRelay',
4638
4639 './utils',
4640 './translation',
4641 './diacritics',
4642
4643 './data/select',
4644 './data/array',
4645 './data/ajax',
4646 './data/tags',
4647 './data/tokenizer',
4648 './data/minimumInputLength',
4649 './data/maximumInputLength',
4650 './data/maximumSelectionLength',
4651
4652 './dropdown',
4653 './dropdown/search',
4654 './dropdown/hidePlaceholder',
4655 './dropdown/infiniteScroll',
4656 './dropdown/attachBody',
4657 './dropdown/minimumResultsForSearch',
4658 './dropdown/selectOnClose',
4659 './dropdown/closeOnSelect',
4660
4661 './i18n/en'
4662 ], function ($, require,
4663
4664 ResultsList,
4665
4666 SingleSelection, MultipleSelection, Placeholder, AllowClear,
4667 SelectionSearch, EventRelay,
4668
4669 Utils, Translation, DIACRITICS,
4670
4671 SelectData, ArrayData, AjaxData, Tags, Tokenizer,
4672 MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
4673
4674 Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
4675 AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
4676
4677 EnglishTranslation) {
4678 function Defaults () {
4679 this.reset();
4680 }
4681
4682 Defaults.prototype.apply = function (options) {
4683 options = $.extend(true, {}, this.defaults, options);
4684
4685 if (options.dataAdapter == null) {
4686 if (options.ajax != null) {
4687 options.dataAdapter = AjaxData;
4688 } else if (options.data != null) {
4689 options.dataAdapter = ArrayData;
4690 } else {
4691 options.dataAdapter = SelectData;
4692 }
4693
4694 if (options.minimumInputLength > 0) {
4695 options.dataAdapter = Utils.Decorate(
4696 options.dataAdapter,
4697 MinimumInputLength
4698 );
4699 }
4700
4701 if (options.maximumInputLength > 0) {
4702 options.dataAdapter = Utils.Decorate(
4703 options.dataAdapter,
4704 MaximumInputLength
4705 );
4706 }
4707
4708 if (options.maximumSelectionLength > 0) {
4709 options.dataAdapter = Utils.Decorate(
4710 options.dataAdapter,
4711 MaximumSelectionLength
4712 );
4713 }
4714
4715 if (options.tags) {
4716 options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
4717 }
4718
4719 if (options.tokenSeparators != null || options.tokenizer != null) {
4720 options.dataAdapter = Utils.Decorate(
4721 options.dataAdapter,
4722 Tokenizer
4723 );
4724 }
4725
4726 if (options.query != null) {
4727 var Query = require(options.amdBase + 'compat/query');
4728
4729 options.dataAdapter = Utils.Decorate(
4730 options.dataAdapter,
4731 Query
4732 );
4733 }
4734
4735 if (options.initSelection != null) {
4736 var InitSelection = require(options.amdBase + 'compat/initSelection');
4737
4738 options.dataAdapter = Utils.Decorate(
4739 options.dataAdapter,
4740 InitSelection
4741 );
4742 }
4743 }
4744
4745 if (options.resultsAdapter == null) {
4746 options.resultsAdapter = ResultsList;
4747
4748 if (options.ajax != null) {
4749 options.resultsAdapter = Utils.Decorate(
4750 options.resultsAdapter,
4751 InfiniteScroll
4752 );
4753 }
4754
4755 if (options.placeholder != null) {
4756 options.resultsAdapter = Utils.Decorate(
4757 options.resultsAdapter,
4758 HidePlaceholder
4759 );
4760 }
4761
4762 if (options.selectOnClose) {
4763 options.resultsAdapter = Utils.Decorate(
4764 options.resultsAdapter,
4765 SelectOnClose
4766 );
4767 }
4768 }
4769
4770 if (options.dropdownAdapter == null) {
4771 if (options.multiple) {
4772 options.dropdownAdapter = Dropdown;
4773 } else {
4774 var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
4775
4776 options.dropdownAdapter = SearchableDropdown;
4777 }
4778
4779 if (options.minimumResultsForSearch !== 0) {
4780 options.dropdownAdapter = Utils.Decorate(
4781 options.dropdownAdapter,
4782 MinimumResultsForSearch
4783 );
4784 }
4785
4786 if (options.closeOnSelect) {
4787 options.dropdownAdapter = Utils.Decorate(
4788 options.dropdownAdapter,
4789 CloseOnSelect
4790 );
4791 }
4792
4793 if (
4794 options.dropdownCssClass != null ||
4795 options.dropdownCss != null ||
4796 options.adaptDropdownCssClass != null
4797 ) {
4798 var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4799
4800 options.dropdownAdapter = Utils.Decorate(
4801 options.dropdownAdapter,
4802 DropdownCSS
4803 );
4804 }
4805
4806 options.dropdownAdapter = Utils.Decorate(
4807 options.dropdownAdapter,
4808 AttachBody
4809 );
4810 }
4811
4812 if (options.selectionAdapter == null) {
4813 if (options.multiple) {
4814 options.selectionAdapter = MultipleSelection;
4815 } else {
4816 options.selectionAdapter = SingleSelection;
4817 }
4818
4819 // Add the placeholder mixin if a placeholder was specified
4820 if (options.placeholder != null) {
4821 options.selectionAdapter = Utils.Decorate(
4822 options.selectionAdapter,
4823 Placeholder
4824 );
4825 }
4826
4827 if (options.allowClear) {
4828 options.selectionAdapter = Utils.Decorate(
4829 options.selectionAdapter,
4830 AllowClear
4831 );
4832 }
4833
4834 if (options.multiple) {
4835 options.selectionAdapter = Utils.Decorate(
4836 options.selectionAdapter,
4837 SelectionSearch
4838 );
4839 }
4840
4841 if (
4842 options.containerCssClass != null ||
4843 options.containerCss != null ||
4844 options.adaptContainerCssClass != null
4845 ) {
4846 var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4847
4848 options.selectionAdapter = Utils.Decorate(
4849 options.selectionAdapter,
4850 ContainerCSS
4851 );
4852 }
4853
4854 options.selectionAdapter = Utils.Decorate(
4855 options.selectionAdapter,
4856 EventRelay
4857 );
4858 }
4859
4860 if (typeof options.language === 'string') {
4861 // Check if the language is specified with a region
4862 if (options.language.indexOf('-') > 0) {
4863 // Extract the region information if it is included
4864 var languageParts = options.language.split('-');
4865 var baseLanguage = languageParts[0];
4866
4867 options.language = [options.language, baseLanguage];
4868 } else {
4869 options.language = [options.language];
4870 }
4871 }
4872
4873 if (Array.isArray(options.language)) {
4874 var languages = new Translation();
4875 options.language.push('en');
4876
4877 var languageNames = options.language;
4878
4879 for (var l = 0; l < languageNames.length; l++) {
4880 var name = languageNames[l];
4881 var language = {};
4882
4883 try {
4884 // Try to load it with the original name
4885 language = Translation.loadPath(name);
4886 } catch (e) {
4887 try {
4888 // If we couldn't load it, check if it wasn't the full path
4889 name = this.defaults.amdLanguageBase + name;
4890 language = Translation.loadPath(name);
4891 } catch (ex) {
4892 // The translation could not be loaded at all. Sometimes this is
4893 // because of a configuration problem, other times this can be
4894 // because of how Select2 helps load all possible translation files.
4895 if (options.debug && window.console && console.warn) {
4896 console.warn(
4897 'Select2: The language file for "' + name + '" could not be ' +
4898 'automatically loaded. A fallback will be used instead.'
4899 );
4900 }
4901
4902 continue;
4903 }
4904 }
4905
4906 languages.extend(language);
4907 }
4908
4909 options.translations = languages;
4910 } else {
4911 var baseTranslation = Translation.loadPath(
4912 this.defaults.amdLanguageBase + 'en'
4913 );
4914 var customTranslation = new Translation(options.language);
4915
4916 customTranslation.extend(baseTranslation);
4917
4918 options.translations = customTranslation;
4919 }
4920
4921 return options;
4922 };
4923
4924 Defaults.prototype.reset = function () {
4925 function stripDiacritics (text) {
4926 // Used 'uni range + named function' from http://jsperf.com/diacritics/18
4927 function match(a) {
4928 return DIACRITICS[a] || a;
4929 }
4930
4931 return text.replace(/[^\u0000-\u007E]/g, match);
4932 }
4933
4934 function matcher (params, data) {
4935 // Always return the object if there is nothing to compare
4936 if ((params?.term ?? '').trim() === '') {
4937 return data;
4938 }
4939
4940 // Do a recursive check for options with children
4941 if (data.children && data.children.length > 0) {
4942 // Clone the data object if there are children
4943 // This is required as we modify the object to remove any non-matches
4944 var match = $.extend(true, {}, data);
4945
4946 // Check each child of the option
4947 for (var c = data.children.length - 1; c >= 0; c--) {
4948 var child = data.children[c];
4949
4950 var matches = matcher(params, child);
4951
4952 // If there wasn't a match, remove the object in the array
4953 if (matches == null) {
4954 match.children.splice(c, 1);
4955 }
4956 }
4957
4958 // If any children matched, return the new object
4959 if (match.children.length > 0) {
4960 return match;
4961 }
4962
4963 // If there were no matching children, check just the plain object
4964 return matcher(params, match);
4965 }
4966
4967 var original = stripDiacritics(data.text).toUpperCase();
4968 var term = stripDiacritics(params.term).toUpperCase();
4969
4970 // Check if the text contains the term
4971 if (original.indexOf(term) > -1) {
4972 return data;
4973 }
4974
4975 // If it doesn't contain the term, don't return anything
4976 return null;
4977 }
4978
4979 this.defaults = {
4980 amdBase: './',
4981 amdLanguageBase: './i18n/',
4982 closeOnSelect: true,
4983 debug: false,
4984 dropdownAutoWidth: false,
4985 escapeMarkup: Utils.escapeMarkup,
4986 language: EnglishTranslation,
4987 matcher: matcher,
4988 minimumInputLength: 0,
4989 maximumInputLength: 0,
4990 maximumSelectionLength: 0,
4991 minimumResultsForSearch: 0,
4992 selectOnClose: false,
4993 sorter: function (data) {
4994 return data;
4995 },
4996 templateResult: function (result) {
4997 return result.text;
4998 },
4999 templateSelection: function (selection) {
5000 return selection.text;
5001 },
5002 theme: 'default',
5003 width: 'resolve'
5004 };
5005 };
5006
5007 Defaults.prototype.set = function (key, value) {
5008 var camelKey = $.camelCase(key);
5009
5010 var data = {};
5011 data[camelKey] = value;
5012
5013 var convertedData = Utils._convertData(data);
5014
5015 $.extend(true, this.defaults, convertedData);
5016 };
5017
5018 var defaults = new Defaults();
5019
5020 return defaults;
5021 });
5022
5023 S2.define('select2/options',[
5024 'require',
5025 'jquery',
5026 './defaults',
5027 './utils'
5028 ], function (require, $, Defaults, Utils) {
5029 function Options (options, $element) {
5030 this.options = options;
5031
5032 if ($element != null) {
5033 this.fromElement($element);
5034 }
5035
5036 this.options = Defaults.apply(this.options);
5037
5038 if ($element && $element.is('input')) {
5039 var InputCompat = require(this.get('amdBase') + 'compat/inputData');
5040
5041 this.options.dataAdapter = Utils.Decorate(
5042 this.options.dataAdapter,
5043 InputCompat
5044 );
5045 }
5046 }
5047
5048 Options.prototype.fromElement = function ($e) {
5049 var excludedData = ['select2'];
5050
5051 if (this.options.multiple == null) {
5052 this.options.multiple = $e.prop('multiple');
5053 }
5054
5055 if (this.options.disabled == null) {
5056 this.options.disabled = $e.prop('disabled');
5057 }
5058
5059 if (this.options.language == null) {
5060 if ($e.prop('lang')) {
5061 this.options.language = $e.prop('lang').toLowerCase();
5062 } else if ($e.closest('[lang]').prop('lang')) {
5063 this.options.language = $e.closest('[lang]').prop('lang');
5064 }
5065 }
5066
5067 if (this.options.dir == null) {
5068 if ($e.prop('dir')) {
5069 this.options.dir = $e.prop('dir');
5070 } else if ($e.closest('[dir]').prop('dir')) {
5071 this.options.dir = $e.closest('[dir]').prop('dir');
5072 } else {
5073 this.options.dir = 'ltr';
5074 }
5075 }
5076
5077 $e.prop('disabled', this.options.disabled);
5078 $e.prop('multiple', this.options.multiple);
5079
5080 if (Utils.GetData($e[0], 'select2Tags')) {
5081 if (this.options.debug && window.console && console.warn) {
5082 console.warn(
5083 'Select2: The `data-select2-tags` attribute has been changed to ' +
5084 'use the `data-data` and `data-tags="true"` attributes and will be ' +
5085 'removed in future versions of Select2.'
5086 );
5087 }
5088
5089 Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags'));
5090 Utils.StoreData($e[0], 'tags', true);
5091 }
5092
5093 if (Utils.GetData($e[0], 'ajaxUrl')) {
5094 if (this.options.debug && window.console && console.warn) {
5095 console.warn(
5096 'Select2: The `data-ajax-url` attribute has been changed to ' +
5097 '`data-ajax--url` and support for the old attribute will be removed' +
5098 ' in future versions of Select2.'
5099 );
5100 }
5101
5102 $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl'));
5103 Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl'));
5104
5105 }
5106
5107 var dataset = {};
5108
5109 // Prefer the element's `dataset` attribute if it exists
5110 // jQuery 1.x does not correctly handle data attributes with multiple dashes
5111 if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
5112 dataset = $.extend(true, {}, $e[0].dataset, Utils.GetData($e[0]));
5113 } else {
5114 dataset = Utils.GetData($e[0]);
5115 }
5116
5117 var data = $.extend(true, {}, dataset);
5118
5119 data = Utils._convertData(data);
5120
5121 for (var key in data) {
5122 if ($.inArray(key, excludedData) > -1) {
5123 continue;
5124 }
5125
5126 if ($.isPlainObject(this.options[key])) {
5127 $.extend(this.options[key], data[key]);
5128 } else {
5129 this.options[key] = data[key];
5130 }
5131 }
5132
5133 return this;
5134 };
5135
5136 Options.prototype.get = function (key) {
5137 return this.options[key];
5138 };
5139
5140 Options.prototype.set = function (key, val) {
5141 this.options[key] = val;
5142 };
5143
5144 return Options;
5145 });
5146
5147 S2.define('select2/core',[
5148 'jquery',
5149 './options',
5150 './utils',
5151 './keys'
5152 ], function ($, Options, Utils, KEYS) {
5153 var Select2 = function ($element, options) {
5154 if (Utils.GetData($element[0], 'select2') != null) {
5155 Utils.GetData($element[0], 'select2').destroy();
5156 }
5157
5158 this.$element = $element;
5159
5160 this.id = this._generateId($element);
5161
5162 options = options || {};
5163
5164 this.options = new Options(options, $element);
5165
5166 Select2.__super__.constructor.call(this);
5167
5168 // Set up the tabindex
5169
5170 var tabindex = $element.attr('tabindex') || 0;
5171 Utils.StoreData($element[0], 'old-tabindex', tabindex);
5172 $element.attr('tabindex', '-1');
5173
5174 // Set up containers and adapters
5175
5176 var DataAdapter = this.options.get('dataAdapter');
5177 this.dataAdapter = new DataAdapter($element, this.options);
5178
5179 var $container = this.render();
5180
5181 this._placeContainer($container);
5182
5183 var SelectionAdapter = this.options.get('selectionAdapter');
5184 this.selection = new SelectionAdapter($element, this.options);
5185 this.$selection = this.selection.render();
5186
5187 this.selection.position(this.$selection, $container);
5188
5189 var DropdownAdapter = this.options.get('dropdownAdapter');
5190 this.dropdown = new DropdownAdapter($element, this.options);
5191 this.$dropdown = this.dropdown.render();
5192
5193 this.dropdown.position(this.$dropdown, $container);
5194
5195 var ResultsAdapter = this.options.get('resultsAdapter');
5196 this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
5197 this.$results = this.results.render();
5198
5199 this.results.position(this.$results, this.$dropdown);
5200
5201 // Bind events
5202
5203 var self = this;
5204
5205 // Bind the container to all of the adapters
5206 this._bindAdapters();
5207
5208 // Register any DOM event handlers
5209 this._registerDomEvents();
5210
5211 // Register any internal event handlers
5212 this._registerDataEvents();
5213 this._registerSelectionEvents();
5214 this._registerDropdownEvents();
5215 this._registerResultsEvents();
5216 this._registerEvents();
5217
5218 // Set the initial state
5219 this.dataAdapter.current(function (initialData) {
5220 self.trigger('selection:update', {
5221 data: initialData
5222 });
5223 });
5224
5225 // Hide the original select
5226 $element.addClass('select2-hidden-accessible');
5227 $element.attr('aria-hidden', 'true');
5228
5229 // Synchronize any monitored attributes
5230 this._syncAttributes();
5231
5232 Utils.StoreData($element[0], 'select2', this);
5233
5234 // Ensure backwards compatibility with $element.data('select2').
5235 $element.data('select2', this);
5236 };
5237
5238 Utils.Extend(Select2, Utils.Observable);
5239
5240 Select2.prototype._generateId = function ($element) {
5241 var id = '';
5242
5243 if ($element.attr('id') != null) {
5244 id = $element.attr('id');
5245 } else if ($element.attr('name') != null) {
5246 id = $element.attr('name') + '-' + Utils.generateChars(2);
5247 } else {
5248 id = Utils.generateChars(4);
5249 }
5250
5251 id = id.replace(/(:|\.|\[|\]|,)/g, '');
5252 id = 'select2-' + id;
5253
5254 return id;
5255 };
5256
5257 Select2.prototype._placeContainer = function ($container) {
5258 $container.insertAfter(this.$element);
5259
5260 var width = this._resolveWidth(this.$element, this.options.get('width'));
5261
5262 if (width != null) {
5263 $container.css('width', width);
5264 }
5265 };
5266
5267 Select2.prototype._resolveWidth = function ($element, method) {
5268 var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
5269
5270 if (method == 'resolve') {
5271 var styleWidth = this._resolveWidth($element, 'style');
5272
5273 if (styleWidth != null) {
5274 return styleWidth;
5275 }
5276
5277 return this._resolveWidth($element, 'element');
5278 }
5279
5280 if (method == 'element') {
5281 var elementWidth = $element.outerWidth(false);
5282
5283 if (elementWidth <= 0) {
5284 return 'auto';
5285 }
5286
5287 return elementWidth + 'px';
5288 }
5289
5290 if (method == 'style') {
5291 var style = $element.attr('style');
5292
5293 if (typeof(style) !== 'string') {
5294 return null;
5295 }
5296
5297 var attrs = style.split(';');
5298
5299 for (var i = 0, l = attrs.length; i < l; i = i + 1) {
5300 var attr = attrs[i].replace(/\s/g, '');
5301 var matches = attr.match(WIDTH);
5302
5303 if (matches !== null && matches.length >= 1) {
5304 return matches[1];
5305 }
5306 }
5307
5308 return null;
5309 }
5310
5311 return method;
5312 };
5313
5314 Select2.prototype._bindAdapters = function () {
5315 this.dataAdapter.bind(this, this.$container);
5316 this.selection.bind(this, this.$container);
5317
5318 this.dropdown.bind(this, this.$container);
5319 this.results.bind(this, this.$container);
5320 };
5321
5322 Select2.prototype._registerDomEvents = function () {
5323 var self = this;
5324
5325 this.$element.on('change.select2', function () {
5326 self.dataAdapter.current(function (data) {
5327 self.trigger('selection:update', {
5328 data: data
5329 });
5330 });
5331 });
5332
5333 this.$element.on('focus.select2', function (evt) {
5334 self.trigger('focus', evt);
5335 });
5336
5337 this._syncA = Utils.bind(this._syncAttributes, this);
5338 this._syncS = Utils.bind(this._syncSubtree, this);
5339
5340 if (this.$element[0].attachEvent) {
5341 this.$element[0].attachEvent('onpropertychange', this._syncA);
5342 }
5343
5344 var observer = window.MutationObserver ||
5345 window.WebKitMutationObserver ||
5346 window.MozMutationObserver
5347 ;
5348
5349 if (observer != null) {
5350 this._observer = new observer(function (mutations) {
5351 $.each(mutations, self._syncA);
5352 $.each(mutations, self._syncS);
5353 });
5354 this._observer.observe(this.$element[0], {
5355 attributes: true,
5356 childList: true,
5357 subtree: false
5358 });
5359 } else if (this.$element[0].addEventListener) {
5360 this.$element[0].addEventListener(
5361 'DOMAttrModified',
5362 self._syncA,
5363 false
5364 );
5365 this.$element[0].addEventListener(
5366 'DOMNodeInserted',
5367 self._syncS,
5368 false
5369 );
5370 this.$element[0].addEventListener(
5371 'DOMNodeRemoved',
5372 self._syncS,
5373 false
5374 );
5375 }
5376 };
5377
5378 Select2.prototype._registerDataEvents = function () {
5379 var self = this;
5380
5381 this.dataAdapter.on('*', function (name, params) {
5382 self.trigger(name, params);
5383 });
5384 };
5385
5386 Select2.prototype._registerSelectionEvents = function () {
5387 var self = this;
5388 var nonRelayEvents = ['toggle', 'focus'];
5389
5390 this.selection.on('toggle', function () {
5391 self.toggleDropdown();
5392 });
5393
5394 this.selection.on('focus', function (params) {
5395 self.focus(params);
5396 });
5397
5398 this.selection.on('*', function (name, params) {
5399 if ($.inArray(name, nonRelayEvents) !== -1) {
5400 return;
5401 }
5402
5403 self.trigger(name, params);
5404 });
5405 };
5406
5407 Select2.prototype._registerDropdownEvents = function () {
5408 var self = this;
5409
5410 this.dropdown.on('*', function (name, params) {
5411 self.trigger(name, params);
5412 });
5413 };
5414
5415 Select2.prototype._registerResultsEvents = function () {
5416 var self = this;
5417
5418 this.results.on('*', function (name, params) {
5419 self.trigger(name, params);
5420 });
5421 };
5422
5423 Select2.prototype._registerEvents = function () {
5424 var self = this;
5425
5426 this.on('open', function () {
5427 self.$container.addClass('select2-container--open');
5428 });
5429
5430 this.on('close', function () {
5431 self.$container.removeClass('select2-container--open');
5432 });
5433
5434 this.on('enable', function () {
5435 self.$container.removeClass('select2-container--disabled');
5436 });
5437
5438 this.on('disable', function () {
5439 self.$container.addClass('select2-container--disabled');
5440 });
5441
5442 this.on('blur', function () {
5443 self.$container.removeClass('select2-container--focus');
5444 });
5445
5446 this.on('query', function (params) {
5447 if (!self.isOpen()) {
5448 self.trigger('open', {});
5449 }
5450
5451 this.dataAdapter?.query(params, function (data) {
5452 self.trigger('results:all', {
5453 data: data,
5454 query: params
5455 });
5456 });
5457 });
5458
5459 this.on('query:append', function (params) {
5460 this.dataAdapter?.query(params, function (data) {
5461 self.trigger('results:append', {
5462 data: data,
5463 query: params
5464 });
5465 });
5466 });
5467
5468 this.on('keypress', function (evt) {
5469 var key = evt.which;
5470
5471 if (self.isOpen()) {
5472 if (key === KEYS.ESC || key === KEYS.TAB ||
5473 (key === KEYS.UP && evt.altKey)) {
5474 self.close();
5475
5476 evt.preventDefault();
5477 } else if (key === KEYS.ENTER) {
5478 self.trigger('results:select', {});
5479
5480 evt.preventDefault();
5481 } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
5482 self.trigger('results:toggle', {});
5483
5484 evt.preventDefault();
5485 } else if (key === KEYS.UP) {
5486 self.trigger('results:previous', {});
5487
5488 evt.preventDefault();
5489 } else if (key === KEYS.DOWN) {
5490 self.trigger('results:next', {});
5491
5492 evt.preventDefault();
5493 }
5494 } else {
5495 if (key === KEYS.ENTER || key === KEYS.SPACE ||
5496 (key === KEYS.DOWN && evt.altKey)) {
5497 self.open();
5498
5499 evt.preventDefault();
5500 }
5501 }
5502 });
5503 };
5504
5505 Select2.prototype._syncAttributes = function () {
5506 this.options.set('disabled', this.$element.prop('disabled'));
5507
5508 if (this.options.get('disabled')) {
5509 if (this.isOpen()) {
5510 this.close();
5511 }
5512
5513 this.trigger('disable', {});
5514 } else {
5515 this.trigger('enable', {});
5516 }
5517 };
5518
5519 Select2.prototype._syncSubtree = function (evt, mutations) {
5520 var changed = false;
5521 var self = this;
5522
5523 // Ignore any mutation events raised for elements that aren't options or
5524 // optgroups. This handles the case when the select element is destroyed
5525 if (
5526 evt && evt.target && (
5527 evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
5528 )
5529 ) {
5530 return;
5531 }
5532
5533 if (!mutations) {
5534 // If mutation events aren't supported, then we can only assume that the
5535 // change affected the selections
5536 changed = true;
5537 } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
5538 for (var n = 0; n < mutations.addedNodes.length; n++) {
5539 var node = mutations.addedNodes[n];
5540
5541 if (node.selected) {
5542 changed = true;
5543 }
5544 }
5545 } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
5546 changed = true;
5547 }
5548
5549 // Only re-pull the data if we think there is a change
5550 if (changed) {
5551 this.dataAdapter.current(function (currentData) {
5552 self.trigger('selection:update', {
5553 data: currentData
5554 });
5555 });
5556 }
5557 };
5558
5559 /**
5560 * Override the trigger method to automatically trigger pre-events when
5561 * there are events that can be prevented.
5562 */
5563 Select2.prototype.trigger = function (name, args) {
5564 var actualTrigger = Select2.__super__.trigger;
5565 var preTriggerMap = {
5566 'open': 'opening',
5567 'close': 'closing',
5568 'select': 'selecting',
5569 'unselect': 'unselecting',
5570 'clear': 'clearing'
5571 };
5572
5573 if (args === undefined) {
5574 args = {};
5575 }
5576
5577 if (name in preTriggerMap) {
5578 var preTriggerName = preTriggerMap[name];
5579 var preTriggerArgs = {
5580 prevented: false,
5581 name: name,
5582 args: args
5583 };
5584
5585 actualTrigger.call(this, preTriggerName, preTriggerArgs);
5586
5587 if (preTriggerArgs.prevented) {
5588 args.prevented = true;
5589
5590 return;
5591 }
5592 }
5593
5594 actualTrigger.call(this, name, args);
5595 };
5596
5597 Select2.prototype.toggleDropdown = function () {
5598 if (this.options.get('disabled')) {
5599 return;
5600 }
5601
5602 if (this.isOpen()) {
5603 this.close();
5604 } else {
5605 this.open();
5606 }
5607 };
5608
5609 Select2.prototype.open = function () {
5610 if (this.isOpen()) {
5611 return;
5612 }
5613
5614 this.trigger('query', {});
5615 };
5616
5617 Select2.prototype.close = function () {
5618 if (!this.isOpen()) {
5619 return;
5620 }
5621
5622 this.trigger('close', {});
5623 };
5624
5625 Select2.prototype.isOpen = function () {
5626 return this.$container.hasClass('select2-container--open');
5627 };
5628
5629 Select2.prototype.hasFocus = function () {
5630 return this.$container.hasClass('select2-container--focus');
5631 };
5632
5633 Select2.prototype.focus = function (data) {
5634 // No need to re-trigger focus events if we are already focused
5635 if (this.hasFocus()) {
5636 return;
5637 }
5638
5639 this.$container.addClass('select2-container--focus');
5640 this.trigger('focus', {});
5641 };
5642
5643 Select2.prototype.enable = function (args) {
5644 if (this.options.get('debug') && window.console && console.warn) {
5645 console.warn(
5646 'Select2: The `select2("enable")` method has been deprecated and will' +
5647 ' be removed in later Select2 versions. Use $element.prop("disabled")' +
5648 ' instead.'
5649 );
5650 }
5651
5652 if (args == null || args.length === 0) {
5653 args = [true];
5654 }
5655
5656 var disabled = !args[0];
5657
5658 this.$element.prop('disabled', disabled);
5659 };
5660
5661 Select2.prototype.data = function () {
5662 if (this.options.get('debug') &&
5663 arguments.length > 0 && window.console && console.warn) {
5664 console.warn(
5665 'Select2: Data can no longer be set using `select2("data")`. You ' +
5666 'should consider setting the value instead using `$element.val()`.'
5667 );
5668 }
5669
5670 var data = [];
5671
5672 this.dataAdapter.current(function (currentData) {
5673 data = currentData;
5674 });
5675
5676 return data;
5677 };
5678
5679 Select2.prototype.val = function (args) {
5680 if (this.options.get('debug') && window.console && console.warn) {
5681 console.warn(
5682 'Select2: The `select2("val")` method has been deprecated and will be' +
5683 ' removed in later Select2 versions. Use $element.val() instead.'
5684 );
5685 }
5686
5687 if (args == null || args.length === 0) {
5688 return this.$element.val();
5689 }
5690
5691 var newVal = args[0];
5692
5693 if (Array.isArray(newVal)) {
5694 newVal = $.map(newVal, function (obj) {
5695 return obj.toString();
5696 });
5697 }
5698
5699 this.$element.val(newVal).trigger('change');
5700 };
5701
5702 Select2.prototype.destroy = function () {
5703 this.$container.remove();
5704
5705 if (this.$element[0].detachEvent) {
5706 this.$element[0].detachEvent('onpropertychange', this._syncA);
5707 }
5708
5709 if (this._observer != null) {
5710 this._observer.disconnect();
5711 this._observer = null;
5712 } else if (this.$element[0].removeEventListener) {
5713 this.$element[0]
5714 .removeEventListener('DOMAttrModified', this._syncA, false);
5715 this.$element[0]
5716 .removeEventListener('DOMNodeInserted', this._syncS, false);
5717 this.$element[0]
5718 .removeEventListener('DOMNodeRemoved', this._syncS, false);
5719 }
5720
5721 this._syncA = null;
5722 this._syncS = null;
5723
5724 this.$element.off('.select2');
5725 this.$element.attr('tabindex',
5726 Utils.GetData(this.$element[0], 'old-tabindex'));
5727
5728 this.$element.removeClass('select2-hidden-accessible');
5729 this.$element.attr('aria-hidden', 'false');
5730 Utils.RemoveData(this.$element[0]);
5731 this.$element.removeData('select2');
5732
5733 this.dataAdapter.destroy();
5734 this.selection.destroy();
5735 this.dropdown.destroy();
5736 this.results.destroy();
5737
5738 this.dataAdapter = null;
5739 this.selection = null;
5740 this.dropdown = null;
5741 this.results = null;
5742 };
5743
5744 Select2.prototype.render = function () {
5745 var $container = $(
5746 '<span class="select2 select2-container">' +
5747 '<span class="selection"></span>' +
5748 '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
5749 '</span>'
5750 );
5751
5752 $container.attr('dir', this.options.get('dir'));
5753
5754 this.$container = $container;
5755
5756 this.$container.addClass('select2-container--' + this.options.get('theme'));
5757
5758 Utils.StoreData($container[0], 'element', this.$element);
5759
5760 return $container;
5761 };
5762
5763 return Select2;
5764 });
5765
5766 S2.define('select2/compat/utils',[
5767 'jquery'
5768 ], function ($) {
5769 function syncCssClasses ($dest, $src, adapter) {
5770 var classes, replacements = [], adapted;
5771
5772 classes = ($dest?.attr('class') ?? '').trim();
5773
5774 if (classes) {
5775 classes = '' + classes; // for IE which returns object
5776
5777 $(classes.split(/\s+/)).each(function () {
5778 // Save all Select2 classes
5779 if (this.indexOf('select2-') === 0) {
5780 replacements.push(this);
5781 }
5782 });
5783 }
5784
5785 classes = ($src?.attr('class') ?? '').trim();
5786
5787 if (classes) {
5788 classes = '' + classes; // for IE which returns object
5789
5790 $(classes.split(/\s+/)).each(function () {
5791 // Only adapt non-Select2 classes
5792 if (this.indexOf('select2-') !== 0) {
5793 adapted = adapter(this);
5794
5795 if (adapted != null) {
5796 replacements.push(adapted);
5797 }
5798 }
5799 });
5800 }
5801
5802 $dest.attr('class', replacements.join(' '));
5803 }
5804
5805 return {
5806 syncCssClasses: syncCssClasses
5807 };
5808 });
5809
5810 S2.define('select2/compat/containerCss',[
5811 'jquery',
5812 './utils'
5813 ], function ($, CompatUtils) {
5814 // No-op CSS adapter that discards all classes by default
5815 function _containerAdapter (clazz) {
5816 return null;
5817 }
5818
5819 function ContainerCSS () { }
5820
5821 ContainerCSS.prototype.render = function (decorated) {
5822 var $container = decorated.call(this);
5823
5824 var containerCssClass = this.options.get('containerCssClass') || '';
5825
5826 if (typeof containerCssClass === 'function') {
5827 containerCssClass = containerCssClass(this.$element);
5828 }
5829
5830 var containerCssAdapter = this.options.get('adaptContainerCssClass');
5831 containerCssAdapter = containerCssAdapter || _containerAdapter;
5832
5833 if (containerCssClass.indexOf(':all:') !== -1) {
5834 containerCssClass = containerCssClass.replace(':all:', '');
5835
5836 var _cssAdapter = containerCssAdapter;
5837
5838 containerCssAdapter = function (clazz) {
5839 var adapted = _cssAdapter(clazz);
5840
5841 if (adapted != null) {
5842 // Append the old one along with the adapted one
5843 return adapted + ' ' + clazz;
5844 }
5845
5846 return clazz;
5847 };
5848 }
5849
5850 var containerCss = this.options.get('containerCss') || {};
5851
5852 if (typeof containerCss === 'function') {
5853 containerCss = containerCss(this.$element);
5854 }
5855
5856 CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);
5857
5858 $container.css(containerCss);
5859 $container.addClass(containerCssClass);
5860
5861 return $container;
5862 };
5863
5864 return ContainerCSS;
5865 });
5866
5867 S2.define('select2/compat/dropdownCss',[
5868 'jquery',
5869 './utils'
5870 ], function ($, CompatUtils) {
5871 // No-op CSS adapter that discards all classes by default
5872 function _dropdownAdapter (clazz) {
5873 return null;
5874 }
5875
5876 function DropdownCSS () { }
5877
5878 DropdownCSS.prototype.render = function (decorated) {
5879 var $dropdown = decorated.call(this);
5880
5881 var dropdownCssClass = this.options.get('dropdownCssClass') || '';
5882
5883 if (typeof dropdownCssClass === 'function') {
5884 dropdownCssClass = dropdownCssClass(this.$element);
5885 }
5886
5887 var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');
5888 dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;
5889
5890 if (dropdownCssClass.indexOf(':all:') !== -1) {
5891 dropdownCssClass = dropdownCssClass.replace(':all:', '');
5892
5893 var _cssAdapter = dropdownCssAdapter;
5894
5895 dropdownCssAdapter = function (clazz) {
5896 var adapted = _cssAdapter(clazz);
5897
5898 if (adapted != null) {
5899 // Append the old one along with the adapted one
5900 return adapted + ' ' + clazz;
5901 }
5902
5903 return clazz;
5904 };
5905 }
5906
5907 var dropdownCss = this.options.get('dropdownCss') || {};
5908
5909 if (typeof dropdownCss === 'function') {
5910 dropdownCss = dropdownCss(this.$element);
5911 }
5912
5913 CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);
5914
5915 $dropdown.css(dropdownCss);
5916 $dropdown.addClass(dropdownCssClass);
5917
5918 return $dropdown;
5919 };
5920
5921 return DropdownCSS;
5922 });
5923
5924 S2.define('select2/compat/initSelection',[
5925 'jquery'
5926 ], function ($) {
5927 function InitSelection (decorated, $element, options) {
5928 if (options.get('debug') && window.console && console.warn) {
5929 console.warn(
5930 'Select2: The `initSelection` option has been deprecated in favor' +
5931 ' of a custom data adapter that overrides the `current` method. ' +
5932 'This method is now called multiple times instead of a single ' +
5933 'time when the instance is initialized. Support will be removed ' +
5934 'for the `initSelection` option in future versions of Select2'
5935 );
5936 }
5937
5938 this.initSelection = options.get('initSelection');
5939 this._isInitialized = false;
5940
5941 decorated.call(this, $element, options);
5942 }
5943
5944 InitSelection.prototype.current = function (decorated, callback) {
5945 var self = this;
5946
5947 if (this._isInitialized) {
5948 decorated.call(this, callback);
5949
5950 return;
5951 }
5952
5953 this.initSelection.call(null, this.$element, function (data) {
5954 self._isInitialized = true;
5955
5956 if (!Array.isArray(data)) {
5957 data = [data];
5958 }
5959
5960 callback(data);
5961 });
5962 };
5963
5964 return InitSelection;
5965 });
5966
5967 S2.define('select2/compat/inputData',[
5968 'jquery',
5969 '../utils'
5970 ], function ($, Utils) {
5971 function InputData (decorated, $element, options) {
5972 this._currentData = [];
5973 this._valueSeparator = options.get('valueSeparator') || ',';
5974
5975 if ($element.prop('type') === 'hidden') {
5976 if (options.get('debug') && console && console.warn) {
5977 console.warn(
5978 'Select2: Using a hidden input with Select2 is no longer ' +
5979 'supported and may stop working in the future. It is recommended ' +
5980 'to use a `<select>` element instead.'
5981 );
5982 }
5983 }
5984
5985 decorated.call(this, $element, options);
5986 }
5987
5988 InputData.prototype.current = function (_, callback) {
5989 function getSelected (data, selectedIds) {
5990 var selected = [];
5991
5992 if (data.selected || $.inArray(data.id, selectedIds) !== -1) {
5993 data.selected = true;
5994 selected.push(data);
5995 } else {
5996 data.selected = false;
5997 }
5998
5999 if (data.children) {
6000 selected.push.apply(selected, getSelected(data.children, selectedIds));
6001 }
6002
6003 return selected;
6004 }
6005
6006 var selected = [];
6007
6008 for (var d = 0; d < this._currentData.length; d++) {
6009 var data = this._currentData[d];
6010
6011 selected.push.apply(
6012 selected,
6013 getSelected(
6014 data,
6015 this.$element.val().split(
6016 this._valueSeparator
6017 )
6018 )
6019 );
6020 }
6021
6022 callback(selected);
6023 };
6024
6025 InputData.prototype.select = function (_, data) {
6026 if (!this.options.get('multiple')) {
6027 this.current(function (allData) {
6028 $.map(allData, function (data) {
6029 data.selected = false;
6030 });
6031 });
6032
6033 this.$element.val(data.id);
6034 this.$element.trigger('change');
6035 } else {
6036 var value = this.$element.val();
6037 value += this._valueSeparator + data.id;
6038
6039 this.$element.val(value);
6040 this.$element.trigger('change');
6041 }
6042 };
6043
6044 InputData.prototype.unselect = function (_, data) {
6045 var self = this;
6046
6047 data.selected = false;
6048
6049 this.current(function (allData) {
6050 var values = [];
6051
6052 for (var d = 0; d < allData.length; d++) {
6053 var item = allData[d];
6054
6055 if (data.id == item.id) {
6056 continue;
6057 }
6058
6059 values.push(item.id);
6060 }
6061
6062 self.$element.val(values.join(self._valueSeparator));
6063 self.$element.trigger('change');
6064 });
6065 };
6066
6067 InputData.prototype.query = function (_, params, callback) {
6068 var results = [];
6069
6070 for (var d = 0; d < this._currentData.length; d++) {
6071 var data = this._currentData[d];
6072
6073 var matches = this.matches(params, data);
6074
6075 if (matches !== null) {
6076 results.push(matches);
6077 }
6078 }
6079
6080 callback({
6081 results: results
6082 });
6083 };
6084
6085 InputData.prototype.addOptions = function (_, $options) {
6086 var options = $.map($options, function ($option) {
6087 return Utils.GetData($option[0], 'data');
6088 });
6089
6090 this._currentData.push.apply(this._currentData, options);
6091 };
6092
6093 return InputData;
6094 });
6095
6096 S2.define('select2/compat/matcher',[
6097 'jquery'
6098 ], function ($) {
6099 function oldMatcher (matcher) {
6100 function wrappedMatcher (params, data) {
6101 var match = $.extend(true, {}, data);
6102
6103 if (params.term == null || (params?.term ?? '').trim() === '') {
6104 return match;
6105 }
6106
6107 if (data.children) {
6108 for (var c = data.children.length - 1; c >= 0; c--) {
6109 var child = data.children[c];
6110
6111 // Check if the child object matches
6112 // The old matcher returned a boolean true or false
6113 var doesMatch = matcher(params.term, child.text, child);
6114
6115 // If the child didn't match, pop it off
6116 if (!doesMatch) {
6117 match.children.splice(c, 1);
6118 }
6119 }
6120
6121 if (match.children.length > 0) {
6122 return match;
6123 }
6124 }
6125
6126 if (matcher(params.term, data.text, data)) {
6127 return match;
6128 }
6129
6130 return null;
6131 }
6132
6133 return wrappedMatcher;
6134 }
6135
6136 return oldMatcher;
6137 });
6138
6139 S2.define('select2/compat/query',[
6140
6141 ], function () {
6142 function Query (decorated, $element, options) {
6143 if (options.get('debug') && window.console && console.warn) {
6144 console.warn(
6145 'Select2: The `query` option has been deprecated in favor of a ' +
6146 'custom data adapter that overrides the `query` method. Support ' +
6147 'will be removed for the `query` option in future versions of ' +
6148 'Select2.'
6149 );
6150 }
6151
6152 decorated.call(this, $element, options);
6153 }
6154
6155 Query.prototype.query = function (_, params, callback) {
6156 params.callback = callback;
6157
6158 var query = this.options.get('query');
6159
6160 query.call(null, params);
6161 };
6162
6163 return Query;
6164 });
6165
6166 S2.define('select2/dropdown/attachContainer',[
6167
6168 ], function () {
6169 function AttachContainer (decorated, $element, options) {
6170 decorated.call(this, $element, options);
6171 }
6172
6173 AttachContainer.prototype.position =
6174 function (decorated, $dropdown, $container) {
6175 var $dropdownContainer = $container.find('.dropdown-wrapper');
6176 $dropdownContainer.append($dropdown);
6177
6178 $dropdown.addClass('select2-dropdown--below');
6179 $container.addClass('select2-container--below');
6180 };
6181
6182 return AttachContainer;
6183 });
6184
6185 S2.define('select2/dropdown/stopPropagation',[
6186
6187 ], function () {
6188 function StopPropagation () { }
6189
6190 StopPropagation.prototype.bind = function (decorated, container, $container) {
6191 decorated.call(this, container, $container);
6192
6193 var stoppedEvents = [
6194 'blur',
6195 'change',
6196 'click',
6197 'dblclick',
6198 'focus',
6199 'focusin',
6200 'focusout',
6201 'input',
6202 'keydown',
6203 'keyup',
6204 'keypress',
6205 'mousedown',
6206 'mouseenter',
6207 'mouseleave',
6208 'mousemove',
6209 'mouseover',
6210 'mouseup',
6211 'search',
6212 'touchend',
6213 'touchstart'
6214 ];
6215
6216 this.$dropdown.on(stoppedEvents.join(' '), function (evt) {
6217 evt.stopPropagation();
6218 });
6219 };
6220
6221 return StopPropagation;
6222 });
6223
6224 S2.define('select2/selection/stopPropagation',[
6225
6226 ], function () {
6227 function StopPropagation () { }
6228
6229 StopPropagation.prototype.bind = function (decorated, container, $container) {
6230 decorated.call(this, container, $container);
6231
6232 var stoppedEvents = [
6233 'blur',
6234 'change',
6235 'click',
6236 'dblclick',
6237 'focus',
6238 'focusin',
6239 'focusout',
6240 'input',
6241 'keydown',
6242 'keyup',
6243 'keypress',
6244 'mousedown',
6245 'mouseenter',
6246 'mouseleave',
6247 'mousemove',
6248 'mouseover',
6249 'mouseup',
6250 'search',
6251 'touchend',
6252 'touchstart'
6253 ];
6254
6255 this.$selection.on(stoppedEvents.join(' '), function (evt) {
6256 evt.stopPropagation();
6257 });
6258 };
6259
6260 return StopPropagation;
6261 });
6262
6263 /*!
6264 * jQuery Mousewheel 3.1.13
6265 *
6266 * Copyright jQuery Foundation and other contributors
6267 * Released under the MIT license
6268 * http://jquery.org/license
6269 */
6270
6271 (function (factory) {
6272 if ( typeof S2.define === 'function' && S2.define.amd ) {
6273 // AMD. Register as an anonymous module.
6274 S2.define('jquery-mousewheel',['jquery'], factory);
6275 } else if (typeof exports === 'object') {
6276 // Node/CommonJS style for Browserify
6277 module.exports = factory;
6278 } else {
6279 // Browser globals
6280 factory(jQuery);
6281 }
6282 }(function ($) {
6283
6284 var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],
6285 toBind = ( 'onwheel' in document || document.documentMode >= 9 ) ?
6286 ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],
6287 slice = Array.prototype.slice,
6288 nullLowestDeltaTimeout, lowestDelta;
6289
6290 if ( $.event.fixHooks ) {
6291 for ( var i = toFix.length; i; ) {
6292 $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
6293 }
6294 }
6295
6296 var special = $.event.special.mousewheel = {
6297 version: '3.1.12',
6298
6299 setup: function() {
6300 if ( this.addEventListener ) {
6301 for ( var i = toBind.length; i; ) {
6302 this.addEventListener( toBind[--i], handler, false );
6303 }
6304 } else {
6305 this.onmousewheel = handler;
6306 }
6307 // Store the line height and page height for this particular element
6308 $.data(this, 'mousewheel-line-height', special.getLineHeight(this));
6309 $.data(this, 'mousewheel-page-height', special.getPageHeight(this));
6310 },
6311
6312 teardown: function() {
6313 if ( this.removeEventListener ) {
6314 for ( var i = toBind.length; i; ) {
6315 this.removeEventListener( toBind[--i], handler, false );
6316 }
6317 } else {
6318 this.onmousewheel = null;
6319 }
6320 // Clean up the data we added to the element
6321 $.removeData(this, 'mousewheel-line-height');
6322 $.removeData(this, 'mousewheel-page-height');
6323 },
6324
6325 getLineHeight: function(elem) {
6326 var $elem = $(elem),
6327 $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();
6328 if (!$parent.length) {
6329 $parent = $('body');
6330 }
6331 return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;
6332 },
6333
6334 getPageHeight: function(elem) {
6335 return $(elem).height();
6336 },
6337
6338 settings: {
6339 adjustOldDeltas: true, // see shouldAdjustOldDeltas() below
6340 normalizeOffset: true // calls getBoundingClientRect for each event
6341 }
6342 };
6343
6344 $.fn.extend({
6345 mousewheel: function(fn) {
6346 return fn ? this.on('mousewheel', fn) : this.trigger('mousewheel');
6347 },
6348
6349 unmousewheel: function(fn) {
6350 return this.off('mousewheel', fn);
6351 }
6352 });
6353
6354
6355 function handler(event) {
6356 var orgEvent = event || window.event,
6357 args = slice.call(arguments, 1),
6358 delta = 0,
6359 deltaX = 0,
6360 deltaY = 0,
6361 absDelta = 0,
6362 offsetX = 0,
6363 offsetY = 0;
6364 event = $.event.fix(orgEvent);
6365 event.type = 'mousewheel';
6366
6367 // Old school scrollwheel delta
6368 if ( 'detail' in orgEvent ) { deltaY = orgEvent.detail * -1; }
6369 if ( 'wheelDelta' in orgEvent ) { deltaY = orgEvent.wheelDelta; }
6370 if ( 'wheelDeltaY' in orgEvent ) { deltaY = orgEvent.wheelDeltaY; }
6371 if ( 'wheelDeltaX' in orgEvent ) { deltaX = orgEvent.wheelDeltaX * -1; }
6372
6373 // Firefox < 17 horizontal scrolling related to DOMMouseScroll event
6374 if ( 'axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
6375 deltaX = deltaY * -1;
6376 deltaY = 0;
6377 }
6378
6379 // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy
6380 delta = deltaY === 0 ? deltaX : deltaY;
6381
6382 // New school wheel delta (wheel event)
6383 if ( 'deltaY' in orgEvent ) {
6384 deltaY = orgEvent.deltaY * -1;
6385 delta = deltaY;
6386 }
6387 if ( 'deltaX' in orgEvent ) {
6388 deltaX = orgEvent.deltaX;
6389 if ( deltaY === 0 ) { delta = deltaX * -1; }
6390 }
6391
6392 // No change actually happened, no reason to go any further
6393 if ( deltaY === 0 && deltaX === 0 ) { return; }
6394
6395 // Need to convert lines and pages to pixels if we aren't already in pixels
6396 // There are three delta modes:
6397 // * deltaMode 0 is by pixels, nothing to do
6398 // * deltaMode 1 is by lines
6399 // * deltaMode 2 is by pages
6400 if ( orgEvent.deltaMode === 1 ) {
6401 var lineHeight = $.data(this, 'mousewheel-line-height');
6402 delta *= lineHeight;
6403 deltaY *= lineHeight;
6404 deltaX *= lineHeight;
6405 } else if ( orgEvent.deltaMode === 2 ) {
6406 var pageHeight = $.data(this, 'mousewheel-page-height');
6407 delta *= pageHeight;
6408 deltaY *= pageHeight;
6409 deltaX *= pageHeight;
6410 }
6411
6412 // Store lowest absolute delta to normalize the delta values
6413 absDelta = Math.max( Math.abs(deltaY), Math.abs(deltaX) );
6414
6415 if ( !lowestDelta || absDelta < lowestDelta ) {
6416 lowestDelta = absDelta;
6417
6418 // Adjust older deltas if necessary
6419 if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
6420 lowestDelta /= 40;
6421 }
6422 }
6423
6424 // Adjust older deltas if necessary
6425 if ( shouldAdjustOldDeltas(orgEvent, absDelta) ) {
6426 // Divide all the things by 40!
6427 delta /= 40;
6428 deltaX /= 40;
6429 deltaY /= 40;
6430 }
6431
6432 // Get a whole, normalized value for the deltas
6433 delta = Math[ delta >= 1 ? 'floor' : 'ceil' ](delta / lowestDelta);
6434 deltaX = Math[ deltaX >= 1 ? 'floor' : 'ceil' ](deltaX / lowestDelta);
6435 deltaY = Math[ deltaY >= 1 ? 'floor' : 'ceil' ](deltaY / lowestDelta);
6436
6437 // Normalise offsetX and offsetY properties
6438 if ( special.settings.normalizeOffset && this.getBoundingClientRect ) {
6439 var boundingRect = this.getBoundingClientRect();
6440 offsetX = event.clientX - boundingRect.left;
6441 offsetY = event.clientY - boundingRect.top;
6442 }
6443
6444 // Add information to the event object
6445 event.deltaX = deltaX;
6446 event.deltaY = deltaY;
6447 event.deltaFactor = lowestDelta;
6448 event.offsetX = offsetX;
6449 event.offsetY = offsetY;
6450 // Go ahead and set deltaMode to 0 since we converted to pixels
6451 // Although this is a little odd since we overwrite the deltaX/Y
6452 // properties with normalized deltas.
6453 event.deltaMode = 0;
6454
6455 // Add event and delta to the front of the arguments
6456 args.unshift(event, delta, deltaX, deltaY);
6457
6458 // Clearout lowestDelta after sometime to better
6459 // handle multiple device types that give different
6460 // a different lowestDelta
6461 // Ex: trackpad = 3 and mouse wheel = 120
6462 if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }
6463 nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);
6464
6465 return ($.event.dispatch || $.event.handle).apply(this, args);
6466 }
6467
6468 function nullLowestDelta() {
6469 lowestDelta = null;
6470 }
6471
6472 function shouldAdjustOldDeltas(orgEvent, absDelta) {
6473 // If this is an older event and the delta is divisable by 120,
6474 // then we are assuming that the browser is treating this as an
6475 // older mouse wheel event and that we should divide the deltas
6476 // by 40 to try and get a more usable deltaFactor.
6477 // Side note, this actually impacts the reported scroll distance
6478 // in older browsers and can cause scrolling to be slower than native.
6479 // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.
6480 return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;
6481 }
6482
6483 }));
6484
6485 S2.define('jquery.select2',[
6486 'jquery',
6487 'jquery-mousewheel',
6488
6489 './select2/core',
6490 './select2/defaults',
6491 './select2/utils'
6492 ], function ($, _, Select2, Defaults, Utils) {
6493 if ($.fn.select2 == null) {
6494 // All methods that should return the element
6495 var thisMethods = ['open', 'close', 'destroy'];
6496
6497 $.fn.select2 = function (options) {
6498 options = options || {};
6499
6500 if (typeof options === 'object') {
6501 this.each(function () {
6502 var instanceOptions = $.extend(true, {}, options);
6503
6504 var instance = new Select2($(this), instanceOptions);
6505 });
6506
6507 return this;
6508 } else if (typeof options === 'string') {
6509 var ret;
6510 var args = Array.prototype.slice.call(arguments, 1);
6511
6512 this.each(function () {
6513 var instance = Utils.GetData(this, 'select2');
6514
6515 if (instance == null && window.console && console.error) {
6516 console.error(
6517 'The select2(\'' + options + '\') method was called on an ' +
6518 'element that is not using Select2.'
6519 );
6520 }
6521
6522 ret = instance[options].apply(instance, args);
6523 });
6524
6525 // Check if we should be returning `this`
6526 if ($.inArray(options, thisMethods) > -1) {
6527 return this;
6528 }
6529
6530 return ret;
6531 } else {
6532 throw new Error('Invalid arguments for Select2: ' + options);
6533 }
6534 };
6535 }
6536
6537 if ($.fn.select2.defaults == null) {
6538 $.fn.select2.defaults = Defaults;
6539 }
6540
6541 return Select2;
6542 });
6543
6544 // Return the AMD loader configuration so it can be used outside of this file
6545 return {
6546 define: S2.define,
6547 require: S2.require
6548 };
6549 }());
6550
6551 // Autoload the jQuery bindings
6552 // We know that all of the modules exist above this, so we're safe
6553 var select2 = S2.require('jquery.select2');
6554
6555 // Hold the AMD module references on the jQuery function that was just loaded
6556 // This allows Select2 to use the internal loader outside of this file, such
6557 // as in the language files.
6558 jQuery.fn.select2.amd = S2;
6559
6560 // Return the Select2 instance for anyone who is importing it.
6561 return select2;
6562 }));
6563