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