PluginProbe
Elementor Website Builder – more than just a page builder / 3.13.3
Elementor Website Builder – more than just a page builder v3.13.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.13.3, at assets/lib/e-select2/js/e-select2.full.js

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