PageSourceSearch

https://www.nomadtravel.co.uk/wp-content/plugins/woocommerce/assets/js/selectWoo/selectWoo.full.js

js nomadtravel.co.uk collected 2026-10-03 22:22:29 UTC 168,794 bytes, 6,605 lines download raw bytes

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

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.