PluginProbe ʕ •ᴥ•ʔ
WooCommerce / 11.0.1
WooCommerce v11.0.1
11.1.0 11.1.0-rc.2 11.1.0-rc.1 11.1.0-beta.2 11.1.0-beta.1 11.0.1 11.0.0 11.0.0-rc.3 11.0.0-rc.2 11.0.0-rc.1 11.0.0-beta.2 11.0.0-beta.1 10.9.4 10.9.3 10.9.2 10.9.1 10.9.0 10.9.0-rc.1 10.9.0-beta.2 10.9.0-beta.1 10.8.1 10.8.0 10.8.0-rc.1 10.8.0-beta.2 10.8.0-beta.1 7.8.0-beta.1 7.8.0-beta.2 7.8.0-rc.1 7.8.0-rc.2 7.8.1 7.8.2 7.8.3 7.8.4 7.9.0 7.9.0-beta.1 7.9.0-beta.2 7.9.0-rc.2 7.9.0-rc.3 7.9.1 7.9.2 8.0.0 8.0.0-beta.1 8.0.0-beta.2 8.0.0-rc.1 8.0.0-rc.2 8.0.1 8.0.2 8.0.3 8.0.4 8.0.5 8.1.0 8.1.0-beta.1 8.1.0-rc.1 8.1.0-rc.2 8.1.1 8.1.2 8.1.3 8.1.4 8.2.0 8.2.0-beta.1 8.2.0-rc.1 8.2.0-rc.2 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.3.0 8.3.0-beta.1 8.3.0-rc.1 8.3.0-rc.2 8.3.1 8.3.2 8.3.3 8.3.4 8.4.0 8.4.0-beta.1 8.4.0-rc.1 8.4.1 8.4.2 8.4.3 8.5.0 8.5.0-beta.1 8.5.0-rc.1 8.5.1 8.5.2 8.5.3 8.5.4 8.5.5 8.6.0 8.6.0-beta.1 8.6.0-rc.1 8.6.1 8.6.2 8.6.3 8.6.4 8.7.0 8.7.0-beta.1 8.7.0-beta.2 8.7.0-rc.1 8.7.1 8.7.2 8.7.3 8.8.0 8.8.0-beta.1 8.8.0-rc.1 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.8.6 8.8.7 8.9.0 8.9.0-beta.1 8.9.0-rc.1 8.9.1 8.9.2 8.9.3 8.9.4 8.9.5 9.0.0 9.0.0-beta.1 9.0.0-beta.2 9.0.0-rc.1 9.0.1 9.0.2 9.0.3 9.0.4 9.1.0 9.1.0-beta.1 9.1.0-rc.1 9.1.1 9.1.2 9.1.3 9.1.4 9.1.5 9.1.6 9.2.0 9.2.0-beta.1 9.2.0-rc.1 9.2.1 9.2.2 9.2.3 9.2.4 9.2.5 9.3.0 9.3.0-beta.1 9.3.0-rc.1 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.3.6 9.4.0 9.4.0-beta.1 9.4.0-beta.2 9.4.0-rc.1 9.4.0-rc.2 9.4.0-rc.3 9.4.0-rc.4 9.4.1 9.4.2 9.4.3 9.4.4 9.4.5 9.5.0 9.5.0-beta.1 9.5.0-beta.2 9.5.0-rc.1 9.5.1 9.5.2 9.5.3 9.5.4 9.6.0 9.6.0-beta.1 9.6.0-beta.2 9.6.0-rc.1 9.6.1 9.6.2 9.6.3 9.6.4 9.7.0 9.7.0-beta.1 9.7.0-rc.1 9.7.1 9.7.2 9.7.3 9.8.0 9.8.0-beta.1 9.8.0-rc.1 9.8.1 9.8.2 9.8.3 9.8.4 9.8.5 9.8.6 9.8.7 9.9.0 9.9.0-beta.1 9.9.0-rc.1 9.9.1 9.9.2 9.9.3 9.9.4 9.9.5 9.9.6 9.9.7 3.7.3 7.1.2 3.8.0 7.2.0 3.8.0-beta.1 7.2.0-beta.1 3.8.0-rc.1 7.2.0-beta.2 3.8.0-rc.2 7.2.0-rc.1 3.8.1 7.2.0-rc.2 3.8.2 7.2.1 3.8.3 7.2.2 3.9.0 7.2.3 3.9.0-beta.1 7.2.4 3.9.0-beta.2 7.3.0 3.9.0-rc.1 7.3.0-beta.1 3.9.0-rc.2 7.3.0-beta.2 3.9.0-rc.3 7.3.0-rc.1 3.9.0-rc.4 7.3.0-rc.2 3.9.1 7.3.1 3.9.2 7.4.0 3.9.3 7.4.0-beta.1 3.9.4 7.4.0-beta.2 3.9.5 7.4.0-rc.1 4.0.0 7.4.0-rc.2 4.0.0-beta.1 7.4.1 4.0.0-rc.1 7.4.2 4.0.0-rc.2 7.5.0 4.0.1 7.5.0-beta.1 4.0.2 7.5.0-beta.2 4.0.3 7.5.0-rc.1 4.0.4 7.5.1 4.1.0 7.5.2 4.1.0-beta.1 7.6.0 4.1.0-beta.2 7.6.0-beta.1 4.1.0-rc.1 7.6.0-beta.2 4.1.0-rc.2 7.6.0-rc.1 4.1.1 7.6.0-rc.2 4.1.2 7.6.0-rc.3 4.1.3 7.6.1 4.1.4 7.6.2 4.2.0 7.7.0 4.2.0-RC.1 7.7.0-beta.1 4.2.0-RC.2 7.7.0-beta.2 4.2.0-beta.1 7.7.0-rc.1 4.2.1 7.7.1 4.2.2 7.7.2 4.2.3 7.7.3 4.2.4 7.8.0 4.2.5 4.3.0 4.3.0-beta.1 4.3.0-rc.1 4.3.0-rc.2 4.3.0-rc.3 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.4.0 4.4.0-beta.1 4.4.0-rc.1 4.4.1 4.4.2 4.4.3 4.4.4 4.5.0 4.5.0-beta.1 4.5.0-rc.1 4.5.0-rc.3 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.6.0-beta.1 4.6.0-rc.1 4.6.1 4.6.2 4.6.3 4.6.4 4.6.5 4.7.0 4.7.0-beta.1 4.7.0-beta.2 4.7.0-rc.1 4.7.1 4.7.1-beta.1 4.7.2 4.7.3 4.7.4 4.8.0 4.8.0-beta.1 4.8.0-rc.1 4.8.0-rc.2 4.8.1 4.8.2 4.8.3 4.9.0 4.9.0-beta.1 4.9.0-rc.1 4.9.0-rc.2 4.9.1 4.9.2 4.9.3 4.9.4 4.9.5 5.0.0 5.0.0-beta.1 5.0.0-beta.2 5.0.0-rc.1 5.0.0-rc.2 5.0.0-rc.3 5.0.1 5.0.2 5.0.3 5.1.0 5.1.0-beta.1 5.1.0-rc.1 trunk 5.1.1 10.0.0 5.1.2 10.0.0-rc.1 5.1.3 10.0.0-rc.2 5.2.0 10.0.1 5.2.0-beta.1 10.0.2 5.2.0-rc.1 10.0.3 5.2.0-rc.2 10.0.4 5.2.1 10.0.5 5.2.2 10.0.6 5.2.3 10.1.0 5.2.4 10.1.0-rc.1 5.2.5 10.1.0-rc.2 5.3.0 10.1.0-rc.3 5.3.0-beta.1 10.1.0-rc.4 5.3.0-rc.1 10.1.1 5.3.0-rc.2 10.1.2 5.3.1 10.1.3 5.3.2 10.1.4 5.3.3 10.2.0 5.4.0 10.2.0-beta.1 5.4.0-beta.1 10.2.0-beta.2 5.4.0-rc.1 10.2.0-rc.1 5.4.1 10.2.1 5.4.2 10.2.2 5.4.3 10.2.3 5.4.4 10.2.4 5.4.5 10.3.0 5.5.0 10.3.0-beta.1 5.5.0-beta.1 10.3.0-beta.2 5.5.0-rc.1 10.3.0-rc.1 5.5.0-rc.2 10.3.0-rc.2 5.5.1 10.3.1 5.5.2 10.3.2 5.5.3 10.3.3 5.5.4 10.3.4 5.5.5 10.3.5 5.6.0 10.3.6 5.6.0-beta.1 10.3.7 5.6.0-rc.1 10.3.8 5.6.0-rc.2 10.4.0 5.6.1 10.4.0-beta.1 5.6.2 10.4.0-beta.2 5.6.3 10.4.0-rc.1 5.7.0 10.4.1 5.7.0-beta.1 10.4.2 5.7.0-rc.1 10.4.3 5.7.1 10.4.4 5.7.2 10.5.0 5.7.3 10.5.0-beta.1 5.8.0 10.5.0-beta.2 5.8.0-beta.1 10.5.0-rc.1 5.8.0-beta.2 10.5.0-rc.2 5.8.0-rc.1 10.5.0-rc.3 5.8.1 10.5.1 5.8.2 10.5.2 5.9.0 10.5.3 5.9.0-beta.1 10.6.0 5.9.0-rc.1 10.6.0-beta.1 5.9.0-rc.2 10.6.0-beta.2 5.9.1 10.6.0-rc.1 5.9.2 10.6.1 6.0.0 10.6.2 6.0.0-beta.1 10.7.0 6.0.0-rc.1 10.7.0-beta.1 6.0.1 10.7.0-beta.2 6.0.2 10.7.0-rc.1 6.1.0 3.0.0 6.1.0-beta.1 3.0.1 6.1.0-rc.1 3.0.2 6.1.0-rc.2 3.0.3 6.1.1 3.0.4 6.1.2 3.0.5 6.1.3 3.0.6 6.2.0 3.0.7 6.2.0-beta.1 3.0.8 6.2.0-rc.1 3.0.9 6.2.0-rc.2 3.1.0 6.2.1 3.1.1 6.2.2 3.1.2 6.2.3 3.2.0 6.3.0 3.2.1 6.3.0-beta.1 3.2.2 6.3.0-rc.1 3.2.3 6.3.0-rc.2 3.2.4 6.3.1 3.2.5 6.3.2 3.2.6 6.4.0 3.3.0 6.4.0-beta.1 3.3.1 6.4.0-rc.1 3.3.2 6.4.1 3.3.2-rc.1 6.4.2 3.3.3 6.5.0 3.3.4 6.5.0-beta.1 3.3.5 6.5.0-rc.1 3.3.6 6.5.0-rc.2 3.4.0 6.5.1 3.4.0-beta.1 6.5.2 3.4.0-rc.2 6.6.0 3.4.1 6.6.0-beta.1 3.4.2 6.6.0-rc.1 3.4.3 6.6.0-rc.2 3.4.4 6.6.1 3.4.5 6.6.2 3.4.6 6.7.0 3.4.7 6.7.0-beta.1 3.4.8 6.7.0-beta.2 3.5.0 6.7.0-rc.1 3.5.0-beta.1 6.7.1 3.5.0-rc.1 6.8.0 3.5.0-rc.2 6.8.0-beta.1 3.5.1 6.8.0-beta.2 3.5.10 6.8.0-rc.1 3.5.2 6.8.1 3.5.3 6.8.2 3.5.4 6.8.3 3.5.5 6.9.0 3.5.6 6.9.0-beta.1 3.5.7 6.9.0-beta.2 3.5.8 6.9.0-rc.1 3.5.9 6.9.1 3.6.0 6.9.2 3.6.0-beta.1 6.9.3 3.6.0-rc.1 6.9.4 3.6.0-rc.2 6.9.5 3.6.0-rc.3 7.0.0 3.6.1 7.0.0-beta.1 3.6.2 7.0.0-beta.2 3.6.3 7.0.0-beta.3 3.6.4 7.0.0-rc.1 3.6.5 7.0.0-rc.2 3.6.6 7.0.1 3.6.7 7.0.2 3.7.0 7.1.0 3.7.0-beta.1 7.1.0-beta.1 3.7.0-rc.1 7.1.0-beta.2 3.7.0-rc.2 7.1.0-rc.1 3.7.1 7.1.0-rc.2 3.7.2 7.1.1
woocommerce / assets / js / selectWoo / selectWoo.js
woocommerce / assets / js / selectWoo Last commit date
selectWoo.full.js 2 years ago selectWoo.full.min.js 2 years ago selectWoo.js 4 years ago selectWoo.min.js 3 years ago
selectWoo.js
5889 lines
1 /*!
2 * SelectWoo 1.0.10
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 }
44 var S2;(function () { if (!S2 || !S2.requirejs) {
45 if (!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
54 var 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
481 S2.requirejs = requirejs;S2.require = require;S2.define = define;
482 }
483 }());
484 S2.define("almond", function(){});
485
486 /* global jQuery:false, $:false */
487 S2.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
501 S2.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 Utils.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
792 S2.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
1093 container.on('close', function () {
1094 // When the dropdown is closed, aria-expended="false"
1095 self.$results.attr('aria-expanded', 'false');
1096 self.$results.attr('aria-hidden', 'true');
1097 self.$results.removeAttr('aria-activedescendant');
1098 });
1099
1100 container.on('results:toggle', function () {
1101 var $highlighted = self.getHighlightedResults();
1102
1103 if ($highlighted.length === 0) {
1104 return;
1105 }
1106
1107 $highlighted.trigger('mouseup');
1108 });
1109
1110 container.on('results:select', function () {
1111 var $highlighted = self.getHighlightedResults();
1112
1113 if ($highlighted.length === 0) {
1114 return;
1115 }
1116
1117 var data = $highlighted.data('data');
1118
1119 if ($highlighted.attr('data-selected') == 'true') {
1120 self.trigger('close', {});
1121 } else {
1122 self.trigger('select', {
1123 data: data
1124 });
1125 }
1126 });
1127
1128 container.on('results:previous', function () {
1129 var $highlighted = self.getHighlightedResults();
1130
1131 var $options = self.$results.find('[data-selected]');
1132
1133 var currentIndex = $options.index($highlighted);
1134
1135 // If we are already at te top, don't move further
1136 if (currentIndex === 0) {
1137 return;
1138 }
1139
1140 var nextIndex = currentIndex - 1;
1141
1142 // If none are highlighted, highlight the first
1143 if ($highlighted.length === 0) {
1144 nextIndex = 0;
1145 }
1146
1147 var $next = $options.eq(nextIndex);
1148
1149 $next.trigger('mouseenter');
1150
1151 var currentOffset = self.$results.offset().top;
1152 var nextTop = $next.offset().top;
1153 var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);
1154
1155 if (nextIndex === 0) {
1156 self.$results.scrollTop(0);
1157 } else if (nextTop - currentOffset < 0) {
1158 self.$results.scrollTop(nextOffset);
1159 }
1160 });
1161
1162 container.on('results:next', function () {
1163 var $highlighted = self.getHighlightedResults();
1164
1165 var $options = self.$results.find('[data-selected]');
1166
1167 var currentIndex = $options.index($highlighted);
1168
1169 var nextIndex = currentIndex + 1;
1170
1171 // If we are at the last option, stay there
1172 if (nextIndex >= $options.length) {
1173 return;
1174 }
1175
1176 var $next = $options.eq(nextIndex);
1177
1178 $next.trigger('mouseenter');
1179
1180 var currentOffset = self.$results.offset().top +
1181 self.$results.outerHeight(false);
1182 var nextBottom = $next.offset().top + $next.outerHeight(false);
1183 var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;
1184
1185 if (nextIndex === 0) {
1186 self.$results.scrollTop(0);
1187 } else if (nextBottom > currentOffset) {
1188 self.$results.scrollTop(nextOffset);
1189 }
1190 });
1191
1192 container.on('results:focus', function (params) {
1193 params.element.addClass('select2-results__option--highlighted').attr('aria-selected', 'true');
1194 self.$results.attr('aria-activedescendant', params.element.attr('id'));
1195 });
1196
1197 container.on('results:message', function (params) {
1198 self.displayMessage(params);
1199 });
1200
1201 if ($.fn.mousewheel) {
1202 this.$results.on('mousewheel', function (e) {
1203 var top = self.$results.scrollTop();
1204
1205 var bottom = self.$results.get(0).scrollHeight - top + e.deltaY;
1206
1207 var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;
1208 var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();
1209
1210 if (isAtTop) {
1211 self.$results.scrollTop(0);
1212
1213 e.preventDefault();
1214 e.stopPropagation();
1215 } else if (isAtBottom) {
1216 self.$results.scrollTop(
1217 self.$results.get(0).scrollHeight - self.$results.height()
1218 );
1219
1220 e.preventDefault();
1221 e.stopPropagation();
1222 }
1223 });
1224 }
1225
1226 this.$results.on('mouseup', '.select2-results__option[data-selected]',
1227 function (evt) {
1228 var $this = $(this);
1229
1230 var data = $this.data('data');
1231
1232 if ($this.attr('data-selected') === 'true') {
1233 if (self.options.get('multiple')) {
1234 self.trigger('unselect', {
1235 originalEvent: evt,
1236 data: data
1237 });
1238 } else {
1239 self.trigger('close', {});
1240 }
1241
1242 return;
1243 }
1244
1245 self.trigger('select', {
1246 originalEvent: evt,
1247 data: data
1248 });
1249 });
1250
1251 this.$results.on('mouseenter', '.select2-results__option[data-selected]',
1252 function (evt) {
1253 var data = $(this).data('data');
1254
1255 self.getHighlightedResults()
1256 .removeClass('select2-results__option--highlighted')
1257 .attr('aria-selected', 'false');
1258
1259 self.trigger('results:focus', {
1260 data: data,
1261 element: $(this)
1262 });
1263 });
1264 };
1265
1266 Results.prototype.getHighlightedResults = function () {
1267 var $highlighted = this.$results
1268 .find('.select2-results__option--highlighted');
1269
1270 return $highlighted;
1271 };
1272
1273 Results.prototype.destroy = function () {
1274 this.$results.remove();
1275 };
1276
1277 Results.prototype.ensureHighlightVisible = function () {
1278 var $highlighted = this.getHighlightedResults();
1279
1280 if ($highlighted.length === 0) {
1281 return;
1282 }
1283
1284 var $options = this.$results.find('[data-selected]');
1285
1286 var currentIndex = $options.index($highlighted);
1287
1288 var currentOffset = this.$results.offset().top;
1289 var nextTop = $highlighted.offset().top;
1290 var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);
1291
1292 var offsetDelta = nextTop - currentOffset;
1293 nextOffset -= $highlighted.outerHeight(false) * 2;
1294
1295 if (currentIndex <= 2) {
1296 this.$results.scrollTop(0);
1297 } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {
1298 this.$results.scrollTop(nextOffset);
1299 }
1300 };
1301
1302 Results.prototype.template = function (result, container) {
1303 var template = this.options.get('templateResult');
1304 var escapeMarkup = this.options.get('escapeMarkup');
1305
1306 var content = template(result, container);
1307
1308 if (content == null) {
1309 container.style.display = 'none';
1310 } else if (typeof content === 'string') {
1311 container.innerHTML = escapeMarkup(content);
1312 } else {
1313 $(container).append(content);
1314 }
1315 };
1316
1317 return Results;
1318 });
1319
1320 S2.define('select2/keys',[
1321
1322 ], function () {
1323 var KEYS = {
1324 BACKSPACE: 8,
1325 TAB: 9,
1326 ENTER: 13,
1327 SHIFT: 16,
1328 CTRL: 17,
1329 ALT: 18,
1330 ESC: 27,
1331 SPACE: 32,
1332 PAGE_UP: 33,
1333 PAGE_DOWN: 34,
1334 END: 35,
1335 HOME: 36,
1336 LEFT: 37,
1337 UP: 38,
1338 RIGHT: 39,
1339 DOWN: 40,
1340 DELETE: 46
1341 };
1342
1343 return KEYS;
1344 });
1345
1346 S2.define('select2/selection/base',[
1347 'jquery',
1348 '../utils',
1349 '../keys'
1350 ], function ($, Utils, KEYS) {
1351 function BaseSelection ($element, options) {
1352 this.$element = $element;
1353 this.options = options;
1354
1355 BaseSelection.__super__.constructor.call(this);
1356 }
1357
1358 Utils.Extend(BaseSelection, Utils.Observable);
1359
1360 BaseSelection.prototype.render = function () {
1361 var $selection = $(
1362 '<span class="select2-selection" ' +
1363 ' aria-haspopup="true" aria-expanded="false">' +
1364 '</span>'
1365 );
1366
1367 this._tabindex = 0;
1368
1369 if (this.$element.data('old-tabindex') != null) {
1370 this._tabindex = this.$element.data('old-tabindex');
1371 } else if (this.$element.attr('tabindex') != null) {
1372 this._tabindex = this.$element.attr('tabindex');
1373 }
1374
1375 $selection.attr('title', this.$element.attr('title'));
1376 $selection.attr('tabindex', this._tabindex);
1377
1378 this.$selection = $selection;
1379
1380 return $selection;
1381 };
1382
1383 BaseSelection.prototype.bind = function (container, $container) {
1384 var self = this;
1385
1386 var id = container.id + '-container';
1387 var resultsId = container.id + '-results';
1388 var searchHidden = this.options.get('minimumResultsForSearch') === Infinity;
1389
1390 this.container = container;
1391
1392 this.$selection.on('focus', function (evt) {
1393 self.trigger('focus', evt);
1394 });
1395
1396 this.$selection.on('blur', function (evt) {
1397 self._handleBlur(evt);
1398 });
1399
1400 this.$selection.on('keydown', function (evt) {
1401 self.trigger('keypress', evt);
1402
1403 if (evt.which === KEYS.SPACE) {
1404 evt.preventDefault();
1405 }
1406 });
1407
1408 container.on('results:focus', function (params) {
1409 self.$selection.attr('aria-activedescendant', params.data._resultId);
1410 });
1411
1412 container.on('selection:update', function (params) {
1413 self.update(params.data);
1414 });
1415
1416 container.on('open', function () {
1417 // When the dropdown is open, aria-expanded="true"
1418 self.$selection.attr('aria-expanded', 'true');
1419 self.$selection.attr('aria-owns', resultsId);
1420
1421 self._attachCloseHandler(container);
1422 });
1423
1424 container.on('close', function () {
1425 // When the dropdown is closed, aria-expanded="false"
1426 self.$selection.attr('aria-expanded', 'false');
1427 self.$selection.removeAttr('aria-activedescendant');
1428 self.$selection.removeAttr('aria-owns');
1429
1430 // This needs to be delayed as the active element is the body when the
1431 // key is pressed.
1432 window.setTimeout(function () {
1433 self.$selection.trigger( 'focus' );
1434 }, 1);
1435
1436 self._detachCloseHandler(container);
1437 });
1438
1439 container.on('enable', function () {
1440 self.$selection.attr('tabindex', self._tabindex);
1441 });
1442
1443 container.on('disable', function () {
1444 self.$selection.attr('tabindex', '-1');
1445 });
1446 };
1447
1448 BaseSelection.prototype._handleBlur = function (evt) {
1449 var self = this;
1450
1451 // This needs to be delayed as the active element is the body when the tab
1452 // key is pressed, possibly along with others.
1453 window.setTimeout(function () {
1454 // Don't trigger `blur` if the focus is still in the selection
1455 if (
1456 (document.activeElement == self.$selection[0]) ||
1457 ($.contains(self.$selection[0], document.activeElement))
1458 ) {
1459 return;
1460 }
1461
1462 self.trigger('blur', evt);
1463 }, 1);
1464 };
1465
1466 BaseSelection.prototype._attachCloseHandler = function (container) {
1467 var self = this;
1468
1469 $(document.body).on('mousedown.select2.' + container.id, function (e) {
1470 var $target = $(e.target);
1471
1472 var $select = $target.closest('.select2');
1473
1474 var $all = $('.select2.select2-container--open');
1475
1476 $all.each(function () {
1477 var $this = $(this);
1478
1479 if (this == $select[0]) {
1480 return;
1481 }
1482
1483 var $element = $this.data('element');
1484 $element.select2('close');
1485
1486 // Remove any focus when dropdown is closed by clicking outside the select area.
1487 // Timeout of 1 required for close to finish wrapping up.
1488 setTimeout(function(){
1489 $this.find('*:focus').trigger( 'blur' );
1490 $target.trigger( 'focus' );
1491 }, 1);
1492 });
1493 });
1494 };
1495
1496 BaseSelection.prototype._detachCloseHandler = function (container) {
1497 $(document.body).off('mousedown.select2.' + container.id);
1498 };
1499
1500 BaseSelection.prototype.position = function ($selection, $container) {
1501 var $selectionContainer = $container.find('.selection');
1502 $selectionContainer.append($selection);
1503 };
1504
1505 BaseSelection.prototype.destroy = function () {
1506 this._detachCloseHandler(this.container);
1507 };
1508
1509 BaseSelection.prototype.update = function (data) {
1510 throw new Error('The `update` method must be defined in child classes.');
1511 };
1512
1513 return BaseSelection;
1514 });
1515
1516 S2.define('select2/selection/single',[
1517 'jquery',
1518 './base',
1519 '../utils',
1520 '../keys'
1521 ], function ($, BaseSelection, Utils, KEYS) {
1522 function SingleSelection () {
1523 SingleSelection.__super__.constructor.apply(this, arguments);
1524 }
1525
1526 Utils.Extend(SingleSelection, BaseSelection);
1527
1528 SingleSelection.prototype.render = function () {
1529 var $selection = SingleSelection.__super__.render.call(this);
1530
1531 $selection.addClass('select2-selection--single');
1532
1533 $selection.html(
1534 '<span class="select2-selection__rendered"></span>' +
1535 '<span class="select2-selection__arrow" role="presentation">' +
1536 '<b role="presentation"></b>' +
1537 '</span>'
1538 );
1539
1540 return $selection;
1541 };
1542
1543 SingleSelection.prototype.bind = function (container, $container) {
1544 var self = this;
1545
1546 SingleSelection.__super__.bind.apply(this, arguments);
1547
1548 var id = container.id + '-container';
1549
1550 this.$selection.find('.select2-selection__rendered')
1551 .attr('id', id)
1552 .attr('role', 'textbox')
1553 .attr('aria-readonly', 'true');
1554
1555 var label = this.options.get( 'label' );
1556
1557 if ( typeof( label ) === 'string' ) {
1558 this.$selection.attr( 'aria-label', label );
1559 } else {
1560 this.$selection.attr( 'aria-labelledby', id );
1561 }
1562
1563 // This makes single non-search selects work in screen readers. If it causes problems elsewhere, remove.
1564 this.$selection.attr('role', 'combobox');
1565
1566 this.$selection.on('mousedown', function (evt) {
1567 // Only respond to left clicks
1568 if (evt.which !== 1) {
1569 return;
1570 }
1571
1572 self.trigger('toggle', {
1573 originalEvent: evt
1574 });
1575 });
1576
1577 this.$selection.on('focus', function (evt) {
1578 // User focuses on the container
1579 });
1580
1581 this.$selection.on('keydown', function (evt) {
1582 // If user starts typing an alphanumeric key on the keyboard, open if not opened.
1583 if (!container.isOpen() && evt.which >= 48 && evt.which <= 90) {
1584 container.open();
1585 }
1586 });
1587
1588 this.$selection.on('blur', function (evt) {
1589 // User exits the container
1590 });
1591
1592 container.on('focus', function (evt) {
1593 if (!container.isOpen()) {
1594 self.$selection.trigger( 'focus' );
1595 }
1596 });
1597
1598 container.on('selection:update', function (params) {
1599 self.update(params.data);
1600 });
1601 };
1602
1603 SingleSelection.prototype.clear = function () {
1604 this.$selection.find('.select2-selection__rendered').empty();
1605 };
1606
1607 SingleSelection.prototype.display = function (data, container) {
1608 var template = this.options.get('templateSelection');
1609 var escapeMarkup = this.options.get('escapeMarkup');
1610
1611 return escapeMarkup(template(data, container));
1612 };
1613
1614 SingleSelection.prototype.selectionContainer = function () {
1615 return $('<span></span>');
1616 };
1617
1618 SingleSelection.prototype.update = function (data) {
1619 if (data.length === 0) {
1620 this.clear();
1621 return;
1622 }
1623
1624 var selection = data[0];
1625
1626 var $rendered = this.$selection.find('.select2-selection__rendered');
1627 var formatted = Utils.entityDecode(this.display(selection, $rendered));
1628
1629 $rendered.empty().text(formatted);
1630 $rendered.prop('title', selection.title || selection.text);
1631 };
1632
1633 return SingleSelection;
1634 });
1635
1636 S2.define('select2/selection/multiple',[
1637 'jquery',
1638 './base',
1639 '../utils'
1640 ], function ($, BaseSelection, Utils) {
1641 function MultipleSelection ($element, options) {
1642 MultipleSelection.__super__.constructor.apply(this, arguments);
1643 }
1644
1645 Utils.Extend(MultipleSelection, BaseSelection);
1646
1647 MultipleSelection.prototype.render = function () {
1648 var $selection = MultipleSelection.__super__.render.call(this);
1649
1650 $selection.addClass('select2-selection--multiple');
1651
1652 $selection.html(
1653 '<ul class="select2-selection__rendered" aria-live="polite" aria-relevant="additions removals" aria-atomic="true"></ul>'
1654 );
1655
1656 return $selection;
1657 };
1658
1659 MultipleSelection.prototype.bind = function (container, $container) {
1660 var self = this;
1661
1662 MultipleSelection.__super__.bind.apply(this, arguments);
1663
1664 this.$selection.on('click', function (evt) {
1665 self.trigger('toggle', {
1666 originalEvent: evt
1667 });
1668 });
1669
1670 this.$selection.on(
1671 'click',
1672 '.select2-selection__choice__remove',
1673 function (evt) {
1674 // Ignore the event if it is disabled
1675 if (self.options.get('disabled')) {
1676 return;
1677 }
1678
1679 var $remove = $(this);
1680 var $selection = $remove.parent();
1681
1682 var data = $selection.data('data');
1683
1684 self.trigger('unselect', {
1685 originalEvent: evt,
1686 data: data
1687 });
1688 }
1689 );
1690
1691 this.$selection.on('keydown', function (evt) {
1692 // If user starts typing an alphanumeric key on the keyboard, open if not opened.
1693 if (!container.isOpen() && evt.which >= 48 && evt.which <= 90) {
1694 container.open();
1695 }
1696 });
1697
1698 // Focus on the search field when the container is focused instead of the main container.
1699 container.on( 'focus', function(){
1700 self.focusOnSearch();
1701 });
1702 };
1703
1704 MultipleSelection.prototype.clear = function () {
1705 this.$selection.find('.select2-selection__rendered').empty();
1706 };
1707
1708 MultipleSelection.prototype.display = function (data, container) {
1709 var template = this.options.get('templateSelection');
1710 var escapeMarkup = this.options.get('escapeMarkup');
1711
1712 return escapeMarkup(template(data, container));
1713 };
1714
1715 MultipleSelection.prototype.selectionContainer = function () {
1716 var $container = $(
1717 '<li class="select2-selection__choice">' +
1718 '<span class="select2-selection__choice__remove" role="presentation" aria-hidden="true">' +
1719 '&times;' +
1720 '</span>' +
1721 '</li>'
1722 );
1723
1724 return $container;
1725 };
1726
1727 /**
1728 * Focus on the search field instead of the main multiselect container.
1729 */
1730 MultipleSelection.prototype.focusOnSearch = function() {
1731 var self = this;
1732
1733 if ('undefined' !== typeof self.$search) {
1734 // Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
1735 setTimeout(function(){
1736 // Prevent the dropdown opening again when focused from this.
1737 // This gets reset automatically when focus is triggered.
1738 self._keyUpPrevented = true;
1739
1740 self.$search.trigger( 'focus' );
1741 }, 1);
1742 }
1743 }
1744
1745 MultipleSelection.prototype.update = function (data) {
1746 this.clear();
1747
1748 if (data.length === 0) {
1749 return;
1750 }
1751
1752 var $selections = [];
1753
1754 for (var d = 0; d < data.length; d++) {
1755 var selection = data[d];
1756
1757 var $selection = this.selectionContainer();
1758 var removeItemTag = $selection.html();
1759 var formatted = this.display(selection, $selection);
1760 if ('string' === typeof formatted) {
1761 formatted = Utils.entityDecode(formatted.trim());
1762 }
1763
1764 $selection.text(formatted);
1765 $selection.prepend(removeItemTag);
1766 $selection.prop('title', selection.title || selection.text);
1767
1768 $selection.data('data', selection);
1769
1770 $selections.push($selection);
1771 }
1772
1773 var $rendered = this.$selection.find('.select2-selection__rendered');
1774
1775 Utils.appendMany($rendered, $selections);
1776 };
1777
1778 return MultipleSelection;
1779 });
1780
1781 S2.define('select2/selection/placeholder',[
1782 '../utils'
1783 ], function (Utils) {
1784 function Placeholder (decorated, $element, options) {
1785 this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
1786
1787 decorated.call(this, $element, options);
1788 }
1789
1790 Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {
1791 if (typeof placeholder === 'string') {
1792 placeholder = {
1793 id: '',
1794 text: placeholder
1795 };
1796 }
1797
1798 return placeholder;
1799 };
1800
1801 Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {
1802 var $placeholder = this.selectionContainer();
1803
1804 $placeholder.text(Utils.entityDecode(this.display(placeholder)));
1805 $placeholder.addClass('select2-selection__placeholder')
1806 .removeClass('select2-selection__choice');
1807
1808 return $placeholder;
1809 };
1810
1811 Placeholder.prototype.update = function (decorated, data) {
1812 var singlePlaceholder = (
1813 data.length == 1 && data[0].id != this.placeholder.id
1814 );
1815 var multipleSelections = data.length > 1;
1816
1817 if (multipleSelections || singlePlaceholder) {
1818 return decorated.call(this, data);
1819 }
1820
1821 this.clear();
1822
1823 var $placeholder = this.createPlaceholder(this.placeholder);
1824
1825 this.$selection.find('.select2-selection__rendered').append($placeholder);
1826 };
1827
1828 return Placeholder;
1829 });
1830
1831 S2.define('select2/selection/allowClear',[
1832 'jquery',
1833 '../keys'
1834 ], function ($, KEYS) {
1835 function AllowClear () { }
1836
1837 AllowClear.prototype.bind = function (decorated, container, $container) {
1838 var self = this;
1839
1840 decorated.call(this, container, $container);
1841
1842 if (this.placeholder == null) {
1843 if (this.options.get('debug') && window.console && console.error) {
1844 console.error(
1845 'Select2: The `allowClear` option should be used in combination ' +
1846 'with the `placeholder` option.'
1847 );
1848 }
1849 }
1850
1851 this.$selection.on('mousedown', '.select2-selection__clear',
1852 function (evt) {
1853 self._handleClear(evt);
1854 });
1855
1856 container.on('keypress', function (evt) {
1857 self._handleKeyboardClear(evt, container);
1858 });
1859 };
1860
1861 AllowClear.prototype._handleClear = function (_, evt) {
1862 // Ignore the event if it is disabled
1863 if (this.options.get('disabled')) {
1864 return;
1865 }
1866
1867 var $clear = this.$selection.find('.select2-selection__clear');
1868
1869 // Ignore the event if nothing has been selected
1870 if ($clear.length === 0) {
1871 return;
1872 }
1873
1874 evt.stopPropagation();
1875
1876 var data = $clear.data('data');
1877
1878 for (var d = 0; d < data.length; d++) {
1879 var unselectData = {
1880 data: data[d]
1881 };
1882
1883 // Trigger the `unselect` event, so people can prevent it from being
1884 // cleared.
1885 this.trigger('unselect', unselectData);
1886
1887 // If the event was prevented, don't clear it out.
1888 if (unselectData.prevented) {
1889 return;
1890 }
1891 }
1892
1893 this.$element.val(this.placeholder.id).trigger('change');
1894
1895 this.trigger('toggle', {});
1896 };
1897
1898 AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {
1899 if (container.isOpen()) {
1900 return;
1901 }
1902
1903 if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {
1904 this._handleClear(evt);
1905 }
1906 };
1907
1908 AllowClear.prototype.update = function (decorated, data) {
1909 decorated.call(this, data);
1910
1911 if (this.$selection.find('.select2-selection__placeholder').length > 0 ||
1912 data.length === 0) {
1913 return;
1914 }
1915
1916 var $remove = $(
1917 '<span class="select2-selection__clear">' +
1918 '&times;' +
1919 '</span>'
1920 );
1921 $remove.data('data', data);
1922
1923 this.$selection.find('.select2-selection__rendered').prepend($remove);
1924 };
1925
1926 return AllowClear;
1927 });
1928
1929 S2.define('select2/selection/search',[
1930 'jquery',
1931 '../utils',
1932 '../keys'
1933 ], function ($, Utils, KEYS) {
1934 function Search (decorated, $element, options) {
1935 decorated.call(this, $element, options);
1936 }
1937
1938 Search.prototype.render = function (decorated) {
1939 var $search = $(
1940 '<li class="select2-search select2-search--inline">' +
1941 '<input class="select2-search__field" type="text" tabindex="-1"' +
1942 ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
1943 ' spellcheck="false" role="textbox" aria-autocomplete="list" />' +
1944 '</li>'
1945 );
1946
1947 this.$searchContainer = $search;
1948 this.$search = $search.find('input');
1949
1950 var $rendered = decorated.call(this);
1951
1952 this._transferTabIndex();
1953
1954 return $rendered;
1955 };
1956
1957 Search.prototype.bind = function (decorated, container, $container) {
1958 var self = this;
1959 var resultsId = container.id + '-results';
1960
1961 decorated.call(this, container, $container);
1962
1963 container.on('open', function () {
1964 self.$search.attr('aria-owns', resultsId);
1965 self.$search.trigger('focus');
1966 });
1967
1968 container.on('close', function () {
1969 self.$search.val('');
1970 self.$search.removeAttr('aria-activedescendant');
1971 self.$search.removeAttr('aria-owns');
1972 self.$search.trigger('focus');
1973 });
1974
1975 container.on('enable', function () {
1976 self.$search.prop('disabled', false);
1977
1978 self._transferTabIndex();
1979 });
1980
1981 container.on('disable', function () {
1982 self.$search.prop('disabled', true);
1983 });
1984
1985 container.on('focus', function (evt) {
1986 self.$search.trigger('focus');
1987 });
1988
1989 container.on('results:focus', function (params) {
1990 self.$search.attr('aria-activedescendant', params.data._resultId);
1991 });
1992
1993 this.$selection.on('focusin', '.select2-search--inline', function (evt) {
1994 self.trigger('focus', evt);
1995 });
1996
1997 this.$selection.on('focusout', '.select2-search--inline', function (evt) {
1998 self._handleBlur(evt);
1999 });
2000
2001 this.$selection.on('keydown', '.select2-search--inline', function (evt) {
2002 evt.stopPropagation();
2003
2004 self.trigger('keypress', evt);
2005
2006 self._keyUpPrevented = evt.isDefaultPrevented();
2007
2008 var key = evt.which;
2009
2010 if (key === KEYS.BACKSPACE && self.$search.val() === '') {
2011 var $previousChoice = self.$searchContainer
2012 .prev('.select2-selection__choice');
2013
2014 if ($previousChoice.length > 0) {
2015 var item = $previousChoice.data('data');
2016
2017 self.searchRemoveChoice(item);
2018
2019 evt.preventDefault();
2020 }
2021 } else if (evt.which === KEYS.ENTER) {
2022 container.open();
2023 evt.preventDefault();
2024 }
2025 });
2026
2027 // Try to detect the IE version should the `documentMode` property that
2028 // is stored on the document. This is only implemented in IE and is
2029 // slightly cleaner than doing a user agent check.
2030 // This property is not available in Edge, but Edge also doesn't have
2031 // this bug.
2032 var msie = document.documentMode;
2033 var disableInputEvents = msie && msie <= 11;
2034
2035 // Workaround for browsers which do not support the `input` event
2036 // This will prevent double-triggering of events for browsers which support
2037 // both the `keyup` and `input` events.
2038 this.$selection.on(
2039 'input.searchcheck',
2040 '.select2-search--inline',
2041 function (evt) {
2042 // IE will trigger the `input` event when a placeholder is used on a
2043 // search box. To get around this issue, we are forced to ignore all
2044 // `input` events in IE and keep using `keyup`.
2045 if (disableInputEvents) {
2046 self.$selection.off('input.search input.searchcheck');
2047 return;
2048 }
2049
2050 // Unbind the duplicated `keyup` event
2051 self.$selection.off('keyup.search');
2052 }
2053 );
2054
2055 this.$selection.on(
2056 'keyup.search input.search',
2057 '.select2-search--inline',
2058 function (evt) {
2059 // IE will trigger the `input` event when a placeholder is used on a
2060 // search box. To get around this issue, we are forced to ignore all
2061 // `input` events in IE and keep using `keyup`.
2062 if (disableInputEvents && evt.type === 'input') {
2063 self.$selection.off('input.search input.searchcheck');
2064 return;
2065 }
2066
2067 var key = evt.which;
2068
2069 // We can freely ignore events from modifier keys
2070 if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {
2071 return;
2072 }
2073
2074 // Tabbing will be handled during the `keydown` phase
2075 if (key == KEYS.TAB) {
2076 return;
2077 }
2078
2079 self.handleSearch(evt);
2080 }
2081 );
2082 };
2083
2084 /**
2085 * This method will transfer the tabindex attribute from the rendered
2086 * selection to the search box. This allows for the search box to be used as
2087 * the primary focus instead of the selection container.
2088 *
2089 * @private
2090 */
2091 Search.prototype._transferTabIndex = function (decorated) {
2092 this.$search.attr('tabindex', this.$selection.attr('tabindex'));
2093 this.$selection.attr('tabindex', '-1');
2094 };
2095
2096 Search.prototype.createPlaceholder = function (decorated, placeholder) {
2097 this.$search.attr('placeholder', placeholder.text);
2098 };
2099
2100 Search.prototype.update = function (decorated, data) {
2101 var searchHadFocus = this.$search[0] == document.activeElement;
2102
2103 this.$search.attr('placeholder', '');
2104
2105 decorated.call(this, data);
2106
2107 this.$selection.find('.select2-selection__rendered')
2108 .append(this.$searchContainer);
2109
2110 this.resizeSearch();
2111 if (searchHadFocus) {
2112 this.$search.trigger( 'focus' );
2113 }
2114 };
2115
2116 Search.prototype.handleSearch = function () {
2117 this.resizeSearch();
2118
2119 if (!this._keyUpPrevented) {
2120 var input = this.$search.val();
2121
2122 this.trigger('query', {
2123 term: input
2124 });
2125 }
2126
2127 this._keyUpPrevented = false;
2128 };
2129
2130 Search.prototype.searchRemoveChoice = function (decorated, item) {
2131 this.trigger('unselect', {
2132 data: item
2133 });
2134
2135 this.$search.val(item.text);
2136 this.handleSearch();
2137 };
2138
2139 Search.prototype.resizeSearch = function () {
2140 this.$search.css('width', '25px');
2141
2142 var width = '';
2143
2144 if (this.$search.attr('placeholder') !== '') {
2145 width = this.$selection.find('.select2-selection__rendered').innerWidth();
2146 } else {
2147 var minimumWidth = this.$search.val().length + 1;
2148
2149 width = (minimumWidth * 0.75) + 'em';
2150 }
2151
2152 this.$search.css('width', width);
2153 };
2154
2155 return Search;
2156 });
2157
2158 S2.define('select2/selection/eventRelay',[
2159 'jquery'
2160 ], function ($) {
2161 function EventRelay () { }
2162
2163 EventRelay.prototype.bind = function (decorated, container, $container) {
2164 var self = this;
2165 var relayEvents = [
2166 'open', 'opening',
2167 'close', 'closing',
2168 'select', 'selecting',
2169 'unselect', 'unselecting'
2170 ];
2171
2172 var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];
2173
2174 decorated.call(this, container, $container);
2175
2176 container.on('*', function (name, params) {
2177 // Ignore events that should not be relayed
2178 if ($.inArray(name, relayEvents) === -1) {
2179 return;
2180 }
2181
2182 // The parameters should always be an object
2183 params = params || {};
2184
2185 // Generate the jQuery event for the Select2 event
2186 var evt = $.Event('select2:' + name, {
2187 params: params
2188 });
2189
2190 self.$element.trigger(evt);
2191
2192 // Only handle preventable events if it was one
2193 if ($.inArray(name, preventableEvents) === -1) {
2194 return;
2195 }
2196
2197 params.prevented = evt.isDefaultPrevented();
2198 });
2199 };
2200
2201 return EventRelay;
2202 });
2203
2204 S2.define('select2/translation',[
2205 'jquery',
2206 'require'
2207 ], function ($, require) {
2208 function Translation (dict) {
2209 this.dict = dict || {};
2210 }
2211
2212 Translation.prototype.all = function () {
2213 return this.dict;
2214 };
2215
2216 Translation.prototype.get = function (key) {
2217 return this.dict[key];
2218 };
2219
2220 Translation.prototype.extend = function (translation) {
2221 this.dict = $.extend({}, translation.all(), this.dict);
2222 };
2223
2224 // Static functions
2225
2226 Translation._cache = {};
2227
2228 Translation.loadPath = function (path) {
2229 if (!(path in Translation._cache)) {
2230 var translations = require(path);
2231
2232 Translation._cache[path] = translations;
2233 }
2234
2235 return new Translation(Translation._cache[path]);
2236 };
2237
2238 return Translation;
2239 });
2240
2241 S2.define('select2/diacritics',[
2242
2243 ], function () {
2244 var diacritics = {
2245 '\u24B6': 'A',
2246 '\uFF21': 'A',
2247 '\u00C0': 'A',
2248 '\u00C1': 'A',
2249 '\u00C2': 'A',
2250 '\u1EA6': 'A',
2251 '\u1EA4': 'A',
2252 '\u1EAA': 'A',
2253 '\u1EA8': 'A',
2254 '\u00C3': 'A',
2255 '\u0100': 'A',
2256 '\u0102': 'A',
2257 '\u1EB0': 'A',
2258 '\u1EAE': 'A',
2259 '\u1EB4': 'A',
2260 '\u1EB2': 'A',
2261 '\u0226': 'A',
2262 '\u01E0': 'A',
2263 '\u00C4': 'A',
2264 '\u01DE': 'A',
2265 '\u1EA2': 'A',
2266 '\u00C5': 'A',
2267 '\u01FA': 'A',
2268 '\u01CD': 'A',
2269 '\u0200': 'A',
2270 '\u0202': 'A',
2271 '\u1EA0': 'A',
2272 '\u1EAC': 'A',
2273 '\u1EB6': 'A',
2274 '\u1E00': 'A',
2275 '\u0104': 'A',
2276 '\u023A': 'A',
2277 '\u2C6F': 'A',
2278 '\uA732': 'AA',
2279 '\u00C6': 'AE',
2280 '\u01FC': 'AE',
2281 '\u01E2': 'AE',
2282 '\uA734': 'AO',
2283 '\uA736': 'AU',
2284 '\uA738': 'AV',
2285 '\uA73A': 'AV',
2286 '\uA73C': 'AY',
2287 '\u24B7': 'B',
2288 '\uFF22': 'B',
2289 '\u1E02': 'B',
2290 '\u1E04': 'B',
2291 '\u1E06': 'B',
2292 '\u0243': 'B',
2293 '\u0182': 'B',
2294 '\u0181': 'B',
2295 '\u24B8': 'C',
2296 '\uFF23': 'C',
2297 '\u0106': 'C',
2298 '\u0108': 'C',
2299 '\u010A': 'C',
2300 '\u010C': 'C',
2301 '\u00C7': 'C',
2302 '\u1E08': 'C',
2303 '\u0187': 'C',
2304 '\u023B': 'C',
2305 '\uA73E': 'C',
2306 '\u24B9': 'D',
2307 '\uFF24': 'D',
2308 '\u1E0A': 'D',
2309 '\u010E': 'D',
2310 '\u1E0C': 'D',
2311 '\u1E10': 'D',
2312 '\u1E12': 'D',
2313 '\u1E0E': 'D',
2314 '\u0110': 'D',
2315 '\u018B': 'D',
2316 '\u018A': 'D',
2317 '\u0189': 'D',
2318 '\uA779': 'D',
2319 '\u01F1': 'DZ',
2320 '\u01C4': 'DZ',
2321 '\u01F2': 'Dz',
2322 '\u01C5': 'Dz',
2323 '\u24BA': 'E',
2324 '\uFF25': 'E',
2325 '\u00C8': 'E',
2326 '\u00C9': 'E',
2327 '\u00CA': 'E',
2328 '\u1EC0': 'E',
2329 '\u1EBE': 'E',
2330 '\u1EC4': 'E',
2331 '\u1EC2': 'E',
2332 '\u1EBC': 'E',
2333 '\u0112': 'E',
2334 '\u1E14': 'E',
2335 '\u1E16': 'E',
2336 '\u0114': 'E',
2337 '\u0116': 'E',
2338 '\u00CB': 'E',
2339 '\u1EBA': 'E',
2340 '\u011A': 'E',
2341 '\u0204': 'E',
2342 '\u0206': 'E',
2343 '\u1EB8': 'E',
2344 '\u1EC6': 'E',
2345 '\u0228': 'E',
2346 '\u1E1C': 'E',
2347 '\u0118': 'E',
2348 '\u1E18': 'E',
2349 '\u1E1A': 'E',
2350 '\u0190': 'E',
2351 '\u018E': 'E',
2352 '\u24BB': 'F',
2353 '\uFF26': 'F',
2354 '\u1E1E': 'F',
2355 '\u0191': 'F',
2356 '\uA77B': 'F',
2357 '\u24BC': 'G',
2358 '\uFF27': 'G',
2359 '\u01F4': 'G',
2360 '\u011C': 'G',
2361 '\u1E20': 'G',
2362 '\u011E': 'G',
2363 '\u0120': 'G',
2364 '\u01E6': 'G',
2365 '\u0122': 'G',
2366 '\u01E4': 'G',
2367 '\u0193': 'G',
2368 '\uA7A0': 'G',
2369 '\uA77D': 'G',
2370 '\uA77E': 'G',
2371 '\u24BD': 'H',
2372 '\uFF28': 'H',
2373 '\u0124': 'H',
2374 '\u1E22': 'H',
2375 '\u1E26': 'H',
2376 '\u021E': 'H',
2377 '\u1E24': 'H',
2378 '\u1E28': 'H',
2379 '\u1E2A': 'H',
2380 '\u0126': 'H',
2381 '\u2C67': 'H',
2382 '\u2C75': 'H',
2383 '\uA78D': 'H',
2384 '\u24BE': 'I',
2385 '\uFF29': 'I',
2386 '\u00CC': 'I',
2387 '\u00CD': 'I',
2388 '\u00CE': 'I',
2389 '\u0128': 'I',
2390 '\u012A': 'I',
2391 '\u012C': 'I',
2392 '\u0130': 'I',
2393 '\u00CF': 'I',
2394 '\u1E2E': 'I',
2395 '\u1EC8': 'I',
2396 '\u01CF': 'I',
2397 '\u0208': 'I',
2398 '\u020A': 'I',
2399 '\u1ECA': 'I',
2400 '\u012E': 'I',
2401 '\u1E2C': 'I',
2402 '\u0197': 'I',
2403 '\u24BF': 'J',
2404 '\uFF2A': 'J',
2405 '\u0134': 'J',
2406 '\u0248': 'J',
2407 '\u24C0': 'K',
2408 '\uFF2B': 'K',
2409 '\u1E30': 'K',
2410 '\u01E8': 'K',
2411 '\u1E32': 'K',
2412 '\u0136': 'K',
2413 '\u1E34': 'K',
2414 '\u0198': 'K',
2415 '\u2C69': 'K',
2416 '\uA740': 'K',
2417 '\uA742': 'K',
2418 '\uA744': 'K',
2419 '\uA7A2': 'K',
2420 '\u24C1': 'L',
2421 '\uFF2C': 'L',
2422 '\u013F': 'L',
2423 '\u0139': 'L',
2424 '\u013D': 'L',
2425 '\u1E36': 'L',
2426 '\u1E38': 'L',
2427 '\u013B': 'L',
2428 '\u1E3C': 'L',
2429 '\u1E3A': 'L',
2430 '\u0141': 'L',
2431 '\u023D': 'L',
2432 '\u2C62': 'L',
2433 '\u2C60': 'L',
2434 '\uA748': 'L',
2435 '\uA746': 'L',
2436 '\uA780': 'L',
2437 '\u01C7': 'LJ',
2438 '\u01C8': 'Lj',
2439 '\u24C2': 'M',
2440 '\uFF2D': 'M',
2441 '\u1E3E': 'M',
2442 '\u1E40': 'M',
2443 '\u1E42': 'M',
2444 '\u2C6E': 'M',
2445 '\u019C': 'M',
2446 '\u24C3': 'N',
2447 '\uFF2E': 'N',
2448 '\u01F8': 'N',
2449 '\u0143': 'N',
2450 '\u00D1': 'N',
2451 '\u1E44': 'N',
2452 '\u0147': 'N',
2453 '\u1E46': 'N',
2454 '\u0145': 'N',
2455 '\u1E4A': 'N',
2456 '\u1E48': 'N',
2457 '\u0220': 'N',
2458 '\u019D': 'N',
2459 '\uA790': 'N',
2460 '\uA7A4': 'N',
2461 '\u01CA': 'NJ',
2462 '\u01CB': 'Nj',
2463 '\u24C4': 'O',
2464 '\uFF2F': 'O',
2465 '\u00D2': 'O',
2466 '\u00D3': 'O',
2467 '\u00D4': 'O',
2468 '\u1ED2': 'O',
2469 '\u1ED0': 'O',
2470 '\u1ED6': 'O',
2471 '\u1ED4': 'O',
2472 '\u00D5': 'O',
2473 '\u1E4C': 'O',
2474 '\u022C': 'O',
2475 '\u1E4E': 'O',
2476 '\u014C': 'O',
2477 '\u1E50': 'O',
2478 '\u1E52': 'O',
2479 '\u014E': 'O',
2480 '\u022E': 'O',
2481 '\u0230': 'O',
2482 '\u00D6': 'O',
2483 '\u022A': 'O',
2484 '\u1ECE': 'O',
2485 '\u0150': 'O',
2486 '\u01D1': 'O',
2487 '\u020C': 'O',
2488 '\u020E': 'O',
2489 '\u01A0': 'O',
2490 '\u1EDC': 'O',
2491 '\u1EDA': 'O',
2492 '\u1EE0': 'O',
2493 '\u1EDE': 'O',
2494 '\u1EE2': 'O',
2495 '\u1ECC': 'O',
2496 '\u1ED8': 'O',
2497 '\u01EA': 'O',
2498 '\u01EC': 'O',
2499 '\u00D8': 'O',
2500 '\u01FE': 'O',
2501 '\u0186': 'O',
2502 '\u019F': 'O',
2503 '\uA74A': 'O',
2504 '\uA74C': 'O',
2505 '\u01A2': 'OI',
2506 '\uA74E': 'OO',
2507 '\u0222': 'OU',
2508 '\u24C5': 'P',
2509 '\uFF30': 'P',
2510 '\u1E54': 'P',
2511 '\u1E56': 'P',
2512 '\u01A4': 'P',
2513 '\u2C63': 'P',
2514 '\uA750': 'P',
2515 '\uA752': 'P',
2516 '\uA754': 'P',
2517 '\u24C6': 'Q',
2518 '\uFF31': 'Q',
2519 '\uA756': 'Q',
2520 '\uA758': 'Q',
2521 '\u024A': 'Q',
2522 '\u24C7': 'R',
2523 '\uFF32': 'R',
2524 '\u0154': 'R',
2525 '\u1E58': 'R',
2526 '\u0158': 'R',
2527 '\u0210': 'R',
2528 '\u0212': 'R',
2529 '\u1E5A': 'R',
2530 '\u1E5C': 'R',
2531 '\u0156': 'R',
2532 '\u1E5E': 'R',
2533 '\u024C': 'R',
2534 '\u2C64': 'R',
2535 '\uA75A': 'R',
2536 '\uA7A6': 'R',
2537 '\uA782': 'R',
2538 '\u24C8': 'S',
2539 '\uFF33': 'S',
2540 '\u1E9E': 'S',
2541 '\u015A': 'S',
2542 '\u1E64': 'S',
2543 '\u015C': 'S',
2544 '\u1E60': 'S',
2545 '\u0160': 'S',
2546 '\u1E66': 'S',
2547 '\u1E62': 'S',
2548 '\u1E68': 'S',
2549 '\u0218': 'S',
2550 '\u015E': 'S',
2551 '\u2C7E': 'S',
2552 '\uA7A8': 'S',
2553 '\uA784': 'S',
2554 '\u24C9': 'T',
2555 '\uFF34': 'T',
2556 '\u1E6A': 'T',
2557 '\u0164': 'T',
2558 '\u1E6C': 'T',
2559 '\u021A': 'T',
2560 '\u0162': 'T',
2561 '\u1E70': 'T',
2562 '\u1E6E': 'T',
2563 '\u0166': 'T',
2564 '\u01AC': 'T',
2565 '\u01AE': 'T',
2566 '\u023E': 'T',
2567 '\uA786': 'T',
2568 '\uA728': 'TZ',
2569 '\u24CA': 'U',
2570 '\uFF35': 'U',
2571 '\u00D9': 'U',
2572 '\u00DA': 'U',
2573 '\u00DB': 'U',
2574 '\u0168': 'U',
2575 '\u1E78': 'U',
2576 '\u016A': 'U',
2577 '\u1E7A': 'U',
2578 '\u016C': 'U',
2579 '\u00DC': 'U',
2580 '\u01DB': 'U',
2581 '\u01D7': 'U',
2582 '\u01D5': 'U',
2583 '\u01D9': 'U',
2584 '\u1EE6': 'U',
2585 '\u016E': 'U',
2586 '\u0170': 'U',
2587 '\u01D3': 'U',
2588 '\u0214': 'U',
2589 '\u0216': 'U',
2590 '\u01AF': 'U',
2591 '\u1EEA': 'U',
2592 '\u1EE8': 'U',
2593 '\u1EEE': 'U',
2594 '\u1EEC': 'U',
2595 '\u1EF0': 'U',
2596 '\u1EE4': 'U',
2597 '\u1E72': 'U',
2598 '\u0172': 'U',
2599 '\u1E76': 'U',
2600 '\u1E74': 'U',
2601 '\u0244': 'U',
2602 '\u24CB': 'V',
2603 '\uFF36': 'V',
2604 '\u1E7C': 'V',
2605 '\u1E7E': 'V',
2606 '\u01B2': 'V',
2607 '\uA75E': 'V',
2608 '\u0245': 'V',
2609 '\uA760': 'VY',
2610 '\u24CC': 'W',
2611 '\uFF37': 'W',
2612 '\u1E80': 'W',
2613 '\u1E82': 'W',
2614 '\u0174': 'W',
2615 '\u1E86': 'W',
2616 '\u1E84': 'W',
2617 '\u1E88': 'W',
2618 '\u2C72': 'W',
2619 '\u24CD': 'X',
2620 '\uFF38': 'X',
2621 '\u1E8A': 'X',
2622 '\u1E8C': 'X',
2623 '\u24CE': 'Y',
2624 '\uFF39': 'Y',
2625 '\u1EF2': 'Y',
2626 '\u00DD': 'Y',
2627 '\u0176': 'Y',
2628 '\u1EF8': 'Y',
2629 '\u0232': 'Y',
2630 '\u1E8E': 'Y',
2631 '\u0178': 'Y',
2632 '\u1EF6': 'Y',
2633 '\u1EF4': 'Y',
2634 '\u01B3': 'Y',
2635 '\u024E': 'Y',
2636 '\u1EFE': 'Y',
2637 '\u24CF': 'Z',
2638 '\uFF3A': 'Z',
2639 '\u0179': 'Z',
2640 '\u1E90': 'Z',
2641 '\u017B': 'Z',
2642 '\u017D': 'Z',
2643 '\u1E92': 'Z',
2644 '\u1E94': 'Z',
2645 '\u01B5': 'Z',
2646 '\u0224': 'Z',
2647 '\u2C7F': 'Z',
2648 '\u2C6B': 'Z',
2649 '\uA762': 'Z',
2650 '\u24D0': 'a',
2651 '\uFF41': 'a',
2652 '\u1E9A': 'a',
2653 '\u00E0': 'a',
2654 '\u00E1': 'a',
2655 '\u00E2': 'a',
2656 '\u1EA7': 'a',
2657 '\u1EA5': 'a',
2658 '\u1EAB': 'a',
2659 '\u1EA9': 'a',
2660 '\u00E3': 'a',
2661 '\u0101': 'a',
2662 '\u0103': 'a',
2663 '\u1EB1': 'a',
2664 '\u1EAF': 'a',
2665 '\u1EB5': 'a',
2666 '\u1EB3': 'a',
2667 '\u0227': 'a',
2668 '\u01E1': 'a',
2669 '\u00E4': 'a',
2670 '\u01DF': 'a',
2671 '\u1EA3': 'a',
2672 '\u00E5': 'a',
2673 '\u01FB': 'a',
2674 '\u01CE': 'a',
2675 '\u0201': 'a',
2676 '\u0203': 'a',
2677 '\u1EA1': 'a',
2678 '\u1EAD': 'a',
2679 '\u1EB7': 'a',
2680 '\u1E01': 'a',
2681 '\u0105': 'a',
2682 '\u2C65': 'a',
2683 '\u0250': 'a',
2684 '\uA733': 'aa',
2685 '\u00E6': 'ae',
2686 '\u01FD': 'ae',
2687 '\u01E3': 'ae',
2688 '\uA735': 'ao',
2689 '\uA737': 'au',
2690 '\uA739': 'av',
2691 '\uA73B': 'av',
2692 '\uA73D': 'ay',
2693 '\u24D1': 'b',
2694 '\uFF42': 'b',
2695 '\u1E03': 'b',
2696 '\u1E05': 'b',
2697 '\u1E07': 'b',
2698 '\u0180': 'b',
2699 '\u0183': 'b',
2700 '\u0253': 'b',
2701 '\u24D2': 'c',
2702 '\uFF43': 'c',
2703 '\u0107': 'c',
2704 '\u0109': 'c',
2705 '\u010B': 'c',
2706 '\u010D': 'c',
2707 '\u00E7': 'c',
2708 '\u1E09': 'c',
2709 '\u0188': 'c',
2710 '\u023C': 'c',
2711 '\uA73F': 'c',
2712 '\u2184': 'c',
2713 '\u24D3': 'd',
2714 '\uFF44': 'd',
2715 '\u1E0B': 'd',
2716 '\u010F': 'd',
2717 '\u1E0D': 'd',
2718 '\u1E11': 'd',
2719 '\u1E13': 'd',
2720 '\u1E0F': 'd',
2721 '\u0111': 'd',
2722 '\u018C': 'd',
2723 '\u0256': 'd',
2724 '\u0257': 'd',
2725 '\uA77A': 'd',
2726 '\u01F3': 'dz',
2727 '\u01C6': 'dz',
2728 '\u24D4': 'e',
2729 '\uFF45': 'e',
2730 '\u00E8': 'e',
2731 '\u00E9': 'e',
2732 '\u00EA': 'e',
2733 '\u1EC1': 'e',
2734 '\u1EBF': 'e',
2735 '\u1EC5': 'e',
2736 '\u1EC3': 'e',
2737 '\u1EBD': 'e',
2738 '\u0113': 'e',
2739 '\u1E15': 'e',
2740 '\u1E17': 'e',
2741 '\u0115': 'e',
2742 '\u0117': 'e',
2743 '\u00EB': 'e',
2744 '\u1EBB': 'e',
2745 '\u011B': 'e',
2746 '\u0205': 'e',
2747 '\u0207': 'e',
2748 '\u1EB9': 'e',
2749 '\u1EC7': 'e',
2750 '\u0229': 'e',
2751 '\u1E1D': 'e',
2752 '\u0119': 'e',
2753 '\u1E19': 'e',
2754 '\u1E1B': 'e',
2755 '\u0247': 'e',
2756 '\u025B': 'e',
2757 '\u01DD': 'e',
2758 '\u24D5': 'f',
2759 '\uFF46': 'f',
2760 '\u1E1F': 'f',
2761 '\u0192': 'f',
2762 '\uA77C': 'f',
2763 '\u24D6': 'g',
2764 '\uFF47': 'g',
2765 '\u01F5': 'g',
2766 '\u011D': 'g',
2767 '\u1E21': 'g',
2768 '\u011F': 'g',
2769 '\u0121': 'g',
2770 '\u01E7': 'g',
2771 '\u0123': 'g',
2772 '\u01E5': 'g',
2773 '\u0260': 'g',
2774 '\uA7A1': 'g',
2775 '\u1D79': 'g',
2776 '\uA77F': 'g',
2777 '\u24D7': 'h',
2778 '\uFF48': 'h',
2779 '\u0125': 'h',
2780 '\u1E23': 'h',
2781 '\u1E27': 'h',
2782 '\u021F': 'h',
2783 '\u1E25': 'h',
2784 '\u1E29': 'h',
2785 '\u1E2B': 'h',
2786 '\u1E96': 'h',
2787 '\u0127': 'h',
2788 '\u2C68': 'h',
2789 '\u2C76': 'h',
2790 '\u0265': 'h',
2791 '\u0195': 'hv',
2792 '\u24D8': 'i',
2793 '\uFF49': 'i',
2794 '\u00EC': 'i',
2795 '\u00ED': 'i',
2796 '\u00EE': 'i',
2797 '\u0129': 'i',
2798 '\u012B': 'i',
2799 '\u012D': 'i',
2800 '\u00EF': 'i',
2801 '\u1E2F': 'i',
2802 '\u1EC9': 'i',
2803 '\u01D0': 'i',
2804 '\u0209': 'i',
2805 '\u020B': 'i',
2806 '\u1ECB': 'i',
2807 '\u012F': 'i',
2808 '\u1E2D': 'i',
2809 '\u0268': 'i',
2810 '\u0131': 'i',
2811 '\u24D9': 'j',
2812 '\uFF4A': 'j',
2813 '\u0135': 'j',
2814 '\u01F0': 'j',
2815 '\u0249': 'j',
2816 '\u24DA': 'k',
2817 '\uFF4B': 'k',
2818 '\u1E31': 'k',
2819 '\u01E9': 'k',
2820 '\u1E33': 'k',
2821 '\u0137': 'k',
2822 '\u1E35': 'k',
2823 '\u0199': 'k',
2824 '\u2C6A': 'k',
2825 '\uA741': 'k',
2826 '\uA743': 'k',
2827 '\uA745': 'k',
2828 '\uA7A3': 'k',
2829 '\u24DB': 'l',
2830 '\uFF4C': 'l',
2831 '\u0140': 'l',
2832 '\u013A': 'l',
2833 '\u013E': 'l',
2834 '\u1E37': 'l',
2835 '\u1E39': 'l',
2836 '\u013C': 'l',
2837 '\u1E3D': 'l',
2838 '\u1E3B': 'l',
2839 '\u017F': 'l',
2840 '\u0142': 'l',
2841 '\u019A': 'l',
2842 '\u026B': 'l',
2843 '\u2C61': 'l',
2844 '\uA749': 'l',
2845 '\uA781': 'l',
2846 '\uA747': 'l',
2847 '\u01C9': 'lj',
2848 '\u24DC': 'm',
2849 '\uFF4D': 'm',
2850 '\u1E3F': 'm',
2851 '\u1E41': 'm',
2852 '\u1E43': 'm',
2853 '\u0271': 'm',
2854 '\u026F': 'm',
2855 '\u24DD': 'n',
2856 '\uFF4E': 'n',
2857 '\u01F9': 'n',
2858 '\u0144': 'n',
2859 '\u00F1': 'n',
2860 '\u1E45': 'n',
2861 '\u0148': 'n',
2862 '\u1E47': 'n',
2863 '\u0146': 'n',
2864 '\u1E4B': 'n',
2865 '\u1E49': 'n',
2866 '\u019E': 'n',
2867 '\u0272': 'n',
2868 '\u0149': 'n',
2869 '\uA791': 'n',
2870 '\uA7A5': 'n',
2871 '\u01CC': 'nj',
2872 '\u24DE': 'o',
2873 '\uFF4F': 'o',
2874 '\u00F2': 'o',
2875 '\u00F3': 'o',
2876 '\u00F4': 'o',
2877 '\u1ED3': 'o',
2878 '\u1ED1': 'o',
2879 '\u1ED7': 'o',
2880 '\u1ED5': 'o',
2881 '\u00F5': 'o',
2882 '\u1E4D': 'o',
2883 '\u022D': 'o',
2884 '\u1E4F': 'o',
2885 '\u014D': 'o',
2886 '\u1E51': 'o',
2887 '\u1E53': 'o',
2888 '\u014F': 'o',
2889 '\u022F': 'o',
2890 '\u0231': 'o',
2891 '\u00F6': 'o',
2892 '\u022B': 'o',
2893 '\u1ECF': 'o',
2894 '\u0151': 'o',
2895 '\u01D2': 'o',
2896 '\u020D': 'o',
2897 '\u020F': 'o',
2898 '\u01A1': 'o',
2899 '\u1EDD': 'o',
2900 '\u1EDB': 'o',
2901 '\u1EE1': 'o',
2902 '\u1EDF': 'o',
2903 '\u1EE3': 'o',
2904 '\u1ECD': 'o',
2905 '\u1ED9': 'o',
2906 '\u01EB': 'o',
2907 '\u01ED': 'o',
2908 '\u00F8': 'o',
2909 '\u01FF': 'o',
2910 '\u0254': 'o',
2911 '\uA74B': 'o',
2912 '\uA74D': 'o',
2913 '\u0275': 'o',
2914 '\u01A3': 'oi',
2915 '\u0223': 'ou',
2916 '\uA74F': 'oo',
2917 '\u24DF': 'p',
2918 '\uFF50': 'p',
2919 '\u1E55': 'p',
2920 '\u1E57': 'p',
2921 '\u01A5': 'p',
2922 '\u1D7D': 'p',
2923 '\uA751': 'p',
2924 '\uA753': 'p',
2925 '\uA755': 'p',
2926 '\u24E0': 'q',
2927 '\uFF51': 'q',
2928 '\u024B': 'q',
2929 '\uA757': 'q',
2930 '\uA759': 'q',
2931 '\u24E1': 'r',
2932 '\uFF52': 'r',
2933 '\u0155': 'r',
2934 '\u1E59': 'r',
2935 '\u0159': 'r',
2936 '\u0211': 'r',
2937 '\u0213': 'r',
2938 '\u1E5B': 'r',
2939 '\u1E5D': 'r',
2940 '\u0157': 'r',
2941 '\u1E5F': 'r',
2942 '\u024D': 'r',
2943 '\u027D': 'r',
2944 '\uA75B': 'r',
2945 '\uA7A7': 'r',
2946 '\uA783': 'r',
2947 '\u24E2': 's',
2948 '\uFF53': 's',
2949 '\u00DF': 's',
2950 '\u015B': 's',
2951 '\u1E65': 's',
2952 '\u015D': 's',
2953 '\u1E61': 's',
2954 '\u0161': 's',
2955 '\u1E67': 's',
2956 '\u1E63': 's',
2957 '\u1E69': 's',
2958 '\u0219': 's',
2959 '\u015F': 's',
2960 '\u023F': 's',
2961 '\uA7A9': 's',
2962 '\uA785': 's',
2963 '\u1E9B': 's',
2964 '\u24E3': 't',
2965 '\uFF54': 't',
2966 '\u1E6B': 't',
2967 '\u1E97': 't',
2968 '\u0165': 't',
2969 '\u1E6D': 't',
2970 '\u021B': 't',
2971 '\u0163': 't',
2972 '\u1E71': 't',
2973 '\u1E6F': 't',
2974 '\u0167': 't',
2975 '\u01AD': 't',
2976 '\u0288': 't',
2977 '\u2C66': 't',
2978 '\uA787': 't',
2979 '\uA729': 'tz',
2980 '\u24E4': 'u',
2981 '\uFF55': 'u',
2982 '\u00F9': 'u',
2983 '\u00FA': 'u',
2984 '\u00FB': 'u',
2985 '\u0169': 'u',
2986 '\u1E79': 'u',
2987 '\u016B': 'u',
2988 '\u1E7B': 'u',
2989 '\u016D': 'u',
2990 '\u00FC': 'u',
2991 '\u01DC': 'u',
2992 '\u01D8': 'u',
2993 '\u01D6': 'u',
2994 '\u01DA': 'u',
2995 '\u1EE7': 'u',
2996 '\u016F': 'u',
2997 '\u0171': 'u',
2998 '\u01D4': 'u',
2999 '\u0215': 'u',
3000 '\u0217': 'u',
3001 '\u01B0': 'u',
3002 '\u1EEB': 'u',
3003 '\u1EE9': 'u',
3004 '\u1EEF': 'u',
3005 '\u1EED': 'u',
3006 '\u1EF1': 'u',
3007 '\u1EE5': 'u',
3008 '\u1E73': 'u',
3009 '\u0173': 'u',
3010 '\u1E77': 'u',
3011 '\u1E75': 'u',
3012 '\u0289': 'u',
3013 '\u24E5': 'v',
3014 '\uFF56': 'v',
3015 '\u1E7D': 'v',
3016 '\u1E7F': 'v',
3017 '\u028B': 'v',
3018 '\uA75F': 'v',
3019 '\u028C': 'v',
3020 '\uA761': 'vy',
3021 '\u24E6': 'w',
3022 '\uFF57': 'w',
3023 '\u1E81': 'w',
3024 '\u1E83': 'w',
3025 '\u0175': 'w',
3026 '\u1E87': 'w',
3027 '\u1E85': 'w',
3028 '\u1E98': 'w',
3029 '\u1E89': 'w',
3030 '\u2C73': 'w',
3031 '\u24E7': 'x',
3032 '\uFF58': 'x',
3033 '\u1E8B': 'x',
3034 '\u1E8D': 'x',
3035 '\u24E8': 'y',
3036 '\uFF59': 'y',
3037 '\u1EF3': 'y',
3038 '\u00FD': 'y',
3039 '\u0177': 'y',
3040 '\u1EF9': 'y',
3041 '\u0233': 'y',
3042 '\u1E8F': 'y',
3043 '\u00FF': 'y',
3044 '\u1EF7': 'y',
3045 '\u1E99': 'y',
3046 '\u1EF5': 'y',
3047 '\u01B4': 'y',
3048 '\u024F': 'y',
3049 '\u1EFF': 'y',
3050 '\u24E9': 'z',
3051 '\uFF5A': 'z',
3052 '\u017A': 'z',
3053 '\u1E91': 'z',
3054 '\u017C': 'z',
3055 '\u017E': 'z',
3056 '\u1E93': 'z',
3057 '\u1E95': 'z',
3058 '\u01B6': 'z',
3059 '\u0225': 'z',
3060 '\u0240': 'z',
3061 '\u2C6C': 'z',
3062 '\uA763': 'z',
3063 '\u0386': '\u0391',
3064 '\u0388': '\u0395',
3065 '\u0389': '\u0397',
3066 '\u038A': '\u0399',
3067 '\u03AA': '\u0399',
3068 '\u038C': '\u039F',
3069 '\u038E': '\u03A5',
3070 '\u03AB': '\u03A5',
3071 '\u038F': '\u03A9',
3072 '\u03AC': '\u03B1',
3073 '\u03AD': '\u03B5',
3074 '\u03AE': '\u03B7',
3075 '\u03AF': '\u03B9',
3076 '\u03CA': '\u03B9',
3077 '\u0390': '\u03B9',
3078 '\u03CC': '\u03BF',
3079 '\u03CD': '\u03C5',
3080 '\u03CB': '\u03C5',
3081 '\u03B0': '\u03C5',
3082 '\u03C9': '\u03C9',
3083 '\u03C2': '\u03C3'
3084 };
3085
3086 return diacritics;
3087 });
3088
3089 S2.define('select2/data/base',[
3090 '../utils'
3091 ], function (Utils) {
3092 function BaseAdapter ($element, options) {
3093 BaseAdapter.__super__.constructor.call(this);
3094 }
3095
3096 Utils.Extend(BaseAdapter, Utils.Observable);
3097
3098 BaseAdapter.prototype.current = function (callback) {
3099 throw new Error('The `current` method must be defined in child classes.');
3100 };
3101
3102 BaseAdapter.prototype.query = function (params, callback) {
3103 throw new Error('The `query` method must be defined in child classes.');
3104 };
3105
3106 BaseAdapter.prototype.bind = function (container, $container) {
3107 // Can be implemented in subclasses
3108 };
3109
3110 BaseAdapter.prototype.destroy = function () {
3111 // Can be implemented in subclasses
3112 };
3113
3114 BaseAdapter.prototype.generateResultId = function (container, data) {
3115 var id = '';
3116
3117 if (container != null) {
3118 id += container.id
3119 } else {
3120 id += Utils.generateChars(4);
3121 }
3122
3123 id += '-result-';
3124 id += Utils.generateChars(4);
3125
3126 if (data.id != null) {
3127 id += '-' + data.id.toString();
3128 } else {
3129 id += '-' + Utils.generateChars(4);
3130 }
3131 return id;
3132 };
3133
3134 return BaseAdapter;
3135 });
3136
3137 S2.define('select2/data/select',[
3138 './base',
3139 '../utils',
3140 'jquery'
3141 ], function (BaseAdapter, Utils, $) {
3142 function SelectAdapter ($element, options) {
3143 this.$element = $element;
3144 this.options = options;
3145
3146 SelectAdapter.__super__.constructor.call(this);
3147 }
3148
3149 Utils.Extend(SelectAdapter, BaseAdapter);
3150
3151 SelectAdapter.prototype.current = function (callback) {
3152 var data = [];
3153 var self = this;
3154
3155 this.$element.find(':selected').each(function () {
3156 var $option = $(this);
3157
3158 var option = self.item($option);
3159
3160 data.push(option);
3161 });
3162
3163 callback(data);
3164 };
3165
3166 SelectAdapter.prototype.select = function (data) {
3167 var self = this;
3168
3169 data.selected = true;
3170
3171 // If data.element is a DOM node, use it instead
3172 if ($(data.element).is('option')) {
3173 data.element.selected = true;
3174
3175 this.$element.trigger('change');
3176
3177 return;
3178 }
3179
3180 if (this.$element.prop('multiple')) {
3181 this.current(function (currentData) {
3182 var val = [];
3183
3184 data = [data];
3185 data.push.apply(data, currentData);
3186
3187 for (var d = 0; d < data.length; d++) {
3188 var id = data[d].id;
3189
3190 if ($.inArray(id, val) === -1) {
3191 val.push(id);
3192 }
3193 }
3194
3195 self.$element.val(val);
3196 self.$element.trigger('change');
3197 });
3198 } else {
3199 var val = data.id;
3200
3201 this.$element.val(val);
3202 this.$element.trigger('change');
3203 }
3204 };
3205
3206 SelectAdapter.prototype.unselect = function (data) {
3207 var self = this;
3208
3209 if (!this.$element.prop('multiple')) {
3210 return;
3211 }
3212
3213 data.selected = false;
3214
3215 if ($(data.element).is('option')) {
3216 data.element.selected = false;
3217
3218 this.$element.trigger('change');
3219
3220 return;
3221 }
3222
3223 this.current(function (currentData) {
3224 var val = [];
3225
3226 for (var d = 0; d < currentData.length; d++) {
3227 var id = currentData[d].id;
3228
3229 if (id !== data.id && $.inArray(id, val) === -1) {
3230 val.push(id);
3231 }
3232 }
3233
3234 self.$element.val(val);
3235
3236 self.$element.trigger('change');
3237 });
3238 };
3239
3240 SelectAdapter.prototype.bind = function (container, $container) {
3241 var self = this;
3242
3243 this.container = container;
3244
3245 container.on('select', function (params) {
3246 self.select(params.data);
3247 });
3248
3249 container.on('unselect', function (params) {
3250 self.unselect(params.data);
3251 });
3252 };
3253
3254 SelectAdapter.prototype.destroy = function () {
3255 // Remove anything added to child elements
3256 this.$element.find('*').each(function () {
3257 // Remove any custom data set by Select2
3258 $.removeData(this, 'data');
3259 });
3260 };
3261
3262 SelectAdapter.prototype.query = function (params, callback) {
3263 var data = [];
3264 var self = this;
3265
3266 var $options = this.$element.children();
3267
3268 $options.each(function () {
3269 var $option = $(this);
3270
3271 if (!$option.is('option') && !$option.is('optgroup')) {
3272 return;
3273 }
3274
3275 var option = self.item($option);
3276
3277 var matches = self.matches(params, option);
3278
3279 if (matches !== null) {
3280 data.push(matches);
3281 }
3282 });
3283
3284 callback({
3285 results: data
3286 });
3287 };
3288
3289 SelectAdapter.prototype.addOptions = function ($options) {
3290 Utils.appendMany(this.$element, $options);
3291 };
3292
3293 SelectAdapter.prototype.option = function (data) {
3294 var option;
3295
3296 if (data.children) {
3297 option = document.createElement('optgroup');
3298 option.label = data.text;
3299 } else {
3300 option = document.createElement('option');
3301
3302 if (option.textContent !== undefined) {
3303 option.textContent = data.text;
3304 } else {
3305 option.innerText = data.text;
3306 }
3307 }
3308
3309 if (data.id !== undefined) {
3310 option.value = data.id;
3311 }
3312
3313 if (data.disabled) {
3314 option.disabled = true;
3315 }
3316
3317 if (data.selected) {
3318 option.selected = true;
3319 }
3320
3321 if (data.title) {
3322 option.title = data.title;
3323 }
3324
3325 var $option = $(option);
3326
3327 var normalizedData = this._normalizeItem(data);
3328 normalizedData.element = option;
3329
3330 // Override the option's data with the combined data
3331 $.data(option, 'data', normalizedData);
3332
3333 return $option;
3334 };
3335
3336 SelectAdapter.prototype.item = function ($option) {
3337 var data = {};
3338
3339 data = $.data($option[0], 'data');
3340
3341 if (data != null) {
3342 return data;
3343 }
3344
3345 if ($option.is('option')) {
3346 data = {
3347 id: $option.val(),
3348 text: $option.text(),
3349 disabled: $option.prop('disabled'),
3350 selected: $option.prop('selected'),
3351 title: $option.prop('title')
3352 };
3353 } else if ($option.is('optgroup')) {
3354 data = {
3355 text: $option.prop('label'),
3356 children: [],
3357 title: $option.prop('title')
3358 };
3359
3360 var $children = $option.children('option');
3361 var children = [];
3362
3363 for (var c = 0; c < $children.length; c++) {
3364 var $child = $($children[c]);
3365
3366 var child = this.item($child);
3367
3368 children.push(child);
3369 }
3370
3371 data.children = children;
3372 }
3373
3374 data = this._normalizeItem(data);
3375 data.element = $option[0];
3376
3377 $.data($option[0], 'data', data);
3378
3379 return data;
3380 };
3381
3382 SelectAdapter.prototype._normalizeItem = function (item) {
3383 if (!$.isPlainObject(item)) {
3384 item = {
3385 id: item,
3386 text: item
3387 };
3388 }
3389
3390 item = $.extend({}, {
3391 text: ''
3392 }, item);
3393
3394 var defaults = {
3395 selected: false,
3396 disabled: false
3397 };
3398
3399 if (item.id != null) {
3400 item.id = item.id.toString();
3401 }
3402
3403 if (item.text != null) {
3404 item.text = item.text.toString();
3405 }
3406
3407 if (item._resultId == null && item.id) {
3408 item._resultId = this.generateResultId(this.container, item);
3409 }
3410
3411 return $.extend({}, defaults, item);
3412 };
3413
3414 SelectAdapter.prototype.matches = function (params, data) {
3415 var matcher = this.options.get('matcher');
3416
3417 return matcher(params, data);
3418 };
3419
3420 return SelectAdapter;
3421 });
3422
3423 S2.define('select2/data/array',[
3424 './select',
3425 '../utils',
3426 'jquery'
3427 ], function (SelectAdapter, Utils, $) {
3428 function ArrayAdapter ($element, options) {
3429 var data = options.get('data') || [];
3430
3431 ArrayAdapter.__super__.constructor.call(this, $element, options);
3432
3433 this.addOptions(this.convertToOptions(data));
3434 }
3435
3436 Utils.Extend(ArrayAdapter, SelectAdapter);
3437
3438 ArrayAdapter.prototype.select = function (data) {
3439 var $option = this.$element.find('option').filter(function (i, elm) {
3440 return elm.value == data.id.toString();
3441 });
3442
3443 if ($option.length === 0) {
3444 $option = this.option(data);
3445
3446 this.addOptions($option);
3447 }
3448
3449 ArrayAdapter.__super__.select.call(this, data);
3450 };
3451
3452 ArrayAdapter.prototype.convertToOptions = function (data) {
3453 var self = this;
3454
3455 var $existing = this.$element.find('option');
3456 var existingIds = $existing.map(function () {
3457 return self.item($(this)).id;
3458 }).get();
3459
3460 var $options = [];
3461
3462 // Filter out all items except for the one passed in the argument
3463 function onlyItem (item) {
3464 return function () {
3465 return $(this).val() == item.id;
3466 };
3467 }
3468
3469 for (var d = 0; d < data.length; d++) {
3470 var item = this._normalizeItem(data[d]);
3471
3472 // Skip items which were pre-loaded, only merge the data
3473 if ($.inArray(item.id, existingIds) >= 0) {
3474 var $existingOption = $existing.filter(onlyItem(item));
3475
3476 var existingData = this.item($existingOption);
3477 var newData = $.extend(true, {}, item, existingData);
3478
3479 var $newOption = this.option(newData);
3480
3481 $existingOption.replaceWith($newOption);
3482
3483 continue;
3484 }
3485
3486 var $option = this.option(item);
3487
3488 if (item.children) {
3489 var $children = this.convertToOptions(item.children);
3490
3491 Utils.appendMany($option, $children);
3492 }
3493
3494 $options.push($option);
3495 }
3496
3497 return $options;
3498 };
3499
3500 return ArrayAdapter;
3501 });
3502
3503 S2.define('select2/data/ajax',[
3504 './array',
3505 '../utils',
3506 'jquery'
3507 ], function (ArrayAdapter, Utils, $) {
3508 function AjaxAdapter ($element, options) {
3509 this.ajaxOptions = this._applyDefaults(options.get('ajax'));
3510
3511 if (this.ajaxOptions.processResults != null) {
3512 this.processResults = this.ajaxOptions.processResults;
3513 }
3514
3515 AjaxAdapter.__super__.constructor.call(this, $element, options);
3516 }
3517
3518 Utils.Extend(AjaxAdapter, ArrayAdapter);
3519
3520 AjaxAdapter.prototype._applyDefaults = function (options) {
3521 var defaults = {
3522 data: function (params) {
3523 return $.extend({}, params, {
3524 q: params.term
3525 });
3526 },
3527 transport: function (params, success, failure) {
3528 var $request = $.ajax(params);
3529
3530 $request.then(success);
3531 $request.fail(failure);
3532
3533 return $request;
3534 }
3535 };
3536
3537 return $.extend({}, defaults, options, true);
3538 };
3539
3540 AjaxAdapter.prototype.processResults = function (results) {
3541 return results;
3542 };
3543
3544 AjaxAdapter.prototype.query = function (params, callback) {
3545 var matches = [];
3546 var self = this;
3547
3548 if (this._request != null) {
3549 // JSONP requests cannot always be aborted
3550 if ( typeof this._request.abort === 'function' ) {
3551 this._request.abort();
3552 }
3553
3554 this._request = null;
3555 }
3556
3557 var options = $.extend({
3558 type: 'GET'
3559 }, this.ajaxOptions);
3560
3561 if (typeof options.url === 'function') {
3562 options.url = options.url.call(this.$element, params);
3563 }
3564
3565 if (typeof options.data === 'function') {
3566 options.data = options.data.call(this.$element, params);
3567 }
3568
3569 function request () {
3570 var $request = options.transport(options, function (data) {
3571 var results = self.processResults(data, params);
3572
3573 if (self.options.get('debug') && window.console && console.error) {
3574 // Check to make sure that the response included a `results` key.
3575 if (!results || !results.results || ! Array.isArray( results.results ) ) {
3576 console.error(
3577 'Select2: The AJAX results did not return an array in the ' +
3578 '`results` key of the response.'
3579 );
3580 }
3581 }
3582
3583 callback(results);
3584 self.container.focusOnActiveElement();
3585 }, function () {
3586 // Attempt to detect if a request was aborted
3587 // Only works if the transport exposes a status property
3588 if ($request.status && $request.status === '0') {
3589 return;
3590 }
3591
3592 self.trigger('results:message', {
3593 message: 'errorLoading'
3594 });
3595 });
3596
3597 self._request = $request;
3598 }
3599
3600 if (this.ajaxOptions.delay && params.term != null) {
3601 if (this._queryTimeout) {
3602 window.clearTimeout(this._queryTimeout);
3603 }
3604
3605 this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);
3606 } else {
3607 request();
3608 }
3609 };
3610
3611 return AjaxAdapter;
3612 });
3613
3614 S2.define('select2/data/tags',[
3615 'jquery'
3616 ], function ($) {
3617 function Tags (decorated, $element, options) {
3618 var tags = options.get('tags');
3619
3620 var createTag = options.get('createTag');
3621
3622 if (createTag !== undefined) {
3623 this.createTag = createTag;
3624 }
3625
3626 var insertTag = options.get('insertTag');
3627
3628 if (insertTag !== undefined) {
3629 this.insertTag = insertTag;
3630 }
3631
3632 decorated.call(this, $element, options);
3633
3634 if ( Array.isArray( tags ) ) {
3635 for (var t = 0; t < tags.length; t++) {
3636 var tag = tags[t];
3637 var item = this._normalizeItem(tag);
3638
3639 var $option = this.option(item);
3640
3641 this.$element.append($option);
3642 }
3643 }
3644 }
3645
3646 Tags.prototype.query = function (decorated, params, callback) {
3647 var self = this;
3648
3649 this._removeOldTags();
3650
3651 if (params.term == null || params.page != null) {
3652 decorated.call(this, params, callback);
3653 return;
3654 }
3655
3656 function wrapper (obj, child) {
3657 var data = obj.results;
3658
3659 for (var i = 0; i < data.length; i++) {
3660 var option = data[i];
3661
3662 var checkChildren = (
3663 option.children != null &&
3664 !wrapper({
3665 results: option.children
3666 }, true)
3667 );
3668
3669 var optionText = (option.text || '').toUpperCase();
3670 var paramsTerm = (params.term || '').toUpperCase();
3671
3672 var checkText = optionText === paramsTerm;
3673
3674 if (checkText || checkChildren) {
3675 if (child) {
3676 return false;
3677 }
3678
3679 obj.data = data;
3680 callback(obj);
3681
3682 return;
3683 }
3684 }
3685
3686 if (child) {
3687 return true;
3688 }
3689
3690 var tag = self.createTag(params);
3691
3692 if (tag != null) {
3693 var $option = self.option(tag);
3694 $option.attr('data-select2-tag', true);
3695
3696 self.addOptions([$option]);
3697
3698 self.insertTag(data, tag);
3699 }
3700
3701 obj.results = data;
3702
3703 callback(obj);
3704 }
3705
3706 decorated.call(this, params, wrapper);
3707 };
3708
3709 Tags.prototype.createTag = function (decorated, params) {
3710 var term = ( params.term || 0 == params.term ) ? params.term.toString().trim() : '';
3711
3712 if (term === '') {
3713 return null;
3714 }
3715
3716 return {
3717 id: term,
3718 text: term
3719 };
3720 };
3721
3722 Tags.prototype.insertTag = function (_, data, tag) {
3723 data.unshift(tag);
3724 };
3725
3726 Tags.prototype._removeOldTags = function (_) {
3727 var tag = this._lastTag;
3728
3729 var $options = this.$element.find('option[data-select2-tag]');
3730
3731 $options.each(function () {
3732 if (this.selected) {
3733 return;
3734 }
3735
3736 $(this).remove();
3737 });
3738 };
3739
3740 return Tags;
3741 });
3742
3743 S2.define('select2/data/tokenizer',[
3744 'jquery'
3745 ], function ($) {
3746 function Tokenizer (decorated, $element, options) {
3747 var tokenizer = options.get('tokenizer');
3748
3749 if (tokenizer !== undefined) {
3750 this.tokenizer = tokenizer;
3751 }
3752
3753 decorated.call(this, $element, options);
3754 }
3755
3756 Tokenizer.prototype.bind = function (decorated, container, $container) {
3757 decorated.call(this, container, $container);
3758
3759 this.$search = container.dropdown.$search || container.selection.$search ||
3760 $container.find('.select2-search__field');
3761 };
3762
3763 Tokenizer.prototype.query = function (decorated, params, callback) {
3764 var self = this;
3765
3766 function createAndSelect (data) {
3767 // Normalize the data object so we can use it for checks
3768 var item = self._normalizeItem(data);
3769
3770 // Check if the data object already exists as a tag
3771 // Select it if it doesn't
3772 var $existingOptions = self.$element.find('option').filter(function () {
3773 return $(this).val() === item.id;
3774 });
3775
3776 // If an existing option wasn't found for it, create the option
3777 if (!$existingOptions.length) {
3778 var $option = self.option(item);
3779 $option.attr('data-select2-tag', true);
3780
3781 self._removeOldTags();
3782 self.addOptions([$option]);
3783 }
3784
3785 // Select the item, now that we know there is an option for it
3786 select(item);
3787 }
3788
3789 function select (data) {
3790 self.trigger('select', {
3791 data: data
3792 });
3793 }
3794
3795 params.term = params.term || '';
3796
3797 var tokenData = this.tokenizer(params, this.options, createAndSelect);
3798
3799 if (tokenData.term !== params.term) {
3800 // Replace the search term if we have the search box
3801 if (this.$search.length) {
3802 this.$search.val(tokenData.term);
3803 this.$search.trigger( 'focus' );
3804 }
3805
3806 params.term = tokenData.term;
3807 }
3808
3809 decorated.call(this, params, callback);
3810 };
3811
3812 Tokenizer.prototype.tokenizer = function (_, params, options, callback) {
3813 var separators = options.get('tokenSeparators') || [];
3814 var term = params.term;
3815 var i = 0;
3816
3817 var createTag = this.createTag || function (params) {
3818 return {
3819 id: params.term,
3820 text: params.term
3821 };
3822 };
3823
3824 while (i < term.length) {
3825 var termChar = term[i];
3826
3827 if ($.inArray(termChar, separators) === -1) {
3828 i++;
3829
3830 continue;
3831 }
3832
3833 var part = term.substr(0, i);
3834 var partParams = $.extend({}, params, {
3835 term: part
3836 });
3837
3838 var data = createTag(partParams);
3839
3840 if (data == null) {
3841 i++;
3842 continue;
3843 }
3844
3845 callback(data);
3846
3847 // Reset the term to not include the tokenized portion
3848 term = term.substr(i + 1) || '';
3849 i = 0;
3850 }
3851
3852 return {
3853 term: term
3854 };
3855 };
3856
3857 return Tokenizer;
3858 });
3859
3860 S2.define('select2/data/minimumInputLength',[
3861
3862 ], function () {
3863 function MinimumInputLength (decorated, $e, options) {
3864 this.minimumInputLength = options.get('minimumInputLength');
3865
3866 decorated.call(this, $e, options);
3867 }
3868
3869 MinimumInputLength.prototype.query = function (decorated, params, callback) {
3870 params.term = params.term || '';
3871
3872 if (params.term.length < this.minimumInputLength) {
3873 this.trigger('results:message', {
3874 message: 'inputTooShort',
3875 args: {
3876 minimum: this.minimumInputLength,
3877 input: params.term,
3878 params: params
3879 }
3880 });
3881
3882 return;
3883 }
3884
3885 decorated.call(this, params, callback);
3886 };
3887
3888 return MinimumInputLength;
3889 });
3890
3891 S2.define('select2/data/maximumInputLength',[
3892
3893 ], function () {
3894 function MaximumInputLength (decorated, $e, options) {
3895 this.maximumInputLength = options.get('maximumInputLength');
3896
3897 decorated.call(this, $e, options);
3898 }
3899
3900 MaximumInputLength.prototype.query = function (decorated, params, callback) {
3901 params.term = params.term || '';
3902
3903 if (this.maximumInputLength > 0 &&
3904 params.term.length > this.maximumInputLength) {
3905 this.trigger('results:message', {
3906 message: 'inputTooLong',
3907 args: {
3908 maximum: this.maximumInputLength,
3909 input: params.term,
3910 params: params
3911 }
3912 });
3913
3914 return;
3915 }
3916
3917 decorated.call(this, params, callback);
3918 };
3919
3920 return MaximumInputLength;
3921 });
3922
3923 S2.define('select2/data/maximumSelectionLength',[
3924
3925 ], function (){
3926 function MaximumSelectionLength (decorated, $e, options) {
3927 this.maximumSelectionLength = options.get('maximumSelectionLength');
3928
3929 decorated.call(this, $e, options);
3930 }
3931
3932 MaximumSelectionLength.prototype.query =
3933 function (decorated, params, callback) {
3934 var self = this;
3935
3936 this.current(function (currentData) {
3937 var count = currentData != null ? currentData.length : 0;
3938 if (self.maximumSelectionLength > 0 &&
3939 count >= self.maximumSelectionLength) {
3940 self.trigger('results:message', {
3941 message: 'maximumSelected',
3942 args: {
3943 maximum: self.maximumSelectionLength
3944 }
3945 });
3946 return;
3947 }
3948 decorated.call(self, params, callback);
3949 });
3950 };
3951
3952 return MaximumSelectionLength;
3953 });
3954
3955 S2.define('select2/dropdown',[
3956 'jquery',
3957 './utils'
3958 ], function ($, Utils) {
3959 function Dropdown ($element, options) {
3960 this.$element = $element;
3961 this.options = options;
3962
3963 Dropdown.__super__.constructor.call(this);
3964 }
3965
3966 Utils.Extend(Dropdown, Utils.Observable);
3967
3968 Dropdown.prototype.render = function () {
3969 var $dropdown = $(
3970 '<span class="select2-dropdown">' +
3971 '<span class="select2-results"></span>' +
3972 '</span>'
3973 );
3974
3975 $dropdown.attr('dir', this.options.get('dir'));
3976
3977 this.$dropdown = $dropdown;
3978
3979 return $dropdown;
3980 };
3981
3982 Dropdown.prototype.bind = function () {
3983 // Should be implemented in subclasses
3984 };
3985
3986 Dropdown.prototype.position = function ($dropdown, $container) {
3987 // Should be implmented in subclasses
3988 };
3989
3990 Dropdown.prototype.destroy = function () {
3991 // Remove the dropdown from the DOM
3992 this.$dropdown.remove();
3993 };
3994
3995 return Dropdown;
3996 });
3997
3998 S2.define('select2/dropdown/search',[
3999 'jquery',
4000 '../utils'
4001 ], function ($, Utils) {
4002 function Search () { }
4003
4004 Search.prototype.render = function (decorated) {
4005 var $rendered = decorated.call(this);
4006
4007 var $search = $(
4008 '<span class="select2-search select2-search--dropdown">' +
4009 '<input class="select2-search__field" type="text" tabindex="-1"' +
4010 ' autocomplete="off" autocorrect="off" autocapitalize="none"' +
4011 ' spellcheck="false" role="combobox" aria-autocomplete="list" aria-expanded="true" />' +
4012 '</span>'
4013 );
4014
4015 this.$searchContainer = $search;
4016 this.$search = $search.find('input');
4017
4018 $rendered.prepend($search);
4019
4020 return $rendered;
4021 };
4022
4023 Search.prototype.bind = function (decorated, container, $container) {
4024 var self = this;
4025 var resultsId = container.id + '-results';
4026
4027 decorated.call(this, container, $container);
4028
4029 this.$search.on('keydown', function (evt) {
4030 self.trigger('keypress', evt);
4031
4032 self._keyUpPrevented = evt.isDefaultPrevented();
4033 });
4034
4035 // Workaround for browsers which do not support the `input` event
4036 // This will prevent double-triggering of events for browsers which support
4037 // both the `keyup` and `input` events.
4038 this.$search.on('input', function (evt) {
4039 // Unbind the duplicated `keyup` event
4040 $(this).off('keyup');
4041 });
4042
4043 this.$search.on('keyup input', function (evt) {
4044 self.handleSearch(evt);
4045 });
4046
4047 container.on('open', function () {
4048 self.$search.attr('tabindex', 0);
4049 self.$search.attr('aria-owns', resultsId);
4050 self.$search.trigger( 'focus' );
4051
4052 window.setTimeout(function () {
4053 self.$search.trigger( 'focus' );
4054 }, 0);
4055 });
4056
4057 container.on('close', function () {
4058 self.$search.attr('tabindex', -1);
4059 self.$search.removeAttr('aria-activedescendant');
4060 self.$search.removeAttr('aria-owns');
4061 self.$search.val('');
4062 });
4063
4064 container.on('focus', function () {
4065 if (!container.isOpen()) {
4066 self.$search.trigger( 'focus' );
4067 }
4068 });
4069
4070 container.on('results:all', function (params) {
4071 if (params.query.term == null || params.query.term === '') {
4072 var showSearch = self.showSearch(params);
4073
4074 if (showSearch) {
4075 self.$searchContainer.removeClass('select2-search--hide');
4076 } else {
4077 self.$searchContainer.addClass('select2-search--hide');
4078 }
4079 }
4080 });
4081
4082 container.on('results:focus', function (params) {
4083 self.$search.attr('aria-activedescendant', params.data._resultId);
4084 });
4085 };
4086
4087 Search.prototype.handleSearch = function (evt) {
4088 if (!this._keyUpPrevented) {
4089 var input = this.$search.val();
4090
4091 this.trigger('query', {
4092 term: input
4093 });
4094 }
4095
4096 this._keyUpPrevented = false;
4097 };
4098
4099 Search.prototype.showSearch = function (_, params) {
4100 return true;
4101 };
4102
4103 return Search;
4104 });
4105
4106 S2.define('select2/dropdown/hidePlaceholder',[
4107
4108 ], function () {
4109 function HidePlaceholder (decorated, $element, options, dataAdapter) {
4110 this.placeholder = this.normalizePlaceholder(options.get('placeholder'));
4111
4112 decorated.call(this, $element, options, dataAdapter);
4113 }
4114
4115 HidePlaceholder.prototype.append = function (decorated, data) {
4116 data.results = this.removePlaceholder(data.results);
4117
4118 decorated.call(this, data);
4119 };
4120
4121 HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {
4122 if (typeof placeholder === 'string') {
4123 placeholder = {
4124 id: '',
4125 text: placeholder
4126 };
4127 }
4128
4129 return placeholder;
4130 };
4131
4132 HidePlaceholder.prototype.removePlaceholder = function (_, data) {
4133 var modifiedData = data.slice(0);
4134
4135 for (var d = data.length - 1; d >= 0; d--) {
4136 var item = data[d];
4137
4138 if (this.placeholder.id === item.id) {
4139 modifiedData.splice(d, 1);
4140 }
4141 }
4142
4143 return modifiedData;
4144 };
4145
4146 return HidePlaceholder;
4147 });
4148
4149 S2.define('select2/dropdown/infiniteScroll',[
4150 'jquery'
4151 ], function ($) {
4152 function InfiniteScroll (decorated, $element, options, dataAdapter) {
4153 this.lastParams = {};
4154
4155 decorated.call(this, $element, options, dataAdapter);
4156
4157 this.$loadingMore = this.createLoadingMore();
4158 this.loading = false;
4159 }
4160
4161 InfiniteScroll.prototype.append = function (decorated, data) {
4162 this.$loadingMore.remove();
4163 this.loading = false;
4164
4165 decorated.call(this, data);
4166
4167 if (this.showLoadingMore(data)) {
4168 this.$results.append(this.$loadingMore);
4169 }
4170 };
4171
4172 InfiniteScroll.prototype.bind = function (decorated, container, $container) {
4173 var self = this;
4174
4175 decorated.call(this, container, $container);
4176
4177 container.on('query', function (params) {
4178 self.lastParams = params;
4179 self.loading = true;
4180 });
4181
4182 container.on('query:append', function (params) {
4183 self.lastParams = params;
4184 self.loading = true;
4185 });
4186
4187 this.$results.on('scroll', function () {
4188 var isLoadMoreVisible = $.contains(
4189 document.documentElement,
4190 self.$loadingMore[0]
4191 );
4192
4193 if (self.loading || !isLoadMoreVisible) {
4194 return;
4195 }
4196
4197 var currentOffset = self.$results.offset().top +
4198 self.$results.outerHeight(false);
4199 var loadingMoreOffset = self.$loadingMore.offset().top +
4200 self.$loadingMore.outerHeight(false);
4201
4202 if (currentOffset + 50 >= loadingMoreOffset) {
4203 self.loadMore();
4204 }
4205 });
4206 };
4207
4208 InfiniteScroll.prototype.loadMore = function () {
4209 this.loading = true;
4210
4211 var params = $.extend({}, {page: 1}, this.lastParams);
4212
4213 params.page++;
4214
4215 this.trigger('query:append', params);
4216 };
4217
4218 InfiniteScroll.prototype.showLoadingMore = function (_, data) {
4219 return data.pagination && data.pagination.more;
4220 };
4221
4222 InfiniteScroll.prototype.createLoadingMore = function () {
4223 var $option = $(
4224 '<li ' +
4225 'class="select2-results__option select2-results__option--load-more"' +
4226 'role="option" aria-disabled="true"></li>'
4227 );
4228
4229 var message = this.options.get('translations').get('loadingMore');
4230
4231 $option.html(message(this.lastParams));
4232
4233 return $option;
4234 };
4235
4236 return InfiniteScroll;
4237 });
4238
4239 S2.define('select2/dropdown/attachBody',[
4240 'jquery',
4241 '../utils'
4242 ], function ($, Utils) {
4243 function AttachBody (decorated, $element, options) {
4244 this.$dropdownParent = options.get('dropdownParent') || $(document.body);
4245
4246 decorated.call(this, $element, options);
4247 }
4248
4249 AttachBody.prototype.bind = function (decorated, container, $container) {
4250 var self = this;
4251
4252 var setupResultsEvents = false;
4253
4254 decorated.call(this, container, $container);
4255
4256 container.on('open', function () {
4257 self._showDropdown();
4258 self._attachPositioningHandler(container);
4259
4260 if (!setupResultsEvents) {
4261 setupResultsEvents = true;
4262
4263 container.on('results:all', function () {
4264 self._positionDropdown();
4265 self._resizeDropdown();
4266 });
4267
4268 container.on('results:append', function () {
4269 self._positionDropdown();
4270 self._resizeDropdown();
4271 });
4272 }
4273 });
4274
4275 container.on('close', function () {
4276 self._hideDropdown();
4277 self._detachPositioningHandler(container);
4278 });
4279
4280 this.$dropdownContainer.on('mousedown', function (evt) {
4281 evt.stopPropagation();
4282 });
4283 };
4284
4285 AttachBody.prototype.destroy = function (decorated) {
4286 decorated.call(this);
4287
4288 this.$dropdownContainer.remove();
4289 };
4290
4291 AttachBody.prototype.position = function (decorated, $dropdown, $container) {
4292 // Clone all of the container classes
4293 $dropdown.attr('class', $container.attr('class'));
4294
4295 $dropdown.removeClass('select2');
4296 $dropdown.addClass('select2-container--open');
4297
4298 $dropdown.css({
4299 position: 'absolute',
4300 top: -999999
4301 });
4302
4303 this.$container = $container;
4304 };
4305
4306 AttachBody.prototype.render = function (decorated) {
4307 var $container = $('<span></span>');
4308
4309 var $dropdown = decorated.call(this);
4310 $container.append($dropdown);
4311
4312 this.$dropdownContainer = $container;
4313
4314 return $container;
4315 };
4316
4317 AttachBody.prototype._hideDropdown = function (decorated) {
4318 this.$dropdownContainer.detach();
4319 };
4320
4321 AttachBody.prototype._attachPositioningHandler =
4322 function (decorated, container) {
4323 var self = this;
4324
4325 var scrollEvent = 'scroll.select2.' + container.id;
4326 var resizeEvent = 'resize.select2.' + container.id;
4327 var orientationEvent = 'orientationchange.select2.' + container.id;
4328
4329 var $watchers = this.$container.parents().filter(Utils.hasScroll);
4330 $watchers.each(function () {
4331 $(this).data('select2-scroll-position', {
4332 x: $(this).scrollLeft(),
4333 y: $(this).scrollTop()
4334 });
4335 });
4336
4337 $watchers.on(scrollEvent, function (ev) {
4338 var position = $(this).data('select2-scroll-position');
4339 $(this).scrollTop(position.y);
4340 });
4341
4342 $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,
4343 function (e) {
4344 self._positionDropdown();
4345 self._resizeDropdown();
4346 });
4347 };
4348
4349 AttachBody.prototype._detachPositioningHandler =
4350 function (decorated, container) {
4351 var scrollEvent = 'scroll.select2.' + container.id;
4352 var resizeEvent = 'resize.select2.' + container.id;
4353 var orientationEvent = 'orientationchange.select2.' + container.id;
4354
4355 var $watchers = this.$container.parents().filter(Utils.hasScroll);
4356 $watchers.off(scrollEvent);
4357
4358 $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);
4359 };
4360
4361 AttachBody.prototype._positionDropdown = function () {
4362 var $window = $(window);
4363
4364 var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');
4365 var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');
4366
4367 var newDirection = null;
4368
4369 var offset = this.$container.offset();
4370
4371 offset.bottom = offset.top + this.$container.outerHeight(false);
4372
4373 var container = {
4374 height: this.$container.outerHeight(false)
4375 };
4376
4377 container.top = offset.top;
4378 container.bottom = offset.top + container.height;
4379
4380 var dropdown = {
4381 height: this.$dropdown.outerHeight(false)
4382 };
4383
4384 var viewport = {
4385 top: $window.scrollTop(),
4386 bottom: $window.scrollTop() + $window.height()
4387 };
4388
4389 var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);
4390 var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);
4391
4392 var css = {
4393 left: offset.left,
4394 top: container.bottom
4395 };
4396
4397 // Determine what the parent element is to use for calciulating the offset
4398 var $offsetParent = this.$dropdownParent;
4399
4400 // For statically positoned elements, we need to get the element
4401 // that is determining the offset
4402 if ($offsetParent.css('position') === 'static') {
4403 $offsetParent = $offsetParent.offsetParent();
4404 }
4405
4406 var parentOffset = $offsetParent.offset();
4407
4408 css.left -= parentOffset.left;
4409
4410 if (!isCurrentlyAbove && !isCurrentlyBelow) {
4411 newDirection = 'below';
4412 }
4413
4414 if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {
4415 newDirection = 'above';
4416 } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {
4417 newDirection = 'below';
4418 }
4419
4420 if (newDirection == 'above' ||
4421 (isCurrentlyAbove && newDirection !== 'below')) {
4422 css.top = container.top - dropdown.height;
4423 }
4424
4425 if (newDirection != null) {
4426 this.$dropdown
4427 .removeClass('select2-dropdown--below select2-dropdown--above')
4428 .addClass('select2-dropdown--' + newDirection);
4429 this.$container
4430 .removeClass('select2-container--below select2-container--above')
4431 .addClass('select2-container--' + newDirection);
4432 }
4433
4434 this.$dropdownContainer.css(css);
4435 };
4436
4437 AttachBody.prototype._resizeDropdown = function () {
4438 var css = {
4439 width: this.$container.outerWidth(false) + 'px'
4440 };
4441
4442 if (this.options.get('dropdownAutoWidth')) {
4443 css.minWidth = css.width;
4444 css.position = 'relative';
4445 css.width = 'auto';
4446 }
4447
4448 this.$dropdown.css(css);
4449 };
4450
4451 AttachBody.prototype._showDropdown = function (decorated) {
4452 this.$dropdownContainer.appendTo(this.$dropdownParent);
4453
4454 this._positionDropdown();
4455 this._resizeDropdown();
4456 };
4457
4458 return AttachBody;
4459 });
4460
4461 S2.define('select2/dropdown/minimumResultsForSearch',[
4462
4463 ], function () {
4464 function countResults (data) {
4465 var count = 0;
4466
4467 for (var d = 0; d < data.length; d++) {
4468 var item = data[d];
4469
4470 if (item.children) {
4471 count += countResults(item.children);
4472 } else {
4473 count++;
4474 }
4475 }
4476
4477 return count;
4478 }
4479
4480 function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {
4481 this.minimumResultsForSearch = options.get('minimumResultsForSearch');
4482
4483 if (this.minimumResultsForSearch < 0) {
4484 this.minimumResultsForSearch = Infinity;
4485 }
4486
4487 decorated.call(this, $element, options, dataAdapter);
4488 }
4489
4490 MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {
4491 if (countResults(params.data.results) < this.minimumResultsForSearch) {
4492 return false;
4493 }
4494
4495 return decorated.call(this, params);
4496 };
4497
4498 return MinimumResultsForSearch;
4499 });
4500
4501 S2.define('select2/dropdown/selectOnClose',[
4502
4503 ], function () {
4504 function SelectOnClose () { }
4505
4506 SelectOnClose.prototype.bind = function (decorated, container, $container) {
4507 var self = this;
4508
4509 decorated.call(this, container, $container);
4510
4511 container.on('close', function (params) {
4512 self._handleSelectOnClose(params);
4513 });
4514 };
4515
4516 SelectOnClose.prototype._handleSelectOnClose = function (_, params) {
4517 if (params && params.originalSelect2Event != null) {
4518 var event = params.originalSelect2Event;
4519
4520 // Don't select an item if the close event was triggered from a select or
4521 // unselect event
4522 if (event._type === 'select' || event._type === 'unselect') {
4523 return;
4524 }
4525 }
4526
4527 var $highlightedResults = this.getHighlightedResults();
4528
4529 // Only select highlighted results
4530 if ($highlightedResults.length < 1) {
4531 return;
4532 }
4533
4534 var data = $highlightedResults.data('data');
4535
4536 // Don't re-select already selected resulte
4537 if (
4538 (data.element != null && data.element.selected) ||
4539 (data.element == null && data.selected)
4540 ) {
4541 return;
4542 }
4543
4544 this.trigger('select', {
4545 data: data
4546 });
4547 };
4548
4549 return SelectOnClose;
4550 });
4551
4552 S2.define('select2/dropdown/closeOnSelect',[
4553
4554 ], function () {
4555 function CloseOnSelect () { }
4556
4557 CloseOnSelect.prototype.bind = function (decorated, container, $container) {
4558 var self = this;
4559
4560 decorated.call(this, container, $container);
4561
4562 container.on('select', function (evt) {
4563 self._selectTriggered(evt);
4564 });
4565
4566 container.on('unselect', function (evt) {
4567 self._selectTriggered(evt);
4568 });
4569 };
4570
4571 CloseOnSelect.prototype._selectTriggered = function (_, evt) {
4572 var originalEvent = evt.originalEvent;
4573
4574 // Don't close if the control key is being held
4575 if (originalEvent && originalEvent.ctrlKey) {
4576 return;
4577 }
4578
4579 this.trigger('close', {
4580 originalEvent: originalEvent,
4581 originalSelect2Event: evt
4582 });
4583 };
4584
4585 return CloseOnSelect;
4586 });
4587
4588 S2.define('select2/i18n/en',[],function () {
4589 // English
4590 return {
4591 errorLoading: function () {
4592 return 'The results could not be loaded.';
4593 },
4594 inputTooLong: function (args) {
4595 var overChars = args.input.length - args.maximum;
4596
4597 var message = 'Please delete ' + overChars + ' character';
4598
4599 if (overChars != 1) {
4600 message += 's';
4601 }
4602
4603 return message;
4604 },
4605 inputTooShort: function (args) {
4606 var remainingChars = args.minimum - args.input.length;
4607
4608 var message = 'Please enter ' + remainingChars + ' or more characters';
4609
4610 return message;
4611 },
4612 loadingMore: function () {
4613 return 'Loading more results…';
4614 },
4615 maximumSelected: function (args) {
4616 var message = 'You can only select ' + args.maximum + ' item';
4617
4618 if (args.maximum != 1) {
4619 message += 's';
4620 }
4621
4622 return message;
4623 },
4624 noResults: function () {
4625 return 'No results found';
4626 },
4627 searching: function () {
4628 return 'Searching…';
4629 }
4630 };
4631 });
4632
4633 S2.define('select2/defaults',[
4634 'jquery',
4635 'require',
4636
4637 './results',
4638
4639 './selection/single',
4640 './selection/multiple',
4641 './selection/placeholder',
4642 './selection/allowClear',
4643 './selection/search',
4644 './selection/eventRelay',
4645
4646 './utils',
4647 './translation',
4648 './diacritics',
4649
4650 './data/select',
4651 './data/array',
4652 './data/ajax',
4653 './data/tags',
4654 './data/tokenizer',
4655 './data/minimumInputLength',
4656 './data/maximumInputLength',
4657 './data/maximumSelectionLength',
4658
4659 './dropdown',
4660 './dropdown/search',
4661 './dropdown/hidePlaceholder',
4662 './dropdown/infiniteScroll',
4663 './dropdown/attachBody',
4664 './dropdown/minimumResultsForSearch',
4665 './dropdown/selectOnClose',
4666 './dropdown/closeOnSelect',
4667
4668 './i18n/en'
4669 ], function ($, require,
4670
4671 ResultsList,
4672
4673 SingleSelection, MultipleSelection, Placeholder, AllowClear,
4674 SelectionSearch, EventRelay,
4675
4676 Utils, Translation, DIACRITICS,
4677
4678 SelectData, ArrayData, AjaxData, Tags, Tokenizer,
4679 MinimumInputLength, MaximumInputLength, MaximumSelectionLength,
4680
4681 Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,
4682 AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,
4683
4684 EnglishTranslation) {
4685 function Defaults () {
4686 this.reset();
4687 }
4688
4689 Defaults.prototype.apply = function (options) {
4690 options = $.extend(true, {}, this.defaults, options);
4691
4692 if (options.dataAdapter == null) {
4693 if (options.ajax != null) {
4694 options.dataAdapter = AjaxData;
4695 } else if (options.data != null) {
4696 options.dataAdapter = ArrayData;
4697 } else {
4698 options.dataAdapter = SelectData;
4699 }
4700
4701 if (options.minimumInputLength > 0) {
4702 options.dataAdapter = Utils.Decorate(
4703 options.dataAdapter,
4704 MinimumInputLength
4705 );
4706 }
4707
4708 if (options.maximumInputLength > 0) {
4709 options.dataAdapter = Utils.Decorate(
4710 options.dataAdapter,
4711 MaximumInputLength
4712 );
4713 }
4714
4715 if (options.maximumSelectionLength > 0) {
4716 options.dataAdapter = Utils.Decorate(
4717 options.dataAdapter,
4718 MaximumSelectionLength
4719 );
4720 }
4721
4722 if (options.tags) {
4723 options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);
4724 }
4725
4726 if (options.tokenSeparators != null || options.tokenizer != null) {
4727 options.dataAdapter = Utils.Decorate(
4728 options.dataAdapter,
4729 Tokenizer
4730 );
4731 }
4732
4733 if (options.query != null) {
4734 var Query = require(options.amdBase + 'compat/query');
4735
4736 options.dataAdapter = Utils.Decorate(
4737 options.dataAdapter,
4738 Query
4739 );
4740 }
4741
4742 if (options.initSelection != null) {
4743 var InitSelection = require(options.amdBase + 'compat/initSelection');
4744
4745 options.dataAdapter = Utils.Decorate(
4746 options.dataAdapter,
4747 InitSelection
4748 );
4749 }
4750 }
4751
4752 if (options.resultsAdapter == null) {
4753 options.resultsAdapter = ResultsList;
4754
4755 if (options.ajax != null) {
4756 options.resultsAdapter = Utils.Decorate(
4757 options.resultsAdapter,
4758 InfiniteScroll
4759 );
4760 }
4761
4762 if (options.placeholder != null) {
4763 options.resultsAdapter = Utils.Decorate(
4764 options.resultsAdapter,
4765 HidePlaceholder
4766 );
4767 }
4768
4769 if (options.selectOnClose) {
4770 options.resultsAdapter = Utils.Decorate(
4771 options.resultsAdapter,
4772 SelectOnClose
4773 );
4774 }
4775 }
4776
4777 if (options.dropdownAdapter == null) {
4778 if (options.multiple) {
4779 options.dropdownAdapter = Dropdown;
4780 } else {
4781 var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);
4782
4783 options.dropdownAdapter = SearchableDropdown;
4784 }
4785
4786 if (options.minimumResultsForSearch !== 0) {
4787 options.dropdownAdapter = Utils.Decorate(
4788 options.dropdownAdapter,
4789 MinimumResultsForSearch
4790 );
4791 }
4792
4793 if (options.closeOnSelect) {
4794 options.dropdownAdapter = Utils.Decorate(
4795 options.dropdownAdapter,
4796 CloseOnSelect
4797 );
4798 }
4799
4800 if (
4801 options.dropdownCssClass != null ||
4802 options.dropdownCss != null ||
4803 options.adaptDropdownCssClass != null
4804 ) {
4805 var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');
4806
4807 options.dropdownAdapter = Utils.Decorate(
4808 options.dropdownAdapter,
4809 DropdownCSS
4810 );
4811 }
4812
4813 options.dropdownAdapter = Utils.Decorate(
4814 options.dropdownAdapter,
4815 AttachBody
4816 );
4817 }
4818
4819 if (options.selectionAdapter == null) {
4820 if (options.multiple) {
4821 options.selectionAdapter = MultipleSelection;
4822 } else {
4823 options.selectionAdapter = SingleSelection;
4824 }
4825
4826 // Add the placeholder mixin if a placeholder was specified
4827 if (options.placeholder != null) {
4828 options.selectionAdapter = Utils.Decorate(
4829 options.selectionAdapter,
4830 Placeholder
4831 );
4832 }
4833
4834 if (options.allowClear) {
4835 options.selectionAdapter = Utils.Decorate(
4836 options.selectionAdapter,
4837 AllowClear
4838 );
4839 }
4840
4841 if (options.multiple) {
4842 options.selectionAdapter = Utils.Decorate(
4843 options.selectionAdapter,
4844 SelectionSearch
4845 );
4846 }
4847
4848 if (
4849 options.containerCssClass != null ||
4850 options.containerCss != null ||
4851 options.adaptContainerCssClass != null
4852 ) {
4853 var ContainerCSS = require(options.amdBase + 'compat/containerCss');
4854
4855 options.selectionAdapter = Utils.Decorate(
4856 options.selectionAdapter,
4857 ContainerCSS
4858 );
4859 }
4860
4861 options.selectionAdapter = Utils.Decorate(
4862 options.selectionAdapter,
4863 EventRelay
4864 );
4865 }
4866
4867 if (typeof options.language === 'string') {
4868 // Check if the language is specified with a region
4869 if (options.language.indexOf('-') > 0) {
4870 // Extract the region information if it is included
4871 var languageParts = options.language.split('-');
4872 var baseLanguage = languageParts[0];
4873
4874 options.language = [options.language, baseLanguage];
4875 } else {
4876 options.language = [options.language];
4877 }
4878 }
4879
4880 if ( Array.isArray( options.language ) ) {
4881 var languages = new Translation();
4882 options.language.push('en');
4883
4884 var languageNames = options.language;
4885
4886 for (var l = 0; l < languageNames.length; l++) {
4887 var name = languageNames[l];
4888 var language = {};
4889
4890 try {
4891 // Try to load it with the original name
4892 language = Translation.loadPath(name);
4893 } catch (e) {
4894 try {
4895 // If we couldn't load it, check if it wasn't the full path
4896 name = this.defaults.amdLanguageBase + name;
4897 language = Translation.loadPath(name);
4898 } catch (ex) {
4899 // The translation could not be loaded at all. Sometimes this is
4900 // because of a configuration problem, other times this can be
4901 // because of how Select2 helps load all possible translation files.
4902 if (options.debug && window.console && console.warn) {
4903 console.warn(
4904 'Select2: The language file for "' + name + '" could not be ' +
4905 'automatically loaded. A fallback will be used instead.'
4906 );
4907 }
4908
4909 continue;
4910 }
4911 }
4912
4913 languages.extend(language);
4914 }
4915
4916 options.translations = languages;
4917 } else {
4918 var baseTranslation = Translation.loadPath(
4919 this.defaults.amdLanguageBase + 'en'
4920 );
4921 var customTranslation = new Translation(options.language);
4922
4923 customTranslation.extend(baseTranslation);
4924
4925 options.translations = customTranslation;
4926 }
4927
4928 return options;
4929 };
4930
4931 Defaults.prototype.reset = function () {
4932 function stripDiacritics (text) {
4933 // Used 'uni range + named function' from http://jsperf.com/diacritics/18
4934 function match(a) {
4935 return DIACRITICS[a] || a;
4936 }
4937
4938 return text.replace(/[^\u0000-\u007E]/g, match);
4939 }
4940
4941 function matcher (params, data) {
4942 // Always return the object if there is nothing to compare
4943 if ( params.term == null || params.term.toString().trim() === '' ) {
4944 return data;
4945 }
4946
4947 // Do a recursive check for options with children
4948 if (data.children && data.children.length > 0) {
4949 // Clone the data object if there are children
4950 // This is required as we modify the object to remove any non-matches
4951 var match = $.extend(true, {}, data);
4952
4953 // Check each child of the option
4954 for (var c = data.children.length - 1; c >= 0; c--) {
4955 var child = data.children[c];
4956
4957 var matches = matcher(params, child);
4958
4959 // If there wasn't a match, remove the object in the array
4960 if (matches == null) {
4961 match.children.splice(c, 1);
4962 }
4963 }
4964
4965 // If any children matched, return the new object
4966 if (match.children.length > 0) {
4967 return match;
4968 }
4969
4970 // If there were no matching children, check just the plain object
4971 return matcher(params, match);
4972 }
4973
4974 var original = stripDiacritics(data.text).toUpperCase();
4975 var term = stripDiacritics(params.term).toUpperCase();
4976
4977 // Check if the text contains the term
4978 if (original.indexOf(term) > -1) {
4979 return data;
4980 }
4981
4982 // If it doesn't contain the term, don't return anything
4983 return null;
4984 }
4985
4986 this.defaults = {
4987 amdBase: './',
4988 amdLanguageBase: './i18n/',
4989 closeOnSelect: true,
4990 debug: false,
4991 dropdownAutoWidth: false,
4992 escapeMarkup: Utils.escapeMarkup,
4993 language: EnglishTranslation,
4994 matcher: matcher,
4995 minimumInputLength: 0,
4996 maximumInputLength: 0,
4997 maximumSelectionLength: 0,
4998 minimumResultsForSearch: 0,
4999 selectOnClose: false,
5000 sorter: function (data) {
5001 return data;
5002 },
5003 templateResult: function (result) {
5004 return result.text;
5005 },
5006 templateSelection: function (selection) {
5007 return selection.text;
5008 },
5009 theme: 'default',
5010 width: 'resolve'
5011 };
5012 };
5013
5014 Defaults.prototype.set = function (key, value) {
5015 var camelKey = $.camelCase(key);
5016
5017 var data = {};
5018 data[camelKey] = value;
5019
5020 var convertedData = Utils._convertData(data);
5021
5022 $.extend(this.defaults, convertedData);
5023 };
5024
5025 var defaults = new Defaults();
5026
5027 return defaults;
5028 });
5029
5030 S2.define('select2/options',[
5031 'require',
5032 'jquery',
5033 './defaults',
5034 './utils'
5035 ], function (require, $, Defaults, Utils) {
5036 function Options (options, $element) {
5037 this.options = options;
5038
5039 if ($element != null) {
5040 this.fromElement($element);
5041 }
5042
5043 this.options = Defaults.apply(this.options);
5044
5045 if ($element && $element.is('input')) {
5046 var InputCompat = require(this.get('amdBase') + 'compat/inputData');
5047
5048 this.options.dataAdapter = Utils.Decorate(
5049 this.options.dataAdapter,
5050 InputCompat
5051 );
5052 }
5053 }
5054
5055 Options.prototype.fromElement = function ($e) {
5056 var excludedData = ['select2'];
5057
5058 if (this.options.multiple == null) {
5059 this.options.multiple = $e.prop('multiple');
5060 }
5061
5062 if (this.options.disabled == null) {
5063 this.options.disabled = $e.prop('disabled');
5064 }
5065
5066 if (this.options.language == null) {
5067 if ($e.prop('lang')) {
5068 this.options.language = $e.prop('lang').toLowerCase();
5069 } else if ($e.closest('[lang]').prop('lang')) {
5070 this.options.language = $e.closest('[lang]').prop('lang');
5071 }
5072 }
5073
5074 if (this.options.dir == null) {
5075 if ($e.prop('dir')) {
5076 this.options.dir = $e.prop('dir');
5077 } else if ($e.closest('[dir]').prop('dir')) {
5078 this.options.dir = $e.closest('[dir]').prop('dir');
5079 } else {
5080 this.options.dir = 'ltr';
5081 }
5082 }
5083
5084 $e.prop('disabled', this.options.disabled);
5085 $e.prop('multiple', this.options.multiple);
5086
5087 if ($e.data('select2Tags')) {
5088 if (this.options.debug && window.console && console.warn) {
5089 console.warn(
5090 'Select2: The `data-select2-tags` attribute has been changed to ' +
5091 'use the `data-data` and `data-tags="true"` attributes and will be ' +
5092 'removed in future versions of Select2.'
5093 );
5094 }
5095
5096 $e.data('data', $e.data('select2Tags'));
5097 $e.data('tags', true);
5098 }
5099
5100 if ($e.data('ajaxUrl')) {
5101 if (this.options.debug && window.console && console.warn) {
5102 console.warn(
5103 'Select2: The `data-ajax-url` attribute has been changed to ' +
5104 '`data-ajax--url` and support for the old attribute will be removed' +
5105 ' in future versions of Select2.'
5106 );
5107 }
5108
5109 $e.attr('ajax--url', $e.data('ajaxUrl'));
5110 $e.data('ajax--url', $e.data('ajaxUrl'));
5111 }
5112
5113 var dataset = {};
5114
5115 // Prefer the element's `dataset` attribute if it exists
5116 // jQuery 1.x does not correctly handle data attributes with multiple dashes
5117 if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {
5118 dataset = $.extend(true, {}, $e[0].dataset, $e.data());
5119 } else {
5120 dataset = $e.data();
5121 }
5122
5123 var data = $.extend(true, {}, dataset);
5124
5125 data = Utils._convertData(data);
5126
5127 for (var key in data) {
5128 if ($.inArray(key, excludedData) > -1) {
5129 continue;
5130 }
5131
5132 if ($.isPlainObject(this.options[key])) {
5133 $.extend(this.options[key], data[key]);
5134 } else {
5135 this.options[key] = data[key];
5136 }
5137 }
5138
5139 return this;
5140 };
5141
5142 Options.prototype.get = function (key) {
5143 return this.options[key];
5144 };
5145
5146 Options.prototype.set = function (key, val) {
5147 this.options[key] = val;
5148 };
5149
5150 return Options;
5151 });
5152
5153 S2.define('select2/core',[
5154 'jquery',
5155 './options',
5156 './utils',
5157 './keys'
5158 ], function ($, Options, Utils, KEYS) {
5159 var Select2 = function ($element, options) {
5160 if ($element.data('select2') != null) {
5161 $element.data('select2').destroy();
5162 }
5163
5164 this.$element = $element;
5165
5166 this.id = this._generateId($element);
5167
5168 options = options || {};
5169
5170 this.options = new Options(options, $element);
5171
5172 Select2.__super__.constructor.call(this);
5173
5174 // Set up the tabindex
5175
5176 var tabindex = $element.attr('tabindex') || 0;
5177 $element.data('old-tabindex', tabindex);
5178 $element.attr('tabindex', '-1');
5179
5180 // Set up containers and adapters
5181
5182 var DataAdapter = this.options.get('dataAdapter');
5183 this.dataAdapter = new DataAdapter($element, this.options);
5184
5185 var $container = this.render();
5186
5187 this._placeContainer($container);
5188
5189 var SelectionAdapter = this.options.get('selectionAdapter');
5190 this.selection = new SelectionAdapter($element, this.options);
5191 this.$selection = this.selection.render();
5192
5193 this.selection.position(this.$selection, $container);
5194
5195 var DropdownAdapter = this.options.get('dropdownAdapter');
5196 this.dropdown = new DropdownAdapter($element, this.options);
5197 this.$dropdown = this.dropdown.render();
5198
5199 this.dropdown.position(this.$dropdown, $container);
5200
5201 var ResultsAdapter = this.options.get('resultsAdapter');
5202 this.results = new ResultsAdapter($element, this.options, this.dataAdapter);
5203 this.$results = this.results.render();
5204
5205 this.results.position(this.$results, this.$dropdown);
5206
5207 // Bind events
5208
5209 var self = this;
5210
5211 // Bind the container to all of the adapters
5212 this._bindAdapters();
5213
5214 // Register any DOM event handlers
5215 this._registerDomEvents();
5216
5217 // Register any internal event handlers
5218 this._registerDataEvents();
5219 this._registerSelectionEvents();
5220 this._registerDropdownEvents();
5221 this._registerResultsEvents();
5222 this._registerEvents();
5223
5224 // Set the initial state
5225 this.dataAdapter.current(function (initialData) {
5226 self.trigger('selection:update', {
5227 data: initialData
5228 });
5229 });
5230
5231 // Hide the original select
5232 $element.addClass('select2-hidden-accessible');
5233 $element.attr('aria-hidden', 'true');
5234
5235 // Synchronize any monitored attributes
5236 this._syncAttributes();
5237
5238 $element.data('select2', this);
5239 };
5240
5241 Utils.Extend(Select2, Utils.Observable);
5242
5243 Select2.prototype._generateId = function ($element) {
5244 var id = '';
5245
5246 if ($element.attr('id') != null) {
5247 id = $element.attr('id');
5248 } else if ($element.attr('name') != null) {
5249 id = $element.attr('name') + '-' + Utils.generateChars(2);
5250 } else {
5251 id = Utils.generateChars(4);
5252 }
5253
5254 id = id.replace(/(:|\.|\[|\]|,)/g, '');
5255 id = 'select2-' + id;
5256
5257 return id;
5258 };
5259
5260 Select2.prototype._placeContainer = function ($container) {
5261 $container.insertAfter(this.$element);
5262
5263 var width = this._resolveWidth(this.$element, this.options.get('width'));
5264
5265 if (width != null) {
5266 $container.css('width', width);
5267 }
5268 };
5269
5270 Select2.prototype._resolveWidth = function ($element, method) {
5271 var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;
5272
5273 if (method == 'resolve') {
5274 var styleWidth = this._resolveWidth($element, 'style');
5275
5276 if (styleWidth != null) {
5277 return styleWidth;
5278 }
5279
5280 return this._resolveWidth($element, 'element');
5281 }
5282
5283 if (method == 'element') {
5284 var elementWidth = $element.outerWidth(false);
5285
5286 if (elementWidth <= 0) {
5287 return 'auto';
5288 }
5289
5290 return elementWidth + 'px';
5291 }
5292
5293 if (method == 'style') {
5294 var style = $element.attr('style');
5295
5296 if (typeof(style) !== 'string') {
5297 return null;
5298 }
5299
5300 var attrs = style.split(';');
5301
5302 for (var i = 0, l = attrs.length; i < l; i = i + 1) {
5303 var attr = attrs[i].replace(/\s/g, '');
5304 var matches = attr.match(WIDTH);
5305
5306 if (matches !== null && matches.length >= 1) {
5307 return matches[1];
5308 }
5309 }
5310
5311 return null;
5312 }
5313
5314 return method;
5315 };
5316
5317 Select2.prototype._bindAdapters = function () {
5318 this.dataAdapter.bind(this, this.$container);
5319 this.selection.bind(this, this.$container);
5320
5321 this.dropdown.bind(this, this.$container);
5322 this.results.bind(this, this.$container);
5323 };
5324
5325 Select2.prototype._registerDomEvents = function () {
5326 var self = this;
5327
5328 this.$element.on('change.select2', function () {
5329 self.dataAdapter.current(function (data) {
5330 self.trigger('selection:update', {
5331 data: data
5332 });
5333 });
5334 });
5335
5336 this.$element.on('focus.select2', function (evt) {
5337 self.trigger('focus', evt);
5338 });
5339
5340 this._syncA = Utils.bind(this._syncAttributes, this);
5341 this._syncS = Utils.bind(this._syncSubtree, this);
5342
5343 if (this.$element[0].attachEvent) {
5344 this.$element[0].attachEvent('onpropertychange', this._syncA);
5345 }
5346
5347 var observer = window.MutationObserver ||
5348 window.WebKitMutationObserver ||
5349 window.MozMutationObserver
5350 ;
5351
5352 if (observer != null) {
5353 this._observer = new observer(function (mutations) {
5354 $.each(mutations, self._syncA);
5355 $.each(mutations, self._syncS);
5356 });
5357 this._observer.observe(this.$element[0], {
5358 attributes: true,
5359 childList: true,
5360 subtree: false
5361 });
5362 } else if (this.$element[0].addEventListener) {
5363 this.$element[0].addEventListener(
5364 'DOMAttrModified',
5365 self._syncA,
5366 false
5367 );
5368 this.$element[0].addEventListener(
5369 'DOMNodeInserted',
5370 self._syncS,
5371 false
5372 );
5373 this.$element[0].addEventListener(
5374 'DOMNodeRemoved',
5375 self._syncS,
5376 false
5377 );
5378 }
5379 };
5380
5381 Select2.prototype._registerDataEvents = function () {
5382 var self = this;
5383
5384 this.dataAdapter.on('*', function (name, params) {
5385 self.trigger(name, params);
5386 });
5387 };
5388
5389 Select2.prototype._registerSelectionEvents = function () {
5390 var self = this;
5391 var nonRelayEvents = ['toggle', 'focus'];
5392
5393 this.selection.on('toggle', function () {
5394 self.toggleDropdown();
5395 });
5396
5397 this.selection.on('focus', function (params) {
5398 self.focus(params);
5399 });
5400
5401 this.selection.on('*', function (name, params) {
5402 if ($.inArray(name, nonRelayEvents) !== -1) {
5403 return;
5404 }
5405
5406 self.trigger(name, params);
5407 });
5408 };
5409
5410 Select2.prototype._registerDropdownEvents = function () {
5411 var self = this;
5412
5413 this.dropdown.on('*', function (name, params) {
5414 self.trigger(name, params);
5415 });
5416 };
5417
5418 Select2.prototype._registerResultsEvents = function () {
5419 var self = this;
5420
5421 this.results.on('*', function (name, params) {
5422 self.trigger(name, params);
5423 });
5424 };
5425
5426 Select2.prototype._registerEvents = function () {
5427 var self = this;
5428
5429 this.on('open', function () {
5430 self.$container.addClass('select2-container--open');
5431 });
5432
5433 this.on('close', function () {
5434 self.$container.removeClass('select2-container--open');
5435 });
5436
5437 this.on('enable', function () {
5438 self.$container.removeClass('select2-container--disabled');
5439 });
5440
5441 this.on('disable', function () {
5442 self.$container.addClass('select2-container--disabled');
5443 });
5444
5445 this.on('blur', function () {
5446 self.$container.removeClass('select2-container--focus');
5447 });
5448
5449 this.on('query', function (params) {
5450 if (!self.isOpen()) {
5451 self.trigger('open', {});
5452 }
5453
5454 this.dataAdapter.query(params, function (data) {
5455 self.trigger('results:all', {
5456 data: data,
5457 query: params
5458 });
5459 });
5460 });
5461
5462 this.on('query:append', function (params) {
5463 this.dataAdapter.query(params, function (data) {
5464 self.trigger('results:append', {
5465 data: data,
5466 query: params
5467 });
5468 });
5469 });
5470
5471 this.on('open', function(){
5472 // Focus on the active element when opening dropdown.
5473 // Needs 1 ms delay because of other 1 ms setTimeouts when rendering.
5474 setTimeout(function(){
5475 self.focusOnActiveElement();
5476 }, 1);
5477 });
5478
5479 $(document).on('keydown', function (evt) {
5480 var key = evt.which;
5481 if (self.isOpen()) {
5482 if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) {
5483 self.close();
5484
5485 evt.preventDefault();
5486 } else if (key === KEYS.ENTER || key === KEYS.TAB) {
5487 self.trigger('results:select', {});
5488
5489 evt.preventDefault();
5490 } else if ((key === KEYS.SPACE && evt.ctrlKey)) {
5491 self.trigger('results:toggle', {});
5492
5493 evt.preventDefault();
5494 } else if (key === KEYS.UP) {
5495 self.trigger('results:previous', {});
5496
5497 evt.preventDefault();
5498 } else if (key === KEYS.DOWN) {
5499 self.trigger('results:next', {});
5500
5501 evt.preventDefault();
5502 }
5503
5504 var $searchField = self.$dropdown.find('.select2-search__field');
5505 if (! $searchField.length) {
5506 $searchField = self.$container.find('.select2-search__field');
5507 }
5508
5509 // Move the focus to the selected element on keyboard navigation.
5510 // Required for screen readers to work properly.
5511 if (key === KEYS.DOWN || key === KEYS.UP) {
5512 self.focusOnActiveElement();
5513 } else {
5514 // Focus on the search if user starts typing.
5515 $searchField.trigger( 'focus' );
5516 // Focus back to active selection when finished typing.
5517 // Small delay so typed character can be read by screen reader.
5518 setTimeout(function(){
5519 self.focusOnActiveElement();
5520 }, 1000);
5521 }
5522 } else if (self.hasFocus()) {
5523 if (key === KEYS.ENTER || key === KEYS.SPACE ||
5524 key === KEYS.DOWN) {
5525 self.open();
5526 evt.preventDefault();
5527 }
5528 }
5529 });
5530 };
5531
5532 Select2.prototype.focusOnActiveElement = function () {
5533 // Don't mess with the focus on touchscreens because it causes havoc with on-screen keyboards.
5534 if (this.isOpen() && ! Utils.isTouchscreen()) {
5535 this.$results.find('li.select2-results__option--highlighted').trigger( 'focus' );
5536 }
5537 };
5538
5539 Select2.prototype._syncAttributes = function () {
5540 this.options.set('disabled', this.$element.prop('disabled'));
5541
5542 if (this.options.get('disabled')) {
5543 if (this.isOpen()) {
5544 this.close();
5545 }
5546
5547 this.trigger('disable', {});
5548 } else {
5549 this.trigger('enable', {});
5550 }
5551 };
5552
5553 Select2.prototype._syncSubtree = function (evt, mutations) {
5554 var changed = false;
5555 var self = this;
5556
5557 // Ignore any mutation events raised for elements that aren't options or
5558 // optgroups. This handles the case when the select element is destroyed
5559 if (
5560 evt && evt.target && (
5561 evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP'
5562 )
5563 ) {
5564 return;
5565 }
5566
5567 if (!mutations) {
5568 // If mutation events aren't supported, then we can only assume that the
5569 // change affected the selections
5570 changed = true;
5571 } else if (mutations.addedNodes && mutations.addedNodes.length > 0) {
5572 for (var n = 0; n < mutations.addedNodes.length; n++) {
5573 var node = mutations.addedNodes[n];
5574
5575 if (node.selected) {
5576 changed = true;
5577 }
5578 }
5579 } else if (mutations.removedNodes && mutations.removedNodes.length > 0) {
5580 changed = true;
5581 }
5582
5583 // Only re-pull the data if we think there is a change
5584 if (changed) {
5585 this.dataAdapter.current(function (currentData) {
5586 self.trigger('selection:update', {
5587 data: currentData
5588 });
5589 });
5590 }
5591 };
5592
5593 /**
5594 * Override the trigger method to automatically trigger pre-events when
5595 * there are events that can be prevented.
5596 */
5597 Select2.prototype.trigger = function (name, args) {
5598 var actualTrigger = Select2.__super__.trigger;
5599 var preTriggerMap = {
5600 'open': 'opening',
5601 'close': 'closing',
5602 'select': 'selecting',
5603 'unselect': 'unselecting'
5604 };
5605
5606 if (args === undefined) {
5607 args = {};
5608 }
5609
5610 if (name in preTriggerMap) {
5611 var preTriggerName = preTriggerMap[name];
5612 var preTriggerArgs = {
5613 prevented: false,
5614 name: name,
5615 args: args
5616 };
5617
5618 actualTrigger.call(this, preTriggerName, preTriggerArgs);
5619
5620 if (preTriggerArgs.prevented) {
5621 args.prevented = true;
5622
5623 return;
5624 }
5625 }
5626
5627 actualTrigger.call(this, name, args);
5628 };
5629
5630 Select2.prototype.toggleDropdown = function () {
5631 if (this.options.get('disabled')) {
5632 return;
5633 }
5634
5635 if (this.isOpen()) {
5636 this.close();
5637 } else {
5638 this.open();
5639 }
5640 };
5641
5642 Select2.prototype.open = function () {
5643 if (this.isOpen()) {
5644 return;
5645 }
5646
5647 this.trigger('query', {});
5648 };
5649
5650 Select2.prototype.close = function () {
5651 if (!this.isOpen()) {
5652 return;
5653 }
5654
5655 this.trigger('close', {});
5656 };
5657
5658 Select2.prototype.isOpen = function () {
5659 return this.$container.hasClass('select2-container--open');
5660 };
5661
5662 Select2.prototype.hasFocus = function () {
5663 return this.$container.hasClass('select2-container--focus');
5664 };
5665
5666 Select2.prototype.focus = function (data) {
5667 // No need to re-trigger focus events if we are already focused
5668 if (this.hasFocus()) {
5669 return;
5670 }
5671
5672 this.$container.addClass('select2-container--focus');
5673 this.trigger('focus', {});
5674 };
5675
5676 Select2.prototype.enable = function (args) {
5677 if (this.options.get('debug') && window.console && console.warn) {
5678 console.warn(
5679 'Select2: The `select2("enable")` method has been deprecated and will' +
5680 ' be removed in later Select2 versions. Use $element.prop("disabled")' +
5681 ' instead.'
5682 );
5683 }
5684
5685 if (args == null || args.length === 0) {
5686 args = [true];
5687 }
5688
5689 var disabled = !args[0];
5690
5691 this.$element.prop('disabled', disabled);
5692 };
5693
5694 Select2.prototype.data = function () {
5695 if (this.options.get('debug') &&
5696 arguments.length > 0 && window.console && console.warn) {
5697 console.warn(
5698 'Select2: Data can no longer be set using `select2("data")`. You ' +
5699 'should consider setting the value instead using `$element.val()`.'
5700 );
5701 }
5702
5703 var data = [];
5704
5705 this.dataAdapter.current(function (currentData) {
5706 data = currentData;
5707 });
5708
5709 return data;
5710 };
5711
5712 Select2.prototype.val = function (args) {
5713 if (this.options.get('debug') && window.console && console.warn) {
5714 console.warn(
5715 'Select2: The `select2("val")` method has been deprecated and will be' +
5716 ' removed in later Select2 versions. Use $element.val() instead.'
5717 );
5718 }
5719
5720 if (args == null || args.length === 0) {
5721 return this.$element.val();
5722 }
5723
5724 var newVal = args[0];
5725
5726 if ( Array.isArray( newVal ) ) {
5727 newVal = $.map(newVal, function (obj) {
5728 return obj.toString();
5729 });
5730 }
5731
5732 this.$element.val(newVal).trigger('change');
5733 };
5734
5735 Select2.prototype.destroy = function () {
5736 this.$container.remove();
5737
5738 if (this.$element[0].detachEvent) {
5739 this.$element[0].detachEvent('onpropertychange', this._syncA);
5740 }
5741
5742 if (this._observer != null) {
5743 this._observer.disconnect();
5744 this._observer = null;
5745 } else if (this.$element[0].removeEventListener) {
5746 this.$element[0]
5747 .removeEventListener('DOMAttrModified', this._syncA, false);
5748 this.$element[0]
5749 .removeEventListener('DOMNodeInserted', this._syncS, false);
5750 this.$element[0]
5751 .removeEventListener('DOMNodeRemoved', this._syncS, false);
5752 }
5753
5754 this._syncA = null;
5755 this._syncS = null;
5756
5757 this.$element.off('.select2');
5758 this.$element.attr('tabindex', this.$element.data('old-tabindex'));
5759
5760 this.$element.removeClass('select2-hidden-accessible');
5761 this.$element.attr('aria-hidden', 'false');
5762 this.$element.removeData('select2');
5763
5764 this.dataAdapter.destroy();
5765 this.selection.destroy();
5766 this.dropdown.destroy();
5767 this.results.destroy();
5768
5769 this.dataAdapter = null;
5770 this.selection = null;
5771 this.dropdown = null;
5772 this.results = null;
5773 };
5774
5775 Select2.prototype.render = function () {
5776 var $container = $(
5777 '<span class="select2 select2-container">' +
5778 '<span class="selection"></span>' +
5779 '<span class="dropdown-wrapper" aria-hidden="true"></span>' +
5780 '</span>'
5781 );
5782
5783 $container.attr('dir', this.options.get('dir'));
5784
5785 this.$container = $container;
5786
5787 this.$container.addClass('select2-container--' + this.options.get('theme'));
5788
5789 $container.data('element', this.$element);
5790
5791 return $container;
5792 };
5793
5794 return Select2;
5795 });
5796
5797 S2.define('jquery-mousewheel',[
5798 'jquery'
5799 ], function ($) {
5800 // Used to shim jQuery.mousewheel for non-full builds.
5801 return $;
5802 });
5803
5804 S2.define('jquery.select2',[
5805 'jquery',
5806 'jquery-mousewheel',
5807
5808 './select2/core',
5809 './select2/defaults'
5810 ], function ($, _, Select2, Defaults) {
5811 if ($.fn.selectWoo == null) {
5812 // All methods that should return the element
5813 var thisMethods = ['open', 'close', 'destroy'];
5814
5815 $.fn.selectWoo = function (options) {
5816 options = options || {};
5817
5818 if (typeof options === 'object') {
5819 this.each(function () {
5820 var instanceOptions = $.extend(true, {}, options);
5821
5822 var instance = new Select2($(this), instanceOptions);
5823 });
5824
5825 return this;
5826 } else if (typeof options === 'string') {
5827 var ret;
5828 var args = Array.prototype.slice.call(arguments, 1);
5829
5830 this.each(function () {
5831 var instance = $(this).data('select2');
5832
5833 if (instance == null && window.console && console.error) {
5834 console.error(
5835 'The select2(\'' + options + '\') method was called on an ' +
5836 'element that is not using Select2.'
5837 );
5838 }
5839
5840 ret = instance[options].apply(instance, args);
5841 });
5842
5843 // Check if we should be returning `this`
5844 if ($.inArray(options, thisMethods) > -1) {
5845 return this;
5846 }
5847
5848 return ret;
5849 } else {
5850 throw new Error('Invalid arguments for Select2: ' + options);
5851 }
5852 };
5853 }
5854
5855 if ($.fn.select2 != null && $.fn.select2.defaults != null) {
5856 $.fn.selectWoo.defaults = $.fn.select2.defaults;
5857 }
5858
5859 if ($.fn.selectWoo.defaults == null) {
5860 $.fn.selectWoo.defaults = Defaults;
5861 }
5862
5863 // Also register selectWoo under select2 if select2 is not already present.
5864 $.fn.select2 = $.fn.select2 || $.fn.selectWoo;
5865
5866 return Select2;
5867 });
5868
5869 // Return the AMD loader configuration so it can be used outside of this file
5870 return {
5871 define: S2.define,
5872 require: S2.require
5873 };
5874 }());
5875
5876 // Autoload the jQuery bindings
5877 // We know that all of the modules exist above this, so we're safe
5878 var select2 = S2.require('jquery.select2');
5879
5880 // Hold the AMD module references on the jQuery function that was just loaded
5881 // This allows Select2 to use the internal loader outside of this file, such
5882 // as in the language files.
5883 jQuery.fn.select2.amd = S2;
5884 jQuery.fn.selectWoo.amd = S2;
5885
5886 // Return the Select2 instance for anyone who is importing it.
5887 return select2;
5888 }));
5889