PageSourceSearch

https://nemlanka-com-454922.hostingersite.com/wp-content/plugins/w…/js/selectWoo/selectWoo.full.js?ver=1.0.6

js nemlanka-com-454922.hostingersite.com collected 2026-10-03 04:44:54 UTC 167,722 bytes, 6,585 lines download raw bytes

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

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.